diff --git a/.agents/skills/opcua-v20-migration/README.md b/.agents/skills/opcua-v20-migration/README.md index 0b45bd5c3f..347e8a05cc 100644 --- a/.agents/skills/opcua-v20-migration/README.md +++ b/.agents/skills/opcua-v20-migration/README.md @@ -19,7 +19,7 @@ Trigger this skill when a user asks for any of: ## When NOT to use - The user is starting a new OPC UA project from scratch — point them at - `Docs/README.md` and the `Applications/ConsoleReferenceClient` / + `docs/README.md` and the `samples/ConsoleReferenceClient` / `ConsoleReferenceServer` samples instead. - The user is migrating **within** 1.5.x (point or service-release upgrades). - The user is debugging server-side OPC UA functional behaviour — try the @@ -53,16 +53,16 @@ opcua-v20-migration/ This skill **distils** the following authoritative repo files. When you update the skill, also update them (and vice versa) so the views stay in sync: -- [`Docs/MigrationGuide.md`](../../../Docs/MigrationGuide.md) — the migration +- [`docs/MigrationGuide.md`](../../../docs/MigrationGuide.md) — the migration guide landing page (small; just an index across versions). -- [`Docs/migrate/2.0.x/README.md`](../../../Docs/migrate/2.0.x/README.md) — +- [`docs/migrate/2.0.x/README.md`](../../../docs/migrate/2.0.x/README.md) — the 2.0 version landing page + the same symptom → sub-doc table this skill uses to load only what's needed. -- [`Docs/migrate/2.0.x/`](../../../Docs/migrate/2.0.x/) — the 12 thematic +- [`docs/migrate/2.0.x/`](../../../docs/migrate/2.0.x/) — the 12 thematic sub-docs (telemetry, packages, source-generation, types, encoders, node-states, identity, certificates, configuration, sessions-subscriptions, alarms-model-change, timeprovider). -- [`Tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md`](../../../Tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md) +- [`tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md`](../../../tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md) — the package's own NuGet README. ## License diff --git a/.agents/skills/opcua-v20-migration/SKILL.md b/.agents/skills/opcua-v20-migration/SKILL.md index a98e8a7ee4..3418d30c26 100644 --- a/.agents/skills/opcua-v20-migration/SKILL.md +++ b/.agents/skills/opcua-v20-migration/SKILL.md @@ -26,10 +26,10 @@ metadata: version: "1.0.0" upstream: https://github.com/OPCFoundation/UA-.NETStandard canonical-docs: - - Docs/MigrationGuide.md # landing page (small) - - Docs/migrate/2.0.x/README.md # 2.0 version landing + sub-doc index - - Docs/migrate/2.0.x/ # 12 thematic sub-docs (load only what you need) - - Tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md + - docs/MigrationGuide.md # landing page (small) + - docs/migrate/2.0.x/README.md # 2.0 version landing + sub-doc index + - docs/migrate/2.0.x/ # 12 thematic sub-docs (load only what you need) + - tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md --- # OPC UA .NET Standard 1.5.378 → 2.0 Migration @@ -42,28 +42,28 @@ Upgrade existing OPC UA .NET Standard consumer projects from 1.5.378 **Context-efficiency rule.** The full migration content is no longer in a single ~150 KB document; it is split across 12 thematic sub-docs under -[`Docs/migrate/2.0.x/`](../../../Docs/migrate/2.0.x/README.md). -**Do not load `Docs/MigrationGuide.md` into context** — it is now a thin +[`docs/migrate/2.0.x/`](../../../docs/migrate/2.0.x/README.md). +**Do not load `docs/MigrationGuide.md` into context** — it is now a thin landing page. Instead, match the user's symptom to a row below and load the **single** sub-doc named in that row. | When the user hits… | Load only | | --- | --- | -| `CS0029` / `CS1503` / `CS0266` on `NodeId`, `Variant`, `DataValue`, `ExtensionObject`, `QualifiedName`, `LocalizedText`, `ArrayOf` / `MatrixOf`, `ByteString`, `StatusCode`, `XmlElement`, `EnumValue`, or `[Obsolete]` on built-in type APIs (analyzer `UA0001`–`UA0020`) | [`Docs/migrate/2.0.x/types.md`](../../../Docs/migrate/2.0.x/types.md) | -| `Utils.LogX`, `Utils.Trace`, static logger helpers (`Utils.SetLogger` / `Utils.SetLogLevel` removed), `ITelemetryContext` constructor parameter shape per type, OLD-vs-NEW logger snippets, fluent `AddOpcUa().AddLogging().AddMetrics()` registration, breaking-changes inventory across Core / Configuration / Client / Server / PubSub / Certificate / Transport, migration utilities (`DefaultTelemetry`, `Telemetry.NullLogger`, `Utils.Fallback.Logger`) | [`Docs/migrate/2.0.x/telemetry.md`](../../../Docs/migrate/2.0.x/telemetry.md) | -| Package upgrades, TFM changes, `Newtonsoft.Json` removal from `Opc.Ua.Core`, new published packages | [`Docs/migrate/2.0.x/packages.md`](../../../Docs/migrate/2.0.x/packages.md) | -| Source-generated `*Collection` shims, NodeManager generator, default of `bool` properties, project structure | [`Docs/migrate/2.0.x/source-generation.md`](../../../Docs/migrate/2.0.x/source-generation.md) | -| `IEncodeableFactoryBuilder`, `IType`, JSON / XML / binary encoders, `EncodeableFactory.GlobalFactory`, `IJsonEncodeable`, `ComplexTypes` namespace move | [`Docs/migrate/2.0.x/encoders.md`](../../../Docs/migrate/2.0.x/encoders.md) | -| Custom NodeManagers, `NodeState` clone / read / write helpers, `Clone` → `CreateCopy`, `OnAfterCreate(CancellationToken)`, `INodeManager3`, `INodeCache.InvalidateNode`, generics on `BaseVariableState` / `BaseVariableTypeState` | [`Docs/migrate/2.0.x/node-states.md`](../../../Docs/migrate/2.0.x/node-states.md) | -| `IUserIdentityTokenHandler`, `IClientIdentityProvider`, `IUserTokenAuthenticator`, `IAccessTokenProvider`, `ITokenIssuer`, caller-supplied secrets, secret store | [`Docs/migrate/2.0.x/identity.md`](../../../Docs/migrate/2.0.x/identity.md) | -| `CertificateValidator` rename (`UA0021`), ref-counted `Certificate` wrapper, `CertificateManager`, `ICertificateProvider`, obsoleted `X509Certificate2` direct-exposure APIs | [`Docs/migrate/2.0.x/certificates.md`](../../../Docs/migrate/2.0.x/certificates.md) | -| `ApplicationConfiguration` changes, Data-Contract serializer removal, `ParseExtension` / `UpdateExtension` signature, session / browser state persistence | [`Docs/migrate/2.0.x/configuration.md`](../../../Docs/migrate/2.0.x/configuration.md) | -| `Session` → `ManagedSession`, V2 subscription engine, GDS-client `Task` → `ValueTask` modernisation, removed obsolete GDS APIs, durable subscriptions, PubSub, reverse-connect | [`Docs/migrate/2.0.x/sessions-subscriptions.md`](../../../Docs/migrate/2.0.x/sessions-subscriptions.md) | -| `AlarmConditionState` state-transition behaviour, auto-emitted `GeneralModelChangeEvent`, `ModelChangeAggregator` | [`Docs/migrate/2.0.x/alarms-model-change.md`](../../../Docs/migrate/2.0.x/alarms-model-change.md) | -| `DateTime.UtcNow`, `Timer`, deterministic-time tests, `System.TimeProvider` adoption | [`Docs/migrate/2.0.x/timeprovider.md`](../../../Docs/migrate/2.0.x/timeprovider.md) | +| `CS0029` / `CS1503` / `CS0266` on `NodeId`, `Variant`, `DataValue`, `ExtensionObject`, `QualifiedName`, `LocalizedText`, `ArrayOf` / `MatrixOf`, `ByteString`, `StatusCode`, `XmlElement`, `EnumValue`, or `[Obsolete]` on built-in type APIs (analyzer `UA0001`–`UA0020`) | [`docs/migrate/2.0.x/types.md`](../../../docs/migrate/2.0.x/types.md) | +| `Utils.LogX`, `Utils.Trace`, static logger helpers (`Utils.SetLogger` / `Utils.SetLogLevel` removed), `ITelemetryContext` constructor parameter shape per type, OLD-vs-NEW logger snippets, fluent `AddOpcUa().AddLogging().AddMetrics()` registration, breaking-changes inventory across Core / Configuration / Client / Server / PubSub / Certificate / Transport, migration utilities (`DefaultTelemetry`, `Telemetry.NullLogger`, `Utils.Fallback.Logger`) | [`docs/migrate/2.0.x/telemetry.md`](../../../docs/migrate/2.0.x/telemetry.md) | +| Package upgrades, TFM changes, `Newtonsoft.Json` removal from `Opc.Ua.Core`, new published packages | [`docs/migrate/2.0.x/packages.md`](../../../docs/migrate/2.0.x/packages.md) | +| Source-generated `*Collection` shims, NodeManager generator, default of `bool` properties, project structure | [`docs/migrate/2.0.x/source-generation.md`](../../../docs/migrate/2.0.x/source-generation.md) | +| `IEncodeableFactoryBuilder`, `IType`, JSON / XML / binary encoders, `EncodeableFactory.GlobalFactory`, `IJsonEncodeable`, `ComplexTypes` namespace move | [`docs/migrate/2.0.x/encoders.md`](../../../docs/migrate/2.0.x/encoders.md) | +| Custom NodeManagers, `NodeState` clone / read / write helpers, `Clone` → `CreateCopy`, `OnAfterCreate(CancellationToken)`, `INodeManager3`, `INodeCache.InvalidateNode`, generics on `BaseVariableState` / `BaseVariableTypeState` | [`docs/migrate/2.0.x/node-states.md`](../../../docs/migrate/2.0.x/node-states.md) | +| `IUserIdentityTokenHandler`, `IClientIdentityProvider`, `IUserTokenAuthenticator`, `IAccessTokenProvider`, `ITokenIssuer`, caller-supplied secrets, secret store | [`docs/migrate/2.0.x/identity.md`](../../../docs/migrate/2.0.x/identity.md) | +| `CertificateValidator` rename (`UA0021`), ref-counted `Certificate` wrapper, `CertificateManager`, `ICertificateProvider`, obsoleted `X509Certificate2` direct-exposure APIs | [`docs/migrate/2.0.x/certificates.md`](../../../docs/migrate/2.0.x/certificates.md) | +| `ApplicationConfiguration` changes, Data-Contract serializer removal, `ParseExtension` / `UpdateExtension` signature, session / browser state persistence | [`docs/migrate/2.0.x/configuration.md`](../../../docs/migrate/2.0.x/configuration.md) | +| `Session` → `ManagedSession`, V2 subscription engine, GDS-client `Task` → `ValueTask` modernisation, removed obsolete GDS APIs, durable subscriptions, PubSub, reverse-connect | [`docs/migrate/2.0.x/sessions-subscriptions.md`](../../../docs/migrate/2.0.x/sessions-subscriptions.md) | +| `AlarmConditionState` state-transition behaviour, auto-emitted `GeneralModelChangeEvent`, `ModelChangeAggregator` | [`docs/migrate/2.0.x/alarms-model-change.md`](../../../docs/migrate/2.0.x/alarms-model-change.md) | +| `DateTime.UtcNow`, `Timer`, deterministic-time tests, `System.TimeProvider` adoption | [`docs/migrate/2.0.x/timeprovider.md`](../../../docs/migrate/2.0.x/timeprovider.md) | If the user's symptom does not obviously map to one row, read -[`Docs/migrate/2.0.x/README.md`](../../../Docs/migrate/2.0.x/README.md) (small — +[`docs/migrate/2.0.x/README.md`](../../../docs/migrate/2.0.x/README.md) (small — the same table plus a short intro) and pick from there. Avoid loading multiple sub-docs unless the symptom genuinely spans two areas (for example, `node-states.md` *and* `types.md` when a NodeManager runs into @@ -153,7 +153,7 @@ dotnet format analyzers .sln \ migration window, then peel each entry back as you fix the rule. - **The legacy `Quickstarts.Servers` meta-package does not exist on 2.0.** If your project depends on it, switch to a `` to - `Applications/Quickstarts.Servers` or to an equivalent project of your own. + `samples/Quickstarts.Servers` or to an equivalent project of your own. --- @@ -287,7 +287,7 @@ MigrationAnalyzer package is removed. added inline to each csproj. - The `OPCFoundation.NetStandard.Opc.Ua.Quickstarts.Servers` meta-package is not published on 2.0 — consumers must switch to a `` to - `Applications/Quickstarts.Servers` or an equivalent first-party project. + `samples/Quickstarts.Servers` or an equivalent first-party project. - Public APIs returning a `Collection` will hit `CS0050` because the generator's shim is `internal` by design — migrate the public surface to `List` / `ArrayOf` first. @@ -336,7 +336,7 @@ material. Load them on demand via your agent runtime's ### Canonical upstream docs -- [`Docs/MigrationGuide.md`](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md) — the human-facing migration guide landing page (~3 KB; intentionally small, just an index across versions). -- [`Docs/migrate/2.0.x/README.md`](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/migrate/2.0.x/README.md) — the 2.0 migration index + the same symptom → sub-doc table this skill uses. -- [`Docs/migrate/2.0.x/`](https://github.com/OPCFoundation/UA-.NETStandard/tree/master/Docs/migrate/2.0.x) — the 12 thematic sub-docs (telemetry, packages, source-generation, types, encoders, node-states, identity, certificates, configuration, sessions-subscriptions, alarms-model-change, timeprovider). -- [`Tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md`](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md) — the package's own README, shipped inside the NuGet. +- [`docs/MigrationGuide.md`](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md) — the human-facing migration guide landing page (~3 KB; intentionally small, just an index across versions). +- [`docs/migrate/2.0.x/README.md`](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/migrate/2.0.x/README.md) — the 2.0 migration index + the same symptom → sub-doc table this skill uses. +- [`docs/migrate/2.0.x/`](https://github.com/OPCFoundation/UA-.NETStandard/tree/master/docs/migrate/2.0.x) — the 12 thematic sub-docs (telemetry, packages, source-generation, types, encoders, node-states, identity, certificates, configuration, sessions-subscriptions, alarms-model-change, timeprovider). +- [`tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md`](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md) — the package's own README, shipped inside the NuGet. diff --git a/.agents/skills/opcua-v20-migration/references/analyzer-rules.md b/.agents/skills/opcua-v20-migration/references/analyzer-rules.md index 16bf4792a5..66424a7de1 100644 --- a/.agents/skills/opcua-v20-migration/references/analyzer-rules.md +++ b/.agents/skills/opcua-v20-migration/references/analyzer-rules.md @@ -365,7 +365,7 @@ config.CertificateManager.Options.AcceptError = (cert, error) => // or implement ICertificateValidatorEx.ValidateAsync for full control. ``` -See [`Docs/migrate/2.0.x/certificates.md`](../../../Docs/migrate/2.0.x/certificates.md) +See [`docs/migrate/2.0.x/certificates.md`](../../../../docs/migrate/2.0.x/certificates.md) §"Certificate Manager and segregated interfaces" for the structural model in full. --- diff --git a/.agents/skills/opcua-v20-migration/references/known-gaps.md b/.agents/skills/opcua-v20-migration/references/known-gaps.md index 3390455efb..5c8883a151 100644 --- a/.agents/skills/opcua-v20-migration/references/known-gaps.md +++ b/.agents/skills/opcua-v20-migration/references/known-gaps.md @@ -63,7 +63,7 @@ happen on plain 1.5.378 too. not published on 2.0. **Mitigation:** consumers must switch to a `` to -`Applications/Quickstarts.Servers` in this repo, or to an equivalent +`samples/Quickstarts.Servers` in this repo, or to an equivalent first-party project of their own. All 2.0 packages are published to the OPC Foundation Azure Artifacts preview feed (`https://opcfoundation.visualstudio.com/opcua-netstandard/_packaging/opcua-preview/nuget/v3/index.json`) diff --git a/.agents/skills/opcua-v20-migration/references/migration-patterns.md b/.agents/skills/opcua-v20-migration/references/migration-patterns.md index 2174854953..018cc13c61 100644 --- a/.agents/skills/opcua-v20-migration/references/migration-patterns.md +++ b/.agents/skills/opcua-v20-migration/references/migration-patterns.md @@ -698,7 +698,7 @@ sc = sc.WithAggregateBits(agg); 4. **Build incrementally.** Fix one priority layer at a time and rebuild to track progress. 5. **Refer to canonical docs.** The - [`Docs/migrate/2.0.x/`](../../../Docs/migrate/2.0.x/) sub-docs are the + [`docs/migrate/2.0.x/`](../../../../docs/migrate/2.0.x/) sub-docs are the upstream source of truth — sync this skill against them on every PR. Use the symptom → sub-doc table in `SKILL.md` to load only the relevant one. diff --git a/.agents/skills/opcua-v20-migration/references/package-install.md b/.agents/skills/opcua-v20-migration/references/package-install.md index e55f0164d3..c4120799fd 100644 --- a/.agents/skills/opcua-v20-migration/references/package-install.md +++ b/.agents/skills/opcua-v20-migration/references/package-install.md @@ -75,7 +75,7 @@ Common packages and their 2.0 paths: | `OPCFoundation.NetStandard.Opc.Ua.Server` | Unchanged name. | | `OPCFoundation.NetStandard.Opc.Ua.Bindings.Https` | Unchanged name. | | `OPCFoundation.NetStandard.Opc.Ua.Gds.Common` | **New in 2.0** — intermediate project with shared GDS types. If you reference `Gds.Client.Common` or `Gds.Server.Common`, they now depend on it transitively (no action needed in most cases). | -| `OPCFoundation.NetStandard.Opc.Ua.Quickstarts.Servers` | **Not published on 2.0** — switch to a `` to `Applications/Quickstarts.Servers` or equivalent. | +| `OPCFoundation.NetStandard.Opc.Ua.Quickstarts.Servers` | **Not published on 2.0** — switch to a `` to `samples/Quickstarts.Servers` or equivalent. | If your solution already uses **Central Package Management** (`Directory.Packages.props`), update there instead: diff --git a/.agents/skills/opcua-v20-migration/references/runtime-shim.md b/.agents/skills/opcua-v20-migration/references/runtime-shim.md index 29362e84c7..55e85f1d12 100644 --- a/.agents/skills/opcua-v20-migration/references/runtime-shim.md +++ b/.agents/skills/opcua-v20-migration/references/runtime-shim.md @@ -44,7 +44,7 @@ so call sites bind: - Sync + APM wrappers for the `GlobalDiscoveryServerClient` / `LocalDiscoveryServerClient` / `ServerPushConfigurationClient` (UA0015) - `GlobalDiscoverySampleServer` 1.5.378-shape ctor (in-tree at - `Libraries/Opc.Ua.Gds.Server.Common/GlobalDiscoverySampleServer.cs`) — the 5-arg + `src/Opc.Ua.Gds.Server.Common/GlobalDiscoverySampleServer.cs`) — the 5-arg variant without `ITelemetryContext` ### Conversion helpers diff --git a/.agents/skills/opcua-v20-migration/references/source-generator.md b/.agents/skills/opcua-v20-migration/references/source-generator.md index 1e30230cb8..d51a375407 100644 --- a/.agents/skills/opcua-v20-migration/references/source-generator.md +++ b/.agents/skills/opcua-v20-migration/references/source-generator.md @@ -92,7 +92,7 @@ reference (`global::Acme.WaterPump`, `global::Vendor.Devices.BoilerState`, etc). Zero matches or > 1 matches → the generator emits **no** shim and reports `MIG01` instead, with the help link pointing at this skill's [`analyzer-rules.md`](analyzer-rules.md#mig01--generator-cant-resolve-element-type-for-foocollection) -and [`Docs/migrate/2.0.x/source-generation.md`](../../../Docs/migrate/2.0.x/source-generation.md). +and [`docs/migrate/2.0.x/source-generation.md`](../../../../docs/migrate/2.0.x/source-generation.md). ## Generated file shape diff --git a/.azurepipelines/generate-slnx.ps1 b/.azurepipelines/generate-slnx.ps1 index 61f2821598..99316465e2 100644 --- a/.azurepipelines/generate-slnx.ps1 +++ b/.azurepipelines/generate-slnx.ps1 @@ -6,8 +6,8 @@ .DESCRIPTION Replaces the static `UA Core Library.slnx`. The single source of truth for the project graph is `UA.slnx`; this script reads it, - drops every folder whose name starts with `/Tests/` or - `/Fuzzing/` (and every project inside those folders), and writes + drops every folder whose name starts with `/tests/` or + `/fuzzing/` (and every project inside those folders), and writes the result. Whether each remaining project actually produces a NuGet on @@ -30,7 +30,7 @@ .PARAMETER ExcludeFolderPrefixes Folder-name prefixes (as they appear inside the source .slnx) to - drop entirely. Default: `/Tests/`, `/Fuzzing/`, `/Solution Items/`. + drop entirely. Default: `/tests/`, `/fuzzing/`, `/Solution Items/`. Folder matching is whole-name based on the `Name=` attribute, so `/Solution Items/` and any `/Solution Items/...` sub-folder matches the prefix. @@ -43,7 +43,7 @@ param( [string]$OutputPath, [string]$SourceSolution, - [string[]]$ExcludeFolderPrefixes = @('/Tests/', '/Fuzzing/', '/Solution Items/') + [string[]]$ExcludeFolderPrefixes = @('/tests/', '/fuzzing/', '/Solution Items/') ) $ErrorActionPreference = 'Stop' diff --git a/.azurepipelines/preview.yml b/.azurepipelines/preview.yml index 104f8d1c6b..789ea451bd 100644 --- a/.azurepipelines/preview.yml +++ b/.azurepipelines/preview.yml @@ -101,10 +101,10 @@ jobs: displayName: 'List of assemblies to sign' inputs: script: | - dir /b /s Stack\Opc.Ua*.dll > .\list.txt - dir /b /s Tools\Opc.Ua*.dll >> .\list.txt - dir /b /s Libraries\Opc.Ua*.dll >> .\list.txt - dir /b /s Applications\McpServer\bin\Opc.Ua*.dll >> .\list.txt + dir /b /s src\Opc.Ua*.dll > .\list.txt + dir /b /s tools\Opc.Ua*.dll >> .\list.txt + dir /b /s src\Opc.Ua*.dll >> .\list.txt + dir /b /s tools\Opc.Ua.Mcp\bin\Opc.Ua*.dll >> .\list.txt dir /b /s .azurepipelines\*.* >> .\list.txt type .\list.txt - task: CmdLine@2 @@ -127,7 +127,7 @@ jobs: continueOnError: true inputs: command: 'pack' - # Scoped to nuget/ — the MigrationAnalyzer nuspec at Tools/Opc.Ua.MigrationAnalyzer/ + # Scoped to nuget/ — the MigrationAnalyzer nuspec at tools/Opc.Ua.MigrationAnalyzer/ # uses MSBuild $(...) substitutions ($(shimBin), $(repoRoot), $(analyzerDll)) # that only `dotnet pack`'s _SetMigrationAnalyzerNuspecProperties target can # resolve. Standalone `nuget.exe pack` leaves them literal and crashes with diff --git a/.azurepipelines/sample-ha-longhaul.yml b/.azurepipelines/sample-ha-longhaul.yml index 4d990d94ad..b23e26b1b5 100644 --- a/.azurepipelines/sample-ha-longhaul.yml +++ b/.azurepipelines/sample-ha-longhaul.yml @@ -27,7 +27,7 @@ parameters: variables: configuration: 'Release' targetFramework: 'net10.0' - testProject: 'Tests/Opc.Ua.Redundancy.Samples.Tests/Opc.Ua.Redundancy.Samples.Tests.csproj' + testProject: 'tests/Opc.Ua.Redundancy.Samples.Tests/Opc.Ua.Redundancy.Samples.Tests.csproj' pool: vmImage: 'ubuntu-24.04' diff --git a/.azurepipelines/signlistDebug.txt b/.azurepipelines/signlistDebug.txt index 840c7255c0..a46dae4851 100644 --- a/.azurepipelines/signlistDebug.txt +++ b/.azurepipelines/signlistDebug.txt @@ -1,118 +1,118 @@ -Tools\Opc.Ua.SourceGeneration.Core\bin\Debug\netstandard2.0\Opc.Ua.SourceGeneration.Core.dll -Stack\Opc.Ua.Types\bin\Debug\netstandard2.0\Opc.Ua.Types.dll -Stack\Opc.Ua.Types\bin\Debug\netstandard2.1\Opc.Ua.Types.dll -Stack\Opc.Ua.Types\bin\Debug\net472\Opc.Ua.Types.dll -Stack\Opc.Ua.Types\bin\Debug\net48\Opc.Ua.Types.dll -Stack\Opc.Ua.Types\bin\Debug\net8.0\Opc.Ua.Types.dll -Stack\Opc.Ua.Types\bin\Debug\net9.0\Opc.Ua.Types.dll -Stack\Opc.Ua.Types\bin\Debug\net10.0\Opc.Ua.Types.dll -Stack\Opc.Ua.Core.Types\bin\Debug\netstandard2.1\Opc.Ua.Core.Types.dll -Stack\Opc.Ua.Core.Types\bin\Debug\net472\Opc.Ua.Core.Types.dll -Stack\Opc.Ua.Core.Types\bin\Debug\net48\Opc.Ua.Core.Types.dll -Stack\Opc.Ua.Core.Types\bin\Debug\net8.0\Opc.Ua.Core.Types.dll -Stack\Opc.Ua.Core.Types\bin\Debug\net9.0\Opc.Ua.Core.Types.dll -Stack\Opc.Ua.Core.Types\bin\Debug\net10.0\Opc.Ua.Core.Types.dll -Stack\Opc.Ua.Core\bin\Debug\netstandard2.1\Opc.Ua.Core.dll -Stack\Opc.Ua.Core\bin\Debug\net472\Opc.Ua.Core.dll -Stack\Opc.Ua.Core\bin\Debug\net48\Opc.Ua.Core.dll -Stack\Opc.Ua.Core\bin\Debug\net8.0\Opc.Ua.Core.dll -Stack\Opc.Ua.Core\bin\Debug\net9.0\Opc.Ua.Core.dll -Stack\Opc.Ua.Core\bin\Debug\net10.0\Opc.Ua.Core.dll -Stack\Opc.Ua.Bindings.Https\bin\Debug\netstandard2.1\Opc.Ua.Bindings.Https.dll -Stack\Opc.Ua.Bindings.Https\bin\Debug\net472\Opc.Ua.Bindings.Https.dll -Stack\Opc.Ua.Bindings.Https\bin\Debug\net48\Opc.Ua.Bindings.Https.dll -Stack\Opc.Ua.Bindings.Https\bin\Debug\net8.0\Opc.Ua.Bindings.Https.dll -Stack\Opc.Ua.Bindings.Https\bin\Debug\net9.0\Opc.Ua.Bindings.Https.dll -Stack\Opc.Ua.Bindings.Https\bin\Debug\net10.0\Opc.Ua.Bindings.Https.dll -Libraries\Opc.Ua.Server\bin\Debug\netstandard2.1\Opc.Ua.Server.dll -Libraries\Opc.Ua.Server\bin\Debug\net472\Opc.Ua.Server.dll -Libraries\Opc.Ua.Server\bin\Debug\net48\Opc.Ua.Server.dll -Libraries\Opc.Ua.Server\bin\Debug\net8.0\Opc.Ua.Server.dll -Libraries\Opc.Ua.Server\bin\Debug\net9.0\Opc.Ua.Server.dll -Libraries\Opc.Ua.Server\bin\Debug\net10.0\Opc.Ua.Server.dll -Libraries\Opc.Ua.Client\bin\Debug\netstandard2.1\Opc.Ua.Client.dll -Libraries\Opc.Ua.Client\bin\Debug\net472\Opc.Ua.Client.dll -Libraries\Opc.Ua.Client\bin\Debug\net48\Opc.Ua.Client.dll -Libraries\Opc.Ua.Client\bin\Debug\net8.0\Opc.Ua.Client.dll -Libraries\Opc.Ua.Client\bin\Debug\net9.0\Opc.Ua.Client.dll -Libraries\Opc.Ua.Client\bin\Debug\net10.0\Opc.Ua.Client.dll -Libraries\Opc.Ua.Client.ComplexTypes\bin\Debug\netstandard2.1\Opc.Ua.Client.ComplexTypes.dll -Libraries\Opc.Ua.Client.ComplexTypes\bin\Debug\net472\Opc.Ua.Client.ComplexTypes.dll -Libraries\Opc.Ua.Client.ComplexTypes\bin\Debug\net48\Opc.Ua.Client.ComplexTypes.dll -Libraries\Opc.Ua.Client.ComplexTypes\bin\Debug\net8.0\Opc.Ua.Client.ComplexTypes.dll -Libraries\Opc.Ua.Client.ComplexTypes\bin\Debug\net9.0\Opc.Ua.Client.ComplexTypes.dll -Libraries\Opc.Ua.Client.ComplexTypes\bin\Debug\net10.0\Opc.Ua.Client.ComplexTypes.dll -Libraries\Opc.Ua.Configuration\bin\Debug\netstandard2.1\Opc.Ua.Configuration.dll -Libraries\Opc.Ua.Configuration\bin\Debug\net472\Opc.Ua.Configuration.dll -Libraries\Opc.Ua.Configuration\bin\Debug\net48\Opc.Ua.Configuration.dll -Libraries\Opc.Ua.Configuration\bin\Debug\net8.0\Opc.Ua.Configuration.dll -Libraries\Opc.Ua.Configuration\bin\Debug\net9.0\Opc.Ua.Configuration.dll -Libraries\Opc.Ua.Configuration\bin\Debug\net10.0\Opc.Ua.Configuration.dll -Libraries\Opc.Ua.Gds.Client.Common\bin\Debug\netstandard2.1\Opc.Ua.Gds.Client.Common.dll -Libraries\Opc.Ua.Gds.Client.Common\bin\Debug\net472\Opc.Ua.Gds.Client.Common.dll -Libraries\Opc.Ua.Gds.Client.Common\bin\Debug\net48\Opc.Ua.Gds.Client.Common.dll -Libraries\Opc.Ua.Gds.Client.Common\bin\Debug\net8.0\Opc.Ua.Gds.Client.Common.dll -Libraries\Opc.Ua.Gds.Client.Common\bin\Debug\net9.0\Opc.Ua.Gds.Client.Common.dll -Libraries\Opc.Ua.Gds.Client.Common\bin\Debug\net10.0\Opc.Ua.Gds.Client.Common.dll -Libraries\Opc.Ua.Gds.Server.Common\bin\Debug\netstandard2.1\Opc.Ua.Gds.Server.Common.dll -Libraries\Opc.Ua.Gds.Server.Common\bin\Debug\net472\Opc.Ua.Gds.Server.Common.dll -Libraries\Opc.Ua.Gds.Server.Common\bin\Debug\net48\Opc.Ua.Gds.Server.Common.dll -Libraries\Opc.Ua.Gds.Server.Common\bin\Debug\net8.0\Opc.Ua.Gds.Server.Common.dll -Libraries\Opc.Ua.Gds.Server.Common\bin\Debug\net9.0\Opc.Ua.Gds.Server.Common.dll -Libraries\Opc.Ua.Gds.Server.Common\bin\Debug\net10.0\Opc.Ua.Gds.Server.Common.dll -Libraries\Opc.Ua.Gds.Common\bin\Debug\netstandard2.1\Opc.Ua.Gds.Common.dll -Libraries\Opc.Ua.Gds.Common\bin\Debug\net472\Opc.Ua.Gds.Common.dll -Libraries\Opc.Ua.Gds.Common\bin\Debug\net48\Opc.Ua.Gds.Common.dll -Libraries\Opc.Ua.Gds.Common\bin\Debug\net8.0\Opc.Ua.Gds.Common.dll -Libraries\Opc.Ua.Gds.Common\bin\Debug\net9.0\Opc.Ua.Gds.Common.dll -Libraries\Opc.Ua.Gds.Common\bin\Debug\net10.0\Opc.Ua.Gds.Common.dll -Stack\Opc.Ua.Security.Certificates\bin\Debug\netstandard2.1\Opc.Ua.Security.Certificates.dll -Stack\Opc.Ua.Security.Certificates\bin\Debug\net472\Opc.Ua.Security.Certificates.dll -Stack\Opc.Ua.Security.Certificates\bin\Debug\net48\Opc.Ua.Security.Certificates.dll -Stack\Opc.Ua.Security.Certificates\bin\Debug\net8.0\Opc.Ua.Security.Certificates.dll -Stack\Opc.Ua.Security.Certificates\bin\Debug\net9.0\Opc.Ua.Security.Certificates.dll -Stack\Opc.Ua.Security.Certificates\bin\Debug\net10.0\Opc.Ua.Security.Certificates.dll -Libraries\Opc.Ua.PubSub\bin\Debug\netstandard2.1\Opc.Ua.PubSub.dll -Libraries\Opc.Ua.PubSub\bin\Debug\net472\Opc.Ua.PubSub.dll -Libraries\Opc.Ua.PubSub\bin\Debug\net48\Opc.Ua.PubSub.dll -Libraries\Opc.Ua.PubSub\bin\Debug\net8.0\Opc.Ua.PubSub.dll -Libraries\Opc.Ua.PubSub\bin\Debug\net9.0\Opc.Ua.PubSub.dll -Libraries\Opc.Ua.PubSub\bin\Debug\net10.0\Opc.Ua.PubSub.dll -Libraries\Opc.Ua.WotCon\bin\Debug\netstandard2.1\Opc.Ua.WotCon.dll -Libraries\Opc.Ua.WotCon\bin\Debug\net472\Opc.Ua.WotCon.dll -Libraries\Opc.Ua.WotCon\bin\Debug\net48\Opc.Ua.WotCon.dll -Libraries\Opc.Ua.WotCon\bin\Debug\net8.0\Opc.Ua.WotCon.dll -Libraries\Opc.Ua.WotCon\bin\Debug\net9.0\Opc.Ua.WotCon.dll -Libraries\Opc.Ua.WotCon\bin\Debug\net10.0\Opc.Ua.WotCon.dll -Libraries\Opc.Ua.WotCon.Client\bin\Debug\netstandard2.1\Opc.Ua.WotCon.Client.dll -Libraries\Opc.Ua.WotCon.Client\bin\Debug\net472\Opc.Ua.WotCon.Client.dll -Libraries\Opc.Ua.WotCon.Client\bin\Debug\net48\Opc.Ua.WotCon.Client.dll -Libraries\Opc.Ua.WotCon.Client\bin\Debug\net8.0\Opc.Ua.WotCon.Client.dll -Libraries\Opc.Ua.WotCon.Client\bin\Debug\net9.0\Opc.Ua.WotCon.Client.dll -Libraries\Opc.Ua.WotCon.Client\bin\Debug\net10.0\Opc.Ua.WotCon.Client.dll -Libraries\Opc.Ua.WotCon.Server\bin\Debug\netstandard2.1\Opc.Ua.WotCon.Server.dll -Libraries\Opc.Ua.WotCon.Server\bin\Debug\net472\Opc.Ua.WotCon.Server.dll -Libraries\Opc.Ua.WotCon.Server\bin\Debug\net48\Opc.Ua.WotCon.Server.dll -Libraries\Opc.Ua.WotCon.Server\bin\Debug\net8.0\Opc.Ua.WotCon.Server.dll -Libraries\Opc.Ua.WotCon.Server\bin\Debug\net9.0\Opc.Ua.WotCon.Server.dll -Libraries\Opc.Ua.WotCon.Server\bin\Debug\net10.0\Opc.Ua.WotCon.Server.dll -Libraries\Opc.Ua.Di\bin\Debug\netstandard2.1\Opc.Ua.Di.dll -Libraries\Opc.Ua.Di\bin\Debug\net472\Opc.Ua.Di.dll -Libraries\Opc.Ua.Di\bin\Debug\net48\Opc.Ua.Di.dll -Libraries\Opc.Ua.Di\bin\Debug\net8.0\Opc.Ua.Di.dll -Libraries\Opc.Ua.Di\bin\Debug\net9.0\Opc.Ua.Di.dll -Libraries\Opc.Ua.Di\bin\Debug\net10.0\Opc.Ua.Di.dll -Libraries\Opc.Ua.Di.Client\bin\Debug\netstandard2.1\Opc.Ua.Di.Client.dll -Libraries\Opc.Ua.Di.Client\bin\Debug\net472\Opc.Ua.Di.Client.dll -Libraries\Opc.Ua.Di.Client\bin\Debug\net48\Opc.Ua.Di.Client.dll -Libraries\Opc.Ua.Di.Client\bin\Debug\net8.0\Opc.Ua.Di.Client.dll -Libraries\Opc.Ua.Di.Client\bin\Debug\net9.0\Opc.Ua.Di.Client.dll -Libraries\Opc.Ua.Di.Client\bin\Debug\net10.0\Opc.Ua.Di.Client.dll -Libraries\Opc.Ua.Di.Server\bin\Debug\netstandard2.1\Opc.Ua.Di.Server.dll -Libraries\Opc.Ua.Di.Server\bin\Debug\net472\Opc.Ua.Di.Server.dll -Libraries\Opc.Ua.Di.Server\bin\Debug\net48\Opc.Ua.Di.Server.dll -Libraries\Opc.Ua.Di.Server\bin\Debug\net8.0\Opc.Ua.Di.Server.dll -Libraries\Opc.Ua.Di.Server\bin\Debug\net9.0\Opc.Ua.Di.Server.dll -Libraries\Opc.Ua.Di.Server\bin\Debug\net10.0\Opc.Ua.Di.Server.dll -Stack\Opc.Ua.Core.Diagnostics\bin\Debug\net10.0\Opc.Ua.Core.Diagnostics.dll -Applications\McpServer\bin\Debug\net10.0\Opc.Ua.Mcp.dll +tools\Opc.Ua.SourceGeneration.Core\bin\Debug\netstandard2.0\Opc.Ua.SourceGeneration.Core.dll +src\Opc.Ua.Types\bin\Debug\netstandard2.0\Opc.Ua.Types.dll +src\Opc.Ua.Types\bin\Debug\netstandard2.1\Opc.Ua.Types.dll +src\Opc.Ua.Types\bin\Debug\net472\Opc.Ua.Types.dll +src\Opc.Ua.Types\bin\Debug\net48\Opc.Ua.Types.dll +src\Opc.Ua.Types\bin\Debug\net8.0\Opc.Ua.Types.dll +src\Opc.Ua.Types\bin\Debug\net9.0\Opc.Ua.Types.dll +src\Opc.Ua.Types\bin\Debug\net10.0\Opc.Ua.Types.dll +src\Opc.Ua.Core.Types\bin\Debug\netstandard2.1\Opc.Ua.Core.Types.dll +src\Opc.Ua.Core.Types\bin\Debug\net472\Opc.Ua.Core.Types.dll +src\Opc.Ua.Core.Types\bin\Debug\net48\Opc.Ua.Core.Types.dll +src\Opc.Ua.Core.Types\bin\Debug\net8.0\Opc.Ua.Core.Types.dll +src\Opc.Ua.Core.Types\bin\Debug\net9.0\Opc.Ua.Core.Types.dll +src\Opc.Ua.Core.Types\bin\Debug\net10.0\Opc.Ua.Core.Types.dll +src\Opc.Ua.Core\bin\Debug\netstandard2.1\Opc.Ua.Core.dll +src\Opc.Ua.Core\bin\Debug\net472\Opc.Ua.Core.dll +src\Opc.Ua.Core\bin\Debug\net48\Opc.Ua.Core.dll +src\Opc.Ua.Core\bin\Debug\net8.0\Opc.Ua.Core.dll +src\Opc.Ua.Core\bin\Debug\net9.0\Opc.Ua.Core.dll +src\Opc.Ua.Core\bin\Debug\net10.0\Opc.Ua.Core.dll +src\Opc.Ua.Bindings.Https\bin\Debug\netstandard2.1\Opc.Ua.Bindings.Https.dll +src\Opc.Ua.Bindings.Https\bin\Debug\net472\Opc.Ua.Bindings.Https.dll +src\Opc.Ua.Bindings.Https\bin\Debug\net48\Opc.Ua.Bindings.Https.dll +src\Opc.Ua.Bindings.Https\bin\Debug\net8.0\Opc.Ua.Bindings.Https.dll +src\Opc.Ua.Bindings.Https\bin\Debug\net9.0\Opc.Ua.Bindings.Https.dll +src\Opc.Ua.Bindings.Https\bin\Debug\net10.0\Opc.Ua.Bindings.Https.dll +src\Opc.Ua.Server\bin\Debug\netstandard2.1\Opc.Ua.Server.dll +src\Opc.Ua.Server\bin\Debug\net472\Opc.Ua.Server.dll +src\Opc.Ua.Server\bin\Debug\net48\Opc.Ua.Server.dll +src\Opc.Ua.Server\bin\Debug\net8.0\Opc.Ua.Server.dll +src\Opc.Ua.Server\bin\Debug\net9.0\Opc.Ua.Server.dll +src\Opc.Ua.Server\bin\Debug\net10.0\Opc.Ua.Server.dll +src\Opc.Ua.Client\bin\Debug\netstandard2.1\Opc.Ua.Client.dll +src\Opc.Ua.Client\bin\Debug\net472\Opc.Ua.Client.dll +src\Opc.Ua.Client\bin\Debug\net48\Opc.Ua.Client.dll +src\Opc.Ua.Client\bin\Debug\net8.0\Opc.Ua.Client.dll +src\Opc.Ua.Client\bin\Debug\net9.0\Opc.Ua.Client.dll +src\Opc.Ua.Client\bin\Debug\net10.0\Opc.Ua.Client.dll +src\Opc.Ua.Client.ComplexTypes\bin\Debug\netstandard2.1\Opc.Ua.Client.ComplexTypes.dll +src\Opc.Ua.Client.ComplexTypes\bin\Debug\net472\Opc.Ua.Client.ComplexTypes.dll +src\Opc.Ua.Client.ComplexTypes\bin\Debug\net48\Opc.Ua.Client.ComplexTypes.dll +src\Opc.Ua.Client.ComplexTypes\bin\Debug\net8.0\Opc.Ua.Client.ComplexTypes.dll +src\Opc.Ua.Client.ComplexTypes\bin\Debug\net9.0\Opc.Ua.Client.ComplexTypes.dll +src\Opc.Ua.Client.ComplexTypes\bin\Debug\net10.0\Opc.Ua.Client.ComplexTypes.dll +src\Opc.Ua.Configuration\bin\Debug\netstandard2.1\Opc.Ua.Configuration.dll +src\Opc.Ua.Configuration\bin\Debug\net472\Opc.Ua.Configuration.dll +src\Opc.Ua.Configuration\bin\Debug\net48\Opc.Ua.Configuration.dll +src\Opc.Ua.Configuration\bin\Debug\net8.0\Opc.Ua.Configuration.dll +src\Opc.Ua.Configuration\bin\Debug\net9.0\Opc.Ua.Configuration.dll +src\Opc.Ua.Configuration\bin\Debug\net10.0\Opc.Ua.Configuration.dll +src\Opc.Ua.Gds.Client.Common\bin\Debug\netstandard2.1\Opc.Ua.Gds.Client.Common.dll +src\Opc.Ua.Gds.Client.Common\bin\Debug\net472\Opc.Ua.Gds.Client.Common.dll +src\Opc.Ua.Gds.Client.Common\bin\Debug\net48\Opc.Ua.Gds.Client.Common.dll +src\Opc.Ua.Gds.Client.Common\bin\Debug\net8.0\Opc.Ua.Gds.Client.Common.dll +src\Opc.Ua.Gds.Client.Common\bin\Debug\net9.0\Opc.Ua.Gds.Client.Common.dll +src\Opc.Ua.Gds.Client.Common\bin\Debug\net10.0\Opc.Ua.Gds.Client.Common.dll +src\Opc.Ua.Gds.Server.Common\bin\Debug\netstandard2.1\Opc.Ua.Gds.Server.Common.dll +src\Opc.Ua.Gds.Server.Common\bin\Debug\net472\Opc.Ua.Gds.Server.Common.dll +src\Opc.Ua.Gds.Server.Common\bin\Debug\net48\Opc.Ua.Gds.Server.Common.dll +src\Opc.Ua.Gds.Server.Common\bin\Debug\net8.0\Opc.Ua.Gds.Server.Common.dll +src\Opc.Ua.Gds.Server.Common\bin\Debug\net9.0\Opc.Ua.Gds.Server.Common.dll +src\Opc.Ua.Gds.Server.Common\bin\Debug\net10.0\Opc.Ua.Gds.Server.Common.dll +src\Opc.Ua.Gds.Common\bin\Debug\netstandard2.1\Opc.Ua.Gds.Common.dll +src\Opc.Ua.Gds.Common\bin\Debug\net472\Opc.Ua.Gds.Common.dll +src\Opc.Ua.Gds.Common\bin\Debug\net48\Opc.Ua.Gds.Common.dll +src\Opc.Ua.Gds.Common\bin\Debug\net8.0\Opc.Ua.Gds.Common.dll +src\Opc.Ua.Gds.Common\bin\Debug\net9.0\Opc.Ua.Gds.Common.dll +src\Opc.Ua.Gds.Common\bin\Debug\net10.0\Opc.Ua.Gds.Common.dll +src\Opc.Ua.Security.Certificates\bin\Debug\netstandard2.1\Opc.Ua.Security.Certificates.dll +src\Opc.Ua.Security.Certificates\bin\Debug\net472\Opc.Ua.Security.Certificates.dll +src\Opc.Ua.Security.Certificates\bin\Debug\net48\Opc.Ua.Security.Certificates.dll +src\Opc.Ua.Security.Certificates\bin\Debug\net8.0\Opc.Ua.Security.Certificates.dll +src\Opc.Ua.Security.Certificates\bin\Debug\net9.0\Opc.Ua.Security.Certificates.dll +src\Opc.Ua.Security.Certificates\bin\Debug\net10.0\Opc.Ua.Security.Certificates.dll +src\Opc.Ua.PubSub\bin\Debug\netstandard2.1\Opc.Ua.PubSub.dll +src\Opc.Ua.PubSub\bin\Debug\net472\Opc.Ua.PubSub.dll +src\Opc.Ua.PubSub\bin\Debug\net48\Opc.Ua.PubSub.dll +src\Opc.Ua.PubSub\bin\Debug\net8.0\Opc.Ua.PubSub.dll +src\Opc.Ua.PubSub\bin\Debug\net9.0\Opc.Ua.PubSub.dll +src\Opc.Ua.PubSub\bin\Debug\net10.0\Opc.Ua.PubSub.dll +src\Opc.Ua.WotCon\bin\Debug\netstandard2.1\Opc.Ua.WotCon.dll +src\Opc.Ua.WotCon\bin\Debug\net472\Opc.Ua.WotCon.dll +src\Opc.Ua.WotCon\bin\Debug\net48\Opc.Ua.WotCon.dll +src\Opc.Ua.WotCon\bin\Debug\net8.0\Opc.Ua.WotCon.dll +src\Opc.Ua.WotCon\bin\Debug\net9.0\Opc.Ua.WotCon.dll +src\Opc.Ua.WotCon\bin\Debug\net10.0\Opc.Ua.WotCon.dll +src\Opc.Ua.WotCon.Client\bin\Debug\netstandard2.1\Opc.Ua.WotCon.Client.dll +src\Opc.Ua.WotCon.Client\bin\Debug\net472\Opc.Ua.WotCon.Client.dll +src\Opc.Ua.WotCon.Client\bin\Debug\net48\Opc.Ua.WotCon.Client.dll +src\Opc.Ua.WotCon.Client\bin\Debug\net8.0\Opc.Ua.WotCon.Client.dll +src\Opc.Ua.WotCon.Client\bin\Debug\net9.0\Opc.Ua.WotCon.Client.dll +src\Opc.Ua.WotCon.Client\bin\Debug\net10.0\Opc.Ua.WotCon.Client.dll +src\Opc.Ua.WotCon.Server\bin\Debug\netstandard2.1\Opc.Ua.WotCon.Server.dll +src\Opc.Ua.WotCon.Server\bin\Debug\net472\Opc.Ua.WotCon.Server.dll +src\Opc.Ua.WotCon.Server\bin\Debug\net48\Opc.Ua.WotCon.Server.dll +src\Opc.Ua.WotCon.Server\bin\Debug\net8.0\Opc.Ua.WotCon.Server.dll +src\Opc.Ua.WotCon.Server\bin\Debug\net9.0\Opc.Ua.WotCon.Server.dll +src\Opc.Ua.WotCon.Server\bin\Debug\net10.0\Opc.Ua.WotCon.Server.dll +src\Opc.Ua.Di\bin\Debug\netstandard2.1\Opc.Ua.Di.dll +src\Opc.Ua.Di\bin\Debug\net472\Opc.Ua.Di.dll +src\Opc.Ua.Di\bin\Debug\net48\Opc.Ua.Di.dll +src\Opc.Ua.Di\bin\Debug\net8.0\Opc.Ua.Di.dll +src\Opc.Ua.Di\bin\Debug\net9.0\Opc.Ua.Di.dll +src\Opc.Ua.Di\bin\Debug\net10.0\Opc.Ua.Di.dll +src\Opc.Ua.Di.Client\bin\Debug\netstandard2.1\Opc.Ua.Di.Client.dll +src\Opc.Ua.Di.Client\bin\Debug\net472\Opc.Ua.Di.Client.dll +src\Opc.Ua.Di.Client\bin\Debug\net48\Opc.Ua.Di.Client.dll +src\Opc.Ua.Di.Client\bin\Debug\net8.0\Opc.Ua.Di.Client.dll +src\Opc.Ua.Di.Client\bin\Debug\net9.0\Opc.Ua.Di.Client.dll +src\Opc.Ua.Di.Client\bin\Debug\net10.0\Opc.Ua.Di.Client.dll +src\Opc.Ua.Di.Server\bin\Debug\netstandard2.1\Opc.Ua.Di.Server.dll +src\Opc.Ua.Di.Server\bin\Debug\net472\Opc.Ua.Di.Server.dll +src\Opc.Ua.Di.Server\bin\Debug\net48\Opc.Ua.Di.Server.dll +src\Opc.Ua.Di.Server\bin\Debug\net8.0\Opc.Ua.Di.Server.dll +src\Opc.Ua.Di.Server\bin\Debug\net9.0\Opc.Ua.Di.Server.dll +src\Opc.Ua.Di.Server\bin\Debug\net10.0\Opc.Ua.Di.Server.dll +src\Opc.Ua.Core.Diagnostics\bin\Debug\net10.0\Opc.Ua.Core.Diagnostics.dll +tools\Opc.Ua.Mcp\bin\Debug\net10.0\Opc.Ua.Mcp.dll diff --git a/.azurepipelines/signlistRelease.txt b/.azurepipelines/signlistRelease.txt index 156893c9d4..46dfabfaa0 100644 --- a/.azurepipelines/signlistRelease.txt +++ b/.azurepipelines/signlistRelease.txt @@ -1,118 +1,118 @@ -Tools\Opc.Ua.SourceGeneration.Core\bin\Release\netstandard2.0\Opc.Ua.SourceGeneration.Core.dll -Stack\Opc.Ua.Types\bin\Release\netstandard2.0\Opc.Ua.Types.dll -Stack\Opc.Ua.Types\bin\Release\netstandard2.1\Opc.Ua.Types.dll -Stack\Opc.Ua.Types\bin\Release\net472\Opc.Ua.Types.dll -Stack\Opc.Ua.Types\bin\Release\net48\Opc.Ua.Types.dll -Stack\Opc.Ua.Types\bin\Release\net8.0\Opc.Ua.Types.dll -Stack\Opc.Ua.Types\bin\Release\net9.0\Opc.Ua.Types.dll -Stack\Opc.Ua.Types\bin\Release\net10.0\Opc.Ua.Types.dll -Stack\Opc.Ua.Core.Types\bin\Release\netstandard2.1\Opc.Ua.Core.Types.dll -Stack\Opc.Ua.Core.Types\bin\Release\net472\Opc.Ua.Core.Types.dll -Stack\Opc.Ua.Core.Types\bin\Release\net48\Opc.Ua.Core.Types.dll -Stack\Opc.Ua.Core.Types\bin\Release\net8.0\Opc.Ua.Core.Types.dll -Stack\Opc.Ua.Core.Types\bin\Release\net9.0\Opc.Ua.Core.Types.dll -Stack\Opc.Ua.Core.Types\bin\Release\net10.0\Opc.Ua.Core.Types.dll -Stack\Opc.Ua.Core\bin\Release\netstandard2.1\Opc.Ua.Core.dll -Stack\Opc.Ua.Core\bin\Release\net472\Opc.Ua.Core.dll -Stack\Opc.Ua.Core\bin\Release\net48\Opc.Ua.Core.dll -Stack\Opc.Ua.Core\bin\Release\net8.0\Opc.Ua.Core.dll -Stack\Opc.Ua.Core\bin\Release\net9.0\Opc.Ua.Core.dll -Stack\Opc.Ua.Core\bin\Release\net10.0\Opc.Ua.Core.dll -Stack\Opc.Ua.Bindings.Https\bin\Release\netstandard2.1\Opc.Ua.Bindings.Https.dll -Stack\Opc.Ua.Bindings.Https\bin\Release\net472\Opc.Ua.Bindings.Https.dll -Stack\Opc.Ua.Bindings.Https\bin\Release\net48\Opc.Ua.Bindings.Https.dll -Stack\Opc.Ua.Bindings.Https\bin\Release\net8.0\Opc.Ua.Bindings.Https.dll -Stack\Opc.Ua.Bindings.Https\bin\Release\net9.0\Opc.Ua.Bindings.Https.dll -Stack\Opc.Ua.Bindings.Https\bin\Release\net10.0\Opc.Ua.Bindings.Https.dll -Libraries\Opc.Ua.Server\bin\Release\netstandard2.1\Opc.Ua.Server.dll -Libraries\Opc.Ua.Server\bin\Release\net472\Opc.Ua.Server.dll -Libraries\Opc.Ua.Server\bin\Release\net48\Opc.Ua.Server.dll -Libraries\Opc.Ua.Server\bin\Release\net8.0\Opc.Ua.Server.dll -Libraries\Opc.Ua.Server\bin\Release\net9.0\Opc.Ua.Server.dll -Libraries\Opc.Ua.Server\bin\Release\net10.0\Opc.Ua.Server.dll -Libraries\Opc.Ua.Client\bin\Release\netstandard2.1\Opc.Ua.Client.dll -Libraries\Opc.Ua.Client\bin\Release\net472\Opc.Ua.Client.dll -Libraries\Opc.Ua.Client\bin\Release\net48\Opc.Ua.Client.dll -Libraries\Opc.Ua.Client\bin\Release\net8.0\Opc.Ua.Client.dll -Libraries\Opc.Ua.Client\bin\Release\net9.0\Opc.Ua.Client.dll -Libraries\Opc.Ua.Client\bin\Release\net10.0\Opc.Ua.Client.dll -Libraries\Opc.Ua.Client.ComplexTypes\bin\Release\netstandard2.1\Opc.Ua.Client.ComplexTypes.dll -Libraries\Opc.Ua.Client.ComplexTypes\bin\Release\net472\Opc.Ua.Client.ComplexTypes.dll -Libraries\Opc.Ua.Client.ComplexTypes\bin\Release\net48\Opc.Ua.Client.ComplexTypes.dll -Libraries\Opc.Ua.Client.ComplexTypes\bin\Release\net8.0\Opc.Ua.Client.ComplexTypes.dll -Libraries\Opc.Ua.Client.ComplexTypes\bin\Release\net9.0\Opc.Ua.Client.ComplexTypes.dll -Libraries\Opc.Ua.Client.ComplexTypes\bin\Release\net10.0\Opc.Ua.Client.ComplexTypes.dll -Libraries\Opc.Ua.Configuration\bin\Release\netstandard2.1\Opc.Ua.Configuration.dll -Libraries\Opc.Ua.Configuration\bin\Release\net472\Opc.Ua.Configuration.dll -Libraries\Opc.Ua.Configuration\bin\Release\net48\Opc.Ua.Configuration.dll -Libraries\Opc.Ua.Configuration\bin\Release\net8.0\Opc.Ua.Configuration.dll -Libraries\Opc.Ua.Configuration\bin\Release\net9.0\Opc.Ua.Configuration.dll -Libraries\Opc.Ua.Configuration\bin\Release\net10.0\Opc.Ua.Configuration.dll -Libraries\Opc.Ua.Gds.Client.Common\bin\Release\netstandard2.1\Opc.Ua.Gds.Client.Common.dll -Libraries\Opc.Ua.Gds.Client.Common\bin\Release\net472\Opc.Ua.Gds.Client.Common.dll -Libraries\Opc.Ua.Gds.Client.Common\bin\Release\net48\Opc.Ua.Gds.Client.Common.dll -Libraries\Opc.Ua.Gds.Client.Common\bin\Release\net8.0\Opc.Ua.Gds.Client.Common.dll -Libraries\Opc.Ua.Gds.Client.Common\bin\Release\net9.0\Opc.Ua.Gds.Client.Common.dll -Libraries\Opc.Ua.Gds.Client.Common\bin\Release\net10.0\Opc.Ua.Gds.Client.Common.dll -Libraries\Opc.Ua.Gds.Server.Common\bin\Release\netstandard2.1\Opc.Ua.Gds.Server.Common.dll -Libraries\Opc.Ua.Gds.Server.Common\bin\Release\net472\Opc.Ua.Gds.Server.Common.dll -Libraries\Opc.Ua.Gds.Server.Common\bin\Release\net48\Opc.Ua.Gds.Server.Common.dll -Libraries\Opc.Ua.Gds.Server.Common\bin\Release\net8.0\Opc.Ua.Gds.Server.Common.dll -Libraries\Opc.Ua.Gds.Server.Common\bin\Release\net9.0\Opc.Ua.Gds.Server.Common.dll -Libraries\Opc.Ua.Gds.Server.Common\bin\Release\net10.0\Opc.Ua.Gds.Server.Common.dll -Libraries\Opc.Ua.Gds.Common\bin\Release\netstandard2.1\Opc.Ua.Gds.Common.dll -Libraries\Opc.Ua.Gds.Common\bin\Release\net472\Opc.Ua.Gds.Common.dll -Libraries\Opc.Ua.Gds.Common\bin\Release\net48\Opc.Ua.Gds.Common.dll -Libraries\Opc.Ua.Gds.Common\bin\Release\net8.0\Opc.Ua.Gds.Common.dll -Libraries\Opc.Ua.Gds.Common\bin\Release\net9.0\Opc.Ua.Gds.Common.dll -Libraries\Opc.Ua.Gds.Common\bin\Release\net10.0\Opc.Ua.Gds.Common.dll -Stack\Opc.Ua.Security.Certificates\bin\Release\netstandard2.1\Opc.Ua.Security.Certificates.dll -Stack\Opc.Ua.Security.Certificates\bin\Release\net472\Opc.Ua.Security.Certificates.dll -Stack\Opc.Ua.Security.Certificates\bin\Release\net48\Opc.Ua.Security.Certificates.dll -Stack\Opc.Ua.Security.Certificates\bin\Release\net8.0\Opc.Ua.Security.Certificates.dll -Stack\Opc.Ua.Security.Certificates\bin\Release\net9.0\Opc.Ua.Security.Certificates.dll -Stack\Opc.Ua.Security.Certificates\bin\Release\net10.0\Opc.Ua.Security.Certificates.dll -Libraries\Opc.Ua.PubSub\bin\Release\netstandard2.1\Opc.Ua.PubSub.dll -Libraries\Opc.Ua.PubSub\bin\Release\net472\Opc.Ua.PubSub.dll -Libraries\Opc.Ua.PubSub\bin\Release\net48\Opc.Ua.PubSub.dll -Libraries\Opc.Ua.PubSub\bin\Release\net8.0\Opc.Ua.PubSub.dll -Libraries\Opc.Ua.PubSub\bin\Release\net9.0\Opc.Ua.PubSub.dll -Libraries\Opc.Ua.PubSub\bin\Release\net10.0\Opc.Ua.PubSub.dll -Libraries\Opc.Ua.WotCon\bin\Release\netstandard2.1\Opc.Ua.WotCon.dll -Libraries\Opc.Ua.WotCon\bin\Release\net472\Opc.Ua.WotCon.dll -Libraries\Opc.Ua.WotCon\bin\Release\net48\Opc.Ua.WotCon.dll -Libraries\Opc.Ua.WotCon\bin\Release\net8.0\Opc.Ua.WotCon.dll -Libraries\Opc.Ua.WotCon\bin\Release\net9.0\Opc.Ua.WotCon.dll -Libraries\Opc.Ua.WotCon\bin\Release\net10.0\Opc.Ua.WotCon.dll -Libraries\Opc.Ua.WotCon.Client\bin\Release\netstandard2.1\Opc.Ua.WotCon.Client.dll -Libraries\Opc.Ua.WotCon.Client\bin\Release\net472\Opc.Ua.WotCon.Client.dll -Libraries\Opc.Ua.WotCon.Client\bin\Release\net48\Opc.Ua.WotCon.Client.dll -Libraries\Opc.Ua.WotCon.Client\bin\Release\net8.0\Opc.Ua.WotCon.Client.dll -Libraries\Opc.Ua.WotCon.Client\bin\Release\net9.0\Opc.Ua.WotCon.Client.dll -Libraries\Opc.Ua.WotCon.Client\bin\Release\net10.0\Opc.Ua.WotCon.Client.dll -Libraries\Opc.Ua.WotCon.Server\bin\Release\netstandard2.1\Opc.Ua.WotCon.Server.dll -Libraries\Opc.Ua.WotCon.Server\bin\Release\net472\Opc.Ua.WotCon.Server.dll -Libraries\Opc.Ua.WotCon.Server\bin\Release\net48\Opc.Ua.WotCon.Server.dll -Libraries\Opc.Ua.WotCon.Server\bin\Release\net8.0\Opc.Ua.WotCon.Server.dll -Libraries\Opc.Ua.WotCon.Server\bin\Release\net9.0\Opc.Ua.WotCon.Server.dll -Libraries\Opc.Ua.WotCon.Server\bin\Release\net10.0\Opc.Ua.WotCon.Server.dll -Libraries\Opc.Ua.Di\bin\Release\netstandard2.1\Opc.Ua.Di.dll -Libraries\Opc.Ua.Di\bin\Release\net472\Opc.Ua.Di.dll -Libraries\Opc.Ua.Di\bin\Release\net48\Opc.Ua.Di.dll -Libraries\Opc.Ua.Di\bin\Release\net8.0\Opc.Ua.Di.dll -Libraries\Opc.Ua.Di\bin\Release\net9.0\Opc.Ua.Di.dll -Libraries\Opc.Ua.Di\bin\Release\net10.0\Opc.Ua.Di.dll -Libraries\Opc.Ua.Di.Client\bin\Release\netstandard2.1\Opc.Ua.Di.Client.dll -Libraries\Opc.Ua.Di.Client\bin\Release\net472\Opc.Ua.Di.Client.dll -Libraries\Opc.Ua.Di.Client\bin\Release\net48\Opc.Ua.Di.Client.dll -Libraries\Opc.Ua.Di.Client\bin\Release\net8.0\Opc.Ua.Di.Client.dll -Libraries\Opc.Ua.Di.Client\bin\Release\net9.0\Opc.Ua.Di.Client.dll -Libraries\Opc.Ua.Di.Client\bin\Release\net10.0\Opc.Ua.Di.Client.dll -Libraries\Opc.Ua.Di.Server\bin\Release\netstandard2.1\Opc.Ua.Di.Server.dll -Libraries\Opc.Ua.Di.Server\bin\Release\net472\Opc.Ua.Di.Server.dll -Libraries\Opc.Ua.Di.Server\bin\Release\net48\Opc.Ua.Di.Server.dll -Libraries\Opc.Ua.Di.Server\bin\Release\net8.0\Opc.Ua.Di.Server.dll -Libraries\Opc.Ua.Di.Server\bin\Release\net9.0\Opc.Ua.Di.Server.dll -Libraries\Opc.Ua.Di.Server\bin\Release\net10.0\Opc.Ua.Di.Server.dll -Stack\Opc.Ua.Core.Diagnostics\bin\Release\net10.0\Opc.Ua.Core.Diagnostics.dll -Applications\McpServer\bin\Release\net10.0\Opc.Ua.Mcp.dll +tools\Opc.Ua.SourceGeneration.Core\bin\Release\netstandard2.0\Opc.Ua.SourceGeneration.Core.dll +src\Opc.Ua.Types\bin\Release\netstandard2.0\Opc.Ua.Types.dll +src\Opc.Ua.Types\bin\Release\netstandard2.1\Opc.Ua.Types.dll +src\Opc.Ua.Types\bin\Release\net472\Opc.Ua.Types.dll +src\Opc.Ua.Types\bin\Release\net48\Opc.Ua.Types.dll +src\Opc.Ua.Types\bin\Release\net8.0\Opc.Ua.Types.dll +src\Opc.Ua.Types\bin\Release\net9.0\Opc.Ua.Types.dll +src\Opc.Ua.Types\bin\Release\net10.0\Opc.Ua.Types.dll +src\Opc.Ua.Core.Types\bin\Release\netstandard2.1\Opc.Ua.Core.Types.dll +src\Opc.Ua.Core.Types\bin\Release\net472\Opc.Ua.Core.Types.dll +src\Opc.Ua.Core.Types\bin\Release\net48\Opc.Ua.Core.Types.dll +src\Opc.Ua.Core.Types\bin\Release\net8.0\Opc.Ua.Core.Types.dll +src\Opc.Ua.Core.Types\bin\Release\net9.0\Opc.Ua.Core.Types.dll +src\Opc.Ua.Core.Types\bin\Release\net10.0\Opc.Ua.Core.Types.dll +src\Opc.Ua.Core\bin\Release\netstandard2.1\Opc.Ua.Core.dll +src\Opc.Ua.Core\bin\Release\net472\Opc.Ua.Core.dll +src\Opc.Ua.Core\bin\Release\net48\Opc.Ua.Core.dll +src\Opc.Ua.Core\bin\Release\net8.0\Opc.Ua.Core.dll +src\Opc.Ua.Core\bin\Release\net9.0\Opc.Ua.Core.dll +src\Opc.Ua.Core\bin\Release\net10.0\Opc.Ua.Core.dll +src\Opc.Ua.Bindings.Https\bin\Release\netstandard2.1\Opc.Ua.Bindings.Https.dll +src\Opc.Ua.Bindings.Https\bin\Release\net472\Opc.Ua.Bindings.Https.dll +src\Opc.Ua.Bindings.Https\bin\Release\net48\Opc.Ua.Bindings.Https.dll +src\Opc.Ua.Bindings.Https\bin\Release\net8.0\Opc.Ua.Bindings.Https.dll +src\Opc.Ua.Bindings.Https\bin\Release\net9.0\Opc.Ua.Bindings.Https.dll +src\Opc.Ua.Bindings.Https\bin\Release\net10.0\Opc.Ua.Bindings.Https.dll +src\Opc.Ua.Server\bin\Release\netstandard2.1\Opc.Ua.Server.dll +src\Opc.Ua.Server\bin\Release\net472\Opc.Ua.Server.dll +src\Opc.Ua.Server\bin\Release\net48\Opc.Ua.Server.dll +src\Opc.Ua.Server\bin\Release\net8.0\Opc.Ua.Server.dll +src\Opc.Ua.Server\bin\Release\net9.0\Opc.Ua.Server.dll +src\Opc.Ua.Server\bin\Release\net10.0\Opc.Ua.Server.dll +src\Opc.Ua.Client\bin\Release\netstandard2.1\Opc.Ua.Client.dll +src\Opc.Ua.Client\bin\Release\net472\Opc.Ua.Client.dll +src\Opc.Ua.Client\bin\Release\net48\Opc.Ua.Client.dll +src\Opc.Ua.Client\bin\Release\net8.0\Opc.Ua.Client.dll +src\Opc.Ua.Client\bin\Release\net9.0\Opc.Ua.Client.dll +src\Opc.Ua.Client\bin\Release\net10.0\Opc.Ua.Client.dll +src\Opc.Ua.Client.ComplexTypes\bin\Release\netstandard2.1\Opc.Ua.Client.ComplexTypes.dll +src\Opc.Ua.Client.ComplexTypes\bin\Release\net472\Opc.Ua.Client.ComplexTypes.dll +src\Opc.Ua.Client.ComplexTypes\bin\Release\net48\Opc.Ua.Client.ComplexTypes.dll +src\Opc.Ua.Client.ComplexTypes\bin\Release\net8.0\Opc.Ua.Client.ComplexTypes.dll +src\Opc.Ua.Client.ComplexTypes\bin\Release\net9.0\Opc.Ua.Client.ComplexTypes.dll +src\Opc.Ua.Client.ComplexTypes\bin\Release\net10.0\Opc.Ua.Client.ComplexTypes.dll +src\Opc.Ua.Configuration\bin\Release\netstandard2.1\Opc.Ua.Configuration.dll +src\Opc.Ua.Configuration\bin\Release\net472\Opc.Ua.Configuration.dll +src\Opc.Ua.Configuration\bin\Release\net48\Opc.Ua.Configuration.dll +src\Opc.Ua.Configuration\bin\Release\net8.0\Opc.Ua.Configuration.dll +src\Opc.Ua.Configuration\bin\Release\net9.0\Opc.Ua.Configuration.dll +src\Opc.Ua.Configuration\bin\Release\net10.0\Opc.Ua.Configuration.dll +src\Opc.Ua.Gds.Client.Common\bin\Release\netstandard2.1\Opc.Ua.Gds.Client.Common.dll +src\Opc.Ua.Gds.Client.Common\bin\Release\net472\Opc.Ua.Gds.Client.Common.dll +src\Opc.Ua.Gds.Client.Common\bin\Release\net48\Opc.Ua.Gds.Client.Common.dll +src\Opc.Ua.Gds.Client.Common\bin\Release\net8.0\Opc.Ua.Gds.Client.Common.dll +src\Opc.Ua.Gds.Client.Common\bin\Release\net9.0\Opc.Ua.Gds.Client.Common.dll +src\Opc.Ua.Gds.Client.Common\bin\Release\net10.0\Opc.Ua.Gds.Client.Common.dll +src\Opc.Ua.Gds.Server.Common\bin\Release\netstandard2.1\Opc.Ua.Gds.Server.Common.dll +src\Opc.Ua.Gds.Server.Common\bin\Release\net472\Opc.Ua.Gds.Server.Common.dll +src\Opc.Ua.Gds.Server.Common\bin\Release\net48\Opc.Ua.Gds.Server.Common.dll +src\Opc.Ua.Gds.Server.Common\bin\Release\net8.0\Opc.Ua.Gds.Server.Common.dll +src\Opc.Ua.Gds.Server.Common\bin\Release\net9.0\Opc.Ua.Gds.Server.Common.dll +src\Opc.Ua.Gds.Server.Common\bin\Release\net10.0\Opc.Ua.Gds.Server.Common.dll +src\Opc.Ua.Gds.Common\bin\Release\netstandard2.1\Opc.Ua.Gds.Common.dll +src\Opc.Ua.Gds.Common\bin\Release\net472\Opc.Ua.Gds.Common.dll +src\Opc.Ua.Gds.Common\bin\Release\net48\Opc.Ua.Gds.Common.dll +src\Opc.Ua.Gds.Common\bin\Release\net8.0\Opc.Ua.Gds.Common.dll +src\Opc.Ua.Gds.Common\bin\Release\net9.0\Opc.Ua.Gds.Common.dll +src\Opc.Ua.Gds.Common\bin\Release\net10.0\Opc.Ua.Gds.Common.dll +src\Opc.Ua.Security.Certificates\bin\Release\netstandard2.1\Opc.Ua.Security.Certificates.dll +src\Opc.Ua.Security.Certificates\bin\Release\net472\Opc.Ua.Security.Certificates.dll +src\Opc.Ua.Security.Certificates\bin\Release\net48\Opc.Ua.Security.Certificates.dll +src\Opc.Ua.Security.Certificates\bin\Release\net8.0\Opc.Ua.Security.Certificates.dll +src\Opc.Ua.Security.Certificates\bin\Release\net9.0\Opc.Ua.Security.Certificates.dll +src\Opc.Ua.Security.Certificates\bin\Release\net10.0\Opc.Ua.Security.Certificates.dll +src\Opc.Ua.PubSub\bin\Release\netstandard2.1\Opc.Ua.PubSub.dll +src\Opc.Ua.PubSub\bin\Release\net472\Opc.Ua.PubSub.dll +src\Opc.Ua.PubSub\bin\Release\net48\Opc.Ua.PubSub.dll +src\Opc.Ua.PubSub\bin\Release\net8.0\Opc.Ua.PubSub.dll +src\Opc.Ua.PubSub\bin\Release\net9.0\Opc.Ua.PubSub.dll +src\Opc.Ua.PubSub\bin\Release\net10.0\Opc.Ua.PubSub.dll +src\Opc.Ua.WotCon\bin\Release\netstandard2.1\Opc.Ua.WotCon.dll +src\Opc.Ua.WotCon\bin\Release\net472\Opc.Ua.WotCon.dll +src\Opc.Ua.WotCon\bin\Release\net48\Opc.Ua.WotCon.dll +src\Opc.Ua.WotCon\bin\Release\net8.0\Opc.Ua.WotCon.dll +src\Opc.Ua.WotCon\bin\Release\net9.0\Opc.Ua.WotCon.dll +src\Opc.Ua.WotCon\bin\Release\net10.0\Opc.Ua.WotCon.dll +src\Opc.Ua.WotCon.Client\bin\Release\netstandard2.1\Opc.Ua.WotCon.Client.dll +src\Opc.Ua.WotCon.Client\bin\Release\net472\Opc.Ua.WotCon.Client.dll +src\Opc.Ua.WotCon.Client\bin\Release\net48\Opc.Ua.WotCon.Client.dll +src\Opc.Ua.WotCon.Client\bin\Release\net8.0\Opc.Ua.WotCon.Client.dll +src\Opc.Ua.WotCon.Client\bin\Release\net9.0\Opc.Ua.WotCon.Client.dll +src\Opc.Ua.WotCon.Client\bin\Release\net10.0\Opc.Ua.WotCon.Client.dll +src\Opc.Ua.WotCon.Server\bin\Release\netstandard2.1\Opc.Ua.WotCon.Server.dll +src\Opc.Ua.WotCon.Server\bin\Release\net472\Opc.Ua.WotCon.Server.dll +src\Opc.Ua.WotCon.Server\bin\Release\net48\Opc.Ua.WotCon.Server.dll +src\Opc.Ua.WotCon.Server\bin\Release\net8.0\Opc.Ua.WotCon.Server.dll +src\Opc.Ua.WotCon.Server\bin\Release\net9.0\Opc.Ua.WotCon.Server.dll +src\Opc.Ua.WotCon.Server\bin\Release\net10.0\Opc.Ua.WotCon.Server.dll +src\Opc.Ua.Di\bin\Release\netstandard2.1\Opc.Ua.Di.dll +src\Opc.Ua.Di\bin\Release\net472\Opc.Ua.Di.dll +src\Opc.Ua.Di\bin\Release\net48\Opc.Ua.Di.dll +src\Opc.Ua.Di\bin\Release\net8.0\Opc.Ua.Di.dll +src\Opc.Ua.Di\bin\Release\net9.0\Opc.Ua.Di.dll +src\Opc.Ua.Di\bin\Release\net10.0\Opc.Ua.Di.dll +src\Opc.Ua.Di.Client\bin\Release\netstandard2.1\Opc.Ua.Di.Client.dll +src\Opc.Ua.Di.Client\bin\Release\net472\Opc.Ua.Di.Client.dll +src\Opc.Ua.Di.Client\bin\Release\net48\Opc.Ua.Di.Client.dll +src\Opc.Ua.Di.Client\bin\Release\net8.0\Opc.Ua.Di.Client.dll +src\Opc.Ua.Di.Client\bin\Release\net9.0\Opc.Ua.Di.Client.dll +src\Opc.Ua.Di.Client\bin\Release\net10.0\Opc.Ua.Di.Client.dll +src\Opc.Ua.Di.Server\bin\Release\netstandard2.1\Opc.Ua.Di.Server.dll +src\Opc.Ua.Di.Server\bin\Release\net472\Opc.Ua.Di.Server.dll +src\Opc.Ua.Di.Server\bin\Release\net48\Opc.Ua.Di.Server.dll +src\Opc.Ua.Di.Server\bin\Release\net8.0\Opc.Ua.Di.Server.dll +src\Opc.Ua.Di.Server\bin\Release\net9.0\Opc.Ua.Di.Server.dll +src\Opc.Ua.Di.Server\bin\Release\net10.0\Opc.Ua.Di.Server.dll +src\Opc.Ua.Core.Diagnostics\bin\Release\net10.0\Opc.Ua.Core.Diagnostics.dll +tools\Opc.Ua.Mcp\bin\Release\net10.0\Opc.Ua.Mcp.dll diff --git a/.azurepipelines/test.yml b/.azurepipelines/test.yml index 8143646ca5..e2f33581f7 100644 --- a/.azurepipelines/test.yml +++ b/.azurepipelines/test.yml @@ -135,7 +135,7 @@ jobs: condition: and(contains(variables['file'], 'Fuzz.Tests'), ne(variables['fuzzingartifacts.secureFilePath'], '')) inputs: archiveFilePatterns: '$(Agent.TempDirectory)/FuzzingArtifacts.zip' - destinationFolder: ./Fuzzing/Opc.Ua.Encoders.Fuzz.Tests + destinationFolder: ./fuzzing/Opc.Ua.Encoders.Fuzz.Tests cleanDestinationFolder: false overwriteExistingFiles: true continueOnError: true diff --git a/.azurepipelines/testcc.yml b/.azurepipelines/testcc.yml index 4463478cc9..316333a195 100644 --- a/.azurepipelines/testcc.yml +++ b/.azurepipelines/testcc.yml @@ -67,7 +67,7 @@ jobs: condition: ne(variables['fuzzingartifacts.secureFilePath'], '') inputs: archiveFilePatterns: '$(Agent.TempDirectory)/FuzzingArtifacts.zip' - destinationFolder: ./Fuzzing/Opc.Ua.Encoders.Fuzz.Tests + destinationFolder: ./fuzzing/Opc.Ua.Encoders.Fuzz.Tests cleanDestinationFolder: false overwriteExistingFiles: true continueOnError: true @@ -89,7 +89,7 @@ jobs: # that exceeds 10 min so silent hangs surface as a named test failure instead # of burning the step timeout with no diagnostic info. See test.yml for context. # note: /p:CollectCoverage=true is only used to disable deterministic builds - arguments: '--no-restore ${{ variables.DotCliCommandline }} --configuration ${{ parameters.configuration }} /p:CollectCoverage=true --collect:"XPlat Code Coverage" --settings ./Tests/coverlet.runsettings.xml --results-directory $(Agent.TempDirectory) --blame-hang-timeout 10m --blame-hang-dump-type none' + arguments: '--no-restore ${{ variables.DotCliCommandline }} --configuration ${{ parameters.configuration }} /p:CollectCoverage=true --collect:"XPlat Code Coverage" --settings ./tests/coverlet.runsettings.xml --results-directory $(Agent.TempDirectory) --blame-hang-timeout 10m --blame-hang-dump-type none' publishTestResults: false - script: | bash <(curl -s https://codecov.io/bash) -s $(Agent.TempDirectory) diff --git a/.editorconfig b/.editorconfig index f551df06a8..1b20eeba7e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1134,11 +1134,11 @@ dotnet_analyzer.severity = none # disposable lifetimes in tests are managed by fixture setup/teardown. This # matches the CA2007;CA2000 convention already used by # Opc.Ua.Di.Tests and Opc.Ua.MigrationAnalyzer.Tests. -[Tests/**/*.cs] +[tests/**/*.cs] dotnet_diagnostic.CA2007.severity = none dotnet_diagnostic.CA2000.severity = none # Fuzzing test projects (Opc.Ua.*.Fuzz.Tests) are test projects; same rationale. -[Fuzzing/**/*.Fuzz.Tests/**/*.cs] +[fuzzing/**/*.Fuzz.Tests/**/*.cs] dotnet_diagnostic.CA2007.severity = none dotnet_diagnostic.CA2000.severity = none diff --git a/.github/agents/fuzz-tester.agent.md b/.github/agents/fuzz-tester.agent.md index 16cbbaa9fa..55b8ad562e 100644 --- a/.github/agents/fuzz-tester.agent.md +++ b/.github/agents/fuzz-tester.agent.md @@ -7,7 +7,7 @@ name: fuzz-tester You are an OPC UA fuzz-testing specialist for the UA .NET Standard stack. Your job is to run the existing SharpFuzz + libFuzzer toolchain across the three -fuzz areas under `Fuzzing/`, autonomously react to any crash / timeout / +fuzz areas under `fuzzing/`, autonomously react to any crash / timeout / slow-input findings, fix them per the repository guidelines, add the failing input as a regression asset, and keep running until the user says stop. @@ -15,20 +15,20 @@ input as a regression asset, and keep running until the user says stop. - **Solution:** `UA.slnx` at the repo root. - **Fuzz areas** (each is a triple of host / corpus / tests / tools): - - `Fuzzing/Opc.Ua.Encoders.Fuzz` (+ `.Corpus`, `.Tests`, `.Tools`) — Binary / + - `fuzzing/Opc.Ua.Encoders.Fuzz` (+ `.Corpus`, `.Tests`, `.Tools`) — Binary / JSON / XML decoders + idempotent round-trip + built-in-type readers + parser entry points. - - `Fuzzing/Opc.Ua.Certificates.Fuzz` — `X509CRL`, X509 extensions, PEM, + - `fuzzing/Opc.Ua.Certificates.Fuzz` — `X509CRL`, X509 extensions, PEM, PKCS#10, low-level `AsnUtils`. - - `Fuzzing/Opc.Ua.Network.Fuzz` — pcap-binding parsers + `Opc.Ua.Core` + - `fuzzing/Opc.Ua.Network.Fuzz` — pcap-binding parsers + `Opc.Ua.Core` UA-SC seam (`TcpMessageParsers.*`). - **Shared infrastructure** (do NOT reinvent these): - - `Fuzzing/Scripts/fuzz-libfuzzer.ps1` — `dotnet publish -p:LibFuzzer=true`, + - `fuzzing/Scripts/fuzz-libfuzzer.ps1` — `dotnet publish -p:LibFuzzer=true`, `sharpfuzz`-instrument every output DLL, copy seed corpus, invoke `libfuzzer-dotnet`. - - `Fuzzing/Scripts/fuzz-menu.ps1 -AssemblyPath ` — reflection-based + - `fuzzing/Scripts/fuzz-menu.ps1 -AssemblyPath ` — reflection-based enumeration of `FuzzableCode` public static targets in a built area assembly. - - `Fuzzing/Dictionaries/*.dict` — per-format dictionaries: `binary.dict`, + - `fuzzing/Dictionaries/*.dict` — per-format dictionaries: `binary.dict`, `json.dict`, `xml.dict`, `nodeid.dict`, `asn1.dict`, `uasc.dict`, `tcp.dict`. - Per-area `Opc.Ua..Fuzz.Tests/Assets/` — the harness (`FuzzTargetTestsBase`) globs `Assets/crash*.*`, `Assets/timeout*.*`, @@ -69,7 +69,7 @@ These come from `.github/copilot-instructions.md` and `common.props` / (polyfill exists) or `SemaphoreSlim` internally only. - OPC Foundation MIT licence header on every new `.cs` file (copy from a sibling file; copyright year `2005-2026`). -- Polyfills go under `Stack/Opc.Ua.Types/Polyfills/` only when no other +- Polyfills go under `src/Opc.Ua.Types/Polyfills/` only when no other option exists. - Public-API compat with v1.5.378 (`master378`) — never break it without explicit user approval. If a fix needs a breaking change → Phase 7 escalate. @@ -104,10 +104,10 @@ Compute `$engines` as the list of engines to drive in this run: * On Linux, additionally include `aflfuzz` **iff** the `afl-fuzz` binary is on PATH AND `sharpfuzz` is installed (verified in step 1 below). If `afl-fuzz` is missing on Linux, do NOT auto-install — `make install` - needs sudo and a compile toolchain (`Fuzzing/Scripts/install.sh` is the + needs sudo and a compile toolchain (`fuzzing/Scripts/install.sh` is the reference installer). Surface the gap to the user with a one-line note: "afl-fuzz not on PATH; skipping AFL engine. Run - `Fuzzing/Scripts/install.sh` to enable." Continue with libFuzzer only. + `fuzzing/Scripts/install.sh` to enable." Continue with libFuzzer only. * On Windows / macOS, never run afl-fuzz; do not even probe for it. The `Aflfuzz*` targets enumerated in Phase 2 are skipped on those OSes. @@ -146,7 +146,7 @@ blocker and ask the user how to proceed. Pinned to release **`v2025.05.02.0904`** (audit F2: unpinned binary downloads of code-executed-on-the-dev-machine are a supply-chain risk). -Check `Fuzzing/.tools/libfuzzer-dotnet-` exists, where +Check `fuzzing/.tools/libfuzzer-dotnet-` exists, where `` is: * `libfuzzer-dotnet-windows.exe` on Windows @@ -175,13 +175,13 @@ $expected = @{ 'libfuzzer-dotnet-ubuntu' = 'C2C2A90D94C409A4AF339A0D4F244E0442C5A5D249BE0F1252BA07871F285958' 'libfuzzer-dotnet-debian' = 'EFD77B0E4AF48CDC75B8ACC0C2CE8B8C6BEE51521CD5566B4839A7C32832EB4F' } -$actual = (Get-FileHash "Fuzzing/.tools/$asset" -Algorithm SHA256).Hash +$actual = (Get-FileHash "fuzzing/.tools/$asset" -Algorithm SHA256).Hash if ($actual -ne $expected[$asset]) { throw "libfuzzer-dotnet SHA-256 mismatch for $asset (expected $($expected[$asset]), got $actual). Aborting; never execute an unverified binary." } ``` -Create `Fuzzing/.tools/` and add it to the repo's `.gitignore` if not +Create `fuzzing/.tools/` and add it to the repo's `.gitignore` if not already excluded. If the download is blocked (air-gapped, proxy, …), prompt the user to @@ -206,19 +206,19 @@ if (-not $aflFuzz) { ``` If `afl-fuzz` is missing, do NOT attempt to install — the standard install -path is `sudo make install` (`Fuzzing/Scripts/install.sh` automates it but +path is `sudo make install` (`fuzzing/Scripts/install.sh` automates it but requires sudo + a compile toolchain). Continue with `libfuzzer` only. Note the gap in the engine-selection log line emitted in step 0. If `afl-fuzz` is present, also verify `sharpfuzz` (already covered by -step 1) and the AFL helper script: `Fuzzing/Scripts/fuzz-afl.ps1` (already +step 1) and the AFL helper script: `fuzzing/Scripts/fuzz-afl.ps1` (already in the repo). ### 3. Bin / obj clean state for the areas you're about to fuzz ```powershell foreach ($area in @('Opc.Ua.Encoders.Fuzz', 'Opc.Ua.Certificates.Fuzz', 'Opc.Ua.Network.Fuzz')) { - Get-ChildItem "Fuzzing/$area/bin","Fuzzing/$area/obj" -ErrorAction SilentlyContinue | + Get-ChildItem "fuzzing/$area/bin","fuzzing/$area/obj" -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force } ``` @@ -238,8 +238,8 @@ Only purge areas you're going to fuzz. For each chosen area, run (cache results — only rerun on source change): ```powershell -$outDir = "Fuzzing/.runs/$area/bin" -dotnet publish "Fuzzing/$area/$area.csproj" -p:LibFuzzer=true -c Release ` +$outDir = "fuzzing/.runs/$area/bin" +dotnet publish "fuzzing/$area/$area.csproj" -p:LibFuzzer=true -c Release ` --force -o $outDir --nologo # Instrument every output DLL except known exclusions @@ -256,8 +256,8 @@ If `sharpfuzz` errors out on any DLL: stop, report the error, ask the user. For each area: ```powershell -$dll = "Fuzzing/.runs/$area/bin/$area.dll" -$allTargets = & "Fuzzing/Scripts/fuzz-menu.ps1" -AssemblyPath $dll +$dll = "fuzzing/.runs/$area/bin/$area.dll" +$allTargets = & "fuzzing/Scripts/fuzz-menu.ps1" -AssemblyPath $dll # Split by engine: # libFuzzer needs ReadOnlySpan signatures (Libfuzz* convention). @@ -278,19 +278,19 @@ Map each target to a dictionary by name match (case-insensitive): | Target name contains | Dictionary | |---|---| -| `Json` | `Fuzzing/Dictionaries/json.dict` | -| `Xml` | `Fuzzing/Dictionaries/xml.dict` | -| `Binary` | `Fuzzing/Dictionaries/binary.dict` | -| `NodeId`, `RelativePath`, `NumericRange`, `QualifiedName`, `Uuid`, `Parsers`, `Parse` | `Fuzzing/Dictionaries/nodeid.dict` | -| `X509`, `Asn`, `Pkcs`, `PEM` | `Fuzzing/Dictionaries/asn1.dict` | -| `Hello`, `Acknowledge`, `Error`, `ReverseHello`, `Asymmetric`, `OpcUaFrameParser`, `OfflineSecureChannel`, `ServiceCallReassembler`, `Tcp...` (UA-SC contextual) | `Fuzzing/Dictionaries/uasc.dict` | -| `TcpReassembler` (raw TCP / IP) | `Fuzzing/Dictionaries/tcp.dict` | +| `Json` | `fuzzing/Dictionaries/json.dict` | +| `Xml` | `fuzzing/Dictionaries/xml.dict` | +| `Binary` | `fuzzing/Dictionaries/binary.dict` | +| `NodeId`, `RelativePath`, `NumericRange`, `QualifiedName`, `Uuid`, `Parsers`, `Parse` | `fuzzing/Dictionaries/nodeid.dict` | +| `X509`, `Asn`, `Pkcs`, `PEM` | `fuzzing/Dictionaries/asn1.dict` | +| `Hello`, `Acknowledge`, `Error`, `ReverseHello`, `Asymmetric`, `OpcUaFrameParser`, `OfflineSecureChannel`, `ServiceCallReassembler`, `Tcp...` (UA-SC contextual) | `fuzzing/Dictionaries/uasc.dict` | +| `TcpReassembler` (raw TCP / IP) | `fuzzing/Dictionaries/tcp.dict` | If none match, omit `-dict=` (the target still runs, just slower coverage growth). Pick the seed corpus per target by name match against -`Fuzzing/Opc.Ua..Fuzz.Corpus/Testcases./` (Json → `.Json`, Xml → +`fuzzing/Opc.Ua..Fuzz.Corpus/Testcases./` (Json → `.Json`, Xml → `.Xml`, Tcp → `.Tcp` etc.). Fall back to the first `Testcases.*/` directory the area has if no specific match. @@ -304,7 +304,7 @@ without changes. ### 3a. libFuzzer instances (all OSes) ```powershell -$workDir = "Fuzzing/.runs/$area/libfuzz/$target" +$workDir = "fuzzing/.runs/$area/libfuzz/$target" New-Item -ItemType Directory -Force -Path $workDir | Out-Null Copy-Item "$corpus/*.*" -Destination $workDir/Testcases/ -Recurse -Force @@ -316,7 +316,7 @@ $args = @( ) if ($dict) { $args = @("-dict=$dict") + $args } -Start-Process -FilePath "Fuzzing/.tools/libfuzzer-dotnet-" ` +Start-Process -FilePath "fuzzing/.tools/libfuzzer-dotnet-" ` -ArgumentList $args -WorkingDirectory $workDir ` -RedirectStandardOutput "$workDir/libfuzz.log" ` -RedirectStandardError "$workDir/libfuzz.err" ` @@ -329,12 +329,12 @@ libFuzzer writes findings into `$workDir` itself with `crash-*` / ### 3b. afl-fuzz instances (Linux only, opt-in) Only schedule these when `aflfuzz` ∈ `$engines`. On Linux, prefer the -existing `Fuzzing/Scripts/fuzz-afl.ps1` helper since it already handles +existing `fuzzing/Scripts/fuzz-afl.ps1` helper since it already handles publishing, instrumentation, `AFL_SKIP_BIN_CHECK`, and the `afl-fuzz` invocation. Run it once per `Aflfuzz*` target: ```powershell -$workDir = "Fuzzing/.runs/$area/aflfuzz/$target" +$workDir = "fuzzing/.runs/$area/aflfuzz/$target" New-Item -ItemType Directory -Force -Path "$workDir/input" | Out-Null Copy-Item "$corpus/*.*" -Destination "$workDir/input/" -Recurse -Force @@ -382,7 +382,7 @@ engine has its own naming convention, so the glob differs by engine: ### libFuzzer findings ```powershell -Get-ChildItem "Fuzzing/.runs/$area/libfuzz" -Recurse -File ` +Get-ChildItem "fuzzing/.runs/$area/libfuzz" -Recurse -File ` -Include 'crash-*','timeout-*','slow-unit-*' | Where-Object { -not $_.PSIsContainer } ``` @@ -392,11 +392,11 @@ Get-ChildItem "Fuzzing/.runs/$area/libfuzz" -Recurse -File ` ```powershell # afl puts crashes under findings//crashes/ and hangs under # findings//hangs/. The queue/ folder is the live corpus — ignore. -Get-ChildItem "Fuzzing/.runs/$area/aflfuzz/*/findings/*/crashes" ` +Get-ChildItem "fuzzing/.runs/$area/aflfuzz/*/findings/*/crashes" ` -File -ErrorAction SilentlyContinue | Where-Object { $_.Name -ne 'README.txt' } -Get-ChildItem "Fuzzing/.runs/$area/aflfuzz/*/findings/*/hangs" ` +Get-ChildItem "fuzzing/.runs/$area/aflfuzz/*/findings/*/hangs" ` -File -ErrorAction SilentlyContinue | Where-Object { $_.Name -ne 'README.txt' } ``` @@ -414,7 +414,7 @@ For each new finding (either engine): * afl-fuzz `findings/.../crashes/*` → `crash` * afl-fuzz `findings/.../hangs/*` → `timeout` 3. Check whether the SHA-256 hash already exists as - `Fuzzing/Opc.Ua..Fuzz.Tests/Assets/-*` (in any of the + `fuzzing/Opc.Ua..Fuzz.Tests/Assets/-*` (in any of the three areas, since the harness cross-replays). If yes, skip — this is an already-known regression seed; the harness already validates it. Note the finding count and continue. @@ -442,7 +442,7 @@ For each new finding (either engine): capture the full exception type, message, and stack trace. ```powershell - dotnet run --project "Fuzzing/Opc.Ua..Fuzz.Tools" -c Release -- ` + dotnet run --project "fuzzing/Opc.Ua..Fuzz.Tools" -c Release -- ` --playback --stacktrace ``` @@ -526,7 +526,7 @@ $prefix = switch -Wildcard ($findingFile.Name) { 'timeout-*' { 'timeout' } 'slow-unit-*' { 'slow' } } -$dest = "Fuzzing/Opc.Ua..Fuzz.Tests/Assets/$prefix-$sha256" +$dest = "fuzzing/Opc.Ua..Fuzz.Tests/Assets/$prefix-$sha256" Copy-Item $findingFile.FullName -Destination $dest ``` @@ -542,7 +542,7 @@ dotnet build -c Debug --nologo # Regression-test all three fuzz areas on net10.0 foreach ($area in @('Encoders','Certificates','Network')) { - dotnet test "Fuzzing/Opc.Ua.$area.Fuzz.Tests/Opc.Ua.$area.Fuzz.Tests.csproj" ` + dotnet test "fuzzing/Opc.Ua.$area.Fuzz.Tests/Opc.Ua.$area.Fuzz.Tests.csproj" ` -f net10.0 -c Debug --no-build --nologo ` --logger "console;verbosity=minimal" } @@ -603,7 +603,7 @@ Fuzz fix []: Crash input SHA-256: Target: -Originating libFuzzer instance: Fuzzing/.runs/// +Originating libFuzzer instance: fuzzing/.runs/// Symptom: at @@ -619,7 +619,7 @@ Fix: Files touched: - Fuzzing/Opc.Ua..Fuzz.Tests/Assets/- (new regression asset) + fuzzing/Opc.Ua..Fuzz.Tests/Assets/- (new regression asset) Regression test count (net10.0): Encoders , Certificates , Network , total , 0 failed. ``` @@ -712,7 +712,7 @@ When a fix lands, print: enumerator filters them out when `aflfuzz` ∉ `$engines`. - **afl-fuzz on Linux without afl-fuzz installed**: the Setup gate detects this, logs a one-liner ("afl-fuzz not on PATH; skipping AFL engine. Run - `Fuzzing/Scripts/install.sh` to enable.") and continues with libFuzzer + `fuzzing/Scripts/install.sh` to enable.") and continues with libFuzzer only. Do NOT auto-install — `install.sh` requires sudo and a compile toolchain. - **AFL CPU governor warning**: on Linux, afl-fuzz may complain about the @@ -721,7 +721,7 @@ When a fix lands, print: they can run `sudo cpupower frequency-set -g performance` outside the agent. - **AFL_SKIP_BIN_CHECK**: required because the binary under test is - `dotnet`, not a native AFL-instrumented ELF. `Fuzzing/Scripts/fuzz-afl.ps1` + `dotnet`, not a native AFL-instrumented ELF. `fuzzing/Scripts/fuzz-afl.ps1` already sets this; the agent's inline invocation sets it too. - **afl-fuzz `findings//queue/`**: live coverage-expanding corpus — NOT findings. Never copy these to Assets/ or treat them as crashes. @@ -774,7 +774,7 @@ When a fix lands, print: - Rubber-duck still flags substantive issues after 2 review rounds. - The user asks for an option the agent doesn't have (e.g., "fuzz the PubSub area" — that area doesn't exist yet, propose adding it). -- Disk pressure: `Fuzzing/.runs/` exceeding ~2 GB or `/tmp` running low — +- Disk pressure: `fuzzing/.runs/` exceeding ~2 GB or `/tmp` running low — pause and ask whether to discard old run dirs. ## Success criteria @@ -793,4 +793,4 @@ You have successfully completed an autonomous fuzz session when: and the list of pushed commits. - Working tree is clean. `git status` shows no uncommitted modifications related to fuzz work (allowed: untracked work-in-progress under - `Fuzzing/.runs/` and `Fuzzing/.tools/` which are gitignored). + `fuzzing/.runs/` and `fuzzing/.tools/` which are gitignored). diff --git a/.github/agents/opc-ua-codestyle-enforcer.agent.md b/.github/agents/opc-ua-codestyle-enforcer.agent.md index bcd03d8124..a13b191e64 100644 --- a/.github/agents/opc-ua-codestyle-enforcer.agent.md +++ b/.github/agents/opc-ua-codestyle-enforcer.agent.md @@ -17,7 +17,7 @@ You are a code-style enforcement specialist for the OPC UA .NET Standard reposit - `.editorconfig` — Roslyn style rules + Roslynator analyzers. Several CA/RCS rules are promoted to `severity = error` (CA1014, CA1305, CA1307, CA2007, CA2016, CA2213, CA2000, RCS1166, NUnit4002, NUnit2046). - `Directory.Build.props` → imports `common.props` + `targets.props` + `version.props`. - **Analyzers:** Roslynator.Analyzers, Roslynator.Formatting.Analyzers, NUnit.Analyzers, plus built-in .NET analyzers. -- **Polyfills:** `Stack/Opc.Ua.Types/Polyfills/System.cs` provides `IndexOf(char, StringComparison)`, `Replace(string, string, StringComparison)`, `Contains(string, StringComparison)` for net48/netstandard2.0. Always check polyfill availability before using .NET 6+ APIs. +- **Polyfills:** `src/Opc.Ua.Types/Polyfills/System.cs` provides `IndexOf(char, StringComparison)`, `Replace(string, string, StringComparison)`, `Contains(string, StringComparison)` for net48/netstandard2.0. Always check polyfill availability before using .NET 6+ APIs. ## Scoped runs — formatting changed files only @@ -91,9 +91,9 @@ Then build the project(s) and dependent test project(s). | Pattern | What goes wrong | Revert / mitigation | |---|---|---| -| `using Opc.Ua.Security.Certificates;` in a file that uses `Certificate` / `CertificateCollection` as plain identifiers (e.g. 1.5.378 reference fixtures under `Tools/Opc.Ua.MigrationAnalyzer.Core/**`) | `IDE0005` removes the import → `CS0246` on `Certificate` / `CertificateCollection`. | `git checkout HEAD -- ` after the sweep, add the file to a per-file IDE0005 suppression, or add `// dotnet format: keep` comment near the using if you want it preserved across runs. | -| Files that disambiguate via `using OpcUa = Opc.Ua;` and then reference `OpcUa.ObjectTypeIds.X` (e.g. `Tests/Opc.Ua.Gds.Tests/PushTest.cs`) | `IDE0002` strips the `OpcUa.` qualifier → resolves to a conflicting `ObjectTypeIds` in scope → `CS0117`. | Revert the file; if you need the cleanup, do it per-symbol by hand. | -| Multi-TFM files where one TFM's analysis disagrees with another (e.g. `Libraries/Opc.Ua.Server/Server/ServerInternalData.cs` between `net48` and `net10.0`) | The formatter injects literal `<<<<<<<` / `=======` / `>>>>>>>` markers into the file → `CS8300 Merge conflict marker encountered`. | Revert the file; the multi-TFM disagreement needs a manual fix. | +| `using Opc.Ua.Security.Certificates;` in a file that uses `Certificate` / `CertificateCollection` as plain identifiers (e.g. 1.5.378 reference fixtures under `tools/Opc.Ua.MigrationAnalyzer.Core/**`) | `IDE0005` removes the import → `CS0246` on `Certificate` / `CertificateCollection`. | `git checkout HEAD -- ` after the sweep, add the file to a per-file IDE0005 suppression, or add `// dotnet format: keep` comment near the using if you want it preserved across runs. | +| Files that disambiguate via `using OpcUa = Opc.Ua;` and then reference `OpcUa.ObjectTypeIds.X` (e.g. `tests/Opc.Ua.Gds.Tests/PushTest.cs`) | `IDE0002` strips the `OpcUa.` qualifier → resolves to a conflicting `ObjectTypeIds` in scope → `CS0117`. | Revert the file; if you need the cleanup, do it per-symbol by hand. | +| Multi-TFM files where one TFM's analysis disagrees with another (e.g. `src/Opc.Ua.Server/Server/ServerInternalData.cs` between `net48` and `net10.0`) | The formatter injects literal `<<<<<<<` / `=======` / `>>>>>>>` markers into the file → `CS8300 Merge conflict marker encountered`. | Revert the file; the multi-TFM disagreement needs a manual fix. | ## Phase 1 — Discovery: Collect and categorize diagnostics @@ -317,7 +317,7 @@ When master merges bring new projects, they often need: - `Properties/AssemblyInfo.cs` with `[assembly: CLSCompliant(false)]` (CA1014 is enforced at error). - NUnit constraint-model asserts instead of classic asserts (NUnit4002/NUnit2046 are errors). - `ConfigureAwait(false)` on all `await` expressions (CA2007 is an error). -- No `new Random()` — use `UnsecureRandom` from `Stack/Opc.Ua.Types/Utils/UnsecureRandom.cs` (CA5394). +- No `new Random()` — use `UnsecureRandom` from `src/Opc.Ua.Types/Utils/UnsecureRandom.cs` (CA5394). ## Rules intentionally left unfixed diff --git a/.github/agents/opcua-interop-tester.agent.md b/.github/agents/opcua-interop-tester.agent.md index 7b2204c7be..0a35068888 100644 --- a/.github/agents/opcua-interop-tester.agent.md +++ b/.github/agents/opcua-interop-tester.agent.md @@ -9,7 +9,7 @@ You are an expert OPC UA interoperability test engineer. Your role is to systema ## MCP Tools — Primary Test Method -This repository includes an **OPC UA MCP Server** (`Applications/McpServer`) that exposes all OPC UA Part 4 services AND a full packet-capture / offline-decode / replay tool set as MCP tools. **Always prefer using the MCP tools over writing custom C# test code** — they are faster, require no compilation, and cover all standard services plus deep wire-level diagnostics. +This repository includes an **OPC UA MCP Server** (`tools/Opc.Ua.Mcp`) that exposes all OPC UA Part 4 services AND a full packet-capture / offline-decode / replay tool set as MCP tools. **Always prefer using the MCP tools over writing custom C# test code** — they are faster, require no compilation, and cover all standard services plus deep wire-level diagnostics. ### When to Use MCP Tools - **Always** for initial connection, browsing, reading, writing, method calling, subscription testing diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 10c02629a1..c251fa6d5f 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -20,14 +20,15 @@ This is the official OPC UA .NET Standard Stack from the OPC Foundation. It prov - **Build**: Use Visual Studio 2026 or `dotnet build` - **Key solutions**: - `UA.slnx` - Contains all projects -- **Contributor guide**: see [`Docs/DeveloperGuide.md`](../Docs/DeveloperGuide.md) for prerequisites, building (including per-TFM), testing, coding standards, and how-to recipes. +- **Contributor guide**: see [`docs/DeveloperGuide.md`](../docs/DeveloperGuide.md) for prerequisites, building (including per-TFM), testing, coding standards, and how-to recipes. ### Project Structure -- `Libraries/` - Core OPC UA libraries (Client, Server, Configuration, etc.) -- `Applications/` - Reference applications (ConsoleReferenceServer, etc.) -- `Tests/` - Unit and integration tests -- `Stack/` - Core stack implementation -- `Docs/` - Documentation files +- `src/` - Core OPC UA libraries (Client, Server, Configuration, etc.) +- `samples/` - Reference applications (ConsoleReferenceServer, etc.) +- `tests/` - Unit and integration tests +- `tools/` - Source generators, analyzers, and the OPC UA MCP tool +- `docs/` - Documentation files +- `fuzzing/` - Fuzz targets, corpora, and support scripts ### Build Properties - `Directory.Build.props` - Central build properties @@ -77,7 +78,7 @@ This is the official OPC UA .NET Standard Stack from the OPC Foundation. It prov - All source generated code, in particular ObjectType proxies should be used over manually calling service calls inside new clients. - Consider using the source generators to implement emitting "boilerplate", especially if it is related to the OPC UA standard (e.g. information model). - Base services: File System, Certificate manager, Secret store, State machine, Alarms and conditions Streaming subscription, Sessions, etc. in new code. (Documented in docs/*). - - Observability is plumbed through via `ITelemetryContext`. Use it to create an `ILogger` for logging; follow the source-generated logging conventions in [`Docs/DeveloperGuide.md`](../Docs/DeveloperGuide.md#add-a-log-message-source-generated). + - Observability is plumbed through via `ITelemetryContext`. Use it to create an `ILogger` for logging; follow the source-generated logging conventions in [`docs/DeveloperGuide.md`](../docs/DeveloperGuide.md#add-a-log-message-source-generated). - If reuse is not possible, ASK whether to extend an existing feature so it becomes reuseable. ### Code Style @@ -103,12 +104,12 @@ This is the official OPC UA .NET Standard Stack from the OPC Foundation. It prov - Assembly prefix: `Opc.Ua` (Except applications, or if otherwise requested) - Package prefix: `OPCFoundation.NetStandard` - Always use a line break after `` and before `` for all members (except for documentation of fields). This applies to **every** XML-doc summary, including in sample/application code — never write a single-line `/// ... `; always put the text on its own line between the opening and closing tags. -- Use source-generated `[LoggerMessage]` logging; never call `ILogger.LogInformation/LogError/...` directly. Follow the per-file `Log` and per-assembly `EventIds` conventions in [`Docs/DeveloperGuide.md`](../Docs/DeveloperGuide.md#add-a-log-message-source-generated). +- Use source-generated `[LoggerMessage]` logging; never call `ILogger.LogInformation/LogError/...` directly. Follow the per-file `Log` and per-assembly `EventIds` conventions in [`docs/DeveloperGuide.md`](../docs/DeveloperGuide.md#add-a-log-message-source-generated). ### Security Requirements - **Never hardcode credentials, certificates, or secrets** in source code -- **Certificate Management**: All certificates must be managed through the certificate store system (see `Docs/CertificateManager.md`) -- **Secrets**: All secrets must be managed through the secret store system (see `Docs/CertificateManager.md`) +- **Certificate Management**: All certificates must be managed through the certificate store system (see `docs/CertificateManager.md`) +- **Secrets**: All secrets must be managed through the secret store system (see `docs/CertificateManager.md`) - **Security Profiles**: do not use hash algorithms other than SHA2 or higher. - **Authentication**: Properly implement anonymous, username, and X.509 certificate user authentication - **Audit and Redaction**: Use the audit and redaction APIs for sensitive information @@ -121,7 +122,7 @@ This is the official OPC UA .NET Standard Stack from the OPC Foundation. It prov - DO NOT USE the classic Nunit asserts (E.g. Assert.AreEquals) or other libraries. - All new features must include unit tests. Tests should be simple and cover positive and negative scenarios. Unit tests go into the corresponding .Tests project - DO Maintain or improve code coverage - - All projects should have at least 80% coverage (exception Applications, and Test projects). + - All projects should have at least 80% coverage (except sample and test projects). - All client/server as well as pub/sub features must also have Integration tests. Integration tests go into integration projects .Tests. - Tests must be deterministic and pass in CI/CD environment - Code coverage is monitored via Coverlet and MUST NOT decrease @@ -135,13 +136,13 @@ This is the official OPC UA .NET Standard Stack from the OPC Foundation. It prov ### Documentation #### When to Update Documentation -- Add a new doc in `Docs/` when adding new features and link from `/docs/README.md` +- Add a new doc in `docs/` when adding new features and link from `/docs/README.md` - Review all other docs for consistency and when needed, link the new doc from other docs. - When manual migration from 1.5.378 (master378) is required or code was marked [Obsolete], update migrationguide.md - Update `/README.md` for significant changes - Keep `NugetREADME.md` updated for package-related changes - Document breaking changes prominently -- Keep [`Docs/DeveloperGuide.md`](../Docs/DeveloperGuide.md) (the contributor onboarding guide) current when build, test, or coding-convention changes affect contributors. +- Keep [`docs/DeveloperGuide.md`](../docs/DeveloperGuide.md) (the contributor onboarding guide) current when build, test, or coding-convention changes affect contributors. #### Documentation Style - Use clear, technical language @@ -188,7 +189,7 @@ This is the official OPC UA .NET Standard Stack from the OPC Foundation. It prov ### Certificate Management - NEVER commit certificates or secrets of any kind to the repository - Use the certificate manager APIs -- Follow guidelines in `Docs/Certificates.md` +- Follow guidelines in `docs/Certificates.md` - Test with different certificate configurations ### Performance Considerations @@ -203,7 +204,7 @@ This is the official OPC UA .NET Standard Stack from the OPC Foundation. It prov ## Resources - OPC UA Specification: https://reference.opcfoundation.org/ -- Documentation: See `Docs/` directory +- Documentation: See `docs/` directory - Samples Repository: https://github.com/OPCFoundation/UA-.NETStandard-Samples - NuGet Packages: - Types: https://www.nuget.org/packages/OPCFoundation.NetStandard.Opc.Ua.Types/ diff --git a/.github/workflows/buildandtest.yml b/.github/workflows/buildandtest.yml index 80318c0caf..dc985c8cc4 100644 --- a/.github/workflows/buildandtest.yml +++ b/.github/workflows/buildandtest.yml @@ -47,7 +47,7 @@ jobs: aot_matrix: ${{ steps.list.outputs.aot_matrix }} steps: - uses: actions/checkout@v7 - - name: Enumerate Tests/Opc.Ua.*.Tests projects + - name: Enumerate tests/Opc.Ua.*.Tests projects id: list shell: pwsh env: @@ -60,7 +60,7 @@ jobs: # (AOT has its own workflow; the Stress suite is opt-in via the # stress-test workflow). $exclude = @('Aot', 'Stress') - $projects = Get-ChildItem -Path Tests -Directory -Filter 'Opc.Ua.*.Tests' | + $projects = Get-ChildItem -Path tests -Directory -Filter 'Opc.Ua.*.Tests' | Where-Object { Test-Path (Join-Path $_.FullName "$($_.Name).csproj") } | ForEach-Object { $_.Name -replace '^Opc\.Ua\.', '' -replace '\.Tests$', '' } | Where-Object { $exclude -notcontains $_ } | @@ -111,7 +111,7 @@ jobs: DOTNET_VERSION: ${{ matrix.dotnet-version }} CONFIGURATION: ${{ matrix.configuration }} CSPROJ: ${{ matrix.csproj }} - CSPROJECT: "./Tests/Opc.Ua.${{ matrix.csproj }}.Tests/Opc.Ua.${{ matrix.csproj }}.Tests.csproj" + CSPROJECT: "./tests/Opc.Ua.${{ matrix.csproj }}.Tests/Opc.Ua.${{ matrix.csproj }}.Tests.csproj" TESTRESULTS: "TestResults-${{matrix.csproj}}-${{matrix.os}}-${{matrix.framework}}-${{matrix.configuration}}" steps: @@ -148,7 +148,7 @@ jobs: '/p:CustomTestTarget=${{ matrix.customtesttarget }}', '--collect:XPlat Code Coverage', '--settings', - './Tests/coverlet.runsettings.xml', + './tests/coverlet.runsettings.xml', '--results-directory', '${{ env.TESTRESULTS }}') @@ -193,7 +193,7 @@ jobs: include: ${{ fromJSON(needs.discover.outputs.aot_matrix) }} env: - AOTPROJECT: './Tests/Opc.Ua.Aot.Tests/Opc.Ua.Aot.Tests.csproj' + AOTPROJECT: './tests/Opc.Ua.Aot.Tests/Opc.Ua.Aot.Tests.csproj' DOTNET_VERSION: '10.0.x' CONFIGURATION: 'Release' @@ -215,7 +215,7 @@ jobs: run: dotnet publish ${{ env.AOTPROJECT }} --configuration ${{ env.CONFIGURATION }} - name: Run NativeAOT Tests - run: ./Tests/Opc.Ua.Aot.Tests/bin/${{ env.CONFIGURATION }}/net10.0/${{ matrix.rid }}/publish/Opc.Ua.Aot.Tests + run: ./tests/Opc.Ua.Aot.Tests/bin/${{ env.CONFIGURATION }}/net10.0/${{ matrix.rid }}/publish/Opc.Ua.Aot.Tests - name: Upload test results uses: actions/upload-artifact@v7 diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index c63976226d..7422e026a1 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -4,13 +4,13 @@ on: push: branches: [ master, release/*, docker* ] paths-ignore: - - 'Docs/**' - - 'Tests/**' + - 'docs/**' + - 'tests/**' pull_request: branches: [ master ] paths-ignore: - - 'Docs/**' - - 'Tests/**' + - 'docs/**' + - 'tests/**' concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -29,25 +29,25 @@ jobs: include: # Sample servers - image: refserver - dockerfile: ./Applications/ConsoleReferenceServer/Dockerfile + dockerfile: ./samples/ConsoleReferenceServer/Dockerfile - image: ldsserver - dockerfile: ./Applications/ConsoleLdsServer/Dockerfile + dockerfile: ./samples/ConsoleLdsServer/Dockerfile - image: boilerserver - dockerfile: ./Applications/MinimalBoilerServer/Dockerfile + dockerfile: ./samples/MinimalBoilerServer/Dockerfile - image: calcserver - dockerfile: ./Applications/MinimalCalcServer/Dockerfile + dockerfile: ./samples/MinimalCalcServer/Dockerfile - image: mcpserver - dockerfile: ./Applications/McpServer/Dockerfile + dockerfile: ./tools/Opc.Ua.Mcp/Dockerfile - image: redundantserver - dockerfile: ./Applications/RedundantServer/Dockerfile + dockerfile: ./samples/RedundantServer/Dockerfile # Redundant client - image: redundantclient - dockerfile: ./Applications/RedundantClient/Dockerfile + dockerfile: ./samples/RedundantClient/Dockerfile # PubSub samples - image: redundantpubsub - dockerfile: ./Applications/RedundantPubSub/Dockerfile + dockerfile: ./samples/RedundantPubSub/Dockerfile - image: pubsubclient - dockerfile: ./Applications/ConsoleReferencePubSubClient/Dockerfile + dockerfile: ./samples/ConsoleReferencePubSubClient/Dockerfile env: IMAGE_NAME: ${{ matrix.image }} IS_NOT_PR: ${{ !github.head_ref && true }} diff --git a/.github/workflows/preview-publish.yml b/.github/workflows/preview-publish.yml index f0ab9f05c5..f57849648e 100644 --- a/.github/workflows/preview-publish.yml +++ b/.github/workflows/preview-publish.yml @@ -145,10 +145,10 @@ jobs: if: env.SIGNING_CLIENT_SECRET != '' shell: cmd run: | - dir /b /s Stack\Opc.Ua*.dll > .\list.txt - dir /b /s Tools\Opc.Ua*.dll >> .\list.txt - dir /b /s Libraries\Opc.Ua*.dll >> .\list.txt - dir /b /s Applications\McpServer\bin\Opc.Ua*.dll >> .\list.txt + dir /b /s src\Opc.Ua*.dll > .\list.txt + dir /b /s tools\Opc.Ua*.dll >> .\list.txt + dir /b /s src\Opc.Ua*.dll >> .\list.txt + dir /b /s tools\Opc.Ua.Mcp\bin\Opc.Ua*.dll >> .\list.txt dir /b /s .azurepipelines\*.* >> .\list.txt type .\list.txt @@ -188,7 +188,7 @@ jobs: - name: Pack NuGet Legacy (nuget/*.nuspec, version from PACK_MODE) shell: pwsh - # Scoped to nuget/ - the MigrationAnalyzer nuspec at Tools/Opc.Ua.MigrationAnalyzer/ + # Scoped to nuget/ - the MigrationAnalyzer nuspec at tools/Opc.Ua.MigrationAnalyzer/ # uses MSBuild $(...) substitutions that only `dotnet pack` resolves; standalone # `nuget.exe pack` would crash on it. See PR #3872. continue-on-error: true diff --git a/.github/workflows/pump-device-integration-server-docker.yml b/.github/workflows/pump-device-integration-server-docker.yml index 87d0e3419c..45c2ab8acf 100644 --- a/.github/workflows/pump-device-integration-server-docker.yml +++ b/.github/workflows/pump-device-integration-server-docker.yml @@ -4,10 +4,10 @@ on: push: branches: [ master ] paths: - - 'Applications/PumpDeviceIntegrationServer/**' - - 'Libraries/**' - - 'Stack/**' - - 'Tools/**' + - 'samples/PumpDeviceIntegrationServer/**' + - 'src/**' + - 'src/**' + - 'tools/**' - 'Directory.*.props' - 'Directory.Build.targets' - '*.props' @@ -73,7 +73,7 @@ jobs: uses: docker/build-push-action@v7 with: context: . - file: ./Applications/PumpDeviceIntegrationServer/Dockerfile + file: ./samples/PumpDeviceIntegrationServer/Dockerfile build-args: | Version=${{ env.NBGV_Version }} SimpleVersion=${{ env.NBGV_SimpleVersion }} diff --git a/.github/workflows/sample-ha-longhaul.yml b/.github/workflows/sample-ha-longhaul.yml index 4f8f210768..15c06744c8 100644 --- a/.github/workflows/sample-ha-longhaul.yml +++ b/.github/workflows/sample-ha-longhaul.yml @@ -34,7 +34,7 @@ jobs: DOTNET_VERSION: '10.0.x' TARGET_FRAMEWORK: 'net10.0' CONFIGURATION: 'Release' - TESTPROJECT: './Tests/Opc.Ua.Redundancy.Samples.Tests/Opc.Ua.Redundancy.Samples.Tests.csproj' + TESTPROJECT: './tests/Opc.Ua.Redundancy.Samples.Tests/Opc.Ua.Redundancy.Samples.Tests.csproj' SAMPLE_HA_DURATION_MINUTES: ${{ github.event.inputs.duration || '60' }} steps: diff --git a/.github/workflows/stability-test.yml b/.github/workflows/stability-test.yml index 8f4306846a..684e07a645 100644 --- a/.github/workflows/stability-test.yml +++ b/.github/workflows/stability-test.yml @@ -46,12 +46,12 @@ jobs: run: dotnet restore 'UA.slnx' - name: Build Client Tests - run: dotnet build ./Tests/Opc.Ua.Client.Tests/Opc.Ua.Client.Tests.csproj --configuration ${{ env.CONFIGURATION }} --no-restore + run: dotnet build ./tests/Opc.Ua.Client.Tests/Opc.Ua.Client.Tests.csproj --configuration ${{ env.CONFIGURATION }} --no-restore - name: Run Connection Stability Test run: | echo "Starting connection stability test for $TEST_DURATION_MINUTES minutes" - dotnet test ./Tests/Opc.Ua.Client.Tests/Opc.Ua.Client.Tests.csproj \ + dotnet test ./tests/Opc.Ua.Client.Tests/Opc.Ua.Client.Tests.csproj \ --configuration ${{ env.CONFIGURATION }} \ --no-build \ --framework ${{ env.TARGET_FRAMEWORK }} \ diff --git a/.github/workflows/stress-test.yml b/.github/workflows/stress-test.yml index f55e1ca597..a91fe3d5d5 100644 --- a/.github/workflows/stress-test.yml +++ b/.github/workflows/stress-test.yml @@ -31,7 +31,7 @@ jobs: TARGET_FRAMEWORK: 'net10.0' CONFIGURATION: 'Release' CUSTOM_TEST_TARGET: 'net10.0' - STRESS_PROJECT: './Tests/Opc.Ua.Stress.Tests/Opc.Ua.Stress.Tests.csproj' + STRESS_PROJECT: './tests/Opc.Ua.Stress.Tests/Opc.Ua.Stress.Tests.csproj' TESTRESULTS: './TestResults/chaos-tcp' steps: @@ -88,10 +88,10 @@ jobs: 'PowerShell:', " `$env:OPCUA_CHAOS_SEED = '$seed'", " `$env:OPCUA_TEST_SEED = '$seed'", - ' dotnet test .\Tests\Opc.Ua.Stress.Tests\Opc.Ua.Stress.Tests.csproj --framework net10.0 --configuration Release --filter "Category=ChaosTCP"', + ' dotnet test .\tests\Opc.Ua.Stress.Tests\Opc.Ua.Stress.Tests.csproj --framework net10.0 --configuration Release --filter "Category=ChaosTCP"', '', 'Bash:', - " OPCUA_CHAOS_SEED=$seed OPCUA_TEST_SEED=$seed dotnet test ./Tests/Opc.Ua.Stress.Tests/Opc.Ua.Stress.Tests.csproj --framework net10.0 --configuration Release --filter 'Category=ChaosTCP'") + " OPCUA_CHAOS_SEED=$seed OPCUA_TEST_SEED=$seed dotnet test ./tests/Opc.Ua.Stress.Tests/Opc.Ua.Stress.Tests.csproj --framework net10.0 --configuration Release --filter 'Category=ChaosTCP'") $repro | Set-Content -Path (Join-Path $env:TESTRESULTS 'chaos-seed.txt') Write-Host "ChaosTCP seed: $seed" diff --git a/.gitignore b/.gitignore index 69f76ef025..65b8d47902 100644 --- a/.gitignore +++ b/.gitignore @@ -265,9 +265,9 @@ OPC\ Foundation/ testEnvironments.json # UA Fuzzing findings folders -/Fuzzing/**/findings/ -/Fuzzing/**/Testcases/ -!/Fuzzing/**/Testcases/*.bin +/fuzzing/**/findings/ +/fuzzing/**/Testcases/ +!/fuzzing/**/Testcases/*.bin **/Properties/launchSettings.json aot-publish*.txt diff --git a/Directory.Packages.props b/Directory.Packages.props index ec9aae5b62..3590472357 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -130,7 +130,7 @@ diff --git a/README.md b/README.md index 22dadc0483..cd9e845f37 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,8 @@ across industrial control, manufacturing, energy, and IoT systems. LLMs / Copilot can drive an OPC UA client. For the full feature breakdown see -**[OPC UA Profiles and Facets](Docs/Profiles.md)** and the -**[What's New in 2.0](Docs/WhatsNewIn2.0.md)** tour. +**[OPC UA Profiles and Facets](docs/Profiles.md)** and the +**[What's New in 2.0](docs/WhatsNewIn2.0.md)** tour. ## 🚀 Getting started @@ -56,7 +56,7 @@ dotnet build UA.slnx ``` For the supported target frameworks and platform notes see -the [Developer Guide](Docs/DeveloperGuide.md#packages-platform-support-and-versioning). The official NuGet packages +the [Developer Guide](docs/DeveloperGuide.md#packages-platform-support-and-versioning). The official NuGet packages are published to nuget.org under the `OPCFoundation.NetStandard` prefix — the meta package [OPCFoundation.NetStandard.Opc.Ua](https://www.nuget.org/packages/OPCFoundation.NetStandard.Opc.Ua/) @@ -72,35 +72,31 @@ Each sample has its own `README.md` with build and run instructions. **Reference applications** -- [Console Reference Server](Applications/ConsoleReferenceServer/README.md) — +- [Console Reference Server](samples/ConsoleReferenceServer/README.md) — the certified reference server (with Quickstarts, CTT, and Mono configs). Also ships as a - [Docker container](Docs/ContainerReferenceServer.md). -- [Console Reference Client](Applications/ConsoleReferenceClient/README.md) — + [Docker container](docs/ContainerReferenceServer.md). +- [Console Reference Client](samples/ConsoleReferenceClient/README.md) — cross-platform reference client demonstrating sessions, subscriptions, browsing, and method calls. -- [Console LDS Server](Applications/ConsoleLdsServer) — a standalone +- [Console LDS Server](samples/ConsoleLdsServer) — a standalone Local Discovery Server built on `Opc.Ua.Lds.Server`. -- [MCP Server](Applications/McpServer/README.md) — Model Context - Protocol server that exposes OPC UA client operations as MCP tools, - so an LLM / Copilot can browse, read, write, subscribe, and call - methods on any OPC UA server. **PubSub samples** -- [Console Reference PubSub Client](Applications/ConsoleReferencePubSubClient/README.md) — +- [Console Reference PubSub Client](samples/ConsoleReferencePubSubClient/README.md) — one executable with `publisher`, `subscriber`, and `external` (external-server adapter) modes across the supported transport profiles. **Minimal / Device-Integration samples** -- [Minimal Calc Server](Applications/MinimalCalcServer) — minimal +- [Minimal Calc Server](samples/MinimalCalcServer) — minimal server built on the source-generated NodeManager pipeline (Calc model). -- [Minimal Boiler Server](Applications/MinimalBoilerServer) — minimal +- [Minimal Boiler Server](samples/MinimalBoilerServer) — minimal Boiler-model server with the fluent state-machine builder; Native-AOT publishable. -- [Pump Device Integration Server](Applications/PumpDeviceIntegrationServer/README.md) — +- [Pump Device Integration Server](samples/PumpDeviceIntegrationServer/README.md) — minimal Device Integration (Part 100) server using `Opc.Ua.Di.Server`'s fluent builder. @@ -108,11 +104,15 @@ More sample projects are maintained in the companion [OPC UA .NET Samples](https://github.com/OPCFoundation/UA-.NETStandard-Samples) repository. +### Developer tools + +- [OPC UA MCP Server](tools/Opc.Ua.Mcp/README.md) — installable .NET tool and container that exposes OPC UA client operations as MCP tools for LLMs and Copilot. + ## 🔧 Migrating from 1.5.378 to 2.0 The 2.0 release introduces breaking API changes, and comes with a full -[prescriptive migration guide](Docs/MigrationGuide.md) that links to -[per-area documentation](Docs/migrate/2.0.x/README.md) covering +[prescriptive migration guide](docs/MigrationGuide.md) that links to +[per-area documentation](docs/migrate/2.0.x/README.md) covering telemetry, packages, source generation, types, encoders, node states, identity, certificates, configuration, sessions / subscriptions, alarms / model change, and TimeProvider. @@ -123,7 +123,7 @@ Most of the mechanical migration work is automated: install it in your project to get analyzer warnings (`UA0001`–`UA0022`) + one-click code fixes for the patterns in the guide. Setup steps are in the package's - [NugetREADME.md](Tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md). + [NugetREADME.md](tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md). - **Migration agent skill** — the [`opcua-v20-migration`](.agents/skills/opcua-v20-migration/SKILL.md) skill walks Copilot / Claude / any coding agent through installing @@ -152,15 +152,15 @@ vulnerabilities via the process documented in ## 📚 Further reading -- [Documentation index](Docs/README.md) — every per-feature doc with a +- [Documentation index](docs/README.md) — every per-feature doc with a one-line description. -- [What's New in 2.0](Docs/WhatsNewIn2.0.md) — narrative tour of the +- [What's New in 2.0](docs/WhatsNewIn2.0.md) — narrative tour of the 1.5.378 → 2.0 changes grouped by theme and layer. -- [OPC UA Profiles and Facets](Docs/Profiles.md) — facets / transports / +- [OPC UA Profiles and Facets](docs/Profiles.md) — facets / transports / security policies the stack implements. -- [Migration Guide](Docs/MigrationGuide.md) — prescriptive +- [Migration Guide](docs/MigrationGuide.md) — prescriptive per-version migration reference (links to - [`Docs/migrate/2.0.x/`](Docs/migrate/2.0.x/README.md)). + [`docs/migrate/2.0.x/`](docs/migrate/2.0.x/README.md)). - [OPC UA Online Reference](https://reference.opcfoundation.org/) — the official OPC 10000 series specification index. - [OPC UA .NET Samples](https://github.com/OPCFoundation/UA-.NETStandard-Samples) — diff --git a/UA.slnx b/UA.slnx index 5963397d06..765e9cedb6 100644 --- a/UA.slnx +++ b/UA.slnx @@ -1,92 +1,98 @@ - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - + + + - - - - - - + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -101,11 +107,11 @@ - - - - - + + + + + @@ -131,145 +137,138 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - + + - - - - - - + + + + + - - - - - + + + + + diff --git a/azure-pipelines-preview.yml b/azure-pipelines-preview.yml index 57807b8ee9..c763880fea 100644 --- a/azure-pipelines-preview.yml +++ b/azure-pipelines-preview.yml @@ -17,10 +17,10 @@ trigger: - 'main' paths: include: - - 'Stack/**' - - 'Libraries/**' - - 'Tools/**' - - 'Applications/Opc.Ua.*/**' + - 'src/**' + - 'src/**' + - 'tools/**' + - 'samples/Opc.Ua.*/**' variables: # When managedPool is true, route the preview NuGet build to the diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ddda8339ca..d0dfa2157e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -19,7 +19,7 @@ trigger: include: - '*' exclude: - - 'Docs/**' + - 'docs/**' - '**/*.md' pr: autoCancel: 'true' @@ -31,7 +31,7 @@ pr: include: - '*' exclude: - - 'Docs/**' + - 'docs/**' - '**/*.md' # Weekly full-scope run. Fires every Sunday at 02:00 UTC (late Saturday diff --git a/codecov.yml b/codecov.yml index e5cb1f0c68..7aa588777a 100644 --- a/codecov.yml +++ b/codecov.yml @@ -32,8 +32,8 @@ coverage: # Exclude code that should not count against coverage targets. ignore: - - "Tests/**" - - "Applications/**" + - "tests/**" + - "samples/**" - "**/obj/**" - "**/bin/**" - "**/*.g.cs" diff --git a/docs/AlarmsAndConditions.md b/docs/AlarmsAndConditions.md index afdc20836f..6f674e60fb 100644 --- a/docs/AlarmsAndConditions.md +++ b/docs/AlarmsAndConditions.md @@ -83,7 +83,7 @@ await new AlarmConditionTypeClient(session, conditionId, telemetry) `AlarmConditionState` is the central server-side state type for all Part 9 alarms. It is *source-generated* from the standard NodeSet and extended with hand-written behavior. The behavior partial file -(`Stack/Opc.Ua.Core.Types/State/AlarmConditionState.Methods.cs`) wires +(`src/Opc.Ua.Core.Types/State/AlarmConditionState.Methods.cs`) wires every Part 9 method handler during `OnAfterCreate`, so as soon as you populate the optional state nodes the corresponding methods are callable. @@ -108,7 +108,7 @@ generated `AlarmConditionState`: assign to `alarm.SilenceState`, `alarm.OutOfServiceState`, `alarm.LatchedState`, etc. before calling `Create`. The quickstart reference server creates these via `AlarmConditionTypeHolder.Initialize` — -`Applications/Quickstarts.Servers/Alarms/AlarmHolders/`. +`samples/Quickstarts.Servers/Alarms/AlarmHolders/`. ### Driving state from your process @@ -201,7 +201,7 @@ alarm.SetOutOfServiceState(context, false); // SuppressedOrShelved = false ### Alarm groups and first-in-group -`Libraries/Opc.Ua.Server/Alarms/AlarmGroup.cs` wraps a generated +`src/Opc.Ua.Server/Alarms/AlarmGroup.cs` wraps a generated `AlarmGroupState` and provides typed add/remove/enumerate: ```csharp @@ -245,7 +245,7 @@ The first `Evaluate` call always applies the current state, so clients see a coherent suppression state immediately after registration — there is no edge required. -> **Live demo:** The `Applications/Quickstarts.Servers/Alarms/ +> **Live demo:** The `samples/Quickstarts.Servers/Alarms/ > AlarmNodeManager.cs` reference implementation wires this up > end-to-end. It exposes a `/Alarms/AnalogGroup` (`AlarmGroupType`) > containing every analog-source alarm and a writable @@ -592,7 +592,7 @@ session. - [State Machines](StateMachines.md) — generic Part 16 state-machine API used by `AlarmClient.GetShelvingStateAsync` / `ObserveShelvingTransitionsAsync` - [Model Change Tracking](ModelChangeTracking.md) — client cache invalidation on address-space changes -- Source: `Libraries/Opc.Ua.Server/Alarms/`, `Libraries/Opc.Ua.Client/Alarms/`, - `Stack/Opc.Ua.Core.Types/State/AlarmConditionState.Methods.cs` -- Reference client sample: `Applications/ConsoleReferenceClient/AlarmClientSample.cs` -- Conformance tests: `Tests/Opc.Ua.History.Tests/AlarmsAndConditions*.cs` \ No newline at end of file +- Source: `src/Opc.Ua.Server/Alarms/`, `src/Opc.Ua.Client/Alarms/`, + `src/Opc.Ua.Core.Types/State/AlarmConditionState.Methods.cs` +- Reference client sample: `samples/ConsoleReferenceClient/AlarmClientSample.cs` +- Conformance tests: `tests/Opc.Ua.History.Tests/AlarmsAndConditions*.cs` \ No newline at end of file diff --git a/docs/AliasNames.md b/docs/AliasNames.md index 714ee79e54..690c37b720 100644 --- a/docs/AliasNames.md +++ b/docs/AliasNames.md @@ -349,10 +349,10 @@ while letting PubSub drive the rest. * OPC UA Part 17 specification: https://reference.opcfoundation.org/v105/Core/docs/Part17/ -* `Tools/Opc.Ua.SourceGeneration.Core/Design/StandardTypes.xml` — +* `tools/Opc.Ua.SourceGeneration.Core/Design/StandardTypes.xml` — Part 17 type definitions consumed by the source generator. -* `Tests/Opc.Ua.Server.Tests/AliasNames/` — server-side unit tests. -* `Tests/Opc.Ua.Client.Tests/AliasNames/` — mocked-session and live +* `tests/Opc.Ua.Server.Tests/AliasNames/` — server-side unit tests. +* `tests/Opc.Ua.Client.Tests/AliasNames/` — mocked-session and live integration tests. -* `Applications/Quickstarts.Servers/ReferenceServer/ReferenceServer.cs` +* `samples/Quickstarts.Servers/ReferenceServer/ReferenceServer.cs` — `ConfigureAliasNameStore` shows how to seed and register a store. diff --git a/docs/Benchmarks.md b/docs/Benchmarks.md index afe555d40c..ed0e5c0e11 100644 --- a/docs/Benchmarks.md +++ b/docs/Benchmarks.md @@ -9,11 +9,11 @@ still slower, and why, plus planned future work), the **pooled encodeable** ## How to run The benchmarks are BenchmarkDotNet harnesses hosted inside the test projects (a -`BenchmarkSwitcher` in `Tests/Common/Main.cs`). Run a single class from its test +`BenchmarkSwitcher` in `tests/Common/Main.cs`). Run a single class from its test project directory: ```powershell -cd Tests/Opc.Ua.Core.Encoders.Tests +cd tests/Opc.Ua.Core.Encoders.Tests dotnet run -c Release -f net10.0 -- --filter "*BinaryEncoderBenchmarks*" --runtimes net10.0 # add --job short for a faster (higher-variance) directional run ``` @@ -21,7 +21,7 @@ dotnet run -c Release -f net10.0 -- --filter "*BinaryEncoderBenchmarks*" --runti Encoder/decoder benchmark classes live in `Opc.Ua.Core.Encoders.Tests` (`BinaryEncoderBenchmarks`, `BinaryDecoderBenchmarks`, `JsonEncoderBenchmarks`, `JsonEncoderTests`). The end-to-end session benchmarks (`SecurityPolicyBenchmarks`) -live in `Tests/Opc.Ua.Sessions.Tests` and spin up a real in-process client + server +live in `tests/Opc.Ua.Sessions.Tests` and spin up a real in-process client + server across every security policy. > Tip: the combined `--filter *` build is flaky on this repo — run **per class**. @@ -301,7 +301,7 @@ activator pooling feature added in support of `ManagedSessionBuilder.WithPoolNot ### Source -`Tests/Opc.Ua.Client.Tests/Subscription/PooledNotificationBenchmarks.cs` +`tests/Opc.Ua.Client.Tests/Subscription/PooledNotificationBenchmarks.cs` ### Methodology @@ -370,15 +370,15 @@ For `EventFieldList`: ```pwsh # Build release -dotnet build Tests/Opc.Ua.Client.Tests -c Release -f net10.0 +dotnet build tests/Opc.Ua.Client.Tests -c Release -f net10.0 # Run BDN harness -cd Tests/Opc.Ua.Client.Tests/bin/Release/net10.0 +cd tests/Opc.Ua.Client.Tests/bin/Release/net10.0 dotnet Opc.Ua.Client.Tests.dll --filter "*PooledNotificationBenchmarks*" ``` Artifacts (markdown, csv, html) are written to -`Tests/Opc.Ua.Client.Tests/bin/Release/net10.0/BenchmarkDotNet.Artifacts/results/`. +`tests/Opc.Ua.Client.Tests/bin/Release/net10.0/BenchmarkDotNet.Artifacts/results/`. ### Out of scope @@ -396,7 +396,7 @@ activator pool system. ## Server session scalability -The `[Explicit]` macro test `ServerManySessionsLoadTestAsync(int sessionCount)` (`Tests/Opc.Ua.Sessions.Tests/LoadTest.cs`) exercises the reference server under many concurrent sessions. Each session opens its own secure channel, creates one slow-publishing subscription (1000 ms) with a single monitored item on a shared value node, and a separate writer session changes that value periodically; every session is expected to receive value-change notifications over a steady-state window. It runs over `Basic256Sha256` (sign & encrypt) and asserts that all sessions connect and all receive notifications. It is parameterized from a `500` baseline up to a `10000` stress case (500, 1000, 1500, 2000, 2500, 4000, 5000, 8000, 10000), selected by name (e.g. `ServerManySessionsLoadTestAsync(2000)`). +The `[Explicit]` macro test `ServerManySessionsLoadTestAsync(int sessionCount)` (`tests/Opc.Ua.Sessions.Tests/LoadTest.cs`) exercises the reference server under many concurrent sessions. Each session opens its own secure channel, creates one slow-publishing subscription (1000 ms) with a single monitored item on a shared value node, and a separate writer session changes that value periodically; every session is expected to receive value-change notifications over a steady-state window. It runs over `Basic256Sha256` (sign & encrypt) and asserts that all sessions connect and all receive notifications. It is parameterized from a `500` baseline up to a `10000` stress case (500, 1000, 1500, 2000, 2500, 4000, 5000, 8000, 10000), selected by name (e.g. `ServerManySessionsLoadTestAsync(2000)`). > For a deep, code-referenced analysis of *why* a single node tops out here — the establishment vs steady-state boundaries and the built-in controls for degrading gracefully under load — see [Server Session Scalability](ServerScalability.md). @@ -433,7 +433,7 @@ The numbers below were measured on an **Intel Xeon W-2235 (6 physical cores / 12 Channels now normalize their advertised send and receive limits to the largest protocol-safe value that keeps the data plus cookie in the same `ArrayPool` bucket (while preserving the OPC UA 8,192-byte minimum), and both TCP transport creation paths receive that normalized limit. A configured value of either 65,535 or 65,536 consequently uses 65,536-byte arrays instead of 131,072-byte arrays. -The explicit net10.0 harness `SubscriptionArrayPoolDiagnosticsLoadTests` (`Tests/Opc.Ua.Sessions.Tests/SubscriptionArrayPoolDiagnosticsLoadTests.cs`) measures real subscription traffic with 255 and 257 session Publish queues (immediately below and above the parallel Publish threshold) plus a slow-consumer case. Across both configured buffer sizes, all measured scenarios used only the 65,536-byte bucket, rents and returns balanced exactly after quiescence, outstanding buffers returned to zero, peak outstanding buffers stayed between 528 and 536, and the measurement windows triggered no Gen 2 collections. The 500-session regression baseline also completed for `opc.tcp`, `https`, and `opc.https`, with all 500 sessions receiving notifications. +The explicit net10.0 harness `SubscriptionArrayPoolDiagnosticsLoadTests` (`tests/Opc.Ua.Sessions.Tests/SubscriptionArrayPoolDiagnosticsLoadTests.cs`) measures real subscription traffic with 255 and 257 session Publish queues (immediately below and above the parallel Publish threshold) plus a slow-consumer case. Across both configured buffer sizes, all measured scenarios used only the 65,536-byte bucket, rents and returns balanced exactly after quiescence, outstanding buffers returned to zero, peak outstanding buffers stayed between 528 and 536, and the measurement windows triggered no Gen 2 collections. The 500-session regression baseline also completed for `opc.tcp`, `https`, and `opc.https`, with all 500 sessions receiving notifications. The net10.0 in-process short `BufferManagerBenchmarks` run completed 256 `BufferManager.TakeBuffer`/`ReturnBuffer` pairs in 56.18 us versus 52.52 us for direct `ArrayPool.Shared` use, with no managed allocation reported for either pooled path. These short-run timings are directional; the subscription harness is the authoritative ownership and bucket-size check. diff --git a/docs/CertificateManager.md b/docs/CertificateManager.md index 1cea9927bb..3993d0a599 100644 --- a/docs/CertificateManager.md +++ b/docs/CertificateManager.md @@ -499,7 +499,7 @@ the managed session ALSO automatically reacts: from forcing every session in the process to reconnect. The revalidation loop is implemented in -`Libraries/Opc.Ua.Client/Session/ManagedSession.CertificateChanges.cs`. +`src/Opc.Ua.Client/Session/ManagedSession.CertificateChanges.cs`. It uses a bounded `Channel` of capacity 1 with `BoundedChannelFullMode.DropWrite` so the notifier thread never allocates a `Task` or `CancellationTokenSource` per event — duplicate diff --git a/docs/ComplexTypes.md b/docs/ComplexTypes.md index 7215fe8b66..f6fba20877 100644 --- a/docs/ComplexTypes.md +++ b/docs/ComplexTypes.md @@ -911,4 +911,4 @@ TypeInfo TypeInfo { get; } // Type info of the field - [Source-Generated Data Types](SourceGeneratedDataTypes.md) - Auto-generate IEncodeable implementations from annotated POCO classes - [Developer Guide](DeveloperGuide.md#packages-platform-support-and-versioning) - Building, testing, platform support, packages, and versioning - [Diagnostics Documentation](Diagnostics.md) - Logging, telemetry, audit events, server diagnostics, and packet capture -- [Console Reference Client](../Applications/ConsoleReferenceClient/README.md) - Example client implementation +- [Console Reference Client](../samples/ConsoleReferenceClient/README.md) - Example client implementation diff --git a/docs/ContainerReferenceServer.md b/docs/ContainerReferenceServer.md index d0c08fc031..792da38bc7 100644 --- a/docs/ContainerReferenceServer.md +++ b/docs/ContainerReferenceServer.md @@ -16,29 +16,29 @@ In addition to the reference server (`refserver`), the `Docker Sample Images CI` | Image | Sample application | | --- | --- | -| `refserver` | `Applications/ConsoleReferenceServer` | -| `ldsserver` | `Applications/ConsoleLdsServer` | -| `boilerserver` | `Applications/MinimalBoilerServer` | -| `calcserver` | `Applications/MinimalCalcServer` | -| `pumpserver` | `Applications/PumpDeviceIntegrationServer` | -| `mcpserver` | `Applications/McpServer` | -| `redundantserver` | `Applications/RedundantServer` | -| `redundantclient` | `Applications/RedundantClient` | -| `redundantpubsub` | `Applications/RedundantPubSub` | -| `pubsubclient` | `Applications/ConsoleReferencePubSubClient` | +| `refserver` | `samples/ConsoleReferenceServer` | +| `ldsserver` | `samples/ConsoleLdsServer` | +| `boilerserver` | `samples/MinimalBoilerServer` | +| `calcserver` | `samples/MinimalCalcServer` | +| `pumpserver` | `samples/PumpDeviceIntegrationServer` | +| `mcpserver` | `tools/Opc.Ua.Mcp` | +| `redundantserver` | `samples/RedundantServer` | +| `redundantclient` | `samples/RedundantClient` | +| `redundantpubsub` | `samples/RedundantPubSub` | +| `pubsubclient` | `samples/ConsoleReferencePubSubClient` | -For example: `docker pull ghcr.io/opcfoundation/uanetstandard/ldsserver:latest`. Each image has a Dockerfile under its application folder that is built from the repository root as context (for example `docker build -f Applications/ConsoleLdsServer/Dockerfile -t opcua-lds-server .`). +For example: `docker pull ghcr.io/opcfoundation/uanetstandard/ldsserver:latest`. Each image has a Dockerfile under its application folder that is built from the repository root as context (for example `docker build -f samples/ConsoleLdsServer/Dockerfile -t opcua-lds-server .`). ## Building the local containers 1. Open a command prompt which can execute docker commands. -2. Navigate to the folder `Applications/ConsoleReferenceServer`. +2. Navigate to the folder `samples/ConsoleReferenceServer`. 3. Build the docker container by executing the command `dockerbuild.cmd`. On Linux, 1. Open a shell which can execute docker commands. -2. Navigate to the folder `Applications/ConsoleReferenceServer`. +2. Navigate to the folder `samples/ConsoleReferenceServer`. 3. Build the docker container by executing the command `./dockerbuild.sh`. ## Run the reference server container diff --git a/docs/DependencyInjection.md b/docs/DependencyInjection.md index 83a7e10835..5e9c59e4e6 100644 --- a/docs/DependencyInjection.md +++ b/docs/DependencyInjection.md @@ -7,20 +7,20 @@ which every feature library hangs its own fluent `.AddXxx(...)` extension. The dependency injection surface is consistent across: -- The OPC UA Core stack (`Stack/Opc.Ua.Core`) -- Application configuration (`Libraries/Opc.Ua.Configuration`) -- The client (`Libraries/Opc.Ua.Client`) -- The complex types client (`Libraries/Opc.Ua.Client.ComplexTypes`) -- Alarms and conditions client (`Libraries/Opc.Ua.Client.Alarms`) -- The server (`Libraries/Opc.Ua.Server`) -- The GDS client (`Libraries/Opc.Ua.Gds.Client.Common`) -- The GDS server (`Libraries/Opc.Ua.Gds.Server.Common`) -- The LDS server (`Libraries/Opc.Ua.Lds.Server`) -- The WoT Connectivity server (`Libraries/Opc.Ua.WotCon.Server`) -- The WoT Connectivity client (`Libraries/Opc.Ua.WotCon.Client`) -- The PubSub stack (`Libraries/Opc.Ua.PubSub`, - `Libraries/Opc.Ua.PubSub.Udp`, `Libraries/Opc.Ua.PubSub.Mqtt`, - `Libraries/Opc.Ua.PubSub.Server`) — see [`PubSub.md`](PubSub.md) +- The OPC UA Core stack (`src/Opc.Ua.Core`) +- Application configuration (`src/Opc.Ua.Configuration`) +- The client (`src/Opc.Ua.Client`) +- The complex types client (`src/Opc.Ua.Client.ComplexTypes`) +- Alarms and conditions client (`src/Opc.Ua.Client.Alarms`) +- The server (`src/Opc.Ua.Server`) +- The GDS client (`src/Opc.Ua.Gds.Client.Common`) +- The GDS server (`src/Opc.Ua.Gds.Server.Common`) +- The LDS server (`src/Opc.Ua.Lds.Server`) +- The WoT Connectivity server (`src/Opc.Ua.WotCon.Server`) +- The WoT Connectivity client (`src/Opc.Ua.WotCon.Client`) +- The PubSub stack (`src/Opc.Ua.PubSub`, + `src/Opc.Ua.PubSub.Udp`, `src/Opc.Ua.PubSub.Mqtt`, + `src/Opc.Ua.PubSub.Server`) — see [`PubSub.md`](PubSub.md) for the full library reference. The non-dependency-injection public constructors and factories of every library @@ -202,7 +202,7 @@ The `IConfiguration` / `IConfigurationSection` overloads are (`true`), which replaces the reflection-based binder with statically-generated [C# 12 interceptors](https://learn.microsoft.com/dotnet/csharp/whats-new/csharp-12#interceptors). -The `Tests/Opc.Ua.Aot.Tests` project verifies that `dotnet publish` +The `tests/Opc.Ua.Aot.Tests` project verifies that `dotnet publish` under `PublishAot=true` produces zero `IL2026` / `IL3050` warnings from the dependency injection surface. @@ -1061,7 +1061,7 @@ Notes: diagnostic. Those properties are runtime-only — set them in code, not in `appsettings.json`. The affected libraries suppress those diagnostics in their csproj. -- The `Tests/Opc.Ua.Aot.Tests` project verifies the end-to-end AOT +- The `tests/Opc.Ua.Aot.Tests` project verifies the end-to-end AOT path: build + AOT publish produce **zero** `IL2026` / `IL3050` warnings from any dependency injection extension. diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e228e91486..7ab356d5df 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,6 +1,6 @@ # Developer Guide -This guide is the starting point for contributing to the OPC UA .NET Standard stack. It covers what to install, how to build and test, the coding standards ("dos and don'ts"), and task-oriented "how to" recipes (starting with how to add logging). It links out to the topic-specific documents in [Docs/README.md](README.md) rather than repeating them. +This guide is the starting point for contributing to the OPC UA .NET Standard stack. It covers what to install, how to build and test, the coding standards ("dos and don'ts"), and task-oriented "how to" recipes (starting with how to add logging). It links out to the topic-specific documents in [docs/README.md](README.md) rather than repeating them. If you are new here, read the sections in order: [Prerequisites](#prerequisites) → [Repository layout](#repository-layout) → [Building](#building) → [Running tests](#running-tests) → [Coding standards](#coding-standards-dos-and-donts). The [How-to guides](#how-to-guides) and [Packages, platform support, and versioning](#packages-platform-support-and-versioning) sections are reference material you can jump to as needed. @@ -17,13 +17,12 @@ The C# language version is pinned (`LangVersion` 14) and analyzer/style rules ar | Path | Contents | | --- | --- | -| `Stack/` | The core stack: `Opc.Ua.Types`, `Opc.Ua.Core.Types`, `Opc.Ua.Core.Schema`, `Opc.Ua.Core`, `Opc.Ua.Core.Diagnostics`, `Opc.Ua.Security.Certificates`, and `Opc.Ua.Bindings.Https`. | -| `Libraries/` | Higher-level libraries: `Opc.Ua.Client`, `Opc.Ua.Server`, `Opc.Ua.Configuration`, `Opc.Ua.PubSub` (+ transports), the GDS / DI / LDS / WoT libraries, and the `Opc.Ua.Redundancy*` family. | -| `Applications/` | Reference and sample apps: `ConsoleReferenceServer`, `ConsoleReferenceClient`, `Quickstarts.Servers`, the `Minimal*` / `PumpDeviceIntegrationServer` NativeAOT samples, `McpServer`, `Redundant*`, etc. | -| `Tests/` | Unit and integration test projects, mirroring the library structure, plus shared test frameworks. | -| `Tools/` | Build-time tooling, in particular the OPC UA source generators. | -| `Docs/` | This documentation set (indexed by [Docs/README.md](README.md)). | -| `Fuzzing/` | SharpFuzz / libFuzzer fuzz targets (see [Fuzzing.md](../Fuzzing/Fuzzing.md)). | +| `src/` | The core stack and higher-level libraries: `Opc.Ua.Types`, `Opc.Ua.Core*`, `Opc.Ua.Client`, `Opc.Ua.Server`, `Opc.Ua.Configuration`, `Opc.Ua.PubSub` (+ transports), the GDS / DI / LDS / WoT libraries, and the `Opc.Ua.Redundancy*` family. | +| `samples/` | Reference and sample apps: `ConsoleReferenceServer`, `ConsoleReferenceClient`, `Quickstarts.Servers`, the `Minimal*` / `PumpDeviceIntegrationServer` NativeAOT samples, `Redundant*`, etc. | +| `tests/` | Unit and integration test projects, mirroring the library structure, plus shared test frameworks. | +| `tools/` | Source generators, migration analyzers, and the installable `Opc.Ua.Mcp` tool. | +| `docs/` | This documentation set (indexed by [docs/README.md](README.md)). | +| `fuzzing/` | SharpFuzz / libFuzzer fuzz targets (see [Fuzzing.md](../fuzzing/Fuzzing.md)). | Central build configuration lives at the repository root and is imported by every project: @@ -48,7 +47,7 @@ Notes: - **Building a single target framework.** By default the libraries multi-target the whole matrix (see [Packages, platform support, and versioning](#packages-platform-support-and-versioning)). To restrict a local build to one framework, pass `-p:CustomTargetFrameworks`, for example: ```bash - dotnet build Stack/Opc.Ua.Core/Opc.Ua.Core.csproj -f net10.0 -p:CustomTargetFrameworks=net10.0 + dotnet build src/Opc.Ua.Core/Opc.Ua.Core.csproj -f net10.0 -p:CustomTargetFrameworks=net10.0 ``` - **Offline / restricted networks.** `NuGetAudit` is enabled and fails the build with `NU1900` when it cannot reach the audit service. If you build offline, pass `-p:NuGetAudit=false`. @@ -66,7 +65,7 @@ Conventions and requirements: - **Frameworks.** Test projects use either **NUnit** (with `Assert.That` assertions and **Moq** for mocking) or **TUnit** (with its own assertions and mock helpers). Do not mix the two in one project, and do not use the classic NUnit asserts (`Assert.AreEqual`, …). - **Coverage.** Coverage is measured with **Coverlet** and must not regress; every non-application, non-test project should stay at or above **80 %**. - **Before a pull request** the `UA.slnx` suite must pass on at least **.NET Framework 4.8** and **.NET 10.0**. -- **Testing a specific target framework.** The libraries multi-target, but the test executables run on one framework at a time. To run the suite against a non-default framework, set `CustomTestTarget` (supported values: `netstandard2.0`, `netstandard2.1`, `net472`, `net48`, `net8.0`, `net9.0`, `net10.0`). The batch file [`Tests/customtest.bat`](../Tests/customtest.bat) cleans, restores, and runs the tests for a chosen target; in Visual Studio, uncomment and set the `CustomTestTarget` property in [`targets.props`](../targets.props). A clean build for the target is recommended when switching. +- **Testing a specific target framework.** The libraries multi-target, but the test executables run on one framework at a time. To run the suite against a non-default framework, set `CustomTestTarget` (supported values: `netstandard2.0`, `netstandard2.1`, `net472`, `net48`, `net8.0`, `net9.0`, `net10.0`). The batch file [`tests/customtest.bat`](../tests/customtest.bat) cleans, restores, and runs the tests for a chosen target; in Visual Studio, uncomment and set the `CustomTestTarget` property in [`targets.props`](../targets.props). A clean build for the target is recommended when switching. - **CI matrix.** To keep pull-request builds fast, only **net48** and **net8.0** are exercised in the qualifying CI build; the other frameworks run in scheduled/manual CI. Fix all failing, flaky, and CodeQL findings in the pipelines. ## Coding standards (dos and don'ts) @@ -180,8 +179,8 @@ logger.ReadArrayZeroDimension(index, dimensions); ### Other common tasks -- **Add a new feature** — implement it in the right library, add unit and (for client/server/pubsub) integration tests, update or add a doc under `Docs/`, and keep backward compatibility (see [Coding standards](#coding-standards-dos-and-donts)). -- **Add a document** — put it in `Docs/` and link it from [Docs/README.md](README.md). +- **Add a new feature** — implement it in the right library, add unit and (for client/server/pubsub) integration tests, update or add a doc under `docs/`, and keep backward compatibility (see [Coding standards](#coding-standards-dos-and-donts)). +- **Add a document** — put it in `docs/` and link it from [docs/README.md](README.md). - **Add a dependency** — declare the version in `Directory.Packages.props` (Central Package Management), prefer AOT/trimmable and permissively licensed packages, and get maintainer approval first. - **Certificates and secrets** — see [Certificates.md](Certificates.md) and [CertificateManager.md](CertificateManager.md). - **Source-generated node managers / data types** — see [SourceGeneratedNodeManagers.md](SourceGeneratedNodeManagers.md) and [SourceGeneratedDataTypes.md](SourceGeneratedDataTypes.md). @@ -218,7 +217,7 @@ The class libraries currently target: 6. .NET 9.0 7. .NET 10.0 -To keep pull-request CI fast, only (4) and (6) are part of the qualifying build; the other platforms are covered by scheduled or manual CI. See [Running tests](#running-tests) for how to build and test a specific framework locally with `CustomTestTarget` / `Tests/customtest.bat`. +To keep pull-request CI fast, only (4) and (6) are part of the qualifying build; the other platforms are covered by scheduled or manual CI. See [Running tests](#running-tests) for how to build and test a specific framework locally with `CustomTestTarget` / `tests/customtest.bat`. ### Versioning @@ -238,4 +237,4 @@ From **2.0** onward, package versions are produced by [Nerdbank.GitVersioning](h - [Documentation index](README.md) — all topic guides. - [Diagnostics](Diagnostics.md) — telemetry context, logging runtime, metrics, audit events, server diagnostics nodes, and packet capture. - [Dependency Injection](DependencyInjection.md), [Certificates](Certificates.md) / [Certificate Manager](CertificateManager.md), [NativeAOT](NativeAoT.md), [Migration Guide](MigrationGuide.md), [What's New in 2.0](WhatsNewIn2.0.md). -- [Fuzz testing](../Fuzzing/Fuzzing.md). +- [Fuzz testing](../fuzzing/Fuzzing.md). diff --git a/docs/DeviceIntegration.md b/docs/DeviceIntegration.md index e3fad69230..80feee8197 100644 --- a/docs/DeviceIntegration.md +++ b/docs/DeviceIntegration.md @@ -33,7 +33,7 @@ plugs it together. | `Opc.Ua.Di.Server` | Server: `DiNodeManager`, fluent `IDeviceBuilder`, locking service, software-update package store, hosting integration. | | `Opc.Ua.Di.Client` | Client: `DiDeviceClient`, `DiDiscoveryClient`, `DiTopologyClient`, `DiLockClient`, `SoftwareUpdateClient`, hosting integration. | -The running example is `Applications/PumpDeviceIntegrationServer` +The running example is `samples/PumpDeviceIntegrationServer` (companion-spec server with full simulation **and** the Device Integration software-update facet attached to a second declarative device). @@ -375,7 +375,7 @@ configure callback. The interface exposes properties; consumers populate them by attaching `FileState` or `BaseObjectState` children through the standard `NodeState` API. File-backed children commonly use `FileState` wired to an -`IFileSystemProvider` from `Libraries/Opc.Ua.Server/FileSystem`. +`IFileSystemProvider` from `src/Opc.Ua.Server/FileSystem`. ```csharp device.WithSupportInfo(info => @@ -742,7 +742,7 @@ builder.Services }); ``` -The companion sample `Applications/PumpDeviceIntegrationServer` +The companion sample `samples/PumpDeviceIntegrationServer` demonstrates the end-to-end pattern with `SoftwarePackageSeeder`. ### Client-side software update @@ -949,7 +949,7 @@ Custom groups go through `WithFunctionalGroup(qualifiedName, action)`. ### NAMUR alarms (§10.2) -- `DeviceHealthDiagnosticAlarmType` (abstract) and the four concrete alarm types (`FailureAlarmType`, `CheckFunctionAlarmType`, `OffSpecAlarmType`, `MaintenanceRequiredAlarmType`) — generated proxies wired via the fluent `IAlarmBuilder` + `ActivatesAlarm` patterns from `Libraries/Opc.Ua.Server/Fluent`. +- `DeviceHealthDiagnosticAlarmType` (abstract) and the four concrete alarm types (`FailureAlarmType`, `CheckFunctionAlarmType`, `OffSpecAlarmType`, `MaintenanceRequiredAlarmType`) — generated proxies wired via the fluent `IAlarmBuilder` + `ActivatesAlarm` patterns from `src/Opc.Ua.Server/Fluent`. ### DataTypes & VariableTypes diff --git a/docs/Diagnostics.md b/docs/Diagnostics.md index cfa132c76c..7fe700e2e0 100644 --- a/docs/Diagnostics.md +++ b/docs/Diagnostics.md @@ -232,7 +232,7 @@ builder.Services ``` `services.AddOpcUa()` registers -[`ServiceProviderTelemetryContext`](../Stack/Opc.Ua.Core/Stack/Diagnostics/ServiceProviderTelemetryContext.cs) +[`ServiceProviderTelemetryContext`](../src/Opc.Ua.Core/Stack/Diagnostics/ServiceProviderTelemetryContext.cs) as a singleton `ITelemetryContext` via `TryAddSingleton`. That adapter resolves the host's `ILoggerFactory` from DI on first use (falling back to `NullLoggerFactory` when none is registered) and @@ -515,7 +515,7 @@ OPC UA Part 5 defines a family of `AuditXxxEventType` event types that servers raise for security-relevant operations (session lifecycle, secure-channel events, certificate validation, history modification, node management, role mapping, etc.). The stack provides ready-made -helpers in `Libraries/Opc.Ua.Server/Diagnostics/AuditEvents.cs` for +helpers in `src/Opc.Ua.Server/Diagnostics/AuditEvents.cs` for every event type the standard server raises. ### Enabling auditing @@ -592,7 +592,7 @@ Audit events are additionally gated by the `ReceiveEvents` permission: the serve OPC UA Part 5 §6 defines a `Server` object with a rich `ServerStatus` and `ServerDiagnostics` sub-tree. The stack populates these nodes -automatically through `Libraries/Opc.Ua.Server/Diagnostics/DiagnosticsNodeManager.cs`. +automatically through `src/Opc.Ua.Server/Diagnostics/DiagnosticsNodeManager.cs`. ### Enabling diagnostics @@ -1345,7 +1345,7 @@ the upstream advisory feeds and review at least monthly. HIGH or CRITICAL CVEs should be addressed within 30 days. Run `dotnet list package --vulnerable --include-transitive` against -`Stack/Opc.Ua.Core.Diagnostics/Opc.Ua.Core.Diagnostics.csproj` in +`src/Opc.Ua.Core.Diagnostics/Opc.Ua.Core.Diagnostics.csproj` in your CI pipeline; the project does this as part of its release gate. ### Security considerations diff --git a/docs/DurableSubscription.md b/docs/DurableSubscription.md index 31917cac59..29e8c70edc 100644 --- a/docs/DurableSubscription.md +++ b/docs/DurableSubscription.md @@ -15,7 +15,7 @@ If the connection to the client fails the server continues to sample values. On Typically the following porting steps are necessary: -- Provide an implementation of `IMonitoredItemQueueFactory` that sets `SupportsDurableQueues` to true. This factory returns your own implementation of `IMonitoredItemQueue` that persists values to storage and supports large queue sizes. As a reference see [DurableMonitoredItemQueueFactory](../../Applications/Quickstats.Servers/DurableSubscription/DurableMonitoredItemQueueFactory.cs). +- Provide an implementation of `IMonitoredItemQueueFactory` that sets `SupportsDurableQueues` to true. This factory returns your own implementation of `IMonitoredItemQueue` that persists values to storage and supports large queue sizes. As a reference see [DurableMonitoredItemQueueFactory](../../samples/Quickstats.Servers/DurableSubscription/DurableMonitoredItemQueueFactory.cs). - Register the `IMonitoredItemQueueFactory` by overriding the StandardServer method `CreateMonitoredItemQueueFactory`. - Provide an implementation of `ISubscriptionStore` that persists and restores subscriptions to storage to continue them after a server restart. The subscription store shall also enshure persistent queues are provided to the monitored items after a restore. - - Register the `ISubscriptionStore` by overriding the StandardServer method `CreateSubscriptionStore`. diff --git a/docs/FileSystemClient.md b/docs/FileSystemClient.md index 3c3974b2b1..f8d4d92e05 100644 --- a/docs/FileSystemClient.md +++ b/docs/FileSystemClient.md @@ -1,6 +1,6 @@ # FileSystemClient — a `System.IO`-style async client for OPC UA file systems -`FileSystemClient` (in `Libraries/Opc.Ua.Client/FileSystem/`, namespace +`FileSystemClient` (in `src/Opc.Ua.Client/FileSystem/`, namespace `Opc.Ua.Client.FileSystem`) is an ergonomic, async-only wrapper around the OPC UA file-system primitives defined in **Part 5 §C** and **Part 20 §4** — the `FileType`, `FileDirectoryType`, and `TemporaryFileTransferType` @@ -254,7 +254,7 @@ is a no-op. ## What lives where ``` -Libraries/Opc.Ua.Client/FileSystem/ +src/Opc.Ua.Client/FileSystem/ ├── FileSystemClient.cs # entry point ├── FileSystemClientOptions.cs # tuning knobs ├── FileMetadata.cs # internal property snapshot @@ -270,7 +270,7 @@ Libraries/Opc.Ua.Client/FileSystem/ └── UaTemporaryWriteFile.cs # commit/rollback wrapper ``` -Tests live under `Tests/Opc.Ua.Client.Tests/FileSystem/`. +Tests live under `tests/Opc.Ua.Client.Tests/FileSystem/`. ## See also diff --git a/docs/GDS.md b/docs/GDS.md index 6be711c52b..70d9ced1cc 100644 --- a/docs/GDS.md +++ b/docs/GDS.md @@ -444,7 +444,7 @@ The server-side Part 12 features map to these Facets in the OPC UA profile regis The automated conformance checks that run in CI are the NUnit suites: the unit suites in `Opc.Ua.Server.Tests` (address-space exposure, transaction coordinator, TrustList staging, certificate alarms, optional surface) and the end-to-end GDS integration suites in `Opc.Ua.Gds.Tests` — notably `PushTest.cs`, which drives a live push server through the `ServerConfiguration` Methods, and `TrustListValidationTest.cs`. The applicable Facets / conformance units above were identified with the OPC UA profile-graph tooling against `profiles.opcfoundation.org`. -There is no fully-automated CTT harness in this repository, and the formal **OPC UA Compliance Test Tool (UACTT / CTT)** — a licensed OPC Foundation corporate-member GUI application — was **not** run to produce this matrix; no CTT results are claimed here. Run it against the reference server (`Applications/ConsoleReferenceServer`; see [Applications/README.md](../Applications/README.md)) for formal certification. Known UACTT *script* defects encountered in prior manual runs are catalogued in [`plans/ctt-issues.md`](../plans/ctt-issues.md). +There is no fully-automated CTT harness in this repository, and the formal **OPC UA Compliance Test Tool (UACTT / CTT)** — a licensed OPC Foundation corporate-member GUI application — was **not** run to produce this matrix; no CTT results are claimed here. Run it against the reference server (`samples/ConsoleReferenceServer`; see [samples/README.md](../samples/README.md)) for formal certification. Known UACTT *script* defects encountered in prior manual runs are catalogued in [`plans/ctt-issues.md`](../plans/ctt-issues.md). ## GDS Directory (§6.5) diff --git a/docs/HighAvailability.md b/docs/HighAvailability.md index 7b0a208bac..b89c512c91 100644 --- a/docs/HighAvailability.md +++ b/docs/HighAvailability.md @@ -1,6 +1,6 @@ # High Availability and OPC UA Redundancy -This guide maps the OPC UA .NET Standard high-availability APIs to OPC 10000-4 §6.6 Redundancy. It documents the implemented server, client, subscription, session, [Kubernetes](Kubernetes.md), and active/active extension seams; the worked examples are `Applications/RedundantServer` and `Applications/RedundantClient`. +This guide maps the OPC UA .NET Standard high-availability APIs to OPC 10000-4 §6.6 Redundancy. It documents the implemented server, client, subscription, session, [Kubernetes](Kubernetes.md), and active/active extension seams; the worked examples are `samples/RedundantServer` and `samples/RedundantClient`. Redundancy and high availability are opt-in and require adding the extra `OPCFoundation.NetStandard.Opc.Ua.Redundancy.*` NuGet packages (for example `OPCFoundation.NetStandard.Opc.Ua.Redundancy.Server` or `.Client`) to your application. A server or client built only with the standard `OPCFoundation.NetStandard.Opc.Ua.Client` and `OPCFoundation.NetStandard.Opc.Ua.Server` libraries does not support OPC UA redundancy. @@ -389,7 +389,7 @@ services.AddOpcUa() `UseRedundancyConsistency` registers a shared `IRaftConsensus` plus a native `RaftLeaderElection` (`ILeaderElection`). Raft leadership is decided by the consensus protocol itself — a single leader per term, no split-brain — which is stronger than the lease-CAS `SharedStoreLeaseElection`. Because the distributed features register their store and election with `TryAddSingleton`, call `UseRedundancyConsistency` first and they compose over the chosen store and election. -The consensus engine is pluggable through the `IRaftConsensus` seam. By default the DI registration uses a single-node in-package Raft replica (`DefaultRaftConsensus.CreateSingleNode()`, a real RaftNode with in-memory storage/transport that elects itself leader); `InProcessRaftConsensus` is a lighter deterministic in-process alternative for tests and in-process replica sets. For a multi-pod cluster, build a multi-node replica with `DefaultRaftConsensus.CreateCluster(nodeId, memberIds, transport, …)` — a `RaftCs.Transport.NanoMsg` transport (peers addressed by DNS) plus an in-memory or durable `RaftCs.Storage.File` write-ahead log (WAL) — and register it through `RaftConsensusFactory`. On Kubernetes, `UseKubernetesRaftConsensus` (in `Opc.Ua.Redundancy.Kubernetes`) does this for you from the StatefulSet ordinal and headless-Service DNS. RaftCs ships its own `IRaftTransport` (NanoMsg), so Raft shares the NanoMsg substrate with the CRDT gossip layer. The `Applications/RedundantServer` sample (`docker-compose.yml` with the `active-passive.env` env file) is a runnable multi-node example. +The consensus engine is pluggable through the `IRaftConsensus` seam. By default the DI registration uses a single-node in-package Raft replica (`DefaultRaftConsensus.CreateSingleNode()`, a real RaftNode with in-memory storage/transport that elects itself leader); `InProcessRaftConsensus` is a lighter deterministic in-process alternative for tests and in-process replica sets. For a multi-pod cluster, build a multi-node replica with `DefaultRaftConsensus.CreateCluster(nodeId, memberIds, transport, …)` — a `RaftCs.Transport.NanoMsg` transport (peers addressed by DNS) plus an in-memory or durable `RaftCs.Storage.File` write-ahead log (WAL) — and register it through `RaftConsensusFactory`. On Kubernetes, `UseKubernetesRaftConsensus` (in `Opc.Ua.Redundancy.Kubernetes`) does this for you from the StatefulSet ordinal and headless-Service DNS. RaftCs ships its own `IRaftTransport` (NanoMsg), so Raft shares the NanoMsg substrate with the CRDT gossip layer. The `samples/RedundantServer` sample (`docker-compose.yml` with the `active-passive.env` env file) is a runnable multi-node example. On the client side, `AddRaftClientSharedStore` registers a Raft-backed `ISharedKeyValueStore` and a native `RaftLeaderElection` for a client replica set in one call (the `ClientReplicaCoordinator` consumes both), `AddCrdtClientSharedStore` registers the CRDT-gossip (eventual) equivalent, and `AddRedundantClientSharedStore(mode, …)` is the mode-aware entry point that selects between them. @@ -416,7 +416,7 @@ await cache.CacheAsync(variable.NodeId, new DataValue(value, StatusCodes.Good, D (bool fresh, DataValue last) = await cache.TryGetAsync(variable.NodeId, maxAge); ``` -Because the value cache writes through the shared `INodeStateStore`, its confidentiality/integrity is governed by the same `IRecordProtector` as the rest of the mirrored state (fail-closed for external stores without a protector). Cross-process value continuity therefore requires a store that propagates writes between replicas: it is verified on the strong-consistency (Raft) topology; on active/active eventual it depends on the CRDT address-space gossip transport. The `Applications/RedundantServer` sample wires its `HighAvailability.Counter` through this provider — see the sample README's *Sharing values across replicas* section. +Because the value cache writes through the shared `INodeStateStore`, its confidentiality/integrity is governed by the same `IRecordProtector` as the rest of the mirrored state (fail-closed for external stores without a protector). Cross-process value continuity therefore requires a store that propagates writes between replicas: it is verified on the strong-consistency (Raft) topology; on active/active eventual it depends on the CRDT address-space gossip transport. The `samples/RedundantServer` sample wires its `HighAvailability.Counter` through this provider — see the sample README's *Sharing values across replicas* section. ### Shared certificate stores (distributed trust lists) (beyond §6.6, opt-in) @@ -584,9 +584,9 @@ Use the consolidated [Kubernetes High Availability Deployment](Kubernetes.md) gu ## Samples -`Applications/RedundantServer` demonstrates the server-side distributed and redundancy registrations, with `docker-compose` files for active/active and active/passive replica sets. `Applications/RedundantClient` shows the recommended managed-client pattern: a single `ManagedSession` with `WithServerRedundancy()` that connects to any server, reads its redundancy metadata, and fails over transparently — the same code works whether or not the server is configured for redundancy. +`samples/RedundantServer` demonstrates the server-side distributed and redundancy registrations, with `docker-compose` files for active/active and active/passive replica sets. `samples/RedundantClient` shows the recommended managed-client pattern: a single `ManagedSession` with `WithServerRedundancy()` that connects to any server, reads its redundancy metadata, and fails over transparently — the same code works whether or not the server is configured for redundancy. -`Applications/RedundantClient/docker-compose.yml` runs the client and server in one env-driven compose file that covers the full HA matrix. `COMPOSE_PROFILES` (defaulted by an adjacent `.env`) picks one server profile (`server-eventual`, scalable active/active, or `server-strong`, a fixed 3-node Raft quorum) and one client profile (`client-independent`, scalable, or `client-coordinated`, a fixed 3-node client replica set); the eventual server and independent clients scale with `--scale server=N --scale client=M`. **Both sides log their failover / HA behavior, including data loss**: the client turns transparent reconnects and leader handoffs into explicit `FAILOVER:`, `ACTIVE CLIENT:`, `DATA LOSS:`, and `HA OK: Counter continued …` lines, and the server logs its active/standby role transitions and a per-replica `Counter` heartbeat. `server-eventual` shows data loss on failover because each replica owns an independent `Counter`; `server-strong` (active/passive Raft) keeps the `Counter` on a linearizable store and shows **no** data loss. See the [RedundantClient README](../Applications/RedundantClient/README.md#run-with-docker-compose-one-file-the-full-ha-matrix-env-driven). +`samples/RedundantClient/docker-compose.yml` runs the client and server in one env-driven compose file that covers the full HA matrix. `COMPOSE_PROFILES` (defaulted by an adjacent `.env`) picks one server profile (`server-eventual`, scalable active/active, or `server-strong`, a fixed 3-node Raft quorum) and one client profile (`client-independent`, scalable, or `client-coordinated`, a fixed 3-node client replica set); the eventual server and independent clients scale with `--scale server=N --scale client=M`. **Both sides log their failover / HA behavior, including data loss**: the client turns transparent reconnects and leader handoffs into explicit `FAILOVER:`, `ACTIVE CLIENT:`, `DATA LOSS:`, and `HA OK: Counter continued …` lines, and the server logs its active/standby role transitions and a per-replica `Counter` heartbeat. `server-eventual` shows data loss on failover because each replica owns an independent `Counter`; `server-strong` (active/passive Raft) keeps the `Counter` on a linearizable store and shows **no** data loss. See the [RedundantClient README](../samples/RedundantClient/README.md#run-with-docker-compose-one-file-the-full-ha-matrix-env-driven). ## Security considerations @@ -594,7 +594,7 @@ Distributed high-availability deployments protect the shared store as part of th Transparent redundancy uses one logical application identity. Every replica that serves the transparent virtual endpoint must use the same endpoint URL, ApplicationUri, application instance certificate, and private key so clients can validate one server identity and complete `ActivateSession` against any replica. The compromise blast radius of that shared private key is the entire transparent set: an attacker can impersonate the virtual server, terminate or redirect client trust, and participate in failover until the certificate is revoked and trust lists are updated. Prefer non-transparent redundancy with per-replica certificates when that shared-key risk is unacceptable. -The `Applications/RedundantServer` sample includes a worked transparent deployment (`Transparent/docker-compose.yml`): two `REDUNDANCY_MODE=transparent` replicas that share one `ApplicationUri` and one certificate and mirror session + address-space state by CRDT gossip, behind an `nginx` TCP load balancer that publishes a single virtual endpoint. Each replica advertises the load-balancer host, so discovery and `CreateSession` echo the one endpoint the client uses, and a mirrored session resumes on the survivor when a replica fails. The sample seeds the shared certificate into a volume for convenience; a secured deployment provisions it from a secret to every replica (see `Docs/Kubernetes.md`). +The `samples/RedundantServer` sample includes a worked transparent deployment (`Transparent/docker-compose.yml`): two `REDUNDANCY_MODE=transparent` replicas that share one `ApplicationUri` and one certificate and mirror session + address-space state by CRDT gossip, behind an `nginx` TCP load balancer that publishes a single virtual endpoint. Each replica advertises the load-balancer host, so discovery and `CreateSession` echo the one endpoint the client uses, and a mirrored session resumes on the survivor when a replica fails. The sample seeds the shared certificate into a volume for convenience; a secured deployment provisions it from a secret to every replica (see `docs/Kubernetes.md`). Rotate the transparent shared application certificate/key as a coordinated replica-set operation. Issue the replacement certificate with the same virtual identity and endpoint subject alternative names, distribute the new private key through the certificate store or a secret manager without baking it into images, stage client and GDS trust-list updates so both old and new certificates are trusted during the overlap, restart or hot-reload replicas in a controlled window, verify every replica presents the new certificate at the virtual endpoint, then revoke/remove the old certificate and securely delete the old private key from all nodes and secret versions. Treat an emergency rotation after suspected compromise as a fail-closed event: drain or stop replicas that still hold the old key before restoring client access. diff --git a/docs/IdentityProviders.md b/docs/IdentityProviders.md index 4ba902801b..c2d52d189d 100644 --- a/docs/IdentityProviders.md +++ b/docs/IdentityProviders.md @@ -28,8 +28,8 @@ The design is intentionally **symmetric**: ``` The model **does not replace** the existing -[`IUserIdentity`](../Stack/Opc.Ua.Core/Stack/Client/IUserIdentity.cs) / -[`IUserIdentityTokenHandler`](../Stack/Opc.Ua.Core/Stack/Types/IUserIdentityTokenHandler.cs) +[`IUserIdentity`](../src/Opc.Ua.Core/Stack/Client/IUserIdentity.cs) / +[`IUserIdentityTokenHandler`](../src/Opc.Ua.Core/Stack/Types/IUserIdentityTokenHandler.cs) contracts that ship on the wire — those are still the canonical on-the-wire types. The provider model layers on top of those types so legacy callbacks keep working during migration, while new code can diff --git a/docs/Kubernetes.md b/docs/Kubernetes.md index e47c6cd045..f22d8e5616 100644 --- a/docs/Kubernetes.md +++ b/docs/Kubernetes.md @@ -2,7 +2,7 @@ This guide is the single Kubernetes deployment guide for OPC UA high availability. It covers the base `OPCFoundation.NetStandard.Opc.Ua.Redundancy.Server` features and the opt-in `OPCFoundation.NetStandard.Opc.Ua.Redundancy.Kubernetes` extension: Kubernetes Lease leader election, EndpointSlice peer discovery, and HTTP readiness/liveness driven by OPC UA `ServiceLevel`. -See [HighAvailability.md](HighAvailability.md) for the OPC 10000-4 §6.6 redundancy model. The worked server sample is `Applications/RedundantServer`. +See [HighAvailability.md](HighAvailability.md) for the OPC 10000-4 §6.6 redundancy model. The worked server sample is `samples/RedundantServer`. The API names distinguish standardized OPC UA model wiring from deployment extensions. `AddServerRedundancy(...)`, `AddServerServiceLevel(...)`, and `AddRequestServerStateChange(...)` publish or maintain OPC 10000-4 §6.6 nodes/methods; `UseDistributedAddressSpace(...)`, `UseDistributedSessions(...)`, `UseDistributedSubscriptionMirroring(...)`, `UseKubernetesLeaderElection(...)`, `UseKubernetesPeerDiscovery(...)`, and `UseKubernetesReadiness(...)` register beyond-spec extension services. `AddServerRedundancy(...)` does not drive `Server.ServiceLevel` by itself, so Kubernetes readiness must also register a ServiceLevel provider, commonly with `AddServerServiceLevel(...)` or the leader-aware provider used by the sample. diff --git a/docs/McpServer.md b/docs/McpServer.md index 677ce0ed23..4d5e0539a5 100644 --- a/docs/McpServer.md +++ b/docs/McpServer.md @@ -90,15 +90,15 @@ After installation, the `opcua-mcp` command is available globally. ### Option 2: Run from source ```bash -cd Applications/McpServer +cd tools/Opc.Ua.Mcp dotnet run -c Release ``` ### Option 3: Install from local build ```bash -dotnet pack Applications/McpServer/Opc.Ua.Mcp.csproj -c Release -dotnet tool install --global --add-source Applications/McpServer/bin/Release OPCFoundation.NetStandard.Opc.Ua.Mcp +dotnet pack tools/Opc.Ua.Mcp/Opc.Ua.Mcp.csproj -c Release +dotnet tool install --global --add-source tools/Opc.Ua.Mcp/bin/Release OPCFoundation.NetStandard.Opc.Ua.Mcp ``` ## Configuration @@ -384,11 +384,11 @@ runtime and collect publisher responses): ## Architecture ``` -Applications/McpServer/ -├── McpServer.csproj # .NET 10 project, packaged as dotnet tool +tools/Opc.Ua.Mcp/ +├── Opc.Ua.Mcp.csproj # .NET 10 project, packaged as dotnet tool ├── Program.cs # Entry point, stdio + HTTP/SSE transport ├── OpcUaSessionManager.cs # OPC UA client session lifecycle -├── McpServer.Config.xml # OPC UA client application config +├── Opc.Ua.Mcp.Config.xml # OPC UA client application config ├── .mcp/server.json # MCP server manifest for NuGet discovery ├── Tools/ │ ├── ConnectionTools.cs # GetEndpoints, Connect, Disconnect, GetConnectionStatus diff --git a/docs/ModelChangeTracking.md b/docs/ModelChangeTracking.md index c60b7fe705..653874f6f5 100644 --- a/docs/ModelChangeTracking.md +++ b/docs/ModelChangeTracking.md @@ -470,12 +470,12 @@ entire manager out of auto-emit if you want full manual control. ## Reference -- Server source: `Libraries/Opc.Ua.Server/NodeManager/ModelChangeAggregator.cs` +- Server source: `src/Opc.Ua.Server/NodeManager/ModelChangeAggregator.cs` - Server events: `CustomNodeManager.RaiseGeneralModelChangeEvent`, `RaiseSemanticChangeEvent` (and the async equivalents in `AsyncCustomNodeManager`) -- Client source: `Libraries/Opc.Ua.Client/ModelChange/` -- Cache: `Libraries/Opc.Ua.Client/NodeCache/NodeCache.cs` — +- Client source: `src/Opc.Ua.Client/ModelChange/` +- Cache: `src/Opc.Ua.Client/NodeCache/NodeCache.cs` — `InvalidateNode` - Sessions architecture: [Sessions.md](Sessions.md) - Spec: [OPC UA Part 5 §6.4.32 — `BaseModelChangeEventType`](https://reference.opcfoundation.org/v105/Core/docs/Part5/6.4.32/) \ No newline at end of file diff --git a/docs/ModelDependencies.md b/docs/ModelDependencies.md index 327fde5d25..126c871da3 100644 --- a/docs/ModelDependencies.md +++ b/docs/ModelDependencies.md @@ -74,7 +74,7 @@ canonical source of its type-table description. ## Payload wire format (`ModelDependencyV1`) Encoding lives in -`Tools/Opc.Ua.SourceGeneration.Core/Dependency/ModelDependencyV1.cs`: +`tools/Opc.Ua.SourceGeneration.Core/Dependency/ModelDependencyV1.cs`: - Magic header: `0xAA 0xC7` - Version byte: `0x01` @@ -101,7 +101,7 @@ decoded. ## Implementation The Roslyn-side scan lives in -`Tools/Opc.Ua.SourceGeneration/ReferencedModelDependencyScanner.cs` and uses +`tools/Opc.Ua.SourceGeneration/ReferencedModelDependencyScanner.cs` and uses `IAssemblySymbol.GetAttributes()` so it works for both `PortableExecutableReference` and `CompilationReference`, hooks Roslyn's per-symbol incremental cache, avoids file IO, and is AOT-safe inside the @@ -110,7 +110,7 @@ generator. Each attribute is read into a `ModelDependencyReference` whose `ConditionalWeakTable` keyed on the payload string. The emitter lives in -`Tools/Opc.Ua.SourceGeneration.Core/Generators/ModelDependencyGenerator.cs` +`tools/Opc.Ua.SourceGeneration.Core/Generators/ModelDependencyGenerator.cs` and produces one `{prefix}.ModelDependencies.g.cs` per generated model containing assembly-attribute lines for the model itself (with the `ModelDependencyV1` payload) and every model it consumes (with a `null` @@ -118,13 +118,13 @@ payload). The template lives in `ModelDependencyTemplates.cs` and uses the shared `Token` infrastructure for replacement. The cross-namespace prefix override step lives in -`Tools/Opc.Ua.SourceGeneration.Core/Generators.cs` as +`tools/Opc.Ua.SourceGeneration.Core/Generators.cs` as `OverrideDependencyPrefixes`. It runs after `OpenModelDesign` and before generation so that all downstream emitters see the harmonised prefix/name values. The payload-import surface lives directly on -`Tools/Opc.Ua.SourceGeneration.Core/Schema/ModelDesignValidator.cs` (the +`tools/Opc.Ua.SourceGeneration.Core/Schema/ModelDesignValidator.cs` (the former `ModelDesignValidator.SnapshotImport.cs` partial was folded into the main file). The validator's `ImportDependency(dependency, prefix, name)` API queues a `ModelDependencyV1` for ingestion; `ApplyPendingDependencies()` diff --git a/docs/NativeAoT.md b/docs/NativeAoT.md index 2a9ab9b8ff..c95dda8414 100644 --- a/docs/NativeAoT.md +++ b/docs/NativeAoT.md @@ -38,7 +38,7 @@ See the official Microsoft documentation for full details: ## Project Structure ``` -Tests/Opc.Ua.Aot.Tests/ +tests/Opc.Ua.Aot.Tests/ ├── Opc.Ua.Aot.Tests.csproj # Project file (PublishAot=true, net10.0) ├── AotServerFixture.cs # Lightweight AOT-compatible server host ├── AotTestFixture.cs # Shared fixture: starts server + client session @@ -101,7 +101,7 @@ AOT-friendly. ### 1. Publish the Native AOT Binary ```bash -dotnet publish Tests/Opc.Ua.Aot.Tests/Opc.Ua.Aot.Tests.csproj --configuration Release +dotnet publish tests/Opc.Ua.Aot.Tests/Opc.Ua.Aot.Tests.csproj --configuration Release ``` The publish step compiles the entire application (tests, server, and all @@ -113,13 +113,13 @@ several minutes depending on the machine. **Windows (x64):** ```powershell -./Tests/Opc.Ua.Aot.Tests/bin/Release/net10.0/win-x64/publish/Opc.Ua.Aot.Tests.exe +./tests/Opc.Ua.Aot.Tests/bin/Release/net10.0/win-x64/publish/Opc.Ua.Aot.Tests.exe ``` **Linux (x64):** ```bash -./Tests/Opc.Ua.Aot.Tests/bin/Release/net10.0/linux-x64/publish/Opc.Ua.Aot.Tests +./tests/Opc.Ua.Aot.Tests/bin/Release/net10.0/linux-x64/publish/Opc.Ua.Aot.Tests ``` The executable discovers and runs all tests, producing TUnit console output and @@ -131,12 +131,12 @@ For iterative development you can combine both commands: ```bash # Windows -dotnet publish Tests/Opc.Ua.Aot.Tests/Opc.Ua.Aot.Tests.csproj -c Release && ^ - Tests\Opc.Ua.Aot.Tests\bin\Release\net10.0\win-x64\publish\Opc.Ua.Aot.Tests.exe +dotnet publish tests/Opc.Ua.Aot.Tests/Opc.Ua.Aot.Tests.csproj -c Release && ^ + tests\Opc.Ua.Aot.Tests\bin\Release\net10.0\win-x64\publish\Opc.Ua.Aot.Tests.exe # Linux / macOS -dotnet publish Tests/Opc.Ua.Aot.Tests/Opc.Ua.Aot.Tests.csproj -c Release && \ - ./Tests/Opc.Ua.Aot.Tests/bin/Release/net10.0/linux-x64/publish/Opc.Ua.Aot.Tests +dotnet publish tests/Opc.Ua.Aot.Tests/Opc.Ua.Aot.Tests.csproj -c Release && \ + ./tests/Opc.Ua.Aot.Tests/bin/Release/net10.0/linux-x64/publish/Opc.Ua.Aot.Tests ``` > **Note:** `dotnet test` and `dotnet run` do **not** perform AOT compilation. @@ -162,7 +162,7 @@ failures are isolated and clearly visible. ### 1. Choose or Create a Test Class -Place AOT tests in `Tests/Opc.Ua.Aot.Tests/`. Each file should focus on a +Place AOT tests in `tests/Opc.Ua.Aot.Tests/`. Each file should focus on a single area (encoding, sessions, etc.). Apply the shared fixture: ```csharp diff --git a/docs/NodeManagement.md b/docs/NodeManagement.md index f6e3db7ee5..c8b9c11e45 100644 --- a/docs/NodeManagement.md +++ b/docs/NodeManagement.md @@ -182,7 +182,7 @@ public override async ValueTask<(ServiceResult result, NodeId addedNodeId)> AddN ## See also -- [Reference Server](../Applications/README.md) — opt-in example in +- [Reference Server](../samples/README.md) — opt-in example in `ReferenceNodeManager`. - [Source generated NodeManagers](SourceGeneratedNodeManagers.md) — combine NodeManagement with generated models. diff --git a/docs/NodeSetExport.md b/docs/NodeSetExport.md index df4697be82..89aedfbd05 100644 --- a/docs/NodeSetExport.md +++ b/docs/NodeSetExport.md @@ -169,17 +169,17 @@ public void ExportNodesToNodeSet2( ## Related Topics - [Working with ComplexTypes](ComplexTypes.md) -- [Console Reference Client](../Applications/ConsoleReferenceClient/README.md) +- [Console Reference Client](../samples/ConsoleReferenceClient/README.md) - OPC UA NodeSet2 XML Schema specification ## Examples For complete examples of using the NodeSet export functionality, see: -- `Tests/Opc.Ua.Client.Tests/NodeSetExportTest.cs` - Unit tests demonstrating various export scenarios -- `Applications/ConsoleReferenceClient/ClientSamples.cs` - Integration in the reference client +- `tests/Opc.Ua.Client.Tests/NodeSetExportTest.cs` - Unit tests demonstrating various export scenarios +- `samples/ConsoleReferenceClient/ClientSamples.cs` - Integration in the reference client ## See Also - [OPC UA Specification Part 6 - Mappings](https://reference.opcfoundation.org/Core/Part6/v105/) -- NodeSet2 XML Schema: `Stack/Opc.Ua.Core/Schema/UANodeSet.xsd` +- NodeSet2 XML Schema: `src/Opc.Ua.Core/Schema/UANodeSet.xsd` diff --git a/docs/Profiles.md b/docs/Profiles.md index eb89deb5bb..c931b1f0a8 100644 --- a/docs/Profiles.md +++ b/docs/Profiles.md @@ -27,7 +27,7 @@ Foundation registry for the canonical URI form. ## Server Profiles -The reference server (`Applications/ConsoleReferenceServer`) advertises the +The reference server (`samples/ConsoleReferenceServer`) advertises the following profiles in its `ServerProfileArray`: ### Core Server Profiles @@ -56,7 +56,7 @@ following profiles in its `ServerProfileArray`: The `Opc.Ua.Lds.Server` library plus the `ConsoleLdsServer` reference application implement the Local Discovery Server. The LDS application advertises the **[Local Discovery Server 2017 Facet](http://opcfoundation.org/UA-Profile/Server/LocalDiscovery2017)** -(see `Applications/ConsoleLdsServer/Lds.Server.Config.xml`). +(see `samples/ConsoleLdsServer/Lds.Server.Config.xml`). ### Additional facets supported by the implementation (beyond the default advertised set) @@ -74,11 +74,11 @@ canonical URI string before claiming a facet): [Alarms and Conditions](AlarmsAndConditions.md). - **State Machine** (Part 16) — `StateMachineBuilder` and the `FluentFiniteStateMachineState` extensibility in - `Libraries/Opc.Ua.Server/StateMachines/`. The reference server's + `src/Opc.Ua.Server/StateMachines/`. The reference server's `BoilerStateMachineState` is an end-to-end sample. See [State Machines](StateMachines.md). - **File Access** (Part 20) — Server-side `FileSystemNodeManager` + - `IFileSystemProvider` in `Libraries/Opc.Ua.Server/FileSystem/`. The + `IFileSystemProvider` in `src/Opc.Ua.Server/FileSystem/`. The reference server enables it via the `EnableFileSystemNodeManager` option. The matching System.IO-style client lives in [`FileSystemClient`](FileSystemClient.md). @@ -230,14 +230,14 @@ The stack implements the following transport profiles: - Same on-wire `{TypeId, Body}` OPC UA JSON envelope as `opcua+uajson`, multiplexed over WebSocket text frames; distinguished by the negotiated sub-protocol and the advertised TransportProfileUri - Bearer-token variant negotiates the access token in the sub-protocol name (no `Authorization` header — required for browser fetch compatibility); the server extracts the token from the sub-protocol name and feeds it through the standard `ISessionlessIdentityProvider` pipeline - Server-side discovery emission: the WSS factories emit this sub-profile as a discovery-only twin alongside each `SecurityMode.None` WSS binary endpoint, mirroring the HTTPS OpenAPI emission. - - Client surface: `Libraries/Opc.Ua.Client/WebApi/WebApiWssTransportChannel.cs`; fluent shortcut `ManagedSessionBuilder.UseWssOpenApiEndpoint(url)`; DI registration via `services.AddWebApiTransportChannel()` (registers both HTTPS and WSS WebApi channel factories). + - Client surface: `src/Opc.Ua.Client/WebApi/WebApiWssTransportChannel.cs`; fluent shortcut `ManagedSessionBuilder.UseWssOpenApiEndpoint(url)`; DI registration via `services.AddWebApiTransportChannel()` (registers both HTTPS and WSS WebApi channel factories). - Surfaced via `Profiles.WssOpenApiTransport` ### PubSub transports The [PubSub library](PubSub.md) supports the following PubSub transport facets (URIs surfaced by `Profiles.PubSub*Transport` constants in -`Stack/Opc.Ua.Core/Security/Constants/SecurityConstants.cs`). Facet +`src/Opc.Ua.Core/Security/Constants/SecurityConstants.cs`). Facet machinery and conformance unit semantics are defined by [Part 7 §4.3](https://reference.opcfoundation.org/specs/OPC-10000-7/v1.05.06/4.3). @@ -280,7 +280,7 @@ Table 81). The stack supports the following security profiles for secure communication. The canonical set is defined in -`Stack/Opc.Ua.Core/Security/Constants/SecurityPolicies.cs`. +`src/Opc.Ua.Core/Security/Constants/SecurityPolicies.cs`. ### RSA-based security policies @@ -501,9 +501,9 @@ Security policies are configured in the `SecurityPolicies` section: ``` -See the [reference server configuration file](../Applications/ConsoleReferenceServer/Quickstarts.ReferenceServer.Config.xml) +See the [reference server configuration file](../samples/ConsoleReferenceServer/Quickstarts.ReferenceServer.Config.xml) for a complete example, or the -[CTT configuration file](../Applications/ConsoleReferenceServer/Ctt.ReferenceServer.Config.xml) +[CTT configuration file](../samples/ConsoleReferenceServer/Ctt.ReferenceServer.Config.xml) for the variant selected by `--ctt`. ## Related Documentation diff --git a/docs/PubSub.md b/docs/PubSub.md index 02b9fe812c..d0882c8faf 100644 --- a/docs/PubSub.md +++ b/docs/PubSub.md @@ -756,7 +756,7 @@ pubsub.AddPublisher() }); ``` -Subscribers set `GroupId` (consumer group) and `AutoOffsetReset` instead of the delivery guarantee. Writer and reader groups use the same fluent `PubSubConfigurationBuilder` shown under [Fluent builder walkthrough](#fluent-builder-walkthrough); the [reference sample](../Applications/ConsoleReferencePubSubClient/README.md) contains complete Kafka publisher and subscriber configurations. +Subscribers set `GroupId` (consumer group) and `AutoOffsetReset` instead of the delivery guarantee. Writer and reader groups use the same fluent `PubSubConfigurationBuilder` shown under [Fluent builder walkthrough](#fluent-builder-walkthrough); the [reference sample](../samples/ConsoleReferencePubSubClient/README.md) contains complete Kafka publisher and subscriber configurations. **Topic mapping.** Kafka topics come from the OPC UA broker transport settings: `BrokerDataSetWriterTransportDataType.QueueName` / `BrokerDataSetReaderTransportDataType.QueueName` select the per-writer/reader data topic, `BrokerWriterGroupTransportDataType.QueueName` is the writer-group fallback, and `MetaDataQueueName` selects the metadata topic. When `MetaDataQueueName` is unset the transport derives a deterministic fallback from `KafkaConnectionOptions.Topics.Prefix`, the encoding, message type, PublisherId, WriterGroupId, and DataSetWriterId (segments joined with `.`). Use Kafka-safe characters (letters, digits, `.`, `_`, `-`). @@ -1144,7 +1144,7 @@ public enum UadpSecurityWrapOptions - `PubSubNonePolicy` — no signing, no encryption. - `PubSubAes128CtrPolicy` — AES-128-CTR encryption + HMAC-SHA-256 signing (NIST SP 800-38A F.5.1 KAT verified by - `Tests/Opc.Ua.PubSub.Tests/Security/Internal/AesCtrTransformTests`). + `tests/Opc.Ua.PubSub.Tests/Security/Internal/AesCtrTransformTests`). - `PubSubAes256CtrPolicy` — AES-256-CTR + HMAC-SHA-256. Lookup uses @@ -1354,7 +1354,7 @@ register optional companion features Use `IOpcUaBuilder.AddPubSubServer(...)` when the hosted OPC UA server and PubSub runtime are registered together; it registers the runtime before the address-space node manager so startup is order-independent. -See `Libraries/Opc.Ua.PubSub.Server/Hosting/IPubSubServerBuilder.cs`. +See `src/Opc.Ua.PubSub.Server/Hosting/IPubSubServerBuilder.cs`. ## Binding PubSub to an external OPC UA server (client-session adapters) @@ -1711,7 +1711,7 @@ For Actions, leave `ServerActionResponderOptions.AllowUnsecured` at its default ### Sample -See `Applications\ConsoleReferencePubSubClient` (the `external` mode) for a complete host that wires PubSub configuration, transport registration, external session options, publisher/subscriber binding, and Action-to-Call mapping in one process. +See `samples\ConsoleReferencePubSubClient` (the `external` mode) for a complete host that wires PubSub configuration, transport registration, external session options, publisher/subscriber binding, and Action-to-Call mapping in one process. ### See also @@ -1841,13 +1841,13 @@ uses `Confluent.Kafka` / native librdkafka and is not AOT-compatible (see - **No `Newtonsoft.Json`.** The PubSub JSON encoder lives entirely on `System.Text.Json` (which is AOT-friendly). - **Trimmer-clean.** `PubSubAotTests` in - [`Tests/Opc.Ua.Aot.Tests/PubSubAotTests.cs`](../Tests/Opc.Ua.Aot.Tests/PubSubAotTests.cs) + [`tests/Opc.Ua.Aot.Tests/PubSubAotTests.cs`](../tests/Opc.Ua.Aot.Tests/PubSubAotTests.cs) exercise UADP encode/decode, JSON encode/decode, key-ring rotation, scheduler tick dispatch, and metadata-registry lookup inside an AOT-published binary. - **Reference sample.** The combined reference application publishes AOT-clean with zero `IL2026` / `IL3050` warnings: - - [`Applications/ConsoleReferencePubSubClient`](../Applications/ConsoleReferencePubSubClient/README.md) (`publisher` / `subscriber` / `external` modes) + - [`samples/ConsoleReferencePubSubClient`](../samples/ConsoleReferencePubSubClient/README.md) (`publisher` / `subscriber` / `external` modes) ## Spec coverage @@ -1897,4 +1897,4 @@ below maps Part 14 sections to the type / file that implements them. - [Profiles and Facets](Profiles.md#pubsub-transports) - [Certificate Manager](CertificateManager.md) - [Sessions](Sessions.md) — Part 4 service set used by the SKS client. -- [Reference PubSub Client sample (`Applications/ConsoleReferencePubSubClient/README.md`)](../Applications/ConsoleReferencePubSubClient/README.md) +- [Reference PubSub Client sample (`samples/ConsoleReferencePubSubClient/README.md`)](../samples/ConsoleReferencePubSubClient/README.md) diff --git a/docs/README.md b/docs/README.md index 49d8552c82..be9610b2d6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,7 +28,7 @@ Here is a list of available documentation for different topics: * Client-based [NodeSet Export](NodeSetExport.md) - Export server address space to NodeSet2 XML. * Source generated [DataTypes] - How to annotate POCO classes and let the source generator generate the `IEncodeable` implementation. * Runtime [Schema Generation](SchemaGeneration.md) - Produce XSD, OPC Binary (BSD) and JSON Schema (Part 6 Annex C, compact + verbose) for generated encodeable types and dynamically added complex types via the injectable `ISchemaProvider`; schemas are built as object models in code (trimmable, NativeAOT compatible). -* Source generated [NodeManagers](SourceGeneratedNodeManagers.md) - Emit an `AsyncCustomNodeManager` from a model design XML and wire callbacks via the fluent `INodeManagerBuilder` API; supports NativeAOT single-file servers (samples: [MinimalBoilerServer](../Applications/MinimalBoilerServer), [PumpDeviceIntegrationServer](../Applications/PumpDeviceIntegrationServer)). Covers engineering units, property initialisation, alarms, simulation timers, instance creation, NAMUR-style supervision, multi-model composition, and the fluent state-machine builder on top of any `FiniteStateMachineState` subclass. Cross-assembly model references are tracked via the [ModelDependencyAttribute](ModelDependencies.md). Companion-spec packaging — model + server + client library trios — is covered end-to-end by the [Device Integration developer guide](DeviceIntegration.md) using the `Opc.Ua.Di` / `Opc.Ua.Di.Server` / `Opc.Ua.Di.Client` trio as the worked example. +* Source generated [NodeManagers](SourceGeneratedNodeManagers.md) - Emit an `AsyncCustomNodeManager` from a model design XML and wire callbacks via the fluent `INodeManagerBuilder` API; supports NativeAOT single-file servers (samples: [MinimalBoilerServer](../samples/MinimalBoilerServer), [PumpDeviceIntegrationServer](../samples/PumpDeviceIntegrationServer)). Covers engineering units, property initialisation, alarms, simulation timers, instance creation, NAMUR-style supervision, multi-model composition, and the fluent state-machine builder on top of any `FiniteStateMachineState` subclass. Cross-assembly model references are tracked via the [ModelDependencyAttribute](ModelDependencies.md). Companion-spec packaging — model + server + client library trios — is covered end-to-end by the [Device Integration developer guide](DeviceIntegration.md) using the `Opc.Ua.Di` / `Opc.Ua.Di.Server` / `Opc.Ua.Di.Client` trio as the worked example. * Runtime [NodeSets](RuntimeNodeSets.md) - Load one or more NodeSet2 XML documents into the server address space at startup without source generation. Covers file and stream sources, dependency ordering, parent-child browse-path resolution, fluent `Configure` callbacks, default namespace inference, and the default complex-type loading path. Use when the XML content changes independently of the server binary or for rapid prototyping. * [Device Integration (DI) developer guide](DeviceIntegration.md) - End-to-end documentation for the `Opc.Ua.Di*` library trio: fluent `IDeviceBuilder`, device sub-type extensions (`AddSoftware`, `AddBlock`, `AddConfigurableObject`, `AddLifetimeIndication`, `WithSupportInfo`), hosting integration (`AddOpcUaDi` / `ConfigureDevicesFor`), lock service, software-update package store, and client helpers (`DiLockClient`, `DiTopologyClient`, `SoftwareUpdateClient`). Includes a section enumerating supported OPC 10000-100 features against the spec. * [Alias Names](AliasNames.md) - Full server + client support for the OPC UA Part 17 alias-name model (`AliasNameType`, `AliasNameCategoryType`, `FindAlias`, `FindAliasVerbose`, `AddAliasesToCategory`, `DeleteAliasesFromCategory`, `LastChange`). @@ -45,7 +45,7 @@ Here is a list of available documentation for different topics: * [Redundant Sample Integration Tests](RedundancySampleTests.md) - Process-level integration tests that launch the `RedundantServer` / `RedundantClient` / `RedundantPubSub` sample apps and assert on their failover, reconnect, and data-loss-visibility behavior; short-haul variants run on every PR, long-haul soak variants run via dedicated manual/scheduled GitHub Actions and Azure DevOps jobs (`SAMPLE_HA_DURATION_MINUTES`). * [Dependency Injection](DependencyInjection.md) - The unified `services.AddOpcUa()` / `IOpcUaBuilder` surface for hosting OPC UA components in `Microsoft.Extensions.DependencyInjection` / the .NET Generic Host (servers as `IHostedService`, options via `Action` or `IConfiguration`, AOT-friendly). * [AuthorizationService](AuthorizationService.md) - Modern Part 12 `StartRequestToken` / `FinishRequestToken`, `ITokenIssuer`, and GDS token issuance. -* [Fuzz testing](../Fuzzing/Fuzzing.md) - SharpFuzz + afl-fuzz + libFuzzer integration. Three areas: `Encoders` (Binary/JSON/XML decoders, built-in type readers, parser entry points), `Certificates` (`X509CRL`, X509 extension parsers, `PEMReader`, `Pkcs10CertificationRequest`, ASN.1 helpers), and `Network` (UA-SC framing via `Opc.Ua.Core.Diagnostics` + internal `TcpMessageParsers` seam on `Opc.Ua.Core`). The [`fuzz-tester`](../.github/agents/fuzz-tester.agent.md) custom agent drives the whole toolchain autonomously: it detects OS-available engines, runs them in parallel, fixes novel findings per repo guidelines, adds the failing input as a regression asset, and pushes one commit per fix until the user says stop. +* [Fuzz testing](../fuzzing/Fuzzing.md) - SharpFuzz + afl-fuzz + libFuzzer integration. Three areas: `Encoders` (Binary/JSON/XML decoders, built-in type readers, parser entry points), `Certificates` (`X509CRL`, X509 extension parsers, `PEMReader`, `Pkcs10CertificationRequest`, ASN.1 helpers), and `Network` (UA-SC framing via `Opc.Ua.Core.Diagnostics` + internal `TcpMessageParsers` seam on `Opc.Ua.Core`). The [`fuzz-tester`](../.github/agents/fuzz-tester.agent.md) custom agent drives the whole toolchain autonomously: it detects OS-available engines, runs them in parallel, fixes novel findings per repo guidelines, adds the failing input as a regression asset, and pushes one commit per fix until the user says stop. * [KeyCredentialService](KeyCredentialService.md) - Pull, Push, and experimental bridge guidance for Part 12 KeyCredential flows. * [PubSub (Part 14)](PubSub.md) - Publisher/subscriber support library: architecture, fluent builder, transports (UDP / MQTT 3.1.1 + 5.0 / Kafka / Ethernet Layer 2), encodings (UADP / JSON), security, and server-side address space. * [PubSub High Availability](PubSubHighAvailability.md) - Distributed Part 14 §9.1.6 active/standby publishers and subscribers with Cold/Warm/Hot modes, leader election or fenced leases, shared runtime checkpoints, protected SKS key storage, consistency guidance, and Kubernetes deployment notes. @@ -60,9 +60,9 @@ Here is a list of available documentation for different topics: ## Reference application related -* [Reference Client](../Applications/ConsoleReferenceClient/README.md) documentation for configuration of the console reference client using parameters. -* [Reference Server](../Applications/README.md) documentation for running against CTT. -* [ConsoleReferencePubSubClient](../Applications/ConsoleReferencePubSubClient/README.md) documentation for the PubSub reference sample (publisher / subscriber / external-server adapter modes). +* [Reference Client](../samples/ConsoleReferenceClient/README.md) documentation for configuration of the console reference client using parameters. +* [Reference Server](../samples/README.md) documentation for running against CTT. +* [ConsoleReferencePubSubClient](../samples/ConsoleReferencePubSubClient/README.md) documentation for the PubSub reference sample (publisher / subscriber / external-server adapter modes). * [Provisioning Mode](ProvisioningMode.md) for secure certificate provisioning and initial server configuration. * Using the [Container support](ContainerReferenceServer.md) of the Reference Server in Visual Studio 2026 and for local testing. diff --git a/docs/RedundancySampleTests.md b/docs/RedundancySampleTests.md index d47b541fa1..bdfeb708ce 100644 --- a/docs/RedundancySampleTests.md +++ b/docs/RedundancySampleTests.md @@ -1,8 +1,8 @@ # Redundant Sample Integration Tests The `Opc.Ua.Redundancy.Samples.Tests` project contains process-level integration tests that launch the redundant sample applications -— [`RedundantServer`](../Applications/RedundantServer), [`RedundantClient`](../Applications/RedundantClient) and -[`RedundantPubSub`](../Applications/RedundantPubSub) — as real external processes and assert on the high-availability behavior they log +— [`RedundantServer`](../samples/RedundantServer), [`RedundantClient`](../samples/RedundantClient) and +[`RedundantPubSub`](../samples/RedundantPubSub) — as real external processes and assert on the high-availability behavior they log (`FAILOVER:`, `DATA LOSS:`, `HA OK:`, and reconnect events). They exercise the samples in their supported setups so that regressions in the end-to-end high-availability experience are caught automatically, and they demonstrate both successful failover *and* the visibility of data loss. @@ -13,7 +13,7 @@ dedicated, manually triggered CI job (and on a weekly schedule) to validate high Short-haul tests are deterministic and complete in seconds. They are discovered and run automatically by the normal [Build and Test](../.github/workflows/buildandtest.yml) workflow (and the Azure DevOps test stages), because the project follows the -`Tests/Opc.Ua.*.Tests` naming convention. They are tagged with the NUnit category `SampleHaShortHaul`: +`tests/Opc.Ua.*.Tests` naming convention. They are tagged with the NUnit category `SampleHaShortHaul`: * **PubSub demo, hot mode** — runs `RedundantPubSub --role demo --ha-mode hot` and asserts the promoted publisher continues the SequenceNumber across failover with no reset (`SIMULATED: HA OK: sequence continued ...`). @@ -25,7 +25,7 @@ Short-haul tests are deterministic and complete in seconds. They are discovered Run them locally from the repository root: ```powershell -dotnet test Tests/Opc.Ua.Redundancy.Samples.Tests/Opc.Ua.Redundancy.Samples.Tests.csproj --filter "Category=SampleHaShortHaul" +dotnet test tests/Opc.Ua.Redundancy.Samples.Tests/Opc.Ua.Redundancy.Samples.Tests.csproj --filter "Category=SampleHaShortHaul" ``` ## Long-haul tests (manual / scheduled soak) @@ -42,7 +42,7 @@ The soak duration is controlled by the `SAMPLE_HA_DURATION_MINUTES` environment ```powershell $env:SAMPLE_HA_DURATION_MINUTES = "5" -dotnet test Tests/Opc.Ua.Redundancy.Samples.Tests/Opc.Ua.Redundancy.Samples.Tests.csproj --filter "Category=SampleHaLongHaul" +dotnet test tests/Opc.Ua.Redundancy.Samples.Tests/Opc.Ua.Redundancy.Samples.Tests.csproj --filter "Category=SampleHaLongHaul" ``` The long-haul tests run in CI through dedicated, manually triggerable jobs on both platforms: @@ -56,7 +56,7 @@ The long-haul tests run in CI through dedicated, manually triggerable jobs on bo The full multi-replica leader-election topologies — strong (Raft) active/passive and eventual (CRDT gossip) active/active — rely on a stable virtual endpoint with DNS-based re-resolution to a surviving replica. These are demonstrated end-to-end by the docker-compose setups under -[`Applications/RedundantServer`](../Applications/RedundantServer) and [`Applications/RedundantClient`](../Applications/RedundantClient), which run +[`samples/RedundantServer`](../samples/RedundantServer) and [`samples/RedundantClient`](../samples/RedundantClient), which run several replicas on a container network and let you kill the active replica to observe cross-replica failover. The process-level long-haul soak above focuses on the failover-detection, reconnect, and data-loss-visibility behavior that runs deterministically inside a CI runner without container networking. diff --git a/docs/ReverseConnect.md b/docs/ReverseConnect.md index 1787ddf66e..dfefb3b846 100644 --- a/docs/ReverseConnect.md +++ b/docs/ReverseConnect.md @@ -12,8 +12,8 @@ The Reverse Connect option consists of the following elements: * Updated client library which support to * Configure a client endpoint to accept *ReverseHello* messages using a *ReverseConnectManager*. * A client API extension to allow applications to register for reverse connections either by callback or by waiting for the *ReverseHello* message for a specific server endpoint and application Uri combination. An optional filter for server Uris or endpoint Urls can be applied to allow multiple clients to use the same endpoint. -* The C# [Console Reference Server](../Applications/ConsoleReferenceServer) with reverse connect support in the configuration xml. -* The C# Core [Console Reference Client](../Applications/ConsoleReferenceClient) that can initiate a Reverse connection with command line options. +* The C# [Console Reference Server](../samples/ConsoleReferenceServer) with reverse connect support in the configuration xml. +* The C# Core [Console Reference Client](../samples/ConsoleReferenceClient) that can initiate a Reverse connection with command line options. * A modified C# [Aggregation Server](https://github.com/OPCFoundation/UA-.NETStandard-Samples/tree/master/Workshop/Aggregation) that supports incoming and outgoing reverse connections. ## Reverse Connect Handshake diff --git a/docs/RoleBasedUserManagement.md b/docs/RoleBasedUserManagement.md index 5fe6566cb0..3f560cac4f 100644 --- a/docs/RoleBasedUserManagement.md +++ b/docs/RoleBasedUserManagement.md @@ -23,7 +23,7 @@ The nine well-known roles are pre-registered at server start: Reserved roles cannot be modified or removed per Part 18 4.3 - any attempt to call `AddIdentity`, `AddApplication`, `AddEndpoint`, `RemoveIdentity`, `RemoveApplication`, `RemoveEndpoint`, or `RemoveRole` on them returns `Bad_RequestNotAllowed`. -See `Libraries/Opc.Ua.Server/RoleBasedUserManagement/` for the source. +See `src/Opc.Ua.Server/RoleBasedUserManagement/` for the source. ## Server side @@ -222,7 +222,7 @@ The GDS adds the following roles in addition to the standard well-known set: - `RegistrationAuthorityAdmin` - `ApplicationSelfAdmin` -See [GdsRole.cs](https://github.com/OPCFoundation/UA-.NETStandard/blob/main/Libraries/Opc.Ua.Gds.Server.Common/RoleBasedUserManagement/GdsRole.cs). +See [GdsRole.cs](https://github.com/OPCFoundation/UA-.NETStandard/blob/main/src/Opc.Ua.Gds.Server.Common/RoleBasedUserManagement/GdsRole.cs). ## Known limitations @@ -232,6 +232,6 @@ See [GdsRole.cs](https://github.com/OPCFoundation/UA-.NETStandard/blob/main/Libr - [OPC UA Part 18 v1.05.06 - Role-Based Security](https://reference.opcfoundation.org/Core/Part18/v105/docs/) - [OPC UA Part 3 4.9 - Well-Known Roles](https://reference.opcfoundation.org/Core/Part3/v105/docs/4.9) -- `Libraries/Opc.Ua.Server/RoleBasedUserManagement/` -- `Libraries/Opc.Ua.Client/Roles/` -- `Tests/Opc.Ua.Server.Tests/RoleManagerTests.cs` +- `src/Opc.Ua.Server/RoleBasedUserManagement/` +- `src/Opc.Ua.Client/Roles/` +- `tests/Opc.Ua.Server.Tests/RoleManagerTests.cs` diff --git a/docs/Sessions.md b/docs/Sessions.md index 6ff3290cc0..815659e21f 100644 --- a/docs/Sessions.md +++ b/docs/Sessions.md @@ -23,7 +23,7 @@ Everything below explains how these pieces fit together. ## 1. `Session` — the OPC UA session primitive -`Session` (`Libraries/Opc.Ua.Client/Session/Session.cs`) is the lowest-level +`Session` (`src/Opc.Ua.Client/Session/Session.cs`) is the lowest-level client object that maps directly to a UA secure-channel + session pair on the server. It implements `ISession` and exposes the full surface of the OPC UA service set (Read, Write, Browse, Call, AddNodes, etc.) plus @@ -95,7 +95,7 @@ reconnect / recreate cycles. See section 4 for the engine architecture. ### `DefaultSessionFactory` -`DefaultSessionFactory` (`Libraries/Opc.Ua.Client/Session/DefaultSessionFactory.cs`) +`DefaultSessionFactory` (`src/Opc.Ua.Client/Session/DefaultSessionFactory.cs`) is the drop-in `ISessionFactory` that builds raw `Session` instances. It exposes a single tunable knob beyond `ITelemetryContext`: @@ -113,7 +113,7 @@ When `SubscriptionEngineFactory` is `null`, `Session` falls back to ## 2. `SessionReconnectHandler` — legacy reconnect driver -`SessionReconnectHandler` (`Libraries/Opc.Ua.Client/Session/SessionReconnectHandler.cs`) +`SessionReconnectHandler` (`src/Opc.Ua.Client/Session/SessionReconnectHandler.cs`) is the original reconnect helper that ships with `Session`. It implements the timer-driven retry loop, picks between `Session.ReconnectAsync` and `ISessionFactory.RecreateAsync`, handles @@ -164,7 +164,7 @@ below) so that reconnect is handled transparently by the channel manager. ## 3. `ManagedSession` — the connection-state-machine facade -`ManagedSession` (`Libraries/Opc.Ua.Client/Session/ManagedSession.cs`) is +`ManagedSession` (`src/Opc.Ua.Client/Session/ManagedSession.cs`) is an `ISession` facade that wraps a raw `Session` and adds: - A **connection state machine** (`ConnectionStateMachine`) that owns @@ -205,7 +205,7 @@ ManagedSession session = await ManagedSession.CreateAsync( ### `ManagedSessionFactory` -`ManagedSessionFactory` (`Libraries/Opc.Ua.Client/Session/ManagedSessionFactory.cs`) +`ManagedSessionFactory` (`src/Opc.Ua.Client/Session/ManagedSessionFactory.cs`) is the `ISessionFactory` that produces `ManagedSession` (cast as `ISession` to satisfy the interface). Internally it composes a `DefaultSessionFactory` to build the raw inner `Session`, then wraps it. @@ -226,7 +226,7 @@ ISession session = await factory.CreateAsync(...); // actually a ManagedSession ### `ManagedSessionBuilder` -`ManagedSessionBuilder` (`Libraries/Opc.Ua.Client/ClientBuilder/ManagedSessionBuilder.cs`) +`ManagedSessionBuilder` (`src/Opc.Ua.Client/ClientBuilder/ManagedSessionBuilder.cs`) is the fluent / DI-friendly entry point. `Build()` returns an immutable `ManagedSessionOptions` snapshot; `ConnectAsync()` wraps `Build()` plus `ManagedSession.CreateAsync(...)`: @@ -324,7 +324,7 @@ signals. ## 4. `IClientChannelManager` — centralised channel sharing and reconnect `IClientChannelManager` -(`Stack/Opc.Ua.Core/Stack/Client/IClientChannelManager.cs`) is the new +(`src/Opc.Ua.Core/Stack/Client/IClientChannelManager.cs`) is the new central registry of client-side transport channels introduced by issue [#3288](https://github.com/OPCFoundation/UA-.NETStandard/issues/3288). It sits *below* `Session` / `ManagedSession` and is concerned with the @@ -460,7 +460,7 @@ The policy is configurable on the `ClientChannelManager` constructor. On .NET 8 and later, HTTPS endpoints have two independent resilience layers: - **HTTP resilience pipeline** — the named `HttpClient` created through - [`IOpcUaHttpClientFactory`](../Stack/Opc.Ua.Core/Stack/Https/OpcUaHttpClientFactory.cs) + [`IOpcUaHttpClientFactory`](../src/Opc.Ua.Core/Stack/Https/OpcUaHttpClientFactory.cs) uses `AddStandardResilienceHandler` from the `Microsoft.Extensions.Http.Resilience` package. The standard handler applies request-level rate limiting, a total request timeout, retries, @@ -518,7 +518,7 @@ services.AddHttpClient("Opc.Ua.Client") ``` For direct builder usage on .NET 8 and later, call -[`ManagedSessionBuilder.WithHttpsResilience(...)`](../Libraries/Opc.Ua.Client/Fluent/ManagedSessionBuilder.cs): +[`ManagedSessionBuilder.WithHttpsResilience(...)`](../src/Opc.Ua.Client/Fluent/ManagedSessionBuilder.cs): ```csharp ManagedSession session = await new ManagedSessionBuilder(config, telemetry) @@ -767,7 +767,7 @@ IManagedTransportChannel ch = await manager.GetAsync(participant, conn, ct); ### Testing the channel manager The channel manager is covered by a layered stress and chaos test suite in -[`Tests/Opc.Ua.Stress.Tests/`](../Tests/Opc.Ua.Stress.Tests/): +[`tests/Opc.Ua.Stress.Tests/`](../tests/Opc.Ua.Stress.Tests/): - **L1 Contract** — fast deterministic fake-based tests for coalescing, participant result aggregation, retry budgets, hung participants, recreate dispatch, lease lifecycle, gate + bypass, key equivalence, certificate @@ -781,13 +781,13 @@ The channel manager is covered by a layered stress and chaos test suite in ```bash # Contract + Integration (default PR CI): -dotnet test Tests/Opc.Ua.Stress.Tests --filter "Category=Contract|Category=Integration" +dotnet test tests/Opc.Ua.Stress.Tests --filter "Category=Contract|Category=Integration" # ChaosTCP (nightly): -dotnet test Tests/Opc.Ua.Stress.Tests --filter "Category=ChaosTCP" --TestRunParameters.Parameter(Seed=) +dotnet test tests/Opc.Ua.Stress.Tests --filter "Category=ChaosTCP" --TestRunParameters.Parameter(Seed=) # Soak (manual): -dotnet test Tests/Opc.Ua.Stress.Tests --filter "Category=Soak" +dotnet test tests/Opc.Ua.Stress.Tests --filter "Category=Soak" ``` Every chaos test prints its seed at the start of the run. Failed chaos runs can be reproduced by passing the same @@ -796,7 +796,7 @@ seed back to the test host with `--TestRunParameters.Parameter(Seed=)`. ## 5. Subscription engines The `ISubscriptionEngine` abstraction -(`Libraries/Opc.Ua.Client/Session/ISubscriptionEngine.cs`) decouples the +(`src/Opc.Ua.Client/Session/ISubscriptionEngine.cs`) decouples the publish pipeline from `Session`. Each `Session` owns exactly one engine chosen at construction; the engine manages the publish workers, ack queues, keep-alive timers, and dispatch to subscriptions. @@ -806,7 +806,7 @@ queues, keep-alive timers, and dispatch to subscriptions. The historical engine. Owns: - The `Subscription` and `MonitoredItem` classes in - `Libraries/Opc.Ua.Client/Subscription/Classic`. + `src/Opc.Ua.Client/Subscription/Classic`. - A fire-and-forget publish loop driven from `Session.BeginPublish` / `OnPublishComplete`. - The `Subscriptions` collection on `ISession` and `ManagedSession`. @@ -821,7 +821,7 @@ working. ### `DefaultSubscriptionEngine` (V2) The new engine wraps the options-based `SubscriptionManager` -(`Libraries/Opc.Ua.Client/Subscription/SubscriptionManager.cs`) inside +(`src/Opc.Ua.Client/Subscription/SubscriptionManager.cs`) inside the `ISubscriptionEngine` contract. It owns: - The `Subscriptions.Subscription` / `Subscriptions.MonitoredItems.MonitoredItem` diff --git a/docs/SoftwareUpdate.md b/docs/SoftwareUpdate.md index b350346e20..20cda173f9 100644 --- a/docs/SoftwareUpdate.md +++ b/docs/SoftwareUpdate.md @@ -297,7 +297,7 @@ needs to redo browse-path resolution. See [`StateMachines.md`](StateMachines.md) for the generic state-machine API the typed wrappers build on. -## Walkthrough — `Applications/PumpDeviceIntegrationServer` +## Walkthrough — `samples/PumpDeviceIntegrationServer` The pump server doubles as the software-update walkthrough: a second declarative pump (`Pump #2`) created via `ConfigureDevicesFor` has the @@ -346,27 +346,27 @@ device's `SoftwareVersion` reflects the new version. ## Implementation pointers -- Fluent surface: `Libraries/Opc.Ua.Di.Server/Builders/ISoftwareUpdateBuilder.cs` +- Fluent surface: `src/Opc.Ua.Di.Server/Builders/ISoftwareUpdateBuilder.cs` and `DeviceBuilderSoftwareUpdateExtensions.cs`. - Address-space wiring: `SoftwareUpdateFacetWiring.cs` (internal). - State-machine dispatcher: `SoftwareUpdateStateMachineDispatcher.cs` (internal — direct `CurrentState` / `LastTransition` writes until the model source generator emits Part 16 tables for `*StateMachineState`). - File-transfer pipeline: - `Libraries/Opc.Ua.Di.Server/Builders/SoftwareUpdateFileTransferManager.cs` + `src/Opc.Ua.Di.Server/Builders/SoftwareUpdateFileTransferManager.cs` (internal — `GenerateFileForWrite` / `CloseAndCommit` + per-handle transient `FileType` materialisation). - Storage abstractions: - `Libraries/Opc.Ua.Di.Server/SoftwareUpdate/ISoftwarePackageStore.cs` and + `src/Opc.Ua.Di.Server/SoftwareUpdate/ISoftwarePackageStore.cs` and `ISoftwareFolder.cs`. -- Client helpers: `Libraries/Opc.Ua.Di.Client/SoftwareUpdateClient.cs` +- Client helpers: `src/Opc.Ua.Di.Client/SoftwareUpdateClient.cs` (read-only discovery), - `Libraries/Opc.Ua.Di.Client/SoftwareUpdateClient.StateMachine.cs` + `src/Opc.Ua.Di.Client/SoftwareUpdateClient.StateMachine.cs` (typed Part 16 partial), and - `Libraries/Opc.Ua.Di.Client/SoftwareUpdateClient.Upload.cs` + `src/Opc.Ua.Di.Client/SoftwareUpdateClient.Upload.cs` (`UploadPackageAsync` driving the FileTransfer pipeline). - Tests: - `Tests/Opc.Ua.Di.Tests/DeviceBuilderSoftwareUpdateTests.cs`, + `tests/Opc.Ua.Di.Tests/DeviceBuilderSoftwareUpdateTests.cs`, `DeviceBuilderSoftwareUpdateStateChangeTests.cs`, `SoftwareUpdateFileTransferTests.cs` (server side), `SoftwareUpdateClientStateMachineTests.cs`, @@ -375,7 +375,7 @@ device's `SoftwareVersion` reflects the new version. end-to-end against `DiInProcessSessionBridge`), `MemorySoftwareFolderTests.cs`, `PackageStoreTests.cs`, `SoftwareUpdateClientTests.cs`. -- Sample: `Applications/PumpDeviceIntegrationServer/Program.cs` (the +- Sample: `samples/PumpDeviceIntegrationServer/Program.cs` (the `Pump #2` declarative-device block attaches the SU facet). ## Spec references diff --git a/docs/SourceGeneratedDataTypes.md b/docs/SourceGeneratedDataTypes.md index 396d869283..7d73b49419 100644 --- a/docs/SourceGeneratedDataTypes.md +++ b/docs/SourceGeneratedDataTypes.md @@ -44,13 +44,13 @@ source generator project and import its props file: ```xml + Include="..\..\tools\Opc.Ua.SourceGeneration\Opc.Ua.SourceGeneration.csproj"> Analyzer false + Project="..\..\tools\Opc.Ua.SourceGeneration\OPCFoundation.Opc.Ua.SourceGeneration.props" /> ``` ### NuGet Package (external consumers) diff --git a/docs/SourceGeneratedNodeManagers.md b/docs/SourceGeneratedNodeManagers.md index d7f5850c6c..1c2eeade43 100644 --- a/docs/SourceGeneratedNodeManagers.md +++ b/docs/SourceGeneratedNodeManagers.md @@ -5,7 +5,7 @@ ready-to-host `AsyncCustomNodeManager` for an information model design XML, and how to wire callbacks (read/write/method/lifecycle) using the fluent `INodeManagerBuilder` API. The combination is designed for **single-file, NativeAOT-friendly** servers — see -`Applications/MinimalBoilerServer` for the canonical sample. +`samples/MinimalBoilerServer` for the canonical sample. ## What the generator produces @@ -352,9 +352,9 @@ public partial class CalcNodeManager ``` The end-to-end sample lives in -`Applications/MinimalCalcServer/` (model in `Model/Calc.xml`, wiring +`samples/MinimalCalcServer/` (model in `Model/Calc.xml`, wiring in `CalcNodeManager.Configure.cs`). The companion AOT round-trip tests -in `Tests/Opc.Ua.Aot.Tests/CalculatorNodeManagerAotTests.cs` exercise +in `tests/Opc.Ua.Aot.Tests/CalculatorNodeManagerAotTests.cs` exercise each shape over a real `Session.CallAsync(...)`. ## Event sources — typed `Publish` on notifier wrappers @@ -478,10 +478,10 @@ callback. Once attached, all `Publish` extensions resolve against the manager's registry exactly as for generated managers. The end-to-end sample lives in -`Applications/MinimalBoilerServer/BoilerNodeManager.Configure.cs` +`samples/MinimalBoilerServer/BoilerNodeManager.Configure.cs` (wiring `GenerateDrumHeartbeatAsync` on the drum). The companion AOT round-trip test in -`Tests/Opc.Ua.Aot.Tests/PublishedEventsAotTests.cs` subscribes a +`tests/Opc.Ua.Aot.Tests/PublishedEventsAotTests.cs` subscribes a real client `MonitoredItem` with an `EventFilter` and asserts the heartbeats arrive end-to-end under NativeAOT constraints (no JIT, no reflection). @@ -524,7 +524,7 @@ legacy `INodeManagerFactory`. For advanced configuration (custom security policies, additional builder calls), set `OpcUaServerOptions.ConfigureBuilder`. That's the whole server. The Boiler version is in -`Applications/MinimalBoilerServer/Program.cs`. +`samples/MinimalBoilerServer/Program.cs`. ## Multi-namespace and manager-swap subclassing @@ -552,7 +552,7 @@ public sealed class MyExtendedFactory : MyModel.MyModelNodeManagerFactory } ``` -The `Tests/Opc.Ua.Server.Tests/Fluent/GeneratedManagerHybridTests.cs` +The `tests/Opc.Ua.Server.Tests/Fluent/GeneratedManagerHybridTests.cs` suite verifies these subclassing scenarios. ## NativeAOT publishing @@ -575,7 +575,7 @@ Use `Microsoft.Extensions.Logging.Console` for AOT-friendly logging dotnet publish -c Release -r win-x64 ``` -`Applications/MinimalBoilerServer` publishes cleanly with **zero AOT/trim +`samples/MinimalBoilerServer` publishes cleanly with **zero AOT/trim warnings** (~29 MB self-contained EXE). ## Runtime NodeSet alternative @@ -867,7 +867,7 @@ infrastructure and therefore **requires** the manager to derive from The only supported mode for combining models is **source-generated library references**. Each companion spec is built once into its -own model library (a `Libraries/Opc.Ua.{Spec}/` project that +own model library (a `src/Opc.Ua.{Spec}/` project that consumes the ModelDesign XML and emits an `AddOpcUa{Spec}` extension method); the consumer adds project references and calls the generated extensions directly in dependency order: @@ -973,15 +973,15 @@ input is supplied to the others as a resolution dependency (both ## Sample -- `Applications/MinimalBoilerServer/` — a fully self-contained, +- `samples/MinimalBoilerServer/` — a fully self-contained, NativeAOT single-file Boiler server. Read it top-to-bottom in <200 lines. -- `Applications/MinimalCalcServer/` — a calculator server that +- `samples/MinimalCalcServer/` — a calculator server that exercises the typed [methods-with-arguments OnCall overloads](#methods-with-arguments--typed-oncall-overloads) end-to-end (sync `int+int → int`, async `double+double → double`, sync `string+string → string`). -- `Applications/PumpDeviceIntegrationServer/` — the full OPC 40223 +- `samples/PumpDeviceIntegrationServer/` — the full OPC 40223 Pumps companion server. Exercises every fluent extension above (engineering units, identification properties, FunctionalGroup wiring, instance creation, limit alarm with NAMUR-style boolean diff --git a/docs/StateMachines.md b/docs/StateMachines.md index 9d33e89400..1af0783e21 100644 --- a/docs/StateMachines.md +++ b/docs/StateMachines.md @@ -532,16 +532,16 @@ with the spec; this is tracked but deliberately deferred. ## Tests -* `Tests/Opc.Ua.Server.Tests/StateMachines/StateMachineBuilderTests.cs` +* `tests/Opc.Ua.Server.Tests/StateMachines/StateMachineBuilderTests.cs` validates definition-mode chaining, validation, and freeze semantics. -* `Tests/Opc.Ua.Server.Tests/StateMachines/StateMachineBuilderLifecycleTests.cs` +* `tests/Opc.Ua.Server.Tests/StateMachines/StateMachineBuilderLifecycleTests.cs` exercises every lifecycle method, including timed transitions and the layering behavior on top of pre-existing delegates. -* `Tests/Opc.Ua.Server.Tests/StateMachines/FluentFiniteStateMachineStateTests.cs` +* `tests/Opc.Ua.Server.Tests/StateMachines/FluentFiniteStateMachineStateTests.cs` covers the table projections. * The Part 9 conformance tests in - `Tests/Opc.Ua.History.Tests/AlarmsAndConditions*.cs` exercise + `tests/Opc.Ua.History.Tests/AlarmsAndConditions*.cs` exercise `AlarmClient.GetShelvingStateAsync` and `ObserveShelvingTransitionsAsync` end-to-end against the reference server. diff --git a/docs/Subscriptions.md b/docs/Subscriptions.md index 06759f2d18..e0fad40757 100644 --- a/docs/Subscriptions.md +++ b/docs/Subscriptions.md @@ -10,7 +10,7 @@ stack: notifications delivered through the per-item `Notification` event or the per-subscription `FastDataChangeCallback` / `FastEventCallback`. 2. **V2 `ISubscriptionManager` / `ISubscription`** — the options-based - callback API in `Libraries/Opc.Ua.Client/Subscription/`. Items added + callback API in `src/Opc.Ua.Client/Subscription/`. Items added with `subscription.MonitoredItems.TryAdd(name, options, out _)`; notifications delivered through `ISubscriptionNotificationHandler` callbacks. The default engine on `ManagedSession`. @@ -533,7 +533,7 @@ notifications through a `System.Threading.Channels.Channel`. Disposing the enumerator removes the monitored item. This API sits on top of the V2 subscription engine -(`Libraries/Opc.Ua.Client/Subscription`). It is **not** a replacement +(`src/Opc.Ua.Client/Subscription`). It is **not** a replacement for either the classic or V2 callback-based API — it is a thin abstraction targeted at three concrete client scenarios: @@ -870,10 +870,10 @@ matches the use case. ## Reference -- Subscription source: `Libraries/Opc.Ua.Client/Subscription/` -- Streaming source: `Libraries/Opc.Ua.Client/Subscription/Streaming/` -- Helpers: `Libraries/Opc.Ua.Client/Subscription/Streaming/StreamingSubscriptionExtensions.cs` -- Alarm streaming: `Libraries/Opc.Ua.Client/Alarms/AlarmStreamExtensions.cs` +- Subscription source: `src/Opc.Ua.Client/Subscription/` +- Streaming source: `src/Opc.Ua.Client/Subscription/Streaming/` +- Helpers: `src/Opc.Ua.Client/Subscription/Streaming/StreamingSubscriptionExtensions.cs` +- Alarm streaming: `src/Opc.Ua.Client/Alarms/AlarmStreamExtensions.cs` - Sessions architecture and engine choice: [Sessions.md](Sessions.md) - Reference client sample: - `Applications/ConsoleReferenceClient/AlarmClientSample.cs` + `samples/ConsoleReferenceClient/AlarmClientSample.cs` diff --git a/docs/TransferSubscription.md b/docs/TransferSubscription.md index 38ceb2f629..97db912559 100644 --- a/docs/TransferSubscription.md +++ b/docs/TransferSubscription.md @@ -10,8 +10,8 @@ The TransferSubscriptions service for the Server and Client libraries is support * Updated C# Stack that supports the *TransferSubscriptions* service for Client and Server as specified in in [Part 4](https://reference.opcfoundation.org/v104/Core/docs/Part4/5.13.7/) * The updated server library supports to * Transfer subscriptions with optional inital values according to the service specification using the service call. - * **Breaking change**: Modified `INodeManager` interface which is extended with a `TransferMonitoredItems` [method](https://github.com/OPCFoundation/UA-.NETStandard/blob/8c1a659ecf5c1616b3b7f132706324b90f9ff015/Libraries/Opc.Ua.Server/NodeManager/INodeManager.cs#L309), to support the transfer of the monitored items hosted in various types of NodeManagers and to implement a unified way to queue initial values. - * Ported sample `NodeManager` implementations, which can be taken as a reference to port other custom implementations, e.g. [here](https://github.com/OPCFoundation/UA-.NETStandard/blob/8c1a659ecf5c1616b3b7f132706324b90f9ff015/Applications/Quickstarts.Servers/SampleNodeManager/SampleNodeManager.cs#L2937). + * **Breaking change**: Modified `INodeManager` interface which is extended with a `TransferMonitoredItems` [method](https://github.com/OPCFoundation/UA-.NETStandard/blob/8c1a659ecf5c1616b3b7f132706324b90f9ff015/src/Opc.Ua.Server/NodeManager/INodeManager.cs#L309), to support the transfer of the monitored items hosted in various types of NodeManagers and to implement a unified way to queue initial values. + * Ported sample `NodeManager` implementations, which can be taken as a reference to port other custom implementations, e.g. [here](https://github.com/OPCFoundation/UA-.NETStandard/blob/8c1a659ecf5c1616b3b7f132706324b90f9ff015/samples/Quickstarts.Servers/SampleNodeManager/SampleNodeManager.cs#L2937). * Updated client library which supports multiple ways to transfer subscriptions, applicable for any compliant server. The following use cases are supported to transfer a subscription: * **Transfer from active session**: The client creates a new session in the same process and transfers subscriptions into the new session while the old session is still active. @@ -21,10 +21,10 @@ The following use cases are supported to transfer a subscription: * Client Session library enhancements: * A new Session property `DeleteSubscriptionsOnClose` which, if set to `false`, does not delete the subscriptions if a session is closed on the server. To preserve the legacy behavior, the default of the property is `true`. * A new Subscription property `RepublishAfterRestart` which assumes, if set to `true`, that unacknowledged publish requests on the server after a transfer need to be republished to minimize the data loss. Otherwise remaining publish requests are only acknowledged after the transfer. - * A new `Session.TransferSubscriptions` [method](https://github.com/OPCFoundation/UA-.NETStandard/blob/8c1a659ecf5c1616b3b7f132706324b90f9ff015/Libraries/Opc.Ua.Client/Session.cs#L3410) to transfer a subscription managed by the client library. The new API can implicitly handle all of the above mentioned use cases. A requirement on the server side is not only the support of the TransferSubscriptions service, but also the implementation of the `GetMonitoredItems` ([see Part5](https://reference.opcfoundation.org/v104/Core/docs/Part5/9.1/)) standard method. + * A new `Session.TransferSubscriptions` [method](https://github.com/OPCFoundation/UA-.NETStandard/blob/8c1a659ecf5c1616b3b7f132706324b90f9ff015/src/Opc.Ua.Client/Session.cs#L3410) to transfer a subscription managed by the client library. The new API can implicitly handle all of the above mentioned use cases. A requirement on the server side is not only the support of the TransferSubscriptions service, but also the implementation of the `GetMonitoredItems` ([see Part5](https://reference.opcfoundation.org/v104/Core/docs/Part5/9.1/)) standard method. * Existing clients which use the `SessionReconnectHandler` get the improved support (no client changes necessary). -* The updated C# [Reference Server](../Applications/ConsoleReferenceServer) with ported NodeManager samples to support the new [TransferSubscriptions](https://reference.opcfoundation.org/v104/Core/docs/Part4/5.13.7/) service set. -* Multiple [unit tests](https://github.com/OPCFoundation/UA-.NETStandard/blob/8c1a659ecf5c1616b3b7f132706324b90f9ff015/Tests/Opc.Ua.Client.Tests/SubscriptionTest.cs#L455) demonstrating the use cases for subscription transfer. +* The updated C# [Reference Server](../samples/ConsoleReferenceServer) with ported NodeManager samples to support the new [TransferSubscriptions](https://reference.opcfoundation.org/v104/Core/docs/Part4/5.13.7/) service set. +* Multiple [unit tests](https://github.com/OPCFoundation/UA-.NETStandard/blob/8c1a659ecf5c1616b3b7f132706324b90f9ff015/tests/Opc.Ua.Client.Tests/SubscriptionTest.cs#L455) demonstrating the use cases for subscription transfer. * Updated NodeManagers with reference implementation of the necessary functions. ## Porting an existing server diff --git a/docs/Transports.md b/docs/Transports.md index e328fe2dc4..4cf11a32f4 100644 --- a/docs/Transports.md +++ b/docs/Transports.md @@ -259,7 +259,7 @@ the raw-socket default. The OPC UA Secure Conversation (UASC) binary channel pipeline talks to the wire through a narrow byte-level abstraction — -[`IUaSCByteTransport`](../Stack/Opc.Ua.Core/Stack/Tcp/IUaSCByteTransport.cs). +[`IUaSCByteTransport`](../src/Opc.Ua.Core/Stack/Tcp/IUaSCByteTransport.cs). It is the public extension point for plugging in custom transports beyond the built-in TCP and WebSocket implementations. @@ -328,7 +328,7 @@ wire. token while awaiting peer data — long-lived sessions rely on this to tear down cleanly. - [ ] Error mapping. Map transport-layer errors to - [`ServiceResultException`](../Stack/Opc.Ua.Core/Types/Result/ServiceResultException.cs) + [`ServiceResultException`](../src/Opc.Ua.Core/Types/Result/ServiceResultException.cs) with the matching `StatusCodes.BadXxx` (`BadConnectionClosed`, `BadTcpMessageTypeInvalid`, `BadTcpMessageTooLarge`, …) so the channel can route them through normal UA fault paths. @@ -347,7 +347,7 @@ wire. #### Client side -Implement [`IUaSCByteTransportFactory`](../Stack/Opc.Ua.Core/Stack/Tcp/IUaSCByteTransport.cs) +Implement [`IUaSCByteTransportFactory`](../src/Opc.Ua.Core/Stack/Tcp/IUaSCByteTransport.cs) and hand the factory to a subclass of `UaSCUaBinaryTransportChannel`: @@ -384,7 +384,7 @@ see `WssTransportChannel.OnSettingsSaved` for a reference. #### Server side -Implement [`ITransportListener`](../Stack/Opc.Ua.Core/Stack/Transport/ITransportListener.cs) +Implement [`ITransportListener`](../src/Opc.Ua.Core/Stack/Transport/ITransportListener.cs) plus an `ITransportListenerFactory`. For each accepted connection, construct your transport directly (not through the `IUaSCByteTransportFactory`, which is client-side only), then hand it to @@ -413,7 +413,7 @@ the registry to `ServerBase` (via `TransportBindings`) or to ### Worked example -[`InProcessTransport`](../Stack/Opc.Ua.Core/Stack/Tcp/InProcessTransport.cs) +[`InProcessTransport`](../src/Opc.Ua.Core/Stack/Tcp/InProcessTransport.cs) is the public reference implementation that ships in `Opc.Ua.Core`. It uses only public API: two paired transports communicate over a pair of in-memory `System.Threading.Channels.Channel` (one per diff --git a/docs/WebApi.md b/docs/WebApi.md index 5ef29092dc..81ddd781fe 100644 --- a/docs/WebApi.md +++ b/docs/WebApi.md @@ -15,7 +15,7 @@ mounted on the same Kestrel host as the binary and `[UnconditionalSuppressMessage]` attributes. - **Client side**: symmetric `IWebApiClient` in `OPCFoundation.NetStandard.Opc.Ua.Client` under - `Libraries/Opc.Ua.Client/WebApi/`. + `src/Opc.Ua.Client/WebApi/`. ## Quick start @@ -76,7 +76,7 @@ document deliberately omits them. All routes are `POST` with a JSON body holding the matching `Request`; the response body is the matching `Response`. The route table is the source of truth — see -`WebApiServiceRoutes` in `Stack/Opc.Ua.Core/Stack/WebApi/`. +`WebApiServiceRoutes` in `src/Opc.Ua.Core/Stack/WebApi/`. ## Encoding negotiation @@ -151,7 +151,7 @@ serialization uses the stack's existing `JsonEncoder` / `JsonDecoder` driven by `WebApiBodyCodec`. The encoder shape matches the spec's component schemas property-for-property; see `WebApiEncoderConformanceTests` in -`Tests/Opc.Ua.Core.Tests/Stack/WebApi/`. +`tests/Opc.Ua.Core.Tests/Stack/WebApi/`. ## Authentication diff --git a/docs/WhatsNewIn2.0.md b/docs/WhatsNewIn2.0.md index 02ce589bcb..91d3ad534e 100644 --- a/docs/WhatsNewIn2.0.md +++ b/docs/WhatsNewIn2.0.md @@ -407,7 +407,7 @@ opt-in workflow. The build pipeline now runs on a managed DevOps pool with a per-TFM build/test matrix and parallelized client tests. `Nullable` is enabled -across `Stack/`, the nine `Libraries/`, and the `Applications/` projects; +across `src/`, the nine `src/`, and the `samples/` projects; dispose-analyzers (`CA2000`, `CA2213`) are on and clean. The repository follows a strict `dotnet format` baseline (whitespace, IDE, RCS) enforced by the `opc-ua-codestyle-enforcer` agent. Code analysis runs at "preview" diff --git a/docs/migrate/2.0.x/alarms-model-change.md b/docs/migrate/2.0.x/alarms-model-change.md index b2419ee7c1..455d953d9a 100644 --- a/docs/migrate/2.0.x/alarms-model-change.md +++ b/docs/migrate/2.0.x/alarms-model-change.md @@ -26,7 +26,7 @@ the prior behavior, the spec-compliant behavior is what your operators expected anyway. To restore the old behavior, do not populate those optional state nodes (leave them `null`). -The quickstart reference server (`Applications/Quickstarts.Servers/ +The quickstart reference server (`samples/Quickstarts.Servers/ Alarms/AlarmHolders/AlarmConditionTypeHolder.cs`) now creates the `SilenceState`, `OutOfServiceState`, and `LatchedState` nodes by default — so the conformance tests exercise the new compliant diff --git a/docs/migrate/2.0.x/encoders.md b/docs/migrate/2.0.x/encoders.md index 40b1a5da42..7a90bc94ff 100644 --- a/docs/migrate/2.0.x/encoders.md +++ b/docs/migrate/2.0.x/encoders.md @@ -30,11 +30,11 @@ The `[Obsolete]` static `EncodeableFactory.GlobalFactory` was removed. `Encodeab The shared `ComplexTypeSystem` orchestrator, the complex type interfaces and the default (non-reflection-emit) type builder moved to the `Opc.Ua.Core.Schema` assembly under the root `Opc.Ua` namespace (which consumers already import) so they can be used by both client and server and existing code keeps compiling without adding a new `using`. Remove the old `Opc.Ua.Client.ComplexTypes` import if it is now unused (the client-only `NodeCacheResolver` and the `ComplexTypeSystem.Create(session, ...)` helpers stay in `Opc.Ua.Client.ComplexTypes`). The `ComplexTypeSystem(ISession, ...)` constructors were removed; construct a session-bound instance with `ComplexTypeSystem.Create(session, telemetry)` (the default, NativeAOT friendly builder) or `ComplexTypeSystem.Create(session, new ComplexTypeBuilderFactory(), telemetry)` for the Reflection.Emit builder. -Servers build the same stand-ins for runtime-loaded DataTypes **by default** (`StandardServer.LoadComplexTypes`; opt out by setting it to `false`); configure the pass with `AddComplexTypeSystem()` or invoke `IServerInternal.LoadComplexTypesAsync(...)` directly. See `Docs/ComplexTypes.md`. +Servers build the same stand-ins for runtime-loaded DataTypes **by default** (`StandardServer.LoadComplexTypes`; opt out by setting it to `false`); configure the pass with `AddComplexTypeSystem()` or invoke `IServerInternal.LoadComplexTypesAsync(...)` directly. See `docs/ComplexTypes.md`. ### OptionSet DataType support -Concrete Structure-backed sub-types of the abstract `OptionSet` DataType (`i=12755`) are now automatically registered by the default `ComplexTypeSystem` builder with a new runtime class `Opc.Ua.Encoders.OptionSet` (in `Stack/Opc.Ua.Types`). Bit-field metadata is resolved from `DataTypeDefinition` (`EnumDefinition`) or, as a fallback, synthesized from the `OptionSetValues` property (`LocalizedText[]`). +Concrete Structure-backed sub-types of the abstract `OptionSet` DataType (`i=12755`) are now automatically registered by the default `ComplexTypeSystem` builder with a new runtime class `Opc.Ua.Encoders.OptionSet` (in `src/Opc.Ua.Types`). Bit-field metadata is resolved from `DataTypeDefinition` (`EnumDefinition`) or, as a fallback, synthesized from the `OptionSetValues` property (`LocalizedText[]`). Impact on existing code: @@ -68,11 +68,11 @@ Custom encoder/decoder implementations must adjust to comply with the new interf The shared `ComplexTypeSystem` orchestrator, the complex type interfaces and the default (non-reflection-emit) type builder moved to the `Opc.Ua.Core.Schema` assembly under the root `Opc.Ua` namespace (which consumers already import) so they can be used by both client and server and existing code keeps compiling without adding a new `using`. Remove the old `Opc.Ua.Client.ComplexTypes` import if it is now unused (the client-only `NodeCacheResolver` and the `ComplexTypeSystem.Create(session, ...)` helpers stay in `Opc.Ua.Client.ComplexTypes`). The `ComplexTypeSystem(ISession, ...)` constructors were removed; construct a session-bound instance with `ComplexTypeSystem.Create(session, telemetry)` (the default, NativeAOT friendly builder) or `ComplexTypeSystem.Create(session, new ComplexTypeBuilderFactory(), telemetry)` for the Reflection.Emit builder. -Servers build the same stand-ins for runtime-loaded DataTypes **by default** (`StandardServer.LoadComplexTypes`; opt out by setting it to `false`); configure the pass with `AddComplexTypeSystem()` or invoke `IServerInternal.LoadComplexTypesAsync(...)` directly. See `Docs/ComplexTypes.md`. +Servers build the same stand-ins for runtime-loaded DataTypes **by default** (`StandardServer.LoadComplexTypes`; opt out by setting it to `false`); configure the pass with `AddComplexTypeSystem()` or invoke `IServerInternal.LoadComplexTypesAsync(...)` directly. See `docs/ComplexTypes.md`. ### OptionSet DataType support -Concrete Structure-backed sub-types of the abstract `OptionSet` DataType (`i=12755`) are now automatically registered by the default `ComplexTypeSystem` builder with a new runtime class `Opc.Ua.Encoders.OptionSet` (in `Stack/Opc.Ua.Types`). Bit-field metadata is resolved from `DataTypeDefinition` (`EnumDefinition`) or, as a fallback, synthesized from the `OptionSetValues` property (`LocalizedText[]`). +Concrete Structure-backed sub-types of the abstract `OptionSet` DataType (`i=12755`) are now automatically registered by the default `ComplexTypeSystem` builder with a new runtime class `Opc.Ua.Encoders.OptionSet` (in `src/Opc.Ua.Types`). Bit-field metadata is resolved from `DataTypeDefinition` (`EnumDefinition`) or, as a fallback, synthesized from the `OptionSetValues` property (`LocalizedText[]`). Impact on existing code: diff --git a/docs/migrate/2.0.x/node-states.md b/docs/migrate/2.0.x/node-states.md index 72d73a7404..80526f5f07 100644 --- a/docs/migrate/2.0.x/node-states.md +++ b/docs/migrate/2.0.x/node-states.md @@ -62,7 +62,7 @@ Example guidance (mirrors BoilerNodeManager): the node passed to `AddBehaviorToP } ``` -See [NodeStates](../../../Stack/Opc.Ua.Types/State/readme.md) document for more information. +See [NodeStates](../../../src/Opc.Ua.Types/State/readme.md) document for more information. ### NodeState Cloning and Lifecycle diff --git a/docs/migrate/2.0.x/packages.md b/docs/migrate/2.0.x/packages.md index f043abc33a..e7a52fda50 100644 --- a/docs/migrate/2.0.x/packages.md +++ b/docs/migrate/2.0.x/packages.md @@ -6,13 +6,13 @@ Two assemblies that previously shipped only as transitive content inside `Opc.Ua.Core` are now published as standalone NuGet packages. Add an explicit `` only if your project depends on these types without also depending on `Opc.Ua.Core` (which still includes them transitively). -**`OPCFoundation.NetStandard.Opc.Ua.Core.Types`** (project `Stack/Opc.Ua.Core.Types/Opc.Ua.Core.Types.csproj`, `IsPackable=true`, target frameworks `$(LibCoreTargetFrameworks)`). Owns the framework-neutral built-in type and node-state contracts. Headline public types include `IServiceRequest`, `IServiceResponse`, `BaseEventState`, `EventSeverity`, `InstanceStateSnapshot`, `FolderState`, `FolderTypeState`, `LimitAlarmStates`, `ContentFilter` (including `Result` / `ElementResult`), and `MonitoringFilter` / `MonitoringFilterResult`. +**`OPCFoundation.NetStandard.Opc.Ua.Core.Types`** (project `src/Opc.Ua.Core.Types/Opc.Ua.Core.Types.csproj`, `IsPackable=true`, target frameworks `$(LibCoreTargetFrameworks)`). Owns the framework-neutral built-in type and node-state contracts. Headline public types include `IServiceRequest`, `IServiceResponse`, `BaseEventState`, `EventSeverity`, `InstanceStateSnapshot`, `FolderState`, `FolderTypeState`, `LimitAlarmStates`, `ContentFilter` (including `Result` / `ElementResult`), and `MonitoringFilter` / `MonitoringFilterResult`. ```xml ``` -**`OPCFoundation.NetStandard.Opc.Ua.Security.Certificates`** (project `Stack/Opc.Ua.Security.Certificates/Opc.Ua.Security.Certificates.csproj`, `IsPackable=true`, target frameworks `$(LibCoreTargetFrameworks)`). Owns the wrapper certificate type system. Headline public types: `Certificate`, `CertificateCollection`, `IX509Certificate`, `ICertificateFactory`, `ICertificateIssuer`, `CertificateChangeKind`, `X509AuthorityKeyIdentifierExtension`, `X509CrlNumberExtension`, `X509SubjectAltNameExtension`, `CRLReason`. +**`OPCFoundation.NetStandard.Opc.Ua.Security.Certificates`** (project `src/Opc.Ua.Security.Certificates/Opc.Ua.Security.Certificates.csproj`, `IsPackable=true`, target frameworks `$(LibCoreTargetFrameworks)`). Owns the wrapper certificate type system. Headline public types: `Certificate`, `CertificateCollection`, `IX509Certificate`, `ICertificateFactory`, `ICertificateIssuer`, `CertificateChangeKind`, `X509AuthorityKeyIdentifierExtension`, `X509CrlNumberExtension`, `X509SubjectAltNameExtension`, `CRLReason`. ```xml @@ -28,32 +28,32 @@ The minimum SDK is the **.NET 10 SDK**, and projects compile with **`LangVersion | Package | Status in 2.0 | First introduced in | |---|---|---| -| `DotNext` 5.26.3 | Added | `Libraries/Opc.Ua.Lds.Server/Opc.Ua.Lds.Server.csproj` | +| `DotNext` 5.26.3 | Added | `src/Opc.Ua.Lds.Server/Opc.Ua.Lds.Server.csproj` | | `Makaretu.Dns.Multicast` 0.27.0 | Added (pinned) | Centralised pin; previously vendored in-tree, no direct reference yet | | `Microsoft.Bcl.TimeProvider` 10.0.8 | Added (pinned) | Centralised pin; transitive use for `TimeProvider` on net472/net48 | -| `Microsoft.CodeAnalysis.Analyzers` 4.14.0 | Added | `Stack/Opc.Ua.Core/Opc.Ua.Core.csproj` (runtime source-generation surface) | -| `Microsoft.CodeAnalysis.Common` 4.14.0 | Added | `Stack/Opc.Ua.Core/Opc.Ua.Core.csproj` | -| `Microsoft.CodeAnalysis.CSharp` 5.3.0 | Added | `Stack/Opc.Ua.Core/Opc.Ua.Core.csproj` | +| `Microsoft.CodeAnalysis.Analyzers` 4.14.0 | Added | `src/Opc.Ua.Core/Opc.Ua.Core.csproj` (runtime source-generation surface) | +| `Microsoft.CodeAnalysis.Common` 4.14.0 | Added | `src/Opc.Ua.Core/Opc.Ua.Core.csproj` | +| `Microsoft.CodeAnalysis.CSharp` 5.3.0 | Added | `src/Opc.Ua.Core/Opc.Ua.Core.csproj` | | `Microsoft.Extensions.Configuration.Abstractions` 10.0.8 | Added (pinned) | Used by dependency injection integration | | `Microsoft.Extensions.Diagnostics` 10.0.8 | Added (pinned) | Centralised pin | | `Microsoft.Extensions.Hosting` 10.0.8 | Added (pinned) | Centralised pin | | `Microsoft.Extensions.Hosting.Abstractions` 10.0.8 | Added (pinned) | Centralised pin | | `Microsoft.Extensions.Options` 10.0.8 | Added (pinned) | Centralised pin | | `Microsoft.Extensions.Options.ConfigurationExtensions` 10.0.8 | Added (pinned) | Centralised pin | -| `ModelContextProtocol` 1.3.0 | Added | `Applications/McpServer/Opc.Ua.Mcp.csproj` | -| `ModelContextProtocol.AspNetCore` 1.3.0 | Added | `Applications/McpServer/Opc.Ua.Mcp.csproj` | -| `SourceGenerator.Foundations` 2.0.14 | Added | `Tools/Opc.Ua.SourceGeneration.Stack/Opc.Ua.SourceGeneration.Stack.csproj` | -| `System.CommandLine` 2.0.8 | Added | `Applications/McpServer/Opc.Ua.Mcp.csproj` | -| `System.Threading.Channels` 10.0.8 | Added | `Libraries/Opc.Ua.Lds.Server/Opc.Ua.Lds.Server.csproj` | -| `TUnit` 1.45.8 | Added (test-only) | `Tests/Opc.Ua.Server.Tests/Opc.Ua.Server.Tests.csproj` | +| `ModelContextProtocol` 1.3.0 | Added | `tools/Opc.Ua.Mcp/Opc.Ua.Mcp.csproj` | +| `ModelContextProtocol.AspNetCore` 1.3.0 | Added | `tools/Opc.Ua.Mcp/Opc.Ua.Mcp.csproj` | +| `SourceGenerator.Foundations` 2.0.14 | Added | `tools/Opc.Ua.SourceGeneration.Stack/Opc.Ua.SourceGeneration.Stack.csproj` | +| `System.CommandLine` 2.0.8 | Added | `tools/Opc.Ua.Mcp/Opc.Ua.Mcp.csproj` | +| `System.Threading.Channels` 10.0.8 | Added | `src/Opc.Ua.Lds.Server/Opc.Ua.Lds.Server.csproj` | +| `TUnit` 1.45.8 | Added (test-only) | `tests/Opc.Ua.Server.Tests/Opc.Ua.Server.Tests.csproj` | | `NUnit.Analyzers` 4.13.0 | Added (test-only) | Test projects | | `ObjectLayoutInspector` 0.2.0 | Added (test-only) | Test projects | | `System.Reflection.Metadata` 10.0.6 | Added (test-only) | Test projects | -| `Mono.Options` 6.12.0.148 | Removed | Previously referenced by `Applications/ConsoleReferenceServer/MonoReferenceServer.csproj` | +| `Mono.Options` 6.12.0.148 | Removed | Previously referenced by `samples/ConsoleReferenceServer/MonoReferenceServer.csproj` | ### Newtonsoft.Json - what really changed -`Newtonsoft.Json` was removed as a direct dependency of `Stack/Opc.Ua.Core/Opc.Ua.Core.csproj` in 2.0. The only direct `` remaining anywhere under `Libraries/` and `Stack/` is in `Libraries/Opc.Ua.PubSub/Opc.Ua.PubSub.csproj`. Consequences: +`Newtonsoft.Json` was removed as a direct dependency of `src/Opc.Ua.Core/Opc.Ua.Core.csproj` in 2.0. The only direct `` remaining anywhere under `src/` and `src/` is in `src/Opc.Ua.PubSub/Opc.Ua.PubSub.csproj`. Consequences: - Consumers that reached `Newtonsoft.Json` only transitively through `Opc.Ua.Core` now need to add their own explicit reference. - Consumers of `Opc.Ua.PubSub` continue to receive `Newtonsoft.Json` transitively and are unaffected. diff --git a/docs/migrate/2.0.x/pubsub.md b/docs/migrate/2.0.x/pubsub.md index 2eff6ebfe4..6c18ddb96e 100644 --- a/docs/migrate/2.0.x/pubsub.md +++ b/docs/migrate/2.0.x/pubsub.md @@ -89,7 +89,7 @@ for the in-code form. Cites [Part 14 §6.2](https://reference.opcfoundation.org/ The Newtonsoft-based encoder (`Opc.Ua.PubSub.Encoding.JsonNetworkMessage` v1) is replaced with a `System.Text.Json`-backed encoder under -`Libraries/Opc.Ua.PubSub/Encoding/Json/`. Behaviour changes that may surface in +`src/Opc.Ua.PubSub/Encoding/Json/`. Behaviour changes that may surface in callers: - The `Newtonsoft.Json` dependency is dropped from the PubSub layer (it remains diff --git a/docs/migrate/2.0.x/sessions-subscriptions.md b/docs/migrate/2.0.x/sessions-subscriptions.md index e446102b8f..0783e3e7fa 100644 --- a/docs/migrate/2.0.x/sessions-subscriptions.md +++ b/docs/migrate/2.0.x/sessions-subscriptions.md @@ -53,7 +53,7 @@ await Task.WhenAll(asTask, otherTask); **Migration**: -The `ServerCapability` identifiers are source-generated from `Tools/Opc.Ua.SourceGeneration.Core/Design/ServerCapabilities.csv`; each capability emits a `public const string` field. The instance type carrying `Id` / `Description` is `ServerCapabilityInfo`, and the registry exposing `IEnumerable` plus `Find(string?) : ServerCapabilityInfo?` is the static `ServerCapabilities` class in `Opc.Ua.Gds.Client.Common`. +The `ServerCapability` identifiers are source-generated from `tools/Opc.Ua.SourceGeneration.Core/Design/ServerCapabilities.csv`; each capability emits a `public const string` field. The instance type carrying `Id` / `Description` is `ServerCapabilityInfo`, and the registry exposing `IEnumerable` plus `Find(string?) : ServerCapabilityInfo?` is the static `ServerCapabilities` class in `Opc.Ua.Gds.Client.Common`. ```csharp // Before @@ -261,7 +261,7 @@ after the handler `await` completes and calls their static activator pools. The recorded benchmarks show ~315× fewer allocations per `MonitoredItemNotification` and a corresponding drop in gen-0 GC pressure -(see [`Docs/Benchmarks.md` → *Pooled encodeable*](../../Benchmarks.md#pooled-encodeable)). +(see [`docs/Benchmarks.md` → *Pooled encodeable*](../../Benchmarks.md#pooled-encodeable)). **Handler contract change (only when `WithPoolNotifications` is enabled):** Handlers must **not** retain references to notification objects past the @@ -271,7 +271,7 @@ values must **copy** them out of the dispatched struct before returning. The `DataValueChange` / `EventNotification` projection structs are designed not to surface pooled instances directly — copy-by-value of the struct itself is safe and is the recommended pattern. See -[`Docs/Sessions.md`](../../Sessions.md#v2-notification-pooling-opt-in) for full +[`docs/Sessions.md`](../../Sessions.md#v2-notification-pooling-opt-in) for full detail and a code example. ```csharp @@ -333,7 +333,7 @@ This iteration uses single-instance options (no named/keyed registrations); the ### Durable subscriptions and reshaped Subscription tree -**Source-breaking.** Durable subscription support reshapes the subscription tree on both the client and the server. On the client side, the new public surface in `Libraries/Opc.Ua.Client/Subscription/` includes `ISubscription`, `ISubscriptionManager`, `SubscriptionOptions`, and `MonitoredItemOptions` - these are the V2 options-based shapes; the classic `Opc.Ua.Client.Subscription` continues to ship alongside them. On the server side, the new public surface in `Libraries/Opc.Ua.Server/Subscription/...` includes `DataChangeMonitoredItemQueue`, `EventMonitoredItemQueue`, `IDataChangeMonitoredItemQueue`, `IMonitoredItemQueueFactory`, `ISubscriptionStore`, `IStoredSubscription`, `StoredSubscription`, and `StoredMonitoredItem`. +**Source-breaking.** Durable subscription support reshapes the subscription tree on both the client and the server. On the client side, the new public surface in `src/Opc.Ua.Client/Subscription/` includes `ISubscription`, `ISubscriptionManager`, `SubscriptionOptions`, and `MonitoredItemOptions` - these are the V2 options-based shapes; the classic `Opc.Ua.Client.Subscription` continues to ship alongside them. On the server side, the new public surface in `src/Opc.Ua.Server/Subscription/...` includes `DataChangeMonitoredItemQueue`, `EventMonitoredItemQueue`, `IDataChangeMonitoredItemQueue`, `IMonitoredItemQueueFactory`, `ISubscriptionStore`, `IStoredSubscription`, `StoredSubscription`, and `StoredMonitoredItem`. Consumers adopting the new shape may need to add a `using Opc.Ua.Client.Subscriptions;` import alongside the existing `using Opc.Ua.Client;`. Because the V2 records share their type names with the classic records, namespace aliases are required when both are visible in the same file - see [Fluent Builder, V2 Subscriptions, and Dependency Injection](#fluent-builder-v2-subscriptions-and-dependency-injection) for the canonical alias snippet. @@ -343,7 +343,7 @@ The server-side `ISubscriptionStore` definition-persistence methods are asynchro ### PubSub -**Not source-breaking.** No public top-level types in `Opc.Ua.PubSub` were removed or renamed in 2.0. Changes are limited to internal modernization, AOT preparation, and diagnostics improvements. `Newtonsoft.Json` remains a direct `` of `Libraries/Opc.Ua.PubSub/Opc.Ua.PubSub.csproj`, so PubSub consumers keep receiving it transitively (see [Newtonsoft.Json - what really changed](#newtonsoftjson---what-really-changed)). +**Not source-breaking.** No public top-level types in `Opc.Ua.PubSub` were removed or renamed in 2.0. Changes are limited to internal modernization, AOT preparation, and diagnostics improvements. `Newtonsoft.Json` remains a direct `` of `src/Opc.Ua.PubSub/Opc.Ua.PubSub.csproj`, so PubSub consumers keep receiving it transitively (see [Newtonsoft.Json - what really changed](#newtonsoftjson---what-really-changed)). ### Reverse connect @@ -363,7 +363,7 @@ The runtime transport boundary moved from `IMessageSocket` to the new public `IU | `UaSCUaBinaryClientChannel(..., IMessageSocketFactory, ...)` ctor | `UaSCUaBinaryClientChannel(..., IUaSCByteTransportFactory, ...)` ctor | | `ITcpChannelListener.ReconnectToExistingChannel(IMessageSocket, ...)` | `ITcpChannelListener.ReconnectToExistingChannel(IUaSCByteTransport, ...)` | -**If you previously implemented a custom `IMessageSocket`** (rare in practice — almost no consumer subclasses `TcpMessageSocket`): the recommended migration path is to implement [`IUaSCByteTransport`](../../../Stack/Opc.Ua.Core/Stack/Tcp/IUaSCByteTransport.cs) directly. See [`Docs/Transports.md`](../../Transports.md) § "Implementing a custom byte transport" for the contract, an implementation checklist, and a worked example (the public [`InProcessTransport`](../../../Stack/Opc.Ua.Core/Stack/Tcp/InProcessTransport.cs) reference implementation that consumes only the public surface). The new abstraction is chunk-oriented (one Send / Receive per UASC `MessageChunk`) and exposes only `ValueTask`-based async; it is intentionally narrower than the old SAEA-based `IMessageSocket` and most legacy implementations collapse to ~150 lines. +**If you previously implemented a custom `IMessageSocket`** (rare in practice — almost no consumer subclasses `TcpMessageSocket`): the recommended migration path is to implement [`IUaSCByteTransport`](../../../src/Opc.Ua.Core/Stack/Tcp/IUaSCByteTransport.cs) directly. See [`docs/Transports.md`](../../Transports.md) § "Implementing a custom byte transport" for the contract, an implementation checklist, and a worked example (the public [`InProcessTransport`](../../../src/Opc.Ua.Core/Stack/Tcp/InProcessTransport.cs) reference implementation that consumes only the public surface). The new abstraction is chunk-oriented (one Send / Receive per UASC `MessageChunk`) and exposes only `ValueTask`-based async; it is intentionally narrower than the old SAEA-based `IMessageSocket` and most legacy implementations collapse to ~150 lines. ### Transport binding registry — `TransportBindings` static API removed diff --git a/docs/migrate/2.0.x/telemetry.md b/docs/migrate/2.0.x/telemetry.md index e789851c47..f3388ae9c5 100644 --- a/docs/migrate/2.0.x/telemetry.md +++ b/docs/migrate/2.0.x/telemetry.md @@ -66,7 +66,7 @@ builder.Services `AddOpcUa()` registers a `ServiceProviderTelemetryContext` that resolves the host's `ILoggerFactory` from DI on first use. See -[`Docs/Diagnostics.md`](../../Diagnostics.md#wiring-into-microsoftextensionsdependencyinjection) +[`docs/Diagnostics.md`](../../Diagnostics.md#wiring-into-microsoftextensionsdependencyinjection) for the full DI guidance. ### From static `Utils.Log*` methods @@ -250,7 +250,7 @@ test time. **See also** - Related: [packages.md](packages.md), [configuration.md](configuration.md). -- [`Docs/Diagnostics.md`](../../Diagnostics.md) — full +- [`docs/Diagnostics.md`](../../Diagnostics.md) — full end-state usage and extensibility guidance for `ITelemetryContext` (custom contexts, OpenTelemetry wiring, metrics inventory). - [2.0 migration index](README.md) — analyzer quick-start + symptom → sub-doc table. diff --git a/fuzzing/Fuzzing.md b/fuzzing/Fuzzing.md index 7029aaed31..c87f79c37b 100644 --- a/fuzzing/Fuzzing.md +++ b/fuzzing/Fuzzing.md @@ -2,7 +2,7 @@ This project provides integration of [SharpFuzz](https://github.com/Metalnem/sharpfuzz) with the UA.NET Standard libraries, with support for both [afl-fuzz](https://lcamtuf.coredump.cx/afl/) and -[libFuzzer](https://llvm.org/docs/LibFuzzer.html). Each fuzz area lives directly under `Fuzzing/` +[libFuzzer](https://llvm.org/docs/LibFuzzer.html). Each fuzz area lives directly under `fuzzing/` as four sibling folders — host (`*.Fuzz`), corpus (`*.Fuzz.Corpus`), test fixture (`*.Fuzz.Tests`), and tools (`*.Fuzz.Tools`) — and shares a generic NUnit replay harness plus the SharpFuzz host under `Common/`. @@ -22,7 +22,7 @@ under `Common/`. ## Directory layout ``` -Fuzzing/ +fuzzing/ Fuzzing.md # this file Common/ # shared source (no csproj) @@ -54,7 +54,7 @@ Fuzzing/ Opc.Ua.Network.Fuzz.Tests/ Opc.Ua.Network.Fuzz.Tools/ ``` -The flat layout matches the rest of the repository (`Tests/`, `Libraries/`, `Stack/` also list +The flat layout matches the rest of the repository (`tests/`, `src/`, `src/` also list projects directly under the root with no domain grouping). Every csproj folder name equals the csproj filename (without the `.csproj` extension), and every assembly is prefixed with `Opc.Ua.` in line with the repo's `AssemblyPrefix` convention. @@ -105,11 +105,11 @@ public class EncoderTests : FuzzTargetTestsBase `Opc.Ua..Fuzz.Corpus/Testcases./`. Each `Testcases.*/` subdirectory becomes a logical seed bucket and is auto-discovered by `TestAssetUtils.DiscoverTestcaseEncoderSuffixes`. -6. **Add a dictionary.** Put `.dict` under `Fuzzing/Dictionaries/` with common +6. **Add a dictionary.** Put `.dict` under `fuzzing/Dictionaries/` with common tokens / magic bytes / length sentinels — this dramatically improves libFuzzer coverage progression. -7. **Wire into `UA.slnx`.** Add the three new projects to the `/Fuzzing/` folder, the - `*.dict` file under `/Fuzzing/Dictionaries/`, and the seed loose files you want visible in +7. **Wire into `UA.slnx`.** Add the three new projects to the `/fuzzing/` folder, the + `*.dict` file under `/fuzzing/Dictionaries/`, and the seed loose files you want visible in the IDE. 8. **Update this `Fuzzing.md`.** Add a row to the area table. @@ -123,7 +123,7 @@ under the `[Category("Fuzzing")]` filter. The Network area is unusual because it's split across two complementary entry points: * **Phase 4a (no Core changes).** Fuzzes the public surfaces of - `Stack/Opc.Ua.Core.Diagnostics`: `OpcUaFrameParser.Process` (TCP → UA-SC chunk splitter), + `src/Opc.Ua.Core.Diagnostics`: `OpcUaFrameParser.Process` (TCP → UA-SC chunk splitter), `TcpStreamReassembler.Process` (raw TCP), `OfflineSecureChannel.ReadChunk` (UA-SC symmetric decrypt + verify using the stack's own `UaSCUaBinaryChannel.ReadSymmetricMessage`, so every security profile is covered for free), and `ServiceCallReassembler.Push` (chunk @@ -133,7 +133,7 @@ The Network area is unusual because it's split across two complementary entry po dominate throughput. * **Phase 4b (internal Core seam).** Adds `internal static class TcpMessageParsers` in - `Stack/Opc.Ua.Core/Stack/Tcp/TcpMessageParsers.cs` covering the pre-crypto, pre-auth chunk + `src/Opc.Ua.Core/Stack/Tcp/TcpMessageParsers.cs` covering the pre-crypto, pre-auth chunk surface the pcap binding does not expose: `TryParseChunkHeader`, `ReadHelloMessage`, `ReadAcknowledgeMessage`, `ReadErrorMessage`, `ReadReverseHelloMessage`, `ReadAsymmetricMessageHeader`. Surfaced to the fuzz area via @@ -170,7 +170,7 @@ libFuzzer prebuilt binaries are available for Debian / Ubuntu / Windows from the [libfuzzer-dotnet releases](https://github.com/Metalnem/libfuzzer-dotnet/releases). ```bash -cd /Fuzzing +cd /fuzzing sudo apt-get update sudo apt-get install -y build-essential cmake git dotnet-sdk-10.0 # Powershell on Linux (required by the helper scripts): @@ -202,8 +202,8 @@ The dynamic menu script lists every `FuzzableCode` static target in a built area without hardcoding target names: ```powershell -powershell -File Fuzzing/Scripts/fuzz-menu.ps1 ` - -AssemblyPath Fuzzing/Opc.Ua.Network.Fuzz/bin/Debug/net10.0/Opc.Ua.Network.Fuzz.dll +powershell -File fuzzing/Scripts/fuzz-menu.ps1 ` + -AssemblyPath fuzzing/Opc.Ua.Network.Fuzz/bin/Debug/net10.0/Opc.Ua.Network.Fuzz.dll # -Filter narrows the list; -Index selects a target without prompting. ``` @@ -211,7 +211,7 @@ powershell -File Fuzzing/Scripts/fuzz-menu.ps1 ` matching one of the listed names: ```powershell -cd Fuzzing +cd fuzzing powershell -File Scripts/fuzz-libfuzzer.ps1 ` -libFuzzer ./libfuzzer-dotnet-windows.exe ` -project ./Opc.Ua.Encoders.Fuzz/Opc.Ua.Encoders.Fuzz.csproj ` @@ -228,7 +228,7 @@ directory. Run the area's `*.Fuzz.Tools` project with `-p` / `-s` for playback with stack traces: ```bash -dotnet run --project Fuzzing/Opc.Ua.Network.Fuzz.Tools -- --playback --stacktrace +dotnet run --project fuzzing/Opc.Ua.Network.Fuzz.Tools -- --playback --stacktrace ``` The playback tool finds all crashes / timeouts in the default folders and replays them @@ -241,7 +241,7 @@ Run the area's `*.Fuzz.Tools` project with `-t` to (re)generate the area's `Test seed corpus: ```bash -dotnet run --project Fuzzing/Opc.Ua.Network.Fuzz.Tools -- --testcases +dotnet run --project fuzzing/Opc.Ua.Network.Fuzz.Tools -- --testcases ``` This re-runs the deterministic seed-generation pipeline (handshake recorder for Network, @@ -258,20 +258,20 @@ this entire toolchain autonomously. It detects the host OS, picks the available (libFuzzer everywhere, afl-fuzz on Linux when installed), publishes + SharpFuzz-instruments each area's host project, enumerates `FuzzableCode` targets via `Scripts/fuzz-menu.ps1`, launches one detached fuzz process per (area × engine × target) -tuple, and polls the per-instance work dirs under `Fuzzing/.runs/` for new findings. +tuple, and polls the per-instance work dirs under `fuzzing/.runs/` for new findings. When the agent picks up a novel `crash-*` / `timeout-*` / `slow-unit-*` (or afl `crashes/` / `hangs/`) file it: 1. SHA-1 dedups against every `Opc.Ua..Fuzz.Tests/Assets/-` already in the repo so it never re-investigates a known regression seed. -2. Reproduces the crash locally via `dotnet run --project Fuzzing/Opc.Ua..Fuzz.Tools -- --playback --stacktrace`. +2. Reproduces the crash locally via `dotnet run --project fuzzing/Opc.Ua..Fuzz.Tools -- --playback --stacktrace`. 3. Designs a minimal fix following every repo guideline (no SYNC-over-ASYNC, `Span` / `ReadOnlySpan` / `ByteString` in public API, Allman + 4-space + CRLF + MIT header on new files, no `#region`, no `[Obsolete]` usage, NativeAOT-safe, `TreatWarningsAsErrors` clean, no exposed locks). 4. Runs a rubber-duck agent review (max 2 rounds) on the proposed diff. -5. Copies the failing input to `Fuzzing/Opc.Ua..Fuzz.Tests/Assets/-` +5. Copies the failing input to `fuzzing/Opc.Ua..Fuzz.Tests/Assets/-` so the existing harness (`FuzzCrashAssets` / `FuzzTimeoutAssets` / `FuzzSlowAssets`) replays it through every target on every future `dotnet test` run. 6. Rebuilds and runs the three `*.Fuzz.Tests` projects on `net10.0`; the run must end at @@ -294,7 +294,6 @@ any time with *"stop"*, *"halt"*, *"stop fuzzing"*, *"that's enough"*. The agent's own toolchain setup mirrors the manual `Installation` section above: `SharpFuzz.CommandLine` global tool, the `libfuzzer-dotnet` driver under -`Fuzzing/.tools/` (gitignored), and `afl-fuzz` on PATH for the AFL engine on Linux. +`fuzzing/.tools/` (gitignored), and `afl-fuzz` on PATH for the AFL engine on Linux. If any are missing AND cannot be auto-installed (air-gapped box, `sudo` not available, …), the agent surfaces the gap and asks the user how to proceed. - diff --git a/fuzzing/Opc.Ua.Certificates.Fuzz.Tests/Opc.Ua.Certificates.Fuzz.Tests.csproj b/fuzzing/Opc.Ua.Certificates.Fuzz.Tests/Opc.Ua.Certificates.Fuzz.Tests.csproj index 2e9e92fd26..fb73e70f27 100644 --- a/fuzzing/Opc.Ua.Certificates.Fuzz.Tests/Opc.Ua.Certificates.Fuzz.Tests.csproj +++ b/fuzzing/Opc.Ua.Certificates.Fuzz.Tests/Opc.Ua.Certificates.Fuzz.Tests.csproj @@ -36,12 +36,12 @@ - - - + + + - + diff --git a/fuzzing/Opc.Ua.Certificates.Fuzz.Tests/Properties/AssemblyInfo.cs b/fuzzing/Opc.Ua.Certificates.Fuzz.Tests/Properties/AssemblyInfo.cs index a8a34836fb..7798c9bd57 100644 --- a/fuzzing/Opc.Ua.Certificates.Fuzz.Tests/Properties/AssemblyInfo.cs +++ b/fuzzing/Opc.Ua.Certificates.Fuzz.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Fuzzing/Opc.Ua.Certificates.Fuzz.Tests/Properties/AssemblyInfo.cs diff --git a/fuzzing/Opc.Ua.Certificates.Fuzz.Tools/Opc.Ua.Certificates.Fuzz.Tools.csproj b/fuzzing/Opc.Ua.Certificates.Fuzz.Tools/Opc.Ua.Certificates.Fuzz.Tools.csproj index 1e6df8772f..82169d6415 100644 --- a/fuzzing/Opc.Ua.Certificates.Fuzz.Tools/Opc.Ua.Certificates.Fuzz.Tools.csproj +++ b/fuzzing/Opc.Ua.Certificates.Fuzz.Tools/Opc.Ua.Certificates.Fuzz.Tools.csproj @@ -30,7 +30,7 @@ - - + + diff --git a/fuzzing/Opc.Ua.Certificates.Fuzz.Tools/Properties/AssemblyInfo.cs b/fuzzing/Opc.Ua.Certificates.Fuzz.Tools/Properties/AssemblyInfo.cs index fc0688fd26..7798c9bd57 100644 --- a/fuzzing/Opc.Ua.Certificates.Fuzz.Tools/Properties/AssemblyInfo.cs +++ b/fuzzing/Opc.Ua.Certificates.Fuzz.Tools/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Fuzzing/Opc.Ua.Certificates.Fuzz.Tools/Properties/AssemblyInfo.cs diff --git a/fuzzing/Opc.Ua.Certificates.Fuzz/Opc.Ua.Certificates.Fuzz.csproj b/fuzzing/Opc.Ua.Certificates.Fuzz/Opc.Ua.Certificates.Fuzz.csproj index 167ce4c0ed..acea29ec99 100644 --- a/fuzzing/Opc.Ua.Certificates.Fuzz/Opc.Ua.Certificates.Fuzz.csproj +++ b/fuzzing/Opc.Ua.Certificates.Fuzz/Opc.Ua.Certificates.Fuzz.csproj @@ -16,7 +16,7 @@ - - + + diff --git a/fuzzing/Opc.Ua.Certificates.Fuzz/Properties/AssemblyInfo.cs b/fuzzing/Opc.Ua.Certificates.Fuzz/Properties/AssemblyInfo.cs index b7cc71b21b..7798c9bd57 100644 --- a/fuzzing/Opc.Ua.Certificates.Fuzz/Properties/AssemblyInfo.cs +++ b/fuzzing/Opc.Ua.Certificates.Fuzz/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Fuzzing/Opc.Ua.Certificates.Fuzz/Properties/AssemblyInfo.cs diff --git a/fuzzing/Opc.Ua.Encoders.Fuzz.Tests/Opc.Ua.Encoders.Fuzz.Tests.csproj b/fuzzing/Opc.Ua.Encoders.Fuzz.Tests/Opc.Ua.Encoders.Fuzz.Tests.csproj index fc617bedad..e6b9ea0f4f 100644 --- a/fuzzing/Opc.Ua.Encoders.Fuzz.Tests/Opc.Ua.Encoders.Fuzz.Tests.csproj +++ b/fuzzing/Opc.Ua.Encoders.Fuzz.Tests/Opc.Ua.Encoders.Fuzz.Tests.csproj @@ -36,12 +36,12 @@ - - - + + + - + diff --git a/fuzzing/Opc.Ua.Encoders.Fuzz.Tests/Properties/AssemblyInfo.cs b/fuzzing/Opc.Ua.Encoders.Fuzz.Tests/Properties/AssemblyInfo.cs index ec534faa3d..2b9848014c 100644 --- a/fuzzing/Opc.Ua.Encoders.Fuzz.Tests/Properties/AssemblyInfo.cs +++ b/fuzzing/Opc.Ua.Encoders.Fuzz.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Fuzzing/Opc.Ua.Encoders.Fuzz.Tests/Properties/AssemblyInfo.cs diff --git a/fuzzing/Opc.Ua.Encoders.Fuzz.Tools/Opc.Ua.Encoders.Fuzz.Tools.csproj b/fuzzing/Opc.Ua.Encoders.Fuzz.Tools/Opc.Ua.Encoders.Fuzz.Tools.csproj index 90a9471960..4634db0b12 100644 --- a/fuzzing/Opc.Ua.Encoders.Fuzz.Tools/Opc.Ua.Encoders.Fuzz.Tools.csproj +++ b/fuzzing/Opc.Ua.Encoders.Fuzz.Tools/Opc.Ua.Encoders.Fuzz.Tools.csproj @@ -30,7 +30,7 @@ - - + + diff --git a/fuzzing/Opc.Ua.Encoders.Fuzz.Tools/Properties/AssemblyInfo.cs b/fuzzing/Opc.Ua.Encoders.Fuzz.Tools/Properties/AssemblyInfo.cs index 59a285367f..2b9848014c 100644 --- a/fuzzing/Opc.Ua.Encoders.Fuzz.Tools/Properties/AssemblyInfo.cs +++ b/fuzzing/Opc.Ua.Encoders.Fuzz.Tools/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Fuzzing/Opc.Ua.Encoders.Fuzz.Tools/Properties/AssemblyInfo.cs diff --git a/fuzzing/Opc.Ua.Encoders.Fuzz/Opc.Ua.Encoders.Fuzz.csproj b/fuzzing/Opc.Ua.Encoders.Fuzz/Opc.Ua.Encoders.Fuzz.csproj index 8174cb5d3f..77e5597cce 100644 --- a/fuzzing/Opc.Ua.Encoders.Fuzz/Opc.Ua.Encoders.Fuzz.csproj +++ b/fuzzing/Opc.Ua.Encoders.Fuzz/Opc.Ua.Encoders.Fuzz.csproj @@ -16,7 +16,7 @@ - - + + diff --git a/fuzzing/Opc.Ua.Encoders.Fuzz/Properties/AssemblyInfo.cs b/fuzzing/Opc.Ua.Encoders.Fuzz/Properties/AssemblyInfo.cs index b0686a86bf..2b9848014c 100644 --- a/fuzzing/Opc.Ua.Encoders.Fuzz/Properties/AssemblyInfo.cs +++ b/fuzzing/Opc.Ua.Encoders.Fuzz/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Fuzzing/Opc.Ua.Encoders.Fuzz/Properties/AssemblyInfo.cs diff --git a/fuzzing/Opc.Ua.Network.Fuzz.Tests/Opc.Ua.Network.Fuzz.Tests.csproj b/fuzzing/Opc.Ua.Network.Fuzz.Tests/Opc.Ua.Network.Fuzz.Tests.csproj index 66150c45bf..e240ace4e7 100644 --- a/fuzzing/Opc.Ua.Network.Fuzz.Tests/Opc.Ua.Network.Fuzz.Tests.csproj +++ b/fuzzing/Opc.Ua.Network.Fuzz.Tests/Opc.Ua.Network.Fuzz.Tests.csproj @@ -39,12 +39,12 @@ - - - + + + - + diff --git a/fuzzing/Opc.Ua.Network.Fuzz.Tests/Properties/AssemblyInfo.cs b/fuzzing/Opc.Ua.Network.Fuzz.Tests/Properties/AssemblyInfo.cs index 1395e91c57..41e52d6904 100644 --- a/fuzzing/Opc.Ua.Network.Fuzz.Tests/Properties/AssemblyInfo.cs +++ b/fuzzing/Opc.Ua.Network.Fuzz.Tests/Properties/AssemblyInfo.cs @@ -29,5 +29,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Fuzzing/Opc.Ua.Network.Fuzz.Tests/Properties/AssemblyInfo.cs diff --git a/fuzzing/Opc.Ua.Network.Fuzz.Tools/Opc.Ua.Network.Fuzz.Tools.csproj b/fuzzing/Opc.Ua.Network.Fuzz.Tools/Opc.Ua.Network.Fuzz.Tools.csproj index de1e16dfb7..a21e27309e 100644 --- a/fuzzing/Opc.Ua.Network.Fuzz.Tools/Opc.Ua.Network.Fuzz.Tools.csproj +++ b/fuzzing/Opc.Ua.Network.Fuzz.Tools/Opc.Ua.Network.Fuzz.Tools.csproj @@ -36,10 +36,10 @@ - - - - - + + + + + diff --git a/fuzzing/Opc.Ua.Network.Fuzz.Tools/Properties/AssemblyInfo.cs b/fuzzing/Opc.Ua.Network.Fuzz.Tools/Properties/AssemblyInfo.cs index 5d563849bf..41e52d6904 100644 --- a/fuzzing/Opc.Ua.Network.Fuzz.Tools/Properties/AssemblyInfo.cs +++ b/fuzzing/Opc.Ua.Network.Fuzz.Tools/Properties/AssemblyInfo.cs @@ -29,5 +29,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Fuzzing/Opc.Ua.Network.Fuzz.Tools/Properties/AssemblyInfo.cs diff --git a/fuzzing/Opc.Ua.Network.Fuzz/Opc.Ua.Network.Fuzz.csproj b/fuzzing/Opc.Ua.Network.Fuzz/Opc.Ua.Network.Fuzz.csproj index 1c2507ef20..e6b72cd40b 100644 --- a/fuzzing/Opc.Ua.Network.Fuzz/Opc.Ua.Network.Fuzz.csproj +++ b/fuzzing/Opc.Ua.Network.Fuzz/Opc.Ua.Network.Fuzz.csproj @@ -29,6 +29,6 @@ - + diff --git a/fuzzing/Opc.Ua.Network.Fuzz/Properties/AssemblyInfo.cs b/fuzzing/Opc.Ua.Network.Fuzz/Properties/AssemblyInfo.cs index 793d3062aa..41e52d6904 100644 --- a/fuzzing/Opc.Ua.Network.Fuzz/Properties/AssemblyInfo.cs +++ b/fuzzing/Opc.Ua.Network.Fuzz/Properties/AssemblyInfo.cs @@ -29,5 +29,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Fuzzing/Opc.Ua.Network.Fuzz/Properties/AssemblyInfo.cs diff --git a/fuzzing/Opc.Ua.PubSub.Fuzz/Opc.Ua.PubSub.Fuzz.csproj b/fuzzing/Opc.Ua.PubSub.Fuzz/Opc.Ua.PubSub.Fuzz.csproj index 9830cdbc6c..8cd1218181 100644 --- a/fuzzing/Opc.Ua.PubSub.Fuzz/Opc.Ua.PubSub.Fuzz.csproj +++ b/fuzzing/Opc.Ua.PubSub.Fuzz/Opc.Ua.PubSub.Fuzz.csproj @@ -18,6 +18,6 @@ - + diff --git a/fuzzing/Opc.Ua.PubSub.Fuzz/Properties/AssemblyInfo.cs b/fuzzing/Opc.Ua.PubSub.Fuzz/Properties/AssemblyInfo.cs index 31862d51d7..7798c9bd57 100644 --- a/fuzzing/Opc.Ua.PubSub.Fuzz/Properties/AssemblyInfo.cs +++ b/fuzzing/Opc.Ua.PubSub.Fuzz/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Fuzzing/Opc.Ua.PubSub.Fuzz/Properties/AssemblyInfo.cs diff --git a/fuzzing/Scripts/fuzz-menu.ps1 b/fuzzing/Scripts/fuzz-menu.ps1 index 5c31e68015..34cb46c61c 100644 --- a/fuzzing/Scripts/fuzz-menu.ps1 +++ b/fuzzing/Scripts/fuzz-menu.ps1 @@ -1,6 +1,6 @@ <# Lists fuzz targets dynamically from a built fuzz host assembly. -Usage: powershell -File Fuzzing\Scripts\fuzz-menu.ps1 -AssemblyPath Fuzzing\Opc.Ua.Encoders.Fuzz\bin\Debug\net10.0\Opc.Ua.Encoders.Fuzz.dll +Usage: powershell -File fuzzing\Scripts\fuzz-menu.ps1 -AssemblyPath fuzzing\Opc.Ua.Encoders.Fuzz\bin\Debug\net10.0\Opc.Ua.Encoders.Fuzz.dll Pass -Filter to narrow target names and -Index to emit a selected target name without prompting. Per-area libfuzz.* and aflfuzz.* wrappers can call this script to avoid hardcoded target menus. #> diff --git a/nuget/MetaPackageREADME.md b/nuget/MetaPackageREADME.md index 2e4dfe0aa2..76b00157e2 100644 --- a/nuget/MetaPackageREADME.md +++ b/nuget/MetaPackageREADME.md @@ -46,7 +46,7 @@ await application.CheckApplicationInstanceCertificatesAsync(true).ConfigureAwait ## Additional documentation See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) -and the [Docs folder](https://github.com/OPCFoundation/UA-.NETStandard/tree/master/Docs) +and the [documentation folder](https://github.com/OPCFoundation/UA-.NETStandard/tree/master/docs) for the full design guides, transport profiles, certificate management, identity providers, and the 1.5.378 → 2.0 migration guide. diff --git a/plans/23-gds-client-x509-modernization.md b/plans/23-gds-client-x509-modernization.md index 8710558b86..da8a176565 100644 --- a/plans/23-gds-client-x509-modernization.md +++ b/plans/23-gds-client-x509-modernization.md @@ -8,7 +8,7 @@ landed; this is the remaining work item. ## Problem -The public surface of `Libraries/Opc.Ua.Gds.Client.Common` still +The public surface of `src/Opc.Ua.Gds.Client.Common` still exposes legacy .NET certificate types and raw `char[]` passwords: | File | Line | Signature | @@ -36,7 +36,7 @@ Goals (per research §3.13): ## Why this was deferred - `Opc.Ua.Security.Certificates.IX509Certificate` (in - `Libraries/Opc.Ua.Security.Certificates/X509Certificate/IX509Certificate.cs`) + `src/Opc.Ua.Security.Certificates/X509Certificate/IX509Certificate.cs`) is a property‑bag interface — it does **not** expose `RawData` and there is no static `IX509Certificate Certificate.From(X509Certificate2)` factory in the @@ -45,8 +45,8 @@ Goals (per research §3.13): pass `X509Certificate2` instances they already hold; without an interop story this turns into a leaky pseudo‑port. - The cascade is wide — at minimum - `Tests/Opc.Ua.Gds.Tests`, `Tools/GdsAdminUI`, and - `Libraries/Opc.Ua.Gds.Server.Common` consume these signatures. + `tests/Opc.Ua.Gds.Tests`, `tools/GdsAdminUI`, and + `src/Opc.Ua.Gds.Server.Common` consume these signatures. Estimated ~50 call sites. - All other phases shipped clean (Release build 0/0, `Opc.Ua.Gds.Tests` 518 passed). Holding P4.1 keeps the rest @@ -97,24 +97,24 @@ Goals (per research §3.13): ### Phase B — Test cascade -- `Tests/Opc.Ua.Gds.Tests` — adjust call sites to either: +- `tests/Opc.Ua.Gds.Tests` — adjust call sites to either: - construct `IX509Certificate` via the new factory, or - use the `[Obsolete]` shims for legacy paths during transition. - Validate `RegisteredApplicationTests` XML round‑trip parity. -- Run: `dotnet test Tests/Opc.Ua.Gds.Tests/Opc.Ua.Gds.Tests.csproj -c Release -f net10.0 --filter "TestCategory!=Network"`. +- Run: `dotnet test tests/Opc.Ua.Gds.Tests/Opc.Ua.Gds.Tests.csproj -c Release -f net10.0 --filter "TestCategory!=Network"`. ### Phase C — Downstream consumers -- `Libraries/Opc.Ua.Gds.Server.Common` — update where it calls +- `src/Opc.Ua.Gds.Server.Common` — update where it calls `IServerPushConfigurationClient` / `IGlobalDiscoveryServerClient`. -- `Tools/GdsAdminUI` — UI bindings around the rejected list / +- `tools/GdsAdminUI` — UI bindings around the rejected list / certificate add flow. - Verify `dotnet build UA.slnx -c Release` stays at 0/0. ### Phase D — Cleanup - Remove `[Obsolete]` legacy overloads in the next major release. -- Update `Docs/` if certificate handling is documented. +- Update `docs/` if certificate handling is documented. ## Acceptance criteria diff --git a/plans/27-fuzzing-coverage-expansion.md b/plans/27-fuzzing-coverage-expansion.md index bf6cbc3db0..489dc670c4 100644 --- a/plans/27-fuzzing-coverage-expansion.md +++ b/plans/27-fuzzing-coverage-expansion.md @@ -1,8 +1,8 @@ -# Fuzzing coverage expansion under `Fuzzing/` +# Fuzzing coverage expansion under `fuzzing/` ## Problem & goal -The `Fuzzing/` tree currently fuzzes only the **Encoders** area (Binary / JSON / XML +The `fuzzing/` tree currently fuzzes only the **Encoders** area (Binary / JSON / XML decode + encode) via SharpFuzz (afl-fuzz + libFuzzer), with a deterministic NUnit replay suite (`Encoders.Fuzz.Tests`) and corpus/playback tooling (`*.Fuzz.Tools`). Large untrusted-input surfaces are not fuzzed, and the per-area scaffolding is @@ -23,28 +23,28 @@ test projects are wired into `UA.slnx` and CI. ## Current state (baseline) -* `Fuzzing/common/Fuzz/` — shared host: `Program.cs`, `FuzzMethods.cs` +* `fuzzing/common/Fuzz/` — shared host: `Program.cs`, `FuzzMethods.cs` (reflection-driven target discovery over `FuzzableCode`). -* `Fuzzing/common/Fuzz.Tools/` — shared `Program.cs`, `Playback.cs`, `Logging.cs`, +* `fuzzing/common/Fuzz.Tools/` — shared `Program.cs`, `Playback.cs`, `Logging.cs`, and `Testcases.cs` (sample `IEncodeable` builders `ReadRequest`/`ReadResponse`). -* `Fuzzing/Encoders/Fuzz` — `Encoders.Fuzz.csproj` + `FuzzableCode.*` partials. -* `Fuzzing/Encoders/Fuzz.Tests` — generic NUnit harness `EncoderTests.cs` +* `fuzzing/Encoders/Fuzz` — `Encoders.Fuzz.csproj` + `FuzzableCode.*` partials. +* `fuzzing/Encoders/Fuzz.Tests` — generic NUnit harness `EncoderTests.cs` (replays `Testcases/` corpus + `Assets/` crash/timeout/slow blobs through every `FuzzableCode` target). Already `[Category("Fuzzing")]`. -* `Fuzzing/Encoders/Fuzz.Tools` — `Encoders.Testcases.cs` corpus generator. -* `Fuzzing/dictionaries/` — `json.dict`, `xml.dict` (no `binary.dict`). -* `Fuzzing/scripts/` — `fuzz-afl.ps1`, `fuzz-libfuzzer.ps1`, `install.sh`. +* `fuzzing/Encoders/Fuzz.Tools` — `Encoders.Testcases.cs` corpus generator. +* `fuzzing/dictionaries/` — `json.dict`, `xml.dict` (no `binary.dict`). +* `fuzzing/scripts/` — `fuzz-afl.ps1`, `fuzz-libfuzzer.ps1`, `install.sh`. * `UA.slnx` lists the 3 Encoders projects + loose files. Azure `test.yml` / `testcc.yml` - overlay `FuzzingArtifacts.zip` into `Fuzzing/Encoders/Fuzz.Tests` and run the suite. + overlay `FuzzingArtifacts.zip` into `fuzzing/Encoders/Fuzz.Tests` and run the suite. * `Opc.Ua.Core.csproj` already uses `` items (seam pattern exists). -* `Stack/Opc.Ua.Core.Diagnostics` is new — multi-targets `net8.0;net9.0;net10.0` +* `src/Opc.Ua.Core.Diagnostics` is new — multi-targets `net8.0;net9.0;net10.0` and depends on PacketDotNet + SharpPcap. Public surfaces relevant to fuzzing: `OpcUaFrameParser` (TCP → UA-SC chunk splitter), `TcpStreamReassembler` (raw TCP), `OfflineSecureChannel` (re-uses the stack's `UaSCUaBinaryChannel.ReadSymmetricMessage` so all security profiles are covered for free), `ServiceCallReassembler` (chunk → service-call assembly), and `MockServerReplay` / `MockClientReplay` (stateful loopback replay drivers). -* `Tests/Opc.Ua.Core.Diagnostics.Tests` (net10.0-only test project) contains mock +* `tests/Opc.Ua.Core.Diagnostics.Tests` (net10.0-only test project) contains mock handshake / replay helpers (`ReplayTestHelpers`, `MockServerReplayTests`, `MockClientReplayTests`, `OfflineSecureChannelSmokeTests`). These cannot be project-referenced from a multi-TFM fuzz area; the equivalent live helpers @@ -66,7 +66,7 @@ test projects are wired into `UA.slnx` and CI. ## Proposed target structure ``` -Fuzzing/ +fuzzing/ Fuzzing.md # updated: areas, priorities, "how to add an area" common/ Fuzz/ # unchanged host @@ -128,7 +128,7 @@ are discovered from disk instead of the hardcoded `[".Binary", ".Json", ".Xml"]` ### Phase 3 — Certificates / CRL / ASN.1 area (NEW, pre-auth surface) -* New `Fuzzing/Certificates/{Fuzz,Fuzz.Tests,Fuzz.Tools}` referencing +* New `fuzzing/Certificates/{Fuzz,Fuzz.Tests,Fuzz.Tools}` referencing `Opc.Ua.Security.Certificates` (+ Core). * Targets (libFuzzer span + afl stream): * `X509CRL(byte[])` → force `EnsureDecoded` (TBS, revoked entries, extensions, @@ -151,7 +151,7 @@ are discovered from disk instead of the hardcoded `[".Binary", ".Json", ".Xml"]` #### Phase 4a — Network-layer fuzzing via `Opc.Ua.Core.Diagnostics` (no Core changes) -* New `Fuzzing/Network/{Fuzz,Fuzz.Tests,Fuzz.Tools}`, referencing +* New `fuzzing/Network/{Fuzz,Fuzz.Tests,Fuzz.Tools}`, referencing `Opc.Ua.Core.Diagnostics` (+ `Opc.Ua.Core` transitively). Multi-targets `net8.0;net9.0;net10.0` to match the binding's matrix (no net48/net472 — the pcap binding does not support .NET Framework, which is consistent with how @@ -235,19 +235,19 @@ are discovered from disk instead of the hardcoded `[".Binary", ".Json", ".Xml"]` ### Phase 5 — Integration: solution, CI, docs * Add all new `Fuzz`, `Fuzz.Tests`, `Fuzz.Tools` projects + loose files to `UA.slnx` - under the right `Fuzzing//` folders. Specifically: Encoders (hardened), + under the right `fuzzing//` folders. Specifically: Encoders (hardened), Certificates (new), Network (new — hosts both Phase 4a pcap-binding targets and the optional Phase 4b Core UA-SC seam targets in one project tree). * Ensure new `*.Fuzz.Tests` carry `[Category("Fuzzing")]`, are deterministic, and run under the same TFMs / filters as `Encoders.Fuzz.Tests`; confirm Azure `test.yml` picks - them up (they live under `Fuzzing//Fuzz.Tests`). + them up (they live under `fuzzing//Fuzz.Tests`). * `Network.Fuzz.Tests` multi-targets `net8.0;net9.0;net10.0` (matches pcap binding matrix); net48/net472 stays in scope for Encoders / Parsers / Certificates areas. * Rewrite `Fuzzing.md`: mark XML done, document new areas + targets, dictionaries, the dynamic menu, a step-by-step "add a new fuzz area" recipe, and the Network area's replay-driven seed pipeline + `Opc.Ua.Core.Diagnostics` dependency note (TFM matrix + PacketDotNet/SharpPcap). -* Cross-link from `Docs/README.md` if a fuzzing doc is referenced there; cross-link +* Cross-link from `docs/README.md` if a fuzzing doc is referenced there; cross-link the pcap binding's diagnostics docs (if present) so they point to the fuzz benefit. ## Validation strategy @@ -287,7 +287,7 @@ are discovered from disk instead of the hardcoded `[".Binary", ".Json", ".Xml"]` multi-TFM replay helpers. * If `PcapFileReader` / `PcapNgFileWriter` / `UaKeyLogTextReader` / `UaKeyLogJsonReader` fuzzing is added later (defensive, untrusted-file - parsers), fold into the same `Fuzzing/Network/` area as additional + parsers), fold into the same `fuzzing/Network/` area as additional `FuzzableCode.*` partials rather than spinning up a new area. * ASN.1 / cert targets must respect the TFM / BouncyCastle split and NativeAOT rules. * Idempotent / round-trip targets can surface real encoder bugs — triage findings as diff --git a/plans/StateMachineBuilder.md b/plans/StateMachineBuilder.md index acd53e2e9e..5cc9c690ac 100644 --- a/plans/StateMachineBuilder.md +++ b/plans/StateMachineBuilder.md @@ -32,7 +32,7 @@ nothing fluent on top of it. Each consumer reimplements the same ## Proposed surface -### `Libraries/Opc.Ua.Server/Fluent/IStateMachineBuilder.cs` +### `src/Opc.Ua.Server/Fluent/IStateMachineBuilder.cs` ```csharp public interface IStateMachineBuilder @@ -104,7 +104,7 @@ builder.Node("SoftwareUpdate/Installation") ### Client-side observer -`Libraries/Opc.Ua.Di.Client/StateMachineClient.cs`: +`src/Opc.Ua.Di.Client/StateMachineClient.cs`: ```csharp public sealed class StateMachineClient @@ -120,12 +120,12 @@ public sealed class StateMachineClient ## Files to create -- `Libraries/Opc.Ua.Server/Fluent/IStateMachineBuilder.cs` -- `Libraries/Opc.Ua.Server/Fluent/StateMachineBuilderExtensions.cs` -- `Libraries/Opc.Ua.Server/Fluent/StateMachineBuilder.cs` (internal impl) -- `Libraries/Opc.Ua.Di.Client/StateMachineClient.cs` -- `Tests/Opc.Ua.Server.Tests/Fluent/StateMachineBuilderExtensionsTests.cs` -- `Docs/StateMachineBuilder.md` +- `src/Opc.Ua.Server/Fluent/IStateMachineBuilder.cs` +- `src/Opc.Ua.Server/Fluent/StateMachineBuilderExtensions.cs` +- `src/Opc.Ua.Server/Fluent/StateMachineBuilder.cs` (internal impl) +- `src/Opc.Ua.Di.Client/StateMachineClient.cs` +- `tests/Opc.Ua.Server.Tests/Fluent/StateMachineBuilderExtensionsTests.cs` +- `docs/StateMachineBuilder.md` ## Open questions diff --git a/plans/ctt-issues.md b/plans/ctt-issues.md index ae58410e31..44c9970af7 100644 --- a/plans/ctt-issues.md +++ b/plans/ctt-issues.md @@ -761,7 +761,7 @@ no speculative compatibility changes were made. (42):** these need a live A&C loop to attribute conclusively; the console log shows the disabling transition (`Disabling alarm … / Disabled State ConditionDisabled`) and the input-node read (`Test_004.js:43`) failing at the **service** level (`readResult` falsy). Verify the reference - server's alarm source variable (`ns=7;s=Alarms.AnalogSource`, `Applications/Quickstarts.Servers/Alarms/ + server's alarm source variable (`ns=7;s=Alarms.AnalogSource`, `samples/Quickstarts.Servers/Alarms/ AlarmNodeManager.cs`) is readable and that the disabled-condition event fields match Part 9 §5.5.2. Not pinned to a concrete server defect from the log alone. diff --git a/samples/ConsoleLdsServer/ConsoleLdsServer.csproj b/samples/ConsoleLdsServer/ConsoleLdsServer.csproj index 20736362da..1694ff19c0 100644 --- a/samples/ConsoleLdsServer/ConsoleLdsServer.csproj +++ b/samples/ConsoleLdsServer/ConsoleLdsServer.csproj @@ -12,9 +12,9 @@ true - - - + + + diff --git a/samples/ConsoleLdsServer/Dockerfile b/samples/ConsoleLdsServer/Dockerfile index 089d47a9e6..0e95b823cc 100644 --- a/samples/ConsoleLdsServer/Dockerfile +++ b/samples/ConsoleLdsServer/Dockerfile @@ -2,12 +2,12 @@ # # The build context must be the repository ROOT so the project references resolve. # Build directly: -# docker build -f Applications/ConsoleLdsServer/Dockerfile -t opcua-lds-server . +# docker build -f samples/ConsoleLdsServer/Dockerfile -t opcua-lds-server . FROM mcr.microsoft.com/dotnet/sdk AS build WORKDIR /src ENV DOTNET_EnableWriteXorExecute=0 COPY . . -RUN dotnet publish "Applications/ConsoleLdsServer/ConsoleLdsServer.csproj" \ +RUN dotnet publish "samples/ConsoleLdsServer/ConsoleLdsServer.csproj" \ -c Release -f net10.0 -p:PublishAot=false -p:CustomTestTarget=net10.0 \ -o /app/publish diff --git a/samples/ConsoleLdsServer/Properties/AssemblyInfo.cs b/samples/ConsoleLdsServer/Properties/AssemblyInfo.cs index 7eab147645..2b9848014c 100644 --- a/samples/ConsoleLdsServer/Properties/AssemblyInfo.cs +++ b/samples/ConsoleLdsServer/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Applications/ConsoleLdsServer/Properties/AssemblyInfo.cs diff --git a/samples/ConsoleReferenceClient/ConsoleReferenceClient.csproj b/samples/ConsoleReferenceClient/ConsoleReferenceClient.csproj index 48ae4d1648..b34251fd45 100644 --- a/samples/ConsoleReferenceClient/ConsoleReferenceClient.csproj +++ b/samples/ConsoleReferenceClient/ConsoleReferenceClient.csproj @@ -27,10 +27,10 @@ - - - - + + + + diff --git a/samples/ConsoleReferenceClient/Properties/AssemblyInfo.cs b/samples/ConsoleReferenceClient/Properties/AssemblyInfo.cs index 342b4d3136..2b9848014c 100644 --- a/samples/ConsoleReferenceClient/Properties/AssemblyInfo.cs +++ b/samples/ConsoleReferenceClient/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Applications/ConsoleReferenceClient/Properties/AssemblyInfo.cs diff --git a/samples/ConsoleReferenceClient/README.md b/samples/ConsoleReferenceClient/README.md index 02a009fbd8..3f8f9a57b5 100644 --- a/samples/ConsoleReferenceClient/README.md +++ b/samples/ConsoleReferenceClient/README.md @@ -37,7 +37,7 @@ dotnet ConsoleReferenceClient.dll opc.https://localhost:62543/Quickstarts/Refere The reference server (`ConsoleReferenceServer`) advertises the `opc.tcp://`, `opc.https://` and `opc.wss://` endpoints by default; see -[`Docs/Transports.md`](../../Docs/Transports.md) for the full server +[`docs/Transports.md`](../../docs/Transports.md) for the full server configuration story (TLS certificates, mutual TLS, JSON sub-protocol restrictions, etc.). diff --git a/samples/ConsoleReferencePubSubClient/ConsoleReferencePubSubClient.csproj b/samples/ConsoleReferencePubSubClient/ConsoleReferencePubSubClient.csproj index 761efde022..17f916b3c0 100644 --- a/samples/ConsoleReferencePubSubClient/ConsoleReferencePubSubClient.csproj +++ b/samples/ConsoleReferencePubSubClient/ConsoleReferencePubSubClient.csproj @@ -17,13 +17,13 @@ true - - - - - - - + + + + + + + diff --git a/samples/ConsoleReferencePubSubClient/Dockerfile b/samples/ConsoleReferencePubSubClient/Dockerfile index 63af45186b..33c772fb98 100644 --- a/samples/ConsoleReferencePubSubClient/Dockerfile +++ b/samples/ConsoleReferencePubSubClient/Dockerfile @@ -2,12 +2,12 @@ # # The build context must be the repository ROOT so the project references resolve. # Build directly: -# docker build -f Applications/ConsoleReferencePubSubClient/Dockerfile -t opcua-pubsub-client . +# docker build -f samples/ConsoleReferencePubSubClient/Dockerfile -t opcua-pubsub-client . FROM mcr.microsoft.com/dotnet/sdk AS build WORKDIR /src ENV DOTNET_EnableWriteXorExecute=0 COPY . . -RUN dotnet publish "Applications/ConsoleReferencePubSubClient/ConsoleReferencePubSubClient.csproj" \ +RUN dotnet publish "samples/ConsoleReferencePubSubClient/ConsoleReferencePubSubClient.csproj" \ -c Release -f net10.0 -p:PublishAot=false -p:CustomTestTarget=net10.0 \ -o /app/publish diff --git a/samples/ConsoleReferencePubSubClient/Properties/AssemblyInfo.cs b/samples/ConsoleReferencePubSubClient/Properties/AssemblyInfo.cs index 6fd3490cce..7798c9bd57 100644 --- a/samples/ConsoleReferencePubSubClient/Properties/AssemblyInfo.cs +++ b/samples/ConsoleReferencePubSubClient/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Applications/ConsoleReferencePubSubClient/Properties/AssemblyInfo.cs diff --git a/samples/ConsoleReferencePubSubClient/README.md b/samples/ConsoleReferencePubSubClient/README.md index 286bf25014..04636a0145 100644 --- a/samples/ConsoleReferencePubSubClient/README.md +++ b/samples/ConsoleReferencePubSubClient/README.md @@ -86,13 +86,13 @@ Edit and save either file while the bridge is running: > The samples connect to the external server unsecured (`SecurityMode.None`) for > zero-config interop. A production bridge must use `SignAndEncrypt` with a provisioned > application instance certificate. See -> [Docs/PubSub.md external-server adapter section](../../Docs/PubSub.md#binding-pubsub-to-an-external-opc-ua-server-client-session-adapters). +> [docs/PubSub.md external-server adapter section](../../docs/PubSub.md#binding-pubsub-to-an-external-opc-ua-server-client-session-adapters). ## Build / publish ```bash -dotnet build Applications/ConsoleReferencePubSubClient/ConsoleReferencePubSubClient.csproj -dotnet publish Applications/ConsoleReferencePubSubClient/ConsoleReferencePubSubClient.csproj -r win-x64 +dotnet build samples/ConsoleReferencePubSubClient/ConsoleReferencePubSubClient.csproj +dotnet publish samples/ConsoleReferencePubSubClient/ConsoleReferencePubSubClient.csproj -r win-x64 ``` -See [Docs/PubSub.md](../../Docs/PubSub.md) for the full PubSub guide. +See [docs/PubSub.md](../../docs/PubSub.md) for the full PubSub guide. diff --git a/samples/ConsoleReferenceServer/ConsoleReferenceServer.csproj b/samples/ConsoleReferenceServer/ConsoleReferenceServer.csproj index 55076aabbe..f305aaa160 100644 --- a/samples/ConsoleReferenceServer/ConsoleReferenceServer.csproj +++ b/samples/ConsoleReferenceServer/ConsoleReferenceServer.csproj @@ -14,7 +14,7 @@ enable - + - + - - - + + + diff --git a/samples/ConsoleReferenceServer/Dockerfile b/samples/ConsoleReferenceServer/Dockerfile index 6a14f1606c..f7912932e7 100644 --- a/samples/ConsoleReferenceServer/Dockerfile +++ b/samples/ConsoleReferenceServer/Dockerfile @@ -6,27 +6,27 @@ WORKDIR /src # copy csproj and restore as distinct layers COPY *.* . -COPY ["Applications/ConsoleReferenceServer/ConsoleReferenceServer.csproj", "Applications/ConsoleReferenceServer/"] -COPY ["Tools/Opc.Ua.SourceGeneration.Core/Opc.Ua.SourceGeneration.Core.csproj", "Tools/Opc.Ua.SourceGeneration.Core/"] -COPY ["Tools/Opc.Ua.SourceGeneration.Stack/Opc.Ua.SourceGeneration.Stack.csproj", "Tools/Opc.Ua.SourceGeneration.Stack/"] -COPY ["Tools/Opc.Ua.SourceGeneration/Opc.Ua.SourceGeneration.csproj", "Tools/Opc.Ua.SourceGeneration/"] -COPY ["Stack/Opc.Ua.Core.Types/Opc.Ua.Core.Types.csproj", "Stack/Opc.Ua.Core.Types/"] -COPY ["Stack/Opc.Ua.Core/Opc.Ua.Core.csproj", "Stack/Opc.Ua.Core/"] -COPY ["Stack/Opc.Ua.Core.Schema/Opc.Ua.Core.Schema.csproj", "Stack/Opc.Ua.Core.Schema/"] -COPY ["Stack/Opc.Ua.Core.Diagnostics/Opc.Ua.Core.Diagnostics.csproj", "Stack/Opc.Ua.Core.Diagnostics/"] -COPY ["Stack/Opc.Ua.Types/Opc.Ua.Types.csproj", "Stack/Opc.Ua.Types/"] -COPY ["Stack/Opc.Ua.Security.Certificates/Opc.Ua.Security.Certificates.csproj", "Stack/Opc.Ua.Security.Certificates/"] -COPY ["Libraries/Opc.Ua.Client/Opc.Ua.Client.csproj", "Libraries/Opc.Ua.Client/"] -COPY ["Libraries/Opc.Ua.Configuration/Opc.Ua.Configuration.csproj", "Libraries/Opc.Ua.Configuration/"] -COPY ["Libraries/Opc.Ua.Server/Opc.Ua.Server.csproj", "Libraries/Opc.Ua.Server/"] -COPY ["Applications/Quickstarts.Servers/Quickstarts.Servers.csproj", "Applications/Quickstarts.Servers/"] -COPY ["Libraries/Opc.Ua.Gds.Common/Opc.Ua.Gds.Common.csproj", "Libraries/Opc.Ua.Gds.Common/"] -COPY ["Libraries/Opc.Ua.Gds.Server.Common/Opc.Ua.Gds.Server.Common.csproj", "Libraries/Opc.Ua.Gds.Server.Common/"] +COPY ["samples/ConsoleReferenceServer/ConsoleReferenceServer.csproj", "samples/ConsoleReferenceServer/"] +COPY ["tools/Opc.Ua.SourceGeneration.Core/Opc.Ua.SourceGeneration.Core.csproj", "tools/Opc.Ua.SourceGeneration.Core/"] +COPY ["tools/Opc.Ua.SourceGeneration.Stack/Opc.Ua.SourceGeneration.Stack.csproj", "tools/Opc.Ua.SourceGeneration.Stack/"] +COPY ["tools/Opc.Ua.SourceGeneration/Opc.Ua.SourceGeneration.csproj", "tools/Opc.Ua.SourceGeneration/"] +COPY ["src/Opc.Ua.Core.Types/Opc.Ua.Core.Types.csproj", "src/Opc.Ua.Core.Types/"] +COPY ["src/Opc.Ua.Core/Opc.Ua.Core.csproj", "src/Opc.Ua.Core/"] +COPY ["src/Opc.Ua.Core.Schema/Opc.Ua.Core.Schema.csproj", "src/Opc.Ua.Core.Schema/"] +COPY ["src/Opc.Ua.Core.Diagnostics/Opc.Ua.Core.Diagnostics.csproj", "src/Opc.Ua.Core.Diagnostics/"] +COPY ["src/Opc.Ua.Types/Opc.Ua.Types.csproj", "src/Opc.Ua.Types/"] +COPY ["src/Opc.Ua.Security.Certificates/Opc.Ua.Security.Certificates.csproj", "src/Opc.Ua.Security.Certificates/"] +COPY ["src/Opc.Ua.Client/Opc.Ua.Client.csproj", "src/Opc.Ua.Client/"] +COPY ["src/Opc.Ua.Configuration/Opc.Ua.Configuration.csproj", "src/Opc.Ua.Configuration/"] +COPY ["src/Opc.Ua.Server/Opc.Ua.Server.csproj", "src/Opc.Ua.Server/"] +COPY ["samples/Quickstarts.Servers/Quickstarts.Servers.csproj", "samples/Quickstarts.Servers/"] +COPY ["src/Opc.Ua.Gds.Common/Opc.Ua.Gds.Common.csproj", "src/Opc.Ua.Gds.Common/"] +COPY ["src/Opc.Ua.Gds.Server.Common/Opc.Ua.Gds.Server.Common.csproj", "src/Opc.Ua.Gds.Server.Common/"] ENV DOTNET_EnableWriteXorExecute=0 -RUN dotnet restore "Applications/ConsoleReferenceServer/ConsoleReferenceServer.csproj" --force -p:NoHttps=true -p:CustomTestTarget=net10.0 +RUN dotnet restore "samples/ConsoleReferenceServer/ConsoleReferenceServer.csproj" --force -p:NoHttps=true -p:CustomTestTarget=net10.0 COPY . . -WORKDIR "/src/Applications/ConsoleReferenceServer" +WORKDIR "/src/samples/ConsoleReferenceServer" ARG Version ARG SimpleVersion ARG InformationalVersion diff --git a/samples/ConsoleReferenceServer/Properties/AssemblyInfo.cs b/samples/ConsoleReferenceServer/Properties/AssemblyInfo.cs index e757244280..2b9848014c 100644 --- a/samples/ConsoleReferenceServer/Properties/AssemblyInfo.cs +++ b/samples/ConsoleReferenceServer/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Applications/ConsoleReferenceServer/Properties/AssemblyInfo.cs diff --git a/samples/MinimalBoilerServer/Dockerfile b/samples/MinimalBoilerServer/Dockerfile index 7af3e34738..8bdf365b41 100644 --- a/samples/MinimalBoilerServer/Dockerfile +++ b/samples/MinimalBoilerServer/Dockerfile @@ -2,12 +2,12 @@ # # The build context must be the repository ROOT so the project references resolve. # Build directly: -# docker build -f Applications/MinimalBoilerServer/Dockerfile -t opcua-minimal-boiler-server . +# docker build -f samples/MinimalBoilerServer/Dockerfile -t opcua-minimal-boiler-server . FROM mcr.microsoft.com/dotnet/sdk AS build WORKDIR /src ENV DOTNET_EnableWriteXorExecute=0 COPY . . -RUN dotnet publish "Applications/MinimalBoilerServer/MinimalBoilerServer.csproj" \ +RUN dotnet publish "samples/MinimalBoilerServer/MinimalBoilerServer.csproj" \ -c Release -f net10.0 -p:PublishAot=false -p:CustomTestTarget=net10.0 \ -o /app/publish diff --git a/samples/MinimalBoilerServer/MinimalBoilerServer.csproj b/samples/MinimalBoilerServer/MinimalBoilerServer.csproj index c598949bd3..8e3b158535 100644 --- a/samples/MinimalBoilerServer/MinimalBoilerServer.csproj +++ b/samples/MinimalBoilerServer/MinimalBoilerServer.csproj @@ -19,11 +19,11 @@ true - - + + - + Analyzer false diff --git a/samples/MinimalBoilerServer/Properties/AssemblyInfo.cs b/samples/MinimalBoilerServer/Properties/AssemblyInfo.cs index ef0dd76d8f..2b9848014c 100644 --- a/samples/MinimalBoilerServer/Properties/AssemblyInfo.cs +++ b/samples/MinimalBoilerServer/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Applications/MinimalBoilerServer/Properties/AssemblyInfo.cs diff --git a/samples/MinimalCalcServer/Dockerfile b/samples/MinimalCalcServer/Dockerfile index a38f0a6ab5..00ae1cdd6b 100644 --- a/samples/MinimalCalcServer/Dockerfile +++ b/samples/MinimalCalcServer/Dockerfile @@ -2,12 +2,12 @@ # # The build context must be the repository ROOT so the project references resolve. # Build directly: -# docker build -f Applications/MinimalCalcServer/Dockerfile -t opcua-minimal-calc-server . +# docker build -f samples/MinimalCalcServer/Dockerfile -t opcua-minimal-calc-server . FROM mcr.microsoft.com/dotnet/sdk AS build WORKDIR /src ENV DOTNET_EnableWriteXorExecute=0 COPY . . -RUN dotnet publish "Applications/MinimalCalcServer/MinimalCalcServer.csproj" \ +RUN dotnet publish "samples/MinimalCalcServer/MinimalCalcServer.csproj" \ -c Release -f net10.0 -p:PublishAot=false -p:CustomTestTarget=net10.0 \ -o /app/publish diff --git a/samples/MinimalCalcServer/MinimalCalcServer.csproj b/samples/MinimalCalcServer/MinimalCalcServer.csproj index 832e5b8332..1ae20f2479 100644 --- a/samples/MinimalCalcServer/MinimalCalcServer.csproj +++ b/samples/MinimalCalcServer/MinimalCalcServer.csproj @@ -19,11 +19,11 @@ true - - + + - + Analyzer false diff --git a/samples/MinimalCalcServer/Properties/AssemblyInfo.cs b/samples/MinimalCalcServer/Properties/AssemblyInfo.cs index 743319b428..2b9848014c 100644 --- a/samples/MinimalCalcServer/Properties/AssemblyInfo.cs +++ b/samples/MinimalCalcServer/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Applications/MinimalCalcServer/Properties/AssemblyInfo.cs diff --git a/samples/PumpDeviceIntegrationServer/Dockerfile b/samples/PumpDeviceIntegrationServer/Dockerfile index 106ce1e6db..becd489807 100644 --- a/samples/PumpDeviceIntegrationServer/Dockerfile +++ b/samples/PumpDeviceIntegrationServer/Dockerfile @@ -4,11 +4,11 @@ # images. # # IMPORTANT: the build context MUST be the repository ROOT (not this -# folder), because the project pulls in the whole source tree (Stack/, -# Libraries/, Tools/). Build it like this: +# folder), because the project pulls in the whole source tree (src/, +# src/, tools/). Build it like this: # # # from the repository root: -# docker build -f Applications/PumpDeviceIntegrationServer/Dockerfile \ +# docker build -f samples/PumpDeviceIntegrationServer/Dockerfile \ # -t pumpdeviceintegrationserver:local . # # Running `docker build .` from inside this folder will fail fast with a @@ -34,10 +34,10 @@ COPY . . RUN test -f UA.slnx || { \ echo ''; \ echo 'ERROR: build the repository ROOT as the Docker context, not this folder.'; \ - echo ' The image needs the full source tree (Stack/, Libraries/, Tools/).'; \ + echo ' The image needs the full source tree (src/, src/, tools/).'; \ echo ''; \ echo ' From the repository root run:'; \ - echo ' docker build -f Applications/PumpDeviceIntegrationServer/Dockerfile -t pumpdeviceintegrationserver .'; \ + echo ' docker build -f samples/PumpDeviceIntegrationServer/Dockerfile -t pumpdeviceintegrationserver .'; \ echo ''; \ exit 1; \ } @@ -46,10 +46,10 @@ ARG Version ARG SimpleVersion ARG InformationalVersion -RUN dotnet restore "Applications/PumpDeviceIntegrationServer/PumpDeviceIntegrationServer.csproj" \ +RUN dotnet restore "samples/PumpDeviceIntegrationServer/PumpDeviceIntegrationServer.csproj" \ --force -p:NoHttps=true -RUN dotnet publish "Applications/PumpDeviceIntegrationServer/PumpDeviceIntegrationServer.csproj" \ +RUN dotnet publish "samples/PumpDeviceIntegrationServer/PumpDeviceIntegrationServer.csproj" \ --no-restore \ -c Release \ -f net10.0 \ diff --git a/samples/PumpDeviceIntegrationServer/Properties/AssemblyInfo.cs b/samples/PumpDeviceIntegrationServer/Properties/AssemblyInfo.cs index 38e97e4ca3..2b9848014c 100644 --- a/samples/PumpDeviceIntegrationServer/Properties/AssemblyInfo.cs +++ b/samples/PumpDeviceIntegrationServer/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Applications/PumpDeviceIntegrationServer/Properties/AssemblyInfo.cs diff --git a/samples/PumpDeviceIntegrationServer/PumpDeviceIntegrationServer.csproj b/samples/PumpDeviceIntegrationServer/PumpDeviceIntegrationServer.csproj index 27e48ecfc4..175d96b7f7 100644 --- a/samples/PumpDeviceIntegrationServer/PumpDeviceIntegrationServer.csproj +++ b/samples/PumpDeviceIntegrationServer/PumpDeviceIntegrationServer.csproj @@ -13,13 +13,13 @@ true - - - - + + + + - + Analyzer false @@ -52,7 +52,7 @@ - + v105 true diff --git a/samples/PumpDeviceIntegrationServer/README.md b/samples/PumpDeviceIntegrationServer/README.md index 3d4f03b8e4..e898777201 100644 --- a/samples/PumpDeviceIntegrationServer/README.md +++ b/samples/PumpDeviceIntegrationServer/README.md @@ -8,14 +8,14 @@ wired entirely through the fluent `INodeManagerBuilder` API and the DI hosting integration. The pump sample is the integration test for every fluent API extension -shipped under `Libraries/Opc.Ua.Server/Fluent/`. Each extension is +shipped under `src/Opc.Ua.Server/Fluent/`. Each extension is documented in -[Source-generated NodeManagers — Building richer node managers](../../Docs/SourceGeneratedNodeManagers.md#building-richer-node-managers--the-fluent-extension-surface). +[Source-generated NodeManagers — Building richer node managers](../../docs/SourceGeneratedNodeManagers.md#building-richer-node-managers--the-fluent-extension-surface). ## Running the sample ```pwsh -cd Applications/PumpDeviceIntegrationServer +cd samples/PumpDeviceIntegrationServer dotnet run -c Release ``` @@ -51,14 +51,14 @@ publish output on the .NET **AzureLinux 3** base images and runs it as a non-root user. > **Build from the repository root**, not from this folder. The image -> needs the full source tree (`Stack/`, `Libraries/`, `Tools/`), so the +> needs the full source tree (`src/`, `src/`, `tools/`), so the > Docker build context must be the repo root and the Dockerfile is > selected with `-f`. Running `docker build .` from inside this folder > fails fast with a message telling you the correct command. ```pwsh # from the repository root: -docker build -f Applications/PumpDeviceIntegrationServer/Dockerfile ` +docker build -f samples/PumpDeviceIntegrationServer/Dockerfile ` -t pumpdeviceintegrationserver:local . ``` @@ -103,7 +103,7 @@ workflow on every push to `master` and on manual dispatch. | 250 ms simulation tick via `Simulation(...).OnTick(...)` | `Configure` → `AdvanceSimulation` | | Limit alarm with thresholds and acknowledge handler via `CreateLimitAlarm(...).WithLimits(...)` | `WithSupervision` | | Boolean supervision (TwoStateDiscreteState) → alarm activation via `.ActivatesAlarm(...)` | `WithSupervision` | -| Cross-namespace path resolution (Pump #1 in Pumps NS → Operational in Machinery NS → Measurements in Pumps NS, all in one unqualified browse path) | `Libraries/Opc.Ua.Server/Fluent/BrowsePathResolver.cs` | +| Cross-namespace path resolution (Pump #1 in Pumps NS → Operational in Machinery NS → Measurements in Pumps NS, all in one unqualified browse path) | `src/Opc.Ua.Server/Fluent/BrowsePathResolver.cs` | | Cross-pump device-health simulation via `RegisterSupervisedDeviceHealth` + `WithDeviceHealth` | `PumpNodeManager.cs` + `Program.cs` (`Pump #2`) | | DI declarative device + `WithIdentification` | `Program.cs` (`Pump #2`) | | Software-update facet (`ISoftwarePackageStore` + `WithSoftwareUpdate`) | `Program.cs` (`Pump #2`), `SoftwarePackageSeeder.cs` | @@ -136,7 +136,7 @@ and Pumps to DI types resolve through the assembly — no DI NodeSet2 XML needed in this project. The unified attribute carries the compact type-table payload that the consumer's source generator imports at compile time; see -[ModelDependencies.md](../../Docs/ModelDependencies.md) for the wire +[ModelDependencies.md](../../docs/ModelDependencies.md) for the wire format and consumer-side flow. The Machinery and Pumps NodeSet2 XMLs are **source-generated locally @@ -180,7 +180,7 @@ own assembly using the same `` pattern. ## NativeAOT publishing ```pwsh -cd Applications/PumpDeviceIntegrationServer +cd samples/PumpDeviceIntegrationServer dotnet publish -c Release -r win-x64 ``` @@ -190,11 +190,11 @@ generated model factories are statically rooted. ## See also -- [`Docs/DeviceIntegration.md`](../../Docs/DeviceIntegration.md) — +- [`docs/DeviceIntegration.md`](../../docs/DeviceIntegration.md) — full developer guide for the DI library trio (device builder, hosting integration, lock service, software-update package store, client helpers). -- [`Docs/SoftwareUpdate.md`](../../Docs/SoftwareUpdate.md) — +- [`docs/SoftwareUpdate.md`](../../docs/SoftwareUpdate.md) — in-depth coverage of the software-update facet wiring, file-transfer pipeline, and client `UploadPackageAsync`. diff --git a/samples/Quickstarts.Servers/NugetREADME.md b/samples/Quickstarts.Servers/NugetREADME.md index 4e97e4b79f..773684f2e8 100644 --- a/samples/Quickstarts.Servers/NugetREADME.md +++ b/samples/Quickstarts.Servers/NugetREADME.md @@ -39,5 +39,5 @@ await application.StartAsync(new ReferenceServer(telemetry)).ConfigureAwait(fals See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) and the -[Applications folder](https://github.com/OPCFoundation/UA-.NETStandard/tree/master/Applications) +[samples folder](https://github.com/OPCFoundation/UA-.NETStandard/tree/master/samples) for the full quickstart sources. diff --git a/samples/Quickstarts.Servers/Properties/AssemblyInfo.cs b/samples/Quickstarts.Servers/Properties/AssemblyInfo.cs index 106afef45b..2b9848014c 100644 --- a/samples/Quickstarts.Servers/Properties/AssemblyInfo.cs +++ b/samples/Quickstarts.Servers/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Applications/Quickstarts.Servers/Properties/AssemblyInfo.cs diff --git a/samples/Quickstarts.Servers/Quickstarts.Servers.csproj b/samples/Quickstarts.Servers/Quickstarts.Servers.csproj index d37c87735a..a43da6cdd0 100644 --- a/samples/Quickstarts.Servers/Quickstarts.Servers.csproj +++ b/samples/Quickstarts.Servers/Quickstarts.Servers.csproj @@ -21,17 +21,17 @@ - - - + + + - + Analyzer false - + true diff --git a/samples/Quickstarts.Servers/TestData/Generated/TestDataDesign.csv b/samples/Quickstarts.Servers/TestData/Generated/TestDataDesign.csv index a33331d8fa..f21636efff 100644 --- a/samples/Quickstarts.Servers/TestData/Generated/TestDataDesign.csv +++ b/samples/Quickstarts.Servers/TestData/Generated/TestDataDesign.csv @@ -2627,5 +2627,3 @@ MultipleVectors_Encoding_DefaultJson,3626,Object ArrayValueObjectType_MultipleVectorsValue,3627,Variable Data_Static_Array_MultipleVectorsValue,3628,Variable Data_Dynamic_Array_MultipleVectorsValue,3629,Variable - -# Repository move history marker: Applications/Quickstarts.Servers/TestData/Generated/TestDataDesign.csv diff --git a/samples/README.md b/samples/README.md index a5f3f36f1a..b3164ec322 100644 --- a/samples/README.md +++ b/samples/README.md @@ -23,7 +23,7 @@ Please follow instructions in this [article](https://aka.ms/dotnetcoregs) to set ## Start the server 1. Open a command prompt. -2. Navigate to the folder **Applications/ConsoleReferenceServer**. +2. Navigate to the folder **samples/ConsoleReferenceServer**. 3. To run the server sample type `dotnet run --project ConsoleReferenceServer.csproj`. The server is now running and waiting for the connection of the UACTT. ## UACTT test certificates @@ -109,7 +109,7 @@ It is recommended to run the server as retail build with disabled logging, to av ### Running the CTT against a Docker container -Please refer to the [Docker container of the Reference Server](Docs/DockerReferenceServer.md) documentation page. Once setup to map the certificate store and the configuration to a local folder, follow the instructions above to copy the certificates to the PKI and get started. +Please refer to the [Docker container of the Reference Server](docs/DockerReferenceServer.md) documentation page. Once setup to map the certificate store and the configuration to a local folder, follow the instructions above to copy the certificates to the PKI and get started. #### Finding the Address Space Configuration Code diff --git a/samples/RedundantClient/.env b/samples/RedundantClient/.env index 6a2070b36d..420c59cf92 100644 --- a/samples/RedundantClient/.env +++ b/samples/RedundantClient/.env @@ -1,12 +1,12 @@ -# Default environment for Applications/RedundantClient/docker-compose.yml. +# Default environment for samples/RedundantClient/docker-compose.yml. # # docker compose auto-loads this file from the compose file's directory (even when you run -# from the repository root with -f Applications/RedundantClient/docker-compose.yml). It sets +# from the repository root with -f samples/RedundantClient/docker-compose.yml). It sets # the DEFAULT matrix cell — eventual servers + independent clients — so a bare `up` just # works. Override any value on the command line (host env wins over this file), e.g.: # # COMPOSE_PROFILES=server-strong,client-coordinated CLIENT_CONSISTENCY=strong \ -# docker compose -f Applications/RedundantClient/docker-compose.yml up --build +# docker compose -f samples/RedundantClient/docker-compose.yml up --build # Which matrix cell to run: one server profile + one client profile. # server-eventual | server-strong and client-independent | client-coordinated diff --git a/samples/RedundantClient/Dockerfile b/samples/RedundantClient/Dockerfile index f64b9d445d..2651b5d6a6 100644 --- a/samples/RedundantClient/Dockerfile +++ b/samples/RedundantClient/Dockerfile @@ -2,13 +2,13 @@ # # The build context must be the repository ROOT so the project references resolve. # Build directly: -# docker build -f Applications/RedundantClient/Dockerfile -t opcua-redundant-client . -# Or via docker compose (see Applications/RedundantServer/docker-compose.*.yml). +# docker build -f samples/RedundantClient/Dockerfile -t opcua-redundant-client . +# Or via docker compose (see samples/RedundantServer/docker-compose.*.yml). FROM mcr.microsoft.com/dotnet/sdk AS build WORKDIR /src ENV DOTNET_EnableWriteXorExecute=0 COPY . . -RUN dotnet publish "Applications/RedundantClient/RedundantClient.csproj" \ +RUN dotnet publish "samples/RedundantClient/RedundantClient.csproj" \ -c Release -f net10.0 -p:PublishAot=false \ -o /app/publish diff --git a/samples/RedundantClient/Program.cs b/samples/RedundantClient/Program.cs index ed2ffd3248..3eebd99617 100644 --- a/samples/RedundantClient/Program.cs +++ b/samples/RedundantClient/Program.cs @@ -555,7 +555,7 @@ namespace RedundantClient where TSession : ISession { // A compact browse / read / subscribe workload against the redundant session. It - // mirrors the Applications/ConsoleReferenceClient ClientSamples suite but is kept + // mirrors the samples/ConsoleReferenceClient ClientSamples suite but is kept // inline so this sample stays self-contained and NativeAOT-publishable. Console.WriteLine("Suite: browsing the Objects folder..."); var browseDescription = new BrowseDescription diff --git a/samples/RedundantClient/Properties/AssemblyInfo.cs b/samples/RedundantClient/Properties/AssemblyInfo.cs index b72d7e72f7..2b9848014c 100644 --- a/samples/RedundantClient/Properties/AssemblyInfo.cs +++ b/samples/RedundantClient/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Applications/RedundantClient/Properties/AssemblyInfo.cs diff --git a/samples/RedundantClient/README.md b/samples/RedundantClient/README.md index 01fe1bf8ea..9aa3c8d5f7 100644 --- a/samples/RedundantClient/README.md +++ b/samples/RedundantClient/README.md @@ -8,7 +8,7 @@ This console sample shows the recommended way to connect an OPC UA client: build ## Run ```powershell -dotnet run --project Applications\RedundantClient\RedundantClient.csproj -- ` +dotnet run --project samples\RedundantClient\RedundantClient.csproj -- ` --server opc.tcp://localhost:62543/RedundantServer --autoaccept --nosecurity --duration 00:05:00 ``` @@ -22,7 +22,7 @@ dotnet run --project Applications\RedundantClient\RedundantClient.csproj -- ` The sample connects, logs the server's reported `RedundancySupport` (or notes that the server is not redundant), subscribes to `Server.ServerStatus.CurrentTime`, and logs the values together with any transparent connection-state changes (reconnect or failover). To observe failover, lower the active server's service level (for example with the `RedundantServer` sample's manual failover support) or stop the active server; the managed session reconnects to a healthy peer on its own. -See [HighAvailability.md](../../Docs/HighAvailability.md) for the redundancy design and the [RedundantServer](../RedundantServer/README.md) sample for the server side. +See [HighAvailability.md](../../docs/HighAvailability.md) for the redundancy design and the [RedundantServer](../RedundantServer/README.md) sample for the server side. ## Run with docker compose (one file, the full HA matrix, env-driven) @@ -43,18 +43,18 @@ Run from the repository root: ```bash # DEFAULT: 3 eventual servers + 2 independent clients (failover + data loss demoable out of the box). -docker compose -f Applications/RedundantClient/docker-compose.yml up --build +docker compose -f samples/RedundantClient/docker-compose.yml up --build # Scale the eventual server and the independent clients independently: -docker compose -f Applications/RedundantClient/docker-compose.yml up --build --scale server=5 --scale client=3 +docker compose -f samples/RedundantClient/docker-compose.yml up --build --scale server=5 --scale client=3 # STRONG server (no data loss) x independent clients: COMPOSE_PROFILES=server-strong,client-independent \ - docker compose -f Applications/RedundantClient/docker-compose.yml up --build + docker compose -f samples/RedundantClient/docker-compose.yml up --build # Any matrix cell, e.g. STRONG server x EVENTUAL coordinated client: COMPOSE_PROFILES=server-strong,client-coordinated CLIENT_CONSISTENCY=eventual \ - docker compose -f Applications/RedundantClient/docker-compose.yml up --build + docker compose -f samples/RedundantClient/docker-compose.yml up --build ``` To trigger a server failover, stop the replica a client is on — for example scale the eventual servers down (`… up -d --scale server=1`) or `docker kill` one server container (for `server-strong`, stop the Raft leader, e.g. `… stop server-a`). Then watch the **client** log, which turns the transparent failover and its data impact into explicit lines: @@ -82,5 +82,5 @@ Whether the `Counter` shows data loss or continuity depends on the **server** pr Run the client image in multiple containers so each replica is its own process — a single-process demo cannot coordinate a real deployment. The client mode is chosen with `CLIENT_MODE` (which the compose sets per profile); two process-per-replica models are supported: - **Independent managed clients** (`CLIENT_MODE=independent`, the compose default, **2, scalable**): every container builds a `ManagedSession` with `WithServerRedundancy()` and reconnects to a healthy peer independently. Scale the client image with `--scale client=N`, or use the `clients` profile in [`RedundantServer/Scale/docker-compose.yml`](../RedundantServer/Scale/docker-compose.yml). -- **Coordinated single-active replica set** (`CLIENT_MODE=eventual` \| `strong`, the `client-coordinated` profile, **fixed odd quorum, default 3**): each container builds a `RedundantClientSession` over a real Raft cluster among the client replicas (`RaftLeaderElection` + a `RaftSharedKeyValueStore`, or a `HybridSharedKeyValueStore` over CRDT gossip for eventual) — the same building blocks the server uses, mirrored on the client. The processes elect one leader that holds the session and share its protected session secrets, so a follower takes over on leader loss and resumes monitoring. Each replica exposes a transparent `RedundantClientSession` (`ISession`). Because the election is Raft-quorum-based in both eventual and strong, a coordinated set needs an **odd ≥ 3 quorum** (a 2-member set is degenerate); the compose ships a fixed 3-node `client-a/b/c` set. A coordinated set mirrors session secrets through a networked store, so it requires a record protector: set `CLIENT_RECORD_KEY` to a shared base64 32-byte key in production, or `CLIENT_INSECURE=true` for an isolated demo (a well-known, non-secret demo key). See [HighAvailability.md](../../Docs/HighAvailability.md). +- **Coordinated single-active replica set** (`CLIENT_MODE=eventual` \| `strong`, the `client-coordinated` profile, **fixed odd quorum, default 3**): each container builds a `RedundantClientSession` over a real Raft cluster among the client replicas (`RaftLeaderElection` + a `RaftSharedKeyValueStore`, or a `HybridSharedKeyValueStore` over CRDT gossip for eventual) — the same building blocks the server uses, mirrored on the client. The processes elect one leader that holds the session and share its protected session secrets, so a follower takes over on leader loss and resumes monitoring. Each replica exposes a transparent `RedundantClientSession` (`ISession`). Because the election is Raft-quorum-based in both eventual and strong, a coordinated set needs an **odd ≥ 3 quorum** (a 2-member set is degenerate); the compose ships a fixed 3-node `client-a/b/c` set. A coordinated set mirrors session secrets through a networked store, so it requires a record protector: set `CLIENT_RECORD_KEY` to a shared base64 32-byte key in production, or `CLIENT_INSECURE=true` for an isolated demo (a well-known, non-secret demo key). See [HighAvailability.md](../../docs/HighAvailability.md). diff --git a/samples/RedundantClient/RedundantClient.csproj b/samples/RedundantClient/RedundantClient.csproj index 2d4fef4ee2..386a441150 100644 --- a/samples/RedundantClient/RedundantClient.csproj +++ b/samples/RedundantClient/RedundantClient.csproj @@ -20,10 +20,10 @@ - - - - + + + + diff --git a/samples/RedundantClient/docker-compose.yml b/samples/RedundantClient/docker-compose.yml index 8bba0478d7..1f0e9640ce 100644 --- a/samples/RedundantClient/docker-compose.yml +++ b/samples/RedundantClient/docker-compose.yml @@ -21,19 +21,19 @@ # Run from the repository ROOT (the build context is the repo root): # # # DEFAULT: 3 eventual servers + 2 independent clients (failover + data loss demoable). -# docker compose -f Applications/RedundantClient/docker-compose.yml up --build +# docker compose -f samples/RedundantClient/docker-compose.yml up --build # # # Scale the eventual server and the independent clients independently: -# docker compose -f Applications/RedundantClient/docker-compose.yml up --build \ +# docker compose -f samples/RedundantClient/docker-compose.yml up --build \ # --scale server=5 --scale client=3 # # # STRONG server (no data loss) x independent clients: # COMPOSE_PROFILES=server-strong,client-independent \ -# docker compose -f Applications/RedundantClient/docker-compose.yml up --build +# docker compose -f samples/RedundantClient/docker-compose.yml up --build # # # Any matrix cell, e.g. STRONG server x EVENTUAL coordinated client: # COMPOSE_PROFILES=server-strong,client-coordinated CLIENT_CONSISTENCY=eventual \ -# docker compose -f Applications/RedundantClient/docker-compose.yml up --build +# docker compose -f samples/RedundantClient/docker-compose.yml up --build # # Only the eventual server (`server`) and the independent clients (`client`) are # --scale-able; the strong server and the coordinated client are fixed odd Raft quorums @@ -45,13 +45,13 @@ x-server-image: &server-image build: context: ../.. - dockerfile: Applications/RedundantServer/Dockerfile + dockerfile: samples/RedundantServer/Dockerfile image: opcua-redundant-server x-client-image: &client-image build: context: ../.. - dockerfile: Applications/RedundantClient/Dockerfile + dockerfile: samples/RedundantClient/Dockerfile image: opcua-redundant-client # Connect to the `server` name (the eventual service, or the strong server-a alias); # WithServerRedundancy() discovers the redundant set from the connected server and fails diff --git a/samples/RedundantPubSub/.env b/samples/RedundantPubSub/.env index 03de305c9e..25bb550e5c 100644 --- a/samples/RedundantPubSub/.env +++ b/samples/RedundantPubSub/.env @@ -1,4 +1,4 @@ -# Default environment for Applications/RedundantPubSub/docker-compose.yml. +# Default environment for samples/RedundantPubSub/docker-compose.yml. # docker compose auto-loads this file from the compose file directory. # strong = three named Raft publishers + one subscriber; demo = single-container in-process failover. diff --git a/samples/RedundantPubSub/Dockerfile b/samples/RedundantPubSub/Dockerfile index 2d5783cd7e..bcd7370b7f 100644 --- a/samples/RedundantPubSub/Dockerfile +++ b/samples/RedundantPubSub/Dockerfile @@ -2,14 +2,14 @@ # # The build context must be the repository ROOT so project references resolve. # Build directly: -# docker build -f Applications/RedundantPubSub/Dockerfile -t opcua-redundant-pubsub . +# docker build -f samples/RedundantPubSub/Dockerfile -t opcua-redundant-pubsub . # Or via docker compose: -# docker compose -f Applications/RedundantPubSub/docker-compose.yml up --build +# docker compose -f samples/RedundantPubSub/docker-compose.yml up --build FROM mcr.microsoft.com/dotnet/sdk AS build WORKDIR /src ENV DOTNET_EnableWriteXorExecute=0 COPY . . -RUN dotnet publish "Applications/RedundantPubSub/RedundantPubSub.csproj" \ +RUN dotnet publish "samples/RedundantPubSub/RedundantPubSub.csproj" \ -c Release -f net10.0 -p:PublishAot=false -p:NuGetAudit=false \ -o /app/publish diff --git a/samples/RedundantPubSub/Properties/AssemblyInfo.cs b/samples/RedundantPubSub/Properties/AssemblyInfo.cs index 251a46fe17..7798c9bd57 100644 --- a/samples/RedundantPubSub/Properties/AssemblyInfo.cs +++ b/samples/RedundantPubSub/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Applications/RedundantPubSub/Properties/AssemblyInfo.cs diff --git a/samples/RedundantPubSub/README.md b/samples/RedundantPubSub/README.md index 180a25eb9d..9ea7070189 100644 --- a/samples/RedundantPubSub/README.md +++ b/samples/RedundantPubSub/README.md @@ -17,7 +17,7 @@ The sample uses the existing PubSub fluent + DI host surface (`services.AddOpcUa From the repository root: ```powershell -dotnet run --project Applications\RedundantPubSub\RedundantPubSub.csproj -- --role demo --ha-mode hot +dotnet run --project samples\RedundantPubSub\RedundantPubSub.csproj -- --role demo --ha-mode hot ``` The demo runs publisher-a, then prints `FAILOVER: stopping publisher-a; publisher-b is promoted.` and promotes publisher-b. In hot mode it also prints this simulated illustrative line: @@ -29,7 +29,7 @@ SIMULATED: HA OK: sequence continued 3 -> 9 across failover (gap, no reset). Run the same demo with cold mode to make the reset visible: ```powershell -dotnet run --project Applications\RedundantPubSub\RedundantPubSub.csproj -- --role demo --ha-mode cold +dotnet run --project samples\RedundantPubSub\RedundantPubSub.csproj -- --role demo --ha-mode cold ``` The demo prints this simulated illustrative reset line in cold mode: @@ -41,7 +41,7 @@ SIMULATED: DATA LOSS: sequence reset 3 -> 1 (subscriber must reset de-duplicatio Run warm mode to exercise the standby activation path without hot checkpoints: ```powershell -dotnet run --project Applications\RedundantPubSub\RedundantPubSub.csproj -- --role demo --ha-mode warm +dotnet run --project samples\RedundantPubSub\RedundantPubSub.csproj -- --role demo --ha-mode warm ``` The demo prints an explicit `WARM MODE:` note before failover, and its simulated SequenceNumber continuity currently matches the cold-mode reset behavior because warm checkpoints are not persisted in this sample yet. @@ -50,13 +50,13 @@ The demo prints an explicit `WARM MODE:` note before failover, and its simulated From the repository root, the default `.env` selects the `strong` profile: three named publisher replicas with Raft leader election and a Raft-backed shared store, plus three subscriber replicas that form their own Raft-backed active/standby reader set. ```powershell -docker compose -f Applications/RedundantPubSub/docker-compose.yml up --build +docker compose -f samples/RedundantPubSub/docker-compose.yml up --build ``` Trigger publisher failover by stopping the current active publisher container. The publisher logs include `Publisher : -> Active` or `Standby`; stop the active one from another terminal: ```powershell -docker compose -f Applications/RedundantPubSub/docker-compose.yml stop publisher-a +docker compose -f samples/RedundantPubSub/docker-compose.yml stop publisher-a ``` If another publisher was active, stop that publisher instead. The subscriber log demonstrates the behavior: `HA OK: sequence continued -> across failover (gap, no reset)` in hot mode, or `DATA LOSS: sequence reset -> (subscriber must reset de-duplication)` in cold mode. @@ -64,7 +64,7 @@ If another publisher was active, stop that publisher instead. The subscriber log Trigger subscriber failover the same way. The subscriber logs include `Subscriber : -> Active` or `Standby`, and only the active subscriber logs `DataSet with field(s) received`. Stop the active subscriber: ```powershell -docker compose -f Applications/RedundantPubSub/docker-compose.yml stop subscriber-a +docker compose -f samples/RedundantPubSub/docker-compose.yml stop subscriber-a ``` A standby subscriber is promoted to `Active` and resumes dispatching received data sets without losing the multicast stream it already receives. @@ -73,7 +73,7 @@ To run the single-container in-process demo through compose: ```powershell $env:COMPOSE_PROFILES='demo' -docker compose -f Applications/RedundantPubSub/docker-compose.yml up --build +docker compose -f samples/RedundantPubSub/docker-compose.yml up --build ``` ## Notes and simplifications diff --git a/samples/RedundantPubSub/RedundantPubSub.csproj b/samples/RedundantPubSub/RedundantPubSub.csproj index 7a2a5479d4..305bb263eb 100644 --- a/samples/RedundantPubSub/RedundantPubSub.csproj +++ b/samples/RedundantPubSub/RedundantPubSub.csproj @@ -21,10 +21,10 @@ - - - - - + + + + + diff --git a/samples/RedundantPubSub/docker-compose.yml b/samples/RedundantPubSub/docker-compose.yml index a747ab4f21..d9f975c1fd 100644 --- a/samples/RedundantPubSub/docker-compose.yml +++ b/samples/RedundantPubSub/docker-compose.yml @@ -6,7 +6,7 @@ # demo single container running two in-process publishers + subscriber over loopback UDP by default # # Run from the repository ROOT: -# docker compose -f Applications/RedundantPubSub/docker-compose.yml up --build +# docker compose -f samples/RedundantPubSub/docker-compose.yml up --build # # Publisher HA — observe the subscriber logs. With HA_MODE=hot, killing the active publisher # (docker kill ) should produce on every subscriber: @@ -23,7 +23,7 @@ x-pubsub-image: &pubsub-image build: context: ../.. - dockerfile: Applications/RedundantPubSub/Dockerfile + dockerfile: samples/RedundantPubSub/Dockerfile image: opcua-redundant-pubsub x-publisher-env: &publisher-env diff --git a/samples/RedundantServer/Dockerfile b/samples/RedundantServer/Dockerfile index 4c53b05f08..18ba452910 100644 --- a/samples/RedundantServer/Dockerfile +++ b/samples/RedundantServer/Dockerfile @@ -2,13 +2,13 @@ # # The build context must be the repository ROOT so the project references resolve. # Build directly: -# docker build -f Applications/RedundantServer/Dockerfile -t opcua-redundant-server . -# Or via docker compose (see Applications/RedundantServer/docker-compose.*.yml). +# docker build -f samples/RedundantServer/Dockerfile -t opcua-redundant-server . +# Or via docker compose (see samples/RedundantServer/docker-compose.*.yml). FROM mcr.microsoft.com/dotnet/sdk AS build WORKDIR /src ENV DOTNET_EnableWriteXorExecute=0 COPY . . -RUN dotnet publish "Applications/RedundantServer/RedundantServer.csproj" \ +RUN dotnet publish "samples/RedundantServer/RedundantServer.csproj" \ -c Release -f net10.0 -p:PublishAot=false -p:CustomTestTarget=net10.0 \ -o /app/publish diff --git a/samples/RedundantServer/LoadDirection/docker-compose.yml b/samples/RedundantServer/LoadDirection/docker-compose.yml index 9793e152ee..22fe7086f7 100644 --- a/samples/RedundantServer/LoadDirection/docker-compose.yml +++ b/samples/RedundantServer/LoadDirection/docker-compose.yml @@ -14,12 +14,12 @@ # address your LB/Service would expose). # # The build context is the repository root. Run from the repo root: -# docker compose -f Applications/RedundantServer/LoadDirection/docker-compose.yml up --build +# docker compose -f samples/RedundantServer/LoadDirection/docker-compose.yml up --build x-ld-server: &ld-server build: context: ../../.. - dockerfile: Applications/RedundantServer/Dockerfile + dockerfile: samples/RedundantServer/Dockerfile image: opcua-redundant-server command: ["--port", "62543"] diff --git a/samples/RedundantServer/Properties/AssemblyInfo.cs b/samples/RedundantServer/Properties/AssemblyInfo.cs index ae099db88d..2b9848014c 100644 --- a/samples/RedundantServer/Properties/AssemblyInfo.cs +++ b/samples/RedundantServer/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Applications/RedundantServer/Properties/AssemblyInfo.cs diff --git a/samples/RedundantServer/README.md b/samples/RedundantServer/README.md index 9dda8b4185..c75960bacb 100644 --- a/samples/RedundantServer/README.md +++ b/samples/RedundantServer/README.md @@ -7,7 +7,7 @@ The bundled configuration uses the default in-memory shared key/value store. Tha ## Run one instance ```powershell -dotnet run --project Applications\RedundantServer\RedundantServer.csproj -- --port 62543 +dotnet run --project samples\RedundantServer\RedundantServer.csproj -- --port 62543 ``` Connect an OPC UA client to `opc.tcp://localhost:62543/RedundantServer` and browse to `Objects/High Availability`. The `Counter` variable is writable and is also incremented once per second while this server is leader. `ActiveReplica` shows the local active writer label. @@ -34,7 +34,7 @@ applicationUri|applicationName|discoveryUrl1+discoveryUrl2 $env:HA_NODE_ID = "replica-a" $env:REDUNDANCY_MODE = "hot" $env:HA_REDUNDANT_PEERS = "urn:localhost:OPCFoundation:RedundantServer:replica-b|RedundantServer replica-b|opc.tcp://localhost:62544/RedundantServer" -dotnet run --project Applications\RedundantServer\RedundantServer.csproj -- --port 62543 +dotnet run --project samples\RedundantServer\RedundantServer.csproj -- --port 62543 ``` In a second terminal: @@ -43,7 +43,7 @@ In a second terminal: $env:HA_NODE_ID = "replica-b" $env:REDUNDANCY_MODE = "hot" $env:HA_REDUNDANT_PEERS = "urn:localhost:OPCFoundation:RedundantServer:replica-a|RedundantServer replica-a|opc.tcp://localhost:62543/RedundantServer" -dotnet run --project Applications\RedundantServer\RedundantServer.csproj -- --port 62544 +dotnet run --project samples\RedundantServer\RedundantServer.csproj -- --port 62544 ``` With the default in-memory store, each process elects against its own private store, so this two-terminal setup demonstrates endpoint, node id, service-level, and redundancy metadata configuration rather than cross-process state transfer. To turn it into a real HA pair, register a shared `ISharedKeyValueStore` that both processes can reach, as shown below. @@ -121,7 +121,7 @@ The Redis placeholder above is one way to get a shared `ISharedKeyValueStore`. T | `HA_RAFT_BIND` | `tcp://0.0.0.0:6560` | Local Raft transport bind address. | | `HA_RAFT_PEERS` | `tcp://server-b:6560,tcp://server-c:6560` | The other members' Raft transport addresses. | -See `docker-compose.yml` with the `active-passive.env` env file for a runnable 3-node Raft cluster (real cross-container active/passive HA). For Kubernetes, `UseKubernetesRaftConsensus` in `Opc.Ua.Redundancy.Kubernetes` derives the same wiring from the StatefulSet ordinal and headless-Service DNS, with a file WAL on a PersistentVolume; see `Docs/Kubernetes.md`. +See `docker-compose.yml` with the `active-passive.env` env file for a runnable 3-node Raft cluster (real cross-container active/passive HA). For Kubernetes, `UseKubernetesRaftConsensus` in `Opc.Ua.Redundancy.Kubernetes` derives the same wiring from the StatefulSet ordinal and headless-Service DNS, with a file WAL on a PersistentVolume; see `docs/Kubernetes.md`. ## Redundancy mode and discovery settings @@ -155,7 +155,7 @@ Mode-specific nodes shown by the sample: ### GetEndpoints load direction -Setting `HA_BALANCING_URL` registers `UseServerLoadDirection(...)`: every replica publishes its health `ServiceLevel`, a load weight, and its endpoints to the shared store, and a `GetEndpoints` request that arrives on the balancing URL is answered with the best replica's endpoints — the active writer in active/passive, or the least-loaded healthy replica in active/active. Plain discovery on a replica's own URL is unaffected, and this complements (never replaces) the standard client-driven `Server.ServiceLevel` / `RedundantServerArray` selection. In a real deployment a load balancer / Kubernetes `Service` fronts the replicas at the balancing URL; the sample sets `StrongEligibility` when `HA_CONSISTENCY=strong` so the eligibility keyspaces are linearizable. It requires a shared store across replicas (use `HA_CONSISTENCY=strong` / the Raft compose). See `Docs/HighAvailability.md` for the design, conformance, and security notes. +Setting `HA_BALANCING_URL` registers `UseServerLoadDirection(...)`: every replica publishes its health `ServiceLevel`, a load weight, and its endpoints to the shared store, and a `GetEndpoints` request that arrives on the balancing URL is answered with the best replica's endpoints — the active writer in active/passive, or the least-loaded healthy replica in active/active. Plain discovery on a replica's own URL is unaffected, and this complements (never replaces) the standard client-driven `Server.ServiceLevel` / `RedundantServerArray` selection. In a real deployment a load balancer / Kubernetes `Service` fronts the replicas at the balancing URL; the sample sets `StrongEligibility` when `HA_CONSISTENCY=strong` so the eligibility keyspaces are linearizable. It requires a shared store across replicas (use `HA_CONSISTENCY=strong` / the Raft compose). See `docs/HighAvailability.md` for the design, conformance, and security notes. ## Transparent redundancy (single virtual endpoint) @@ -169,7 +169,7 @@ To present one logical server, all replicas must share: Each replica advertises the *virtual* endpoint URL (`HA_HOST` = the load-balancer host). Because that host is a DNS name, the listener binds to all interfaces in the replica's own container while returning `opc.tcp://:62543/...` to clients, so discovery and `CreateSession` echo the single endpoint the client actually uses (`ServerBase.FilterByEndpointUrl` matches the client host to the advertised base address). A client therefore connects to one URL, and on a replica failure the load balancer routes the reconnect to the survivor, where the mirrored session resumes with a token-reuse reconnect (the full `ActivateSession` signature re-check still applies). -`Transparent/docker-compose.yml` runs this end to end: two `REDUNDANCY_MODE=transparent` replicas sharing one `ApplicationUri` and one certificate (seeded into a shared PKI volume by the first replica, then reused by the second) behind an `nginx` TCP load balancer that publishes the single virtual endpoint `opc.tcp://localhost:62543/RedundantServer`, plus a client that connects only to that endpoint. In production the shared certificate is provisioned from a Kubernetes Secret / KMS to every replica rather than self-generated (see `Docs/Kubernetes.md`), which also removes the first-start certificate race. +`Transparent/docker-compose.yml` runs this end to end: two `REDUNDANCY_MODE=transparent` replicas sharing one `ApplicationUri` and one certificate (seeded into a shared PKI volume by the first replica, then reused by the second) behind an `nginx` TCP load balancer that publishes the single virtual endpoint `opc.tcp://localhost:62543/RedundantServer`, plus a client that connects only to that endpoint. In production the shared certificate is provisioned from a Kubernetes Secret / KMS to every replica rather than self-generated (see `docs/Kubernetes.md`), which also removes the first-start certificate race. ## Active/passive vs active/active @@ -178,7 +178,7 @@ The sample selects its redundancy topology with the `HA_MODE` environment variab - **Active/passive (`HA_MODE=ap`)** — `UseDistributedAddressSpace` + `UseDistributedSessions` with leader election. One replica is the active writer; standbys hydrate from the shared store and take over on failover. Redundancy is reported as `RedundancySupport.Hot`, and clients follow `Server.ServiceLevel` / `Server.ServerRedundancy` to find the active replica. - **Active/active (`HA_MODE=aa`)** — `UseActiveActiveRedundancy` (which wires `UseReplicatedAddressSpace` + `UseReplicatedSessions` from one set of gossip options; the individual methods remain for advanced setups). Every replica accepts writes and converges without a leader; redundancy is reported as `RedundancySupport.HotAndMirrored`. Replicas gossip over TCP: set `HA_GOSSIP_PORT` (default `4840`; session entries gossip on `port + 1`) and `HA_GOSSIP_PEERS` (a comma/semicolon list of `host:port` for the other replicas' address-space gossip). A session created on one replica can be resumed on another with `ManagedSessionBuilder.WithTokenReuseFailover()` on the client. -Set `HA_PEER_DISCOVERY=dns` (with `HA_SERVICE_NAME`) to discover peers dynamically instead of a static `HA_GOSSIP_PEERS` list: the sample registers `UseDnsPeerDiscovery`, which keeps the client-facing `RedundantServerSet` (`FindServers`) and the active/active gossip fabric current as replicas scale up and down. Static configuration (`AddServerRedundancy` / `HA_REDUNDANT_PEERS`) is the fallback. `HA_PEER_DISCOVERY=lds` (`UseLdsPeerDiscovery`) and Kubernetes EndpointSlice discovery (`UseKubernetesPeerDiscovery`) are also available — see [Docs/HighAvailability.md → Dynamic peer discovery](../../Docs/HighAvailability.md#dynamic-peer-discovery-beyond-66-opt-in). +Set `HA_PEER_DISCOVERY=dns` (with `HA_SERVICE_NAME`) to discover peers dynamically instead of a static `HA_GOSSIP_PEERS` list: the sample registers `UseDnsPeerDiscovery`, which keeps the client-facing `RedundantServerSet` (`FindServers`) and the active/active gossip fabric current as replicas scale up and down. Static configuration (`AddServerRedundancy` / `HA_REDUNDANT_PEERS`) is the fallback. `HA_PEER_DISCOVERY=lds` (`UseLdsPeerDiscovery`) and Kubernetes EndpointSlice discovery (`UseKubernetesPeerDiscovery`) are also available — see [docs/HighAvailability.md → Dynamic peer discovery](../../docs/HighAvailability.md#dynamic-peer-discovery-beyond-66-opt-in). ### Run two active/passive replicas @@ -190,7 +190,7 @@ $env:HA_NODE_ID = "replica-a" $env:HA_MODE = "ap" $env:REDUNDANCY_MODE = "hot" $env:HA_REDUNDANT_PEERS = "urn:localhost:OPCFoundation:RedundantServer:replica-b|RedundantServer replica-b|opc.tcp://localhost:62544/RedundantServer" -dotnet run --project Applications\RedundantServer\RedundantServer.csproj -- --port 62543 +dotnet run --project samples\RedundantServer\RedundantServer.csproj -- --port 62543 ``` In a second terminal: @@ -201,7 +201,7 @@ $env:HA_NODE_ID = "replica-b" $env:HA_MODE = "ap" $env:REDUNDANCY_MODE = "hot" $env:HA_REDUNDANT_PEERS = "urn:localhost:OPCFoundation:RedundantServer:replica-a|RedundantServer replica-a|opc.tcp://localhost:62543/RedundantServer" -dotnet run --project Applications\RedundantServer\RedundantServer.csproj -- --port 62544 +dotnet run --project samples\RedundantServer\RedundantServer.csproj -- --port 62544 ``` The active replica writes `Counter`, the standby mirrors state through the shared store, and clients use `Server.ServiceLevel`, `Server.ServerRedundancy.RedundancySupport=Hot`, and `FindServers` peer discovery to select or fail over to the active endpoint. @@ -214,7 +214,7 @@ $env:HA_NODE_ID = "replica-a" $env:HA_MODE = "aa" $env:HA_GOSSIP_PORT = "4840" $env:HA_GOSSIP_PEERS = "127.0.0.1:4842" -dotnet run --project Applications\RedundantServer\RedundantServer.csproj -- --port 62543 +dotnet run --project samples\RedundantServer\RedundantServer.csproj -- --port 62543 ``` In a second terminal: @@ -225,7 +225,7 @@ $env:HA_NODE_ID = "replica-b" $env:HA_MODE = "aa" $env:HA_GOSSIP_PORT = "4842" $env:HA_GOSSIP_PEERS = "127.0.0.1:4840" -dotnet run --project Applications\RedundantServer\RedundantServer.csproj -- --port 62544 +dotnet run --project samples\RedundantServer\RedundantServer.csproj -- --port 62544 ``` Both replicas now accept writes to `Counter` and converge: a write on either endpoint propagates to the other by gossip, and the per-second increment runs on every replica, with CRDT last-writer-wins resolving the concurrent updates. Unlike the active/passive store-backed setup, active/active needs no shared `ISharedKeyValueStore` between processes — the gossip transport carries the state. @@ -236,23 +236,23 @@ One compose file — `docker-compose.yml` — runs the sample as a 3-replica set ```powershell # Active/active, eventual consistency (CRDT gossip, no shared store) — the default. -docker compose --env-file Applications\RedundantServer\active-active-eventual.env ` - -f Applications\RedundantServer\docker-compose.yml up --build +docker compose --env-file samples\RedundantServer\active-active-eventual.env ` + -f samples\RedundantServer\docker-compose.yml up --build # Active/active, strong consistency (3-node RaftCs, shared linearizable store). -docker compose --env-file Applications\RedundantServer\active-active-strong.env ` - -f Applications\RedundantServer\docker-compose.yml up --build +docker compose --env-file samples\RedundantServer\active-active-strong.env ` + -f samples\RedundantServer\docker-compose.yml up --build # Active/passive, strong consistency (3-node RaftCs; one active writer, two hot standbys). -docker compose --env-file Applications\RedundantServer\active-passive.env ` - -f Applications\RedundantServer\docker-compose.yml up --build +docker compose --env-file samples\RedundantServer\active-passive.env ` + -f samples\RedundantServer\docker-compose.yml up --build # GetEndpoints load direction over the Raft cluster (sets HA_BALANCING_URL on every replica). -docker compose -f Applications\RedundantServer\LoadDirection\docker-compose.yml up --build +docker compose -f samples\RedundantServer\LoadDirection\docker-compose.yml up --build # Transparent redundancy: replicas as ONE logical server behind an nginx load balancer # on a single virtual endpoint (opc.tcp://localhost:62543/RedundantServer). -docker compose -f Applications\RedundantServer\Transparent\docker-compose.yml up --build +docker compose -f samples\RedundantServer\Transparent\docker-compose.yml up --build ``` Each replica exposes its OPC UA endpoint on the host (`opc.tcp://localhost:62543/RedundantServer`, `:62544`, `:62545`). Set `HA_HOST` to the reachable hostname (the compose file uses the container/service name) so peers and clients connect across the container network. Three replicas run in every topology (Raft needs a 3-node quorum; active/active eventual works with 2 or 3 — remove `server-c` for a 2-node run, so the replica count is configurable). The Raft topologies are real cross-container HA deployments whose RaftCs cluster is the shared, linearizable store; active/active eventual converges leaderlessly over CRDT gossip with no shared store. @@ -262,7 +262,7 @@ Each replica exposes its OPC UA endpoint on the host (`opc.tcp://localhost:62543 `Scale/docker-compose.yml` has a single `server` service for active/active eventual (CRDT gossip) runs. Docker Compose can scale it to any replica count because the sample discovers peers from the `server` DNS alias instead of a fixed `HA_GOSSIP_PEERS` list: ```powershell -docker compose -f Applications\RedundantServer\Scale\docker-compose.yml up --build --scale server=5 +docker compose -f samples\RedundantServer\Scale\docker-compose.yml up --build --scale server=5 ``` The scale file sets `HA_PEER_DISCOVERY=dns` and `HA_SERVICE_NAME=server`; every replica resolves the service alias, removes its own container IP, and seeds gossip with the remaining task IPs on `HA_GOSSIP_PORT` (session gossip uses the next port). No host ports are published, so clients should run inside the same compose network or attach to it. This dynamic scaling path is gossip-only. Dynamic Raft scaling is intentionally unsupported because Raft needs stable replica identities and an odd quorum; use the Kubernetes StatefulSet deployment with `UseKubernetesRaftConsensus` for strong consistency. @@ -270,12 +270,12 @@ The scale file sets `HA_PEER_DISCOVERY=dns` and `HA_SERVICE_NAME=server`; every The same file has a `clients` profile that runs **independent managed clients** in their own containers — each opts into `WithServerRedundancy()` and fails over on its own, so it scales to any count alongside the servers (no shared client store needed): ```powershell -docker compose -f Applications\RedundantServer\Scale\docker-compose.yml --profile clients up --build --scale server=3 --scale client=2 +docker compose -f samples\RedundantServer\Scale\docker-compose.yml --profile clients up --build --scale server=3 --scale client=2 ``` -For a *coordinated* single-active client replica set (exactly one client active, the rest hot/warm/cold standbys), use `AddRedundantClientSession` + a CAS-capable `AddRaftClientSharedStore` (a fixed Raft quorum, like the server's active/passive) rather than independent clients — see [HighAvailability.md](../../Docs/HighAvailability.md). Each client replica is its own process; there is no in-process replica set. +For a *coordinated* single-active client replica set (exactly one client active, the rest hot/warm/cold standbys), use `AddRedundantClientSession` + a CAS-capable `AddRaftClientSharedStore` (a fixed Raft quorum, like the server's active/passive) rather than independent clients — see [HighAvailability.md](../../docs/HighAvailability.md). Each client replica is its own process; there is no in-process replica set. -For a **client-centric** compose that runs the full HA matrix (server consistency × client mode) from one env-driven file and logs failover / HA / **data loss** on both sides, use [`Applications/RedundantClient/docker-compose.yml`](../RedundantClient/docker-compose.yml): `COMPOSE_PROFILES` selects `server-eventual` (shows data loss) or `server-strong` (Raft, no data loss) crossed with `client-independent` or `client-coordinated`. See the [RedundantClient README](../RedundantClient/README.md#run-with-docker-compose-one-file-the-full-ha-matrix-env-driven). +For a **client-centric** compose that runs the full HA matrix (server consistency × client mode) from one env-driven file and logs failover / HA / **data loss** on both sides, use [`samples/RedundantClient/docker-compose.yml`](../RedundantClient/docker-compose.yml): `COMPOSE_PROFILES` selects `server-eventual` (shows data loss) or `server-strong` (Raft, no data loss) crossed with `client-independent` or `client-coordinated`. See the [RedundantClient README](../RedundantClient/README.md#run-with-docker-compose-one-file-the-full-ha-matrix-env-driven). ### Watch replication and failover @@ -283,16 +283,16 @@ The `clients` (and `demo`) profile adds one or more `RedundantClient` instances ```powershell # 1. Start the server set (active/passive here) plus a client that prints the replicated Counter. -docker compose --env-file Applications\RedundantServer\active-passive.env ` - -f Applications\RedundantServer\docker-compose.yml --profile clients up --build +docker compose --env-file samples\RedundantServer\active-passive.env ` + -f samples\RedundantServer\docker-compose.yml --profile clients up --build # 2. In another shell, stop the active/leader replica and watch the client keep going: -docker compose -f Applications\RedundantServer\docker-compose.yml stop server-a +docker compose -f samples\RedundantServer\docker-compose.yml stop server-a ``` The client logs its reconnect/redirect to a surviving replica across the failover. Bring the replica back with `docker compose ... start server-a`; the Raft cluster re-admits it. Set `CLIENT_REPLICAS=3` to run three independent client processes, each of which fails over on its own (for a coordinated single-active client set, use `AddRedundantClientSession` over a Raft client store as above). On the strong-consistency Raft topology the `HighAvailability.Counter` **continues** across the failover: the sample wires it through the distributed value cache (see [Sharing values across replicas](#sharing-values-across-replicas)), so the promoted replica resumes from the last value the former leader shared. -For the broader design, see [HighAvailability.md](..\..\Docs\HighAvailability.md). For an environment-driven replica-set deployment, see [Kubernetes.md](..\..\Docs\Kubernetes.md). +For the broader design, see [HighAvailability.md](..\..\docs\HighAvailability.md). For an environment-driven replica-set deployment, see [Kubernetes.md](..\..\docs\Kubernetes.md). ## Sharing values across replicas diff --git a/samples/RedundantServer/RedundantServer.csproj b/samples/RedundantServer/RedundantServer.csproj index 21649b0005..078ebbc80a 100644 --- a/samples/RedundantServer/RedundantServer.csproj +++ b/samples/RedundantServer/RedundantServer.csproj @@ -19,9 +19,9 @@ true - - - + + + diff --git a/samples/RedundantServer/Scale/docker-compose.yml b/samples/RedundantServer/Scale/docker-compose.yml index 633a6ee8f7..c79d0da929 100644 --- a/samples/RedundantServer/Scale/docker-compose.yml +++ b/samples/RedundantServer/Scale/docker-compose.yml @@ -3,14 +3,14 @@ # transparently. Dynamic Raft (strong) scaling is not supported here. # # Run from the repository root. Scale the servers, and with the clients profile the clients too: -# docker compose -f Applications/RedundantServer/Scale/docker-compose.yml up --build --scale server=5 -# docker compose -f Applications/RedundantServer/Scale/docker-compose.yml --profile clients up --build --scale server=3 --scale client=2 +# docker compose -f samples/RedundantServer/Scale/docker-compose.yml up --build --scale server=5 +# docker compose -f samples/RedundantServer/Scale/docker-compose.yml --profile clients up --build --scale server=3 --scale client=2 services: server: build: context: ../../.. - dockerfile: Applications/RedundantServer/Dockerfile + dockerfile: samples/RedundantServer/Dockerfile image: opcua-redundant-server environment: HA_MODE: aa @@ -29,13 +29,13 @@ services: # Independent managed clients: each opts into WithServerRedundancy and fails over on its own, # so this scales to any count with --scale client=N (no shared client store needed). A # coordinated single-active client replica set instead uses AddRedundantClientSession + a - # Raft client store (fixed quorum); see Docs/HighAvailability.md. Part of the "clients" + # Raft client store (fixed quorum); see docs/HighAvailability.md. Part of the "clients" # profile so `up` without a profile runs the servers only. client: profiles: ["clients"] build: context: ../../.. - dockerfile: Applications/RedundantClient/Dockerfile + dockerfile: samples/RedundantClient/Dockerfile image: opcua-redundant-client depends_on: - server diff --git a/samples/RedundantServer/Transparent/docker-compose.yml b/samples/RedundantServer/Transparent/docker-compose.yml index 773eeb9c22..17b8f21208 100644 --- a/samples/RedundantServer/Transparent/docker-compose.yml +++ b/samples/RedundantServer/Transparent/docker-compose.yml @@ -14,7 +14,7 @@ # transparently on the survivor (full ActivateSession re-check still applies). # # The build context is the repository root. Run from the repo root: -# docker compose -f Applications/RedundantServer/Transparent/docker-compose.yml up --build +# docker compose -f samples/RedundantServer/Transparent/docker-compose.yml up --build # # Single virtual OPC UA endpoint on the host: opc.tcp://localhost:62543/RedundantServer # @@ -27,7 +27,7 @@ services: server-a: build: context: ../../.. - dockerfile: Applications/RedundantServer/Dockerfile + dockerfile: samples/RedundantServer/Dockerfile image: opcua-redundant-server hostname: server-a environment: @@ -60,7 +60,7 @@ services: server-b: build: context: ../../.. - dockerfile: Applications/RedundantServer/Dockerfile + dockerfile: samples/RedundantServer/Dockerfile image: opcua-redundant-server hostname: server-b environment: @@ -95,7 +95,7 @@ services: client: build: context: ../../.. - dockerfile: Applications/RedundantClient/Dockerfile + dockerfile: samples/RedundantClient/Dockerfile image: opcua-redundant-client depends_on: - lb diff --git a/samples/RedundantServer/active-active-eventual.env b/samples/RedundantServer/active-active-eventual.env index 8b61f86f34..ee31f4c647 100644 --- a/samples/RedundantServer/active-active-eventual.env +++ b/samples/RedundantServer/active-active-eventual.env @@ -2,8 +2,8 @@ # writes and converge their address space over gossip; no external shared store. # This is the default topology. # -# docker compose --env-file Applications/RedundantServer/active-active-eventual.env \ -# -f Applications/RedundantServer/docker-compose.yml up --build +# docker compose --env-file samples/RedundantServer/active-active-eventual.env \ +# -f samples/RedundantServer/docker-compose.yml up --build HA_MODE=aa HA_CONSISTENCY=eventual CLIENT_REPLICAS=1 diff --git a/samples/RedundantServer/active-active-strong.env b/samples/RedundantServer/active-active-strong.env index 50d5c5d876..da9e052e30 100644 --- a/samples/RedundantServer/active-active-strong.env +++ b/samples/RedundantServer/active-active-strong.env @@ -2,8 +2,8 @@ # shared key/value store, single-use nonce, and lease are linearizable over a # 3-node RaftCs cluster (a fault-tolerant quorum tolerates losing one replica). # -# docker compose --env-file Applications/RedundantServer/active-active-strong.env \ -# -f Applications/RedundantServer/docker-compose.yml up --build +# docker compose --env-file samples/RedundantServer/active-active-strong.env \ +# -f samples/RedundantServer/docker-compose.yml up --build HA_MODE=aa HA_CONSISTENCY=strong CLIENT_REPLICAS=1 diff --git a/samples/RedundantServer/active-passive.env b/samples/RedundantServer/active-passive.env index 7afd8bdec3..7bc907e8ba 100644 --- a/samples/RedundantServer/active-passive.env +++ b/samples/RedundantServer/active-passive.env @@ -2,8 +2,8 @@ # (the active writer); the other two are hot standbys that take over on leader loss. # The 3-node RaftCs cluster keeps a quorum (2 of 3) when one replica fails. # -# docker compose --env-file Applications/RedundantServer/active-passive.env \ -# -f Applications/RedundantServer/docker-compose.yml up --build +# docker compose --env-file samples/RedundantServer/active-passive.env \ +# -f samples/RedundantServer/docker-compose.yml up --build HA_MODE=ap HA_CONSISTENCY=strong REDUNDANCY_MODE=hot diff --git a/samples/RedundantServer/docker-compose.yml b/samples/RedundantServer/docker-compose.yml index d8e13112a7..658595580f 100644 --- a/samples/RedundantServer/docker-compose.yml +++ b/samples/RedundantServer/docker-compose.yml @@ -4,19 +4,19 @@ # inline or with --env-file. Three built-in topologies, each has a ready-made env file: # # * active/active, eventual consistency (CRDT gossip) — DEFAULT -# --env-file Applications/RedundantServer/active-active-eventual.env +# --env-file samples/RedundantServer/active-active-eventual.env # * active/active, strong consistency (Raft) -# --env-file Applications/RedundantServer/active-active-strong.env +# --env-file samples/RedundantServer/active-active-strong.env # * active/passive, strong consistency (Raft) -# --env-file Applications/RedundantServer/active-passive.env +# --env-file samples/RedundantServer/active-passive.env # # Three server replicas run in every topology (Raft needs 3 for a fault-tolerant quorum; # active/active eventual works with 2 or 3 — remove server-c for a 2-node run). The # replica count is therefore configurable by dropping/adding server-c. # # The build context is the repository root. Run from the repo root, e.g. active/passive: -# docker compose --env-file Applications/RedundantServer/active-passive.env \ -# -f Applications/RedundantServer/docker-compose.yml up --build +# docker compose --env-file samples/RedundantServer/active-passive.env \ +# -f samples/RedundantServer/docker-compose.yml up --build # # OPC UA endpoints on the host: replica-a opc.tcp://localhost:62543/RedundantServer, # replica-b :62544, replica-c :62545. The Raft transport (6560) and CRDT gossip (4840) @@ -28,7 +28,7 @@ x-server: &server build: context: ../.. - dockerfile: Applications/RedundantServer/Dockerfile + dockerfile: samples/RedundantServer/Dockerfile image: opcua-redundant-server command: ["--port", "62543"] @@ -98,7 +98,7 @@ services: profiles: ["clients", "demo"] build: context: ../.. - dockerfile: Applications/RedundantClient/Dockerfile + dockerfile: samples/RedundantClient/Dockerfile image: opcua-redundant-client deploy: replicas: ${CLIENT_REPLICAS:-1} diff --git a/src/Opc.Ua.Bindings.Https/NugetREADME.md b/src/Opc.Ua.Bindings.Https/NugetREADME.md index ad60429833..390df8cf0a 100644 --- a/src/Opc.Ua.Bindings.Https/NugetREADME.md +++ b/src/Opc.Ua.Bindings.Https/NugetREADME.md @@ -112,10 +112,10 @@ choice and REST is unavailable. ## Additional documentation See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) -and the [Transport Profiles guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/Transports.md) +and the [Transport Profiles guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/Transports.md) for the full URI scheme matrix, the -[REST binding guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/WebApi.md) +[REST binding guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/WebApi.md) for the full REST mapping table / authentication models / hosting modes, the -[Reverse Connect guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/ReverseConnect.md), -and the [Profiles overview](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/Profiles.md). +[Reverse Connect guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/ReverseConnect.md), +and the [Profiles overview](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/Profiles.md). diff --git a/src/Opc.Ua.Bindings.Https/Properties/AssemblyInfo.cs b/src/Opc.Ua.Bindings.Https/Properties/AssemblyInfo.cs index e99e3c55ca..2b9848014c 100644 --- a/src/Opc.Ua.Bindings.Https/Properties/AssemblyInfo.cs +++ b/src/Opc.Ua.Bindings.Https/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Stack/Opc.Ua.Bindings.Https/Properties/AssemblyInfo.cs diff --git a/src/Opc.Ua.Client.ComplexTypes/NugetREADME.md b/src/Opc.Ua.Client.ComplexTypes/NugetREADME.md index 253d8dc068..6ea8444fe6 100644 --- a/src/Opc.Ua.Client.ComplexTypes/NugetREADME.md +++ b/src/Opc.Ua.Client.ComplexTypes/NugetREADME.md @@ -52,6 +52,6 @@ emission depends on `System.Reflection.Emit`. ## Additional documentation See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) -and the [Complex Types guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/ComplexTypes.md) +and the [Complex Types guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/ComplexTypes.md) for the full design (legacy reflection-emit loader vs. the NativeAOT-friendly loader in `Opc.Ua.Client`). diff --git a/src/Opc.Ua.Client.ComplexTypes/Opc.Ua.Client.ComplexTypes.csproj b/src/Opc.Ua.Client.ComplexTypes/Opc.Ua.Client.ComplexTypes.csproj index e622144447..85aa0c454e 100644 --- a/src/Opc.Ua.Client.ComplexTypes/Opc.Ua.Client.ComplexTypes.csproj +++ b/src/Opc.Ua.Client.ComplexTypes/Opc.Ua.Client.ComplexTypes.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/Opc.Ua.Client.ComplexTypes/Properties/AssemblyInfo.cs b/src/Opc.Ua.Client.ComplexTypes/Properties/AssemblyInfo.cs index 6f5a874c8d..2b9848014c 100644 --- a/src/Opc.Ua.Client.ComplexTypes/Properties/AssemblyInfo.cs +++ b/src/Opc.Ua.Client.ComplexTypes/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Libraries/Opc.Ua.Client.ComplexTypes/Properties/AssemblyInfo.cs diff --git a/src/Opc.Ua.Client/NugetREADME.md b/src/Opc.Ua.Client/NugetREADME.md index c7258acb45..4251fcff31 100644 --- a/src/Opc.Ua.Client/NugetREADME.md +++ b/src/Opc.Ua.Client/NugetREADME.md @@ -50,8 +50,8 @@ ManagedSession session = await sessionFactory(ct); ## Additional documentation See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) -and the [Sessions guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/Sessions.md) +and the [Sessions guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/Sessions.md) for the session / subscription / channel-manager design, the -[Reverse Connect guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/ReverseConnect.md), +[Reverse Connect guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/ReverseConnect.md), and the -[Transfer Subscription guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/TransferSubscription.md). +[Transfer Subscription guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/TransferSubscription.md). diff --git a/src/Opc.Ua.Client/Opc.Ua.Client.csproj b/src/Opc.Ua.Client/Opc.Ua.Client.csproj index fec90faf22..54a09c9773 100644 --- a/src/Opc.Ua.Client/Opc.Ua.Client.csproj +++ b/src/Opc.Ua.Client/Opc.Ua.Client.csproj @@ -43,12 +43,12 @@ - - + + - + Analyzer false diff --git a/src/Opc.Ua.Client/Properties/AssemblyInfo.cs b/src/Opc.Ua.Client/Properties/AssemblyInfo.cs index f8daf06ac2..2b9848014c 100644 --- a/src/Opc.Ua.Client/Properties/AssemblyInfo.cs +++ b/src/Opc.Ua.Client/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Libraries/Opc.Ua.Client/Properties/AssemblyInfo.cs diff --git a/src/Opc.Ua.Client/Session/ManagedSessionOptions.cs b/src/Opc.Ua.Client/Session/ManagedSessionOptions.cs index 2620c7097b..e2297eb4d4 100644 --- a/src/Opc.Ua.Client/Session/ManagedSessionOptions.cs +++ b/src/Opc.Ua.Client/Session/ManagedSessionOptions.cs @@ -60,7 +60,7 @@ namespace Opc.Ua.Client /// [Obsolete( "Use IdentityProvider for lazy/refresh-capable identities; the eager Identity setter " + - "cannot refresh on token expiry. See Docs/IdentityProviders.md.")] + "cannot refresh on token expiry. See docs/IdentityProviders.md.")] public IUserIdentity? Identity { get; init; } /// diff --git a/src/Opc.Ua.Configuration/NugetREADME.md b/src/Opc.Ua.Configuration/NugetREADME.md index ed054dd14e..48db8d7ce6 100644 --- a/src/Opc.Ua.Configuration/NugetREADME.md +++ b/src/Opc.Ua.Configuration/NugetREADME.md @@ -49,7 +49,7 @@ await application.StartAsync(new MyServer(telemetry)).ConfigureAwait(false); ## Additional documentation See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) -and the [Dependency Injection guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/DependencyInjection.md) +and the [Dependency Injection guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/DependencyInjection.md) for the application builder surface, and the -[Docs folder](https://github.com/OPCFoundation/UA-.NETStandard/tree/master/Docs) +[documentation folder](https://github.com/OPCFoundation/UA-.NETStandard/tree/master/docs) for the configuration file schema and certificate management. diff --git a/src/Opc.Ua.Configuration/Opc.Ua.Configuration.csproj b/src/Opc.Ua.Configuration/Opc.Ua.Configuration.csproj index 84ef97a1f9..cbc5d50655 100644 --- a/src/Opc.Ua.Configuration/Opc.Ua.Configuration.csproj +++ b/src/Opc.Ua.Configuration/Opc.Ua.Configuration.csproj @@ -19,7 +19,7 @@ $(PackageId).Debug - + diff --git a/src/Opc.Ua.Configuration/Properties/AssemblyInfo.cs b/src/Opc.Ua.Configuration/Properties/AssemblyInfo.cs index a3618c2b42..2b9848014c 100644 --- a/src/Opc.Ua.Configuration/Properties/AssemblyInfo.cs +++ b/src/Opc.Ua.Configuration/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Libraries/Opc.Ua.Configuration/Properties/AssemblyInfo.cs diff --git a/src/Opc.Ua.Core.Diagnostics/Bindings/PcapBindings.cs b/src/Opc.Ua.Core.Diagnostics/Bindings/PcapBindings.cs index fff543024f..dbc3e22148 100644 --- a/src/Opc.Ua.Core.Diagnostics/Bindings/PcapBindings.cs +++ b/src/Opc.Ua.Core.Diagnostics/Bindings/PcapBindings.cs @@ -46,7 +46,7 @@ namespace Opc.Ua.Pcap.Bindings /// CurrentObserver from null to a live sink). Build a /// DefaultCaptureSourceFactory over the returned registry, hand it to /// a CaptureSessionManager, and call StartAsync to begin - /// recording. See Docs/Diagnostics.md for the full non-DI recipe. + /// recording. See docs/Diagnostics.md for the full non-DI recipe. /// public static class PcapBindings { diff --git a/src/Opc.Ua.Core.Diagnostics/DependencyInjection/PcapServiceCollectionExtensions.cs b/src/Opc.Ua.Core.Diagnostics/DependencyInjection/PcapServiceCollectionExtensions.cs index f081d1982a..72a75c8c0e 100644 --- a/src/Opc.Ua.Core.Diagnostics/DependencyInjection/PcapServiceCollectionExtensions.cs +++ b/src/Opc.Ua.Core.Diagnostics/DependencyInjection/PcapServiceCollectionExtensions.cs @@ -483,7 +483,7 @@ namespace Opc.Ua.Pcap.DependencyInjection /// Setting this to true must be paired with at least one /// of the following controls applied at the MCP transport layer: /// authentication (Bearer token or mutual TLS) and audit logging. - /// See Docs/Diagnostics.md for the full security model. + /// See docs/Diagnostics.md for the full security model. /// public bool EnableDiagnosticsTools { get; set; } } diff --git a/src/Opc.Ua.Core.Diagnostics/NugetREADME.md b/src/Opc.Ua.Core.Diagnostics/NugetREADME.md index 8958de7df8..1cbed8322c 100644 --- a/src/Opc.Ua.Core.Diagnostics/NugetREADME.md +++ b/src/Opc.Ua.Core.Diagnostics/NugetREADME.md @@ -58,7 +58,7 @@ IChannelCaptureRegistry registry = // PcapBindings.InstallClient(ClientChannelManager.DefaultChannelBindings, registry); ``` -See the [Diagnostics guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/Diagnostics.md#enabling-pcap-capture-without-dependency-injection) +See the [Diagnostics guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/Diagnostics.md#enabling-pcap-capture-without-dependency-injection) for the full non-DI recipe (server, client, and both directions). ## Target frameworks @@ -68,6 +68,6 @@ for the full non-DI recipe (server, client, and both directions). ## Additional documentation See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) -and the [Diagnostics guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/Diagnostics.md) +and the [Diagnostics guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/Diagnostics.md) for the full design (capture-session lifecycle, key-escrow, audit chaining, replay security model). diff --git a/src/Opc.Ua.Core.Diagnostics/Opc.Ua.Core.Diagnostics.csproj b/src/Opc.Ua.Core.Diagnostics/Opc.Ua.Core.Diagnostics.csproj index 301f295f65..5fa0a676e3 100644 --- a/src/Opc.Ua.Core.Diagnostics/Opc.Ua.Core.Diagnostics.csproj +++ b/src/Opc.Ua.Core.Diagnostics/Opc.Ua.Core.Diagnostics.csproj @@ -40,7 +40,7 @@ - + diff --git a/src/Opc.Ua.Core.Diagnostics/Properties/AssemblyInfo.cs b/src/Opc.Ua.Core.Diagnostics/Properties/AssemblyInfo.cs index d68f53c043..7798c9bd57 100644 --- a/src/Opc.Ua.Core.Diagnostics/Properties/AssemblyInfo.cs +++ b/src/Opc.Ua.Core.Diagnostics/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Stack/Opc.Ua.Core.Diagnostics/Properties/AssemblyInfo.cs diff --git a/src/Opc.Ua.Core.Schema/NugetREADME.md b/src/Opc.Ua.Core.Schema/NugetREADME.md index c7002a929b..11f30d6df7 100644 --- a/src/Opc.Ua.Core.Schema/NugetREADME.md +++ b/src/Opc.Ua.Core.Schema/NugetREADME.md @@ -31,4 +31,4 @@ if (provider.TryGetSchema(typeId, UaSchemaFormat.JsonCompact, UaSchemaScope.Type } ``` -See `Docs/SchemaGeneration.md` in the repository for details. +See `docs/SchemaGeneration.md` in the repository for details. diff --git a/src/Opc.Ua.Core.Schema/Properties/AssemblyInfo.cs b/src/Opc.Ua.Core.Schema/Properties/AssemblyInfo.cs index 5f16d89c13..2b9848014c 100644 --- a/src/Opc.Ua.Core.Schema/Properties/AssemblyInfo.cs +++ b/src/Opc.Ua.Core.Schema/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Stack/Opc.Ua.Core.Schema/Properties/AssemblyInfo.cs diff --git a/src/Opc.Ua.Core.Types/NugetREADME.md b/src/Opc.Ua.Core.Types/NugetREADME.md index 964515a609..b68218ceaa 100644 --- a/src/Opc.Ua.Core.Types/NugetREADME.md +++ b/src/Opc.Ua.Core.Types/NugetREADME.md @@ -24,7 +24,7 @@ pulling in the channel layer. ## Additional documentation See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) -and the [Types migration guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/migrate/2.0.x/types.md) +and the [Types migration guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/migrate/2.0.x/types.md) for the full built-in type design, value representation rules, and the migration notes (especially around the readonly-struct conversion of `NodeId`, `Variant`, `DataValue`, etc. in 2.0). diff --git a/src/Opc.Ua.Core.Types/Opc.Ua.Core.Types.csproj b/src/Opc.Ua.Core.Types/Opc.Ua.Core.Types.csproj index 3beb845448..dff5cdbe7d 100644 --- a/src/Opc.Ua.Core.Types/Opc.Ua.Core.Types.csproj +++ b/src/Opc.Ua.Core.Types/Opc.Ua.Core.Types.csproj @@ -23,7 +23,7 @@ - + Analyzer false diff --git a/src/Opc.Ua.Core.Types/Properties/AssemblyInfo.cs b/src/Opc.Ua.Core.Types/Properties/AssemblyInfo.cs index 5e14e45b0c..2b9848014c 100644 --- a/src/Opc.Ua.Core.Types/Properties/AssemblyInfo.cs +++ b/src/Opc.Ua.Core.Types/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Stack/Opc.Ua.Core.Types/Properties/AssemblyInfo.cs diff --git a/src/Opc.Ua.Core/NugetREADME.md b/src/Opc.Ua.Core/NugetREADME.md index 169cb45541..4a77efb115 100644 --- a/src/Opc.Ua.Core/NugetREADME.md +++ b/src/Opc.Ua.Core/NugetREADME.md @@ -42,6 +42,6 @@ services.AddOpcUa(); ## Additional documentation See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) -and the [Docs folder](https://github.com/OPCFoundation/UA-.NETStandard/tree/master/Docs) +and the [documentation folder](https://github.com/OPCFoundation/UA-.NETStandard/tree/master/docs) for the full design guide, transport profiles, certificate management, and the migration guide from 1.5.378. diff --git a/src/Opc.Ua.Core/Opc.Ua.Core.csproj b/src/Opc.Ua.Core/Opc.Ua.Core.csproj index ec9baa7dc7..62964655b7 100644 --- a/src/Opc.Ua.Core/Opc.Ua.Core.csproj +++ b/src/Opc.Ua.Core/Opc.Ua.Core.csproj @@ -47,11 +47,11 @@ - + Analyzer false - + Analyzer false diff --git a/src/Opc.Ua.Core/Properties/AssemblyInfo.cs b/src/Opc.Ua.Core/Properties/AssemblyInfo.cs index 03a3e56ed9..2b9848014c 100644 --- a/src/Opc.Ua.Core/Properties/AssemblyInfo.cs +++ b/src/Opc.Ua.Core/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Stack/Opc.Ua.Core/Properties/AssemblyInfo.cs diff --git a/src/Opc.Ua.Core/Redundancy/NullRecordProtector.cs b/src/Opc.Ua.Core/Redundancy/NullRecordProtector.cs index 2f5a65dc48..88348663ef 100644 --- a/src/Opc.Ua.Core/Redundancy/NullRecordProtector.cs +++ b/src/Opc.Ua.Core/Redundancy/NullRecordProtector.cs @@ -35,7 +35,7 @@ namespace Opc.Ua.Redundancy /// tests. Production deployments backed by a network store (e.g. Redis) /// must configure an authenticated-encryption protector /// (); see - /// Docs/HighAvailability.md. + /// docs/HighAvailability.md. /// public sealed class NullRecordProtector : IOwnedRecordProtector { diff --git a/src/Opc.Ua.Core/Stack/Tcp/InProcessTransport.cs b/src/Opc.Ua.Core/Stack/Tcp/InProcessTransport.cs index cc651f944d..87700055ed 100644 --- a/src/Opc.Ua.Core/Stack/Tcp/InProcessTransport.cs +++ b/src/Opc.Ua.Core/Stack/Tcp/InProcessTransport.cs @@ -47,7 +47,7 @@ namespace Opc.Ua.Bindings /// The implementation uses only the public OPC UA byte-transport surface /// and therefore doubles as a contract validation for the /// extension point documented in - /// Docs/Transports.md § "Implementing a custom byte transport". + /// docs/Transports.md § "Implementing a custom byte transport". /// public sealed class InProcessTransport : IUaSCByteTransport, IDisposable { diff --git a/src/Opc.Ua.Di.Client/Properties/AssemblyInfo.cs b/src/Opc.Ua.Di.Client/Properties/AssemblyInfo.cs index ff6f1ac301..2b9848014c 100644 --- a/src/Opc.Ua.Di.Client/Properties/AssemblyInfo.cs +++ b/src/Opc.Ua.Di.Client/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Libraries/Opc.Ua.Di.Client/Properties/AssemblyInfo.cs diff --git a/src/Opc.Ua.Di.Server/Properties/AssemblyInfo.cs b/src/Opc.Ua.Di.Server/Properties/AssemblyInfo.cs index f9a0e72d4c..2b9848014c 100644 --- a/src/Opc.Ua.Di.Server/Properties/AssemblyInfo.cs +++ b/src/Opc.Ua.Di.Server/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Libraries/Opc.Ua.Di.Server/Properties/AssemblyInfo.cs diff --git a/src/Opc.Ua.Di/Opc.Ua.Di.csproj b/src/Opc.Ua.Di/Opc.Ua.Di.csproj index 329dd467db..5e4c7e113a 100644 --- a/src/Opc.Ua.Di/Opc.Ua.Di.csproj +++ b/src/Opc.Ua.Di/Opc.Ua.Di.csproj @@ -23,15 +23,15 @@ $(PackageId).Debug - + - + Analyzer false - + v105 diff --git a/src/Opc.Ua.PubSub.Kafka/Properties/AssemblyInfo.cs b/src/Opc.Ua.PubSub.Kafka/Properties/AssemblyInfo.cs index 6fff26d185..7798c9bd57 100644 --- a/src/Opc.Ua.PubSub.Kafka/Properties/AssemblyInfo.cs +++ b/src/Opc.Ua.PubSub.Kafka/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Libraries/Opc.Ua.PubSub.Kafka/Properties/AssemblyInfo.cs diff --git a/src/Opc.Ua.PubSub.Mqtt/NugetREADME.md b/src/Opc.Ua.PubSub.Mqtt/NugetREADME.md index 016c28b67a..d82ffeca3a 100644 --- a/src/Opc.Ua.PubSub.Mqtt/NugetREADME.md +++ b/src/Opc.Ua.PubSub.Mqtt/NugetREADME.md @@ -24,5 +24,5 @@ builder.Services.AddOpcUa() ## Additional documentation -See the [PubSub documentation](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/PubSub.md) +See the [PubSub documentation](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/PubSub.md) for transports, encodings, security, and the fluent / DI API. diff --git a/src/Opc.Ua.PubSub.Mqtt/Opc.Ua.PubSub.Mqtt.csproj b/src/Opc.Ua.PubSub.Mqtt/Opc.Ua.PubSub.Mqtt.csproj index 398bd774bb..50b6c81b44 100644 --- a/src/Opc.Ua.PubSub.Mqtt/Opc.Ua.PubSub.Mqtt.csproj +++ b/src/Opc.Ua.PubSub.Mqtt/Opc.Ua.PubSub.Mqtt.csproj @@ -23,7 +23,7 @@ $(PackageId).Debug - + diff --git a/src/Opc.Ua.WotCon/NugetREADME.md b/src/Opc.Ua.WotCon/NugetREADME.md index da926b4e0e..000ab70d7b 100644 --- a/src/Opc.Ua.WotCon/NugetREADME.md +++ b/src/Opc.Ua.WotCon/NugetREADME.md @@ -22,4 +22,4 @@ configuration servers. See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) and the -[WoT Connectivity guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/WoTConnectivity.md). +[WoT Connectivity guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/WoTConnectivity.md). diff --git a/src/Opc.Ua.WotCon/Opc.Ua.WotCon.csproj b/src/Opc.Ua.WotCon/Opc.Ua.WotCon.csproj index b472e925eb..70db071ff4 100644 --- a/src/Opc.Ua.WotCon/Opc.Ua.WotCon.csproj +++ b/src/Opc.Ua.WotCon/Opc.Ua.WotCon.csproj @@ -23,15 +23,15 @@ $(PackageId).Debug - + - + Analyzer false - + v105 annotations @@ -34,7 +34,7 @@ - + @@ -42,9 +42,9 @@ - - - + + + diff --git a/tests/Opc.Ua.Client.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Client.Tests/Properties/AssemblyInfo.cs index 636264d24c..2b9848014c 100644 --- a/tests/Opc.Ua.Client.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Client.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Client.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Configuration.Tests/Opc.Ua.Configuration.Tests.csproj b/tests/Opc.Ua.Configuration.Tests/Opc.Ua.Configuration.Tests.csproj index 97eb28cde6..1ba4aac101 100644 --- a/tests/Opc.Ua.Configuration.Tests/Opc.Ua.Configuration.Tests.csproj +++ b/tests/Opc.Ua.Configuration.Tests/Opc.Ua.Configuration.Tests.csproj @@ -28,7 +28,7 @@ - + diff --git a/tests/Opc.Ua.Configuration.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Configuration.Tests/Properties/AssemblyInfo.cs index d1462ecf34..2b9848014c 100644 --- a/tests/Opc.Ua.Configuration.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Configuration.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Configuration.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Core.Diagnostics.Tests/McpServerTools/McpServerOptionsTests.cs b/tests/Opc.Ua.Core.Diagnostics.Tests/McpServerTools/McpServerOptionsTests.cs index ec031f5067..2c24c4356f 100644 --- a/tests/Opc.Ua.Core.Diagnostics.Tests/McpServerTools/McpServerOptionsTests.cs +++ b/tests/Opc.Ua.Core.Diagnostics.Tests/McpServerTools/McpServerOptionsTests.cs @@ -238,8 +238,8 @@ namespace Opc.Ua.Pcap.Tests.McpServerTools string configuration = GetBuildConfiguration(); string? assemblyPath = Path.Combine( repoRoot, - "Applications", - "McpServer", + "tools", + "Opc.Ua.Mcp", "bin", configuration, "net10.0", @@ -247,7 +247,7 @@ namespace Opc.Ua.Pcap.Tests.McpServerTools if (!File.Exists(assemblyPath)) { - string binPath = Path.Combine(repoRoot, "Applications", "McpServer", "bin"); + string binPath = Path.Combine(repoRoot, "tools", "Opc.Ua.Mcp", "bin"); assemblyPath = Directory.Exists(binPath) ? Directory.EnumerateFiles(binPath, "Opc.Ua.Mcp.dll", SearchOption.AllDirectories) .FirstOrDefault() diff --git a/tests/Opc.Ua.Core.Diagnostics.Tests/McpServerTools/PacketDecodePathValidationTests.cs b/tests/Opc.Ua.Core.Diagnostics.Tests/McpServerTools/PacketDecodePathValidationTests.cs index 1faedf47ba..6610e01f21 100644 --- a/tests/Opc.Ua.Core.Diagnostics.Tests/McpServerTools/PacketDecodePathValidationTests.cs +++ b/tests/Opc.Ua.Core.Diagnostics.Tests/McpServerTools/PacketDecodePathValidationTests.cs @@ -162,8 +162,8 @@ namespace Opc.Ua.Pcap.Tests.McpServerTools string configuration = GetBuildConfiguration(); string? assemblyPath = Path.Combine( repoRoot, - "Applications", - "McpServer", + "tools", + "Opc.Ua.Mcp", "bin", configuration, "net10.0", @@ -171,7 +171,7 @@ namespace Opc.Ua.Pcap.Tests.McpServerTools if (!File.Exists(assemblyPath)) { - string binPath = Path.Combine(repoRoot, "Applications", "McpServer", "bin"); + string binPath = Path.Combine(repoRoot, "tools", "Opc.Ua.Mcp", "bin"); assemblyPath = Directory.Exists(binPath) ? Directory.EnumerateFiles(binPath, "Opc.Ua.Mcp.dll", SearchOption.AllDirectories) .FirstOrDefault() diff --git a/tests/Opc.Ua.Core.Diagnostics.Tests/Opc.Ua.Core.Diagnostics.Tests.csproj b/tests/Opc.Ua.Core.Diagnostics.Tests/Opc.Ua.Core.Diagnostics.Tests.csproj index 2970fb52f2..37a7a80d5c 100644 --- a/tests/Opc.Ua.Core.Diagnostics.Tests/Opc.Ua.Core.Diagnostics.Tests.csproj +++ b/tests/Opc.Ua.Core.Diagnostics.Tests/Opc.Ua.Core.Diagnostics.Tests.csproj @@ -43,18 +43,18 @@ - - - - - + + + + + - diff --git a/tests/Opc.Ua.Core.Diagnostics.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Core.Diagnostics.Tests/Properties/AssemblyInfo.cs index 6488c18042..7798c9bd57 100644 --- a/tests/Opc.Ua.Core.Diagnostics.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Core.Diagnostics.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Core.Diagnostics.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Core.Encoders.Tests/Opc.Ua.Core.Encoders.Tests.csproj b/tests/Opc.Ua.Core.Encoders.Tests/Opc.Ua.Core.Encoders.Tests.csproj index 89e8ee92f8..6318a7e9d6 100644 --- a/tests/Opc.Ua.Core.Encoders.Tests/Opc.Ua.Core.Encoders.Tests.csproj +++ b/tests/Opc.Ua.Core.Encoders.Tests/Opc.Ua.Core.Encoders.Tests.csproj @@ -31,7 +31,7 @@ - + diff --git a/tests/Opc.Ua.Core.Encoders.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Core.Encoders.Tests/Properties/AssemblyInfo.cs index e8df4ec39d..2b9848014c 100644 --- a/tests/Opc.Ua.Core.Encoders.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Core.Encoders.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Core.Encoders.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Core.Schema.Tests/Opc.Ua.Core.Schema.Tests.csproj b/tests/Opc.Ua.Core.Schema.Tests/Opc.Ua.Core.Schema.Tests.csproj index 87747ca336..8f6d6521b7 100644 --- a/tests/Opc.Ua.Core.Schema.Tests/Opc.Ua.Core.Schema.Tests.csproj +++ b/tests/Opc.Ua.Core.Schema.Tests/Opc.Ua.Core.Schema.Tests.csproj @@ -29,7 +29,7 @@ - - + + diff --git a/tests/Opc.Ua.Core.Schema.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Core.Schema.Tests/Properties/AssemblyInfo.cs index 5603226807..2b9848014c 100644 --- a/tests/Opc.Ua.Core.Schema.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Core.Schema.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Core.Schema.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Core.Security.Tests/Opc.Ua.Core.Security.Tests.csproj b/tests/Opc.Ua.Core.Security.Tests/Opc.Ua.Core.Security.Tests.csproj index 5ade3e68b0..d72f1b02c4 100644 --- a/tests/Opc.Ua.Core.Security.Tests/Opc.Ua.Core.Security.Tests.csproj +++ b/tests/Opc.Ua.Core.Security.Tests/Opc.Ua.Core.Security.Tests.csproj @@ -31,12 +31,12 @@ - - - - - - + + + + + + diff --git a/tests/Opc.Ua.Core.Security.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Core.Security.Tests/Properties/AssemblyInfo.cs index 1ca576d162..2b9848014c 100644 --- a/tests/Opc.Ua.Core.Security.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Core.Security.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Core.Security.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Core.TestFramework/Opc.Ua.Core.TestFramework.csproj b/tests/Opc.Ua.Core.TestFramework/Opc.Ua.Core.TestFramework.csproj index b3cdd4929d..705571ee75 100644 --- a/tests/Opc.Ua.Core.TestFramework/Opc.Ua.Core.TestFramework.csproj +++ b/tests/Opc.Ua.Core.TestFramework/Opc.Ua.Core.TestFramework.csproj @@ -13,10 +13,10 @@ - - - - + + + + \ No newline at end of file diff --git a/tests/Opc.Ua.Core.TestFramework/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Core.TestFramework/Properties/AssemblyInfo.cs index 2cd0853903..2b9848014c 100644 --- a/tests/Opc.Ua.Core.TestFramework/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Core.TestFramework/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Core.TestFramework/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Core.Tests/Opc.Ua.Core.Tests.csproj b/tests/Opc.Ua.Core.Tests/Opc.Ua.Core.Tests.csproj index 06d8b9c51b..2560cb222f 100644 --- a/tests/Opc.Ua.Core.Tests/Opc.Ua.Core.Tests.csproj +++ b/tests/Opc.Ua.Core.Tests/Opc.Ua.Core.Tests.csproj @@ -58,9 +58,9 @@ - - - + + + diff --git a/tests/Opc.Ua.Core.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Core.Tests/Properties/AssemblyInfo.cs index 1ae58ba089..2b9848014c 100644 --- a/tests/Opc.Ua.Core.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Core.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Core.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Core.Tests/Security/Certificates/Assets/Test_chain.pem b/tests/Opc.Ua.Core.Tests/Security/Certificates/Assets/Test_chain.pem index aa7cb5db01..c3d24a8eed 100644 --- a/tests/Opc.Ua.Core.Tests/Security/Certificates/Assets/Test_chain.pem +++ b/tests/Opc.Ua.Core.Tests/Security/Certificates/Assets/Test_chain.pem @@ -55,5 +55,3 @@ vch/oDtFXY1go1wlLy89eCFH7fQxSsYvkMvc78t+mLyxGLpwXI0KENgXvEAvcLKp ptG3iTMwJGRdjQ/SSJmyNfRjlQNT0Jm73v9XeOobra7g4kRzuorpBAt1kVwxbfqB nEAozeUTBWB/nDBXsX/ol+YFFbLtc30w6bUE+400/S2pi5J+ymuQPA== -----END CERTIFICATE----- - -# Repository move history marker: Tests/Opc.Ua.Core.Tests/Security/Certificates/Assets/Test_chain.pem diff --git a/tests/Opc.Ua.Core.Tests/Stack/Transport/InProcessTransportTests.cs b/tests/Opc.Ua.Core.Tests/Stack/Transport/InProcessTransportTests.cs index 8a3bd06c17..12e5ecd14e 100644 --- a/tests/Opc.Ua.Core.Tests/Stack/Transport/InProcessTransportTests.cs +++ b/tests/Opc.Ua.Core.Tests/Stack/Transport/InProcessTransportTests.cs @@ -42,7 +42,7 @@ namespace Opc.Ua.Core.Tests.Stack.Transport /// Contract / smoke tests for the public /// reference implementation of /// shipped from - /// Stack/Opc.Ua.Core/Stack/Tcp/InProcessTransport.cs. + /// src/Opc.Ua.Core/Stack/Tcp/InProcessTransport.cs. /// [TestFixture] [Category("CustomByteTransport")] diff --git a/tests/Opc.Ua.Di.Tests/Opc.Ua.Di.Tests.csproj b/tests/Opc.Ua.Di.Tests/Opc.Ua.Di.Tests.csproj index 53319fae85..7b25d3dfb3 100644 --- a/tests/Opc.Ua.Di.Tests/Opc.Ua.Di.Tests.csproj +++ b/tests/Opc.Ua.Di.Tests/Opc.Ua.Di.Tests.csproj @@ -29,16 +29,16 @@ - - - - - - + + + + + + - diff --git a/tests/Opc.Ua.Features.Tests/Opc.Ua.Features.Tests.csproj b/tests/Opc.Ua.Features.Tests/Opc.Ua.Features.Tests.csproj index 26b63da75c..49648de586 100644 --- a/tests/Opc.Ua.Features.Tests/Opc.Ua.Features.Tests.csproj +++ b/tests/Opc.Ua.Features.Tests/Opc.Ua.Features.Tests.csproj @@ -31,10 +31,10 @@ - - - - + + + + diff --git a/tests/Opc.Ua.Features.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Features.Tests/Properties/AssemblyInfo.cs index 7d361d3aa8..7798c9bd57 100644 --- a/tests/Opc.Ua.Features.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Features.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Features.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Gds.Tests/GdsApplicationDirectoryTests.cs b/tests/Opc.Ua.Gds.Tests/GdsApplicationDirectoryTests.cs index 3cddcc080d..fcffaf632d 100644 --- a/tests/Opc.Ua.Gds.Tests/GdsApplicationDirectoryTests.cs +++ b/tests/Opc.Ua.Gds.Tests/GdsApplicationDirectoryTests.cs @@ -338,7 +338,7 @@ namespace Opc.Ua.Gds.Tests // Re-registering the same URI through UpdateApplication preserves the ApplicationId. // (Calling RegisterApplication again with the same URI yields BadEntryExists by design - // in LinqApplicationsDatabase; see Libraries/Opc.Ua.Gds.Server.Common/ApplicationsDatabase/ + // in LinqApplicationsDatabase; see src/Opc.Ua.Gds.Server.Common/ApplicationsDatabase/ // LinqApplicationsDatabase.cs:129. The OPC UA spec wording for idempotent re-add is // ambiguous; tests that expect "same URI returns same id" go through Update.) appRecord.ApplicationId = appId1; diff --git a/tests/Opc.Ua.Gds.Tests/Opc.Ua.Gds.Tests.csproj b/tests/Opc.Ua.Gds.Tests/Opc.Ua.Gds.Tests.csproj index 9bd2133b42..08d4b712c8 100644 --- a/tests/Opc.Ua.Gds.Tests/Opc.Ua.Gds.Tests.csproj +++ b/tests/Opc.Ua.Gds.Tests/Opc.Ua.Gds.Tests.csproj @@ -33,29 +33,29 @@ - + - - - - - - - - + + + + + + + + - + Analyzer false - + PreserveNewest diff --git a/tests/Opc.Ua.Gds.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Gds.Tests/Properties/AssemblyInfo.cs index 1c9ba980b0..2b9848014c 100644 --- a/tests/Opc.Ua.Gds.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Gds.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Gds.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.History.Tests/Opc.Ua.History.Tests.csproj b/tests/Opc.Ua.History.Tests/Opc.Ua.History.Tests.csproj index 17fb9c2ec6..1570522837 100644 --- a/tests/Opc.Ua.History.Tests/Opc.Ua.History.Tests.csproj +++ b/tests/Opc.Ua.History.Tests/Opc.Ua.History.Tests.csproj @@ -32,10 +32,10 @@ - - - - + + + + diff --git a/tests/Opc.Ua.History.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.History.Tests/Properties/AssemblyInfo.cs index 577b465e73..2b9848014c 100644 --- a/tests/Opc.Ua.History.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.History.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.History.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.InformationModel.Tests/Opc.Ua.InformationModel.Tests.csproj b/tests/Opc.Ua.InformationModel.Tests/Opc.Ua.InformationModel.Tests.csproj index febdfb45fe..5bce40da5c 100644 --- a/tests/Opc.Ua.InformationModel.Tests/Opc.Ua.InformationModel.Tests.csproj +++ b/tests/Opc.Ua.InformationModel.Tests/Opc.Ua.InformationModel.Tests.csproj @@ -31,10 +31,10 @@ - - - - + + + + diff --git a/tests/Opc.Ua.InformationModel.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.InformationModel.Tests/Properties/AssemblyInfo.cs index c2a5025207..2b9848014c 100644 --- a/tests/Opc.Ua.InformationModel.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.InformationModel.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.InformationModel.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Lds.Tests/Opc.Ua.Lds.Tests.csproj b/tests/Opc.Ua.Lds.Tests/Opc.Ua.Lds.Tests.csproj index a4a52791da..e0d79c2ccf 100644 --- a/tests/Opc.Ua.Lds.Tests/Opc.Ua.Lds.Tests.csproj +++ b/tests/Opc.Ua.Lds.Tests/Opc.Ua.Lds.Tests.csproj @@ -31,11 +31,11 @@ - - - - - + + + + + diff --git a/tests/Opc.Ua.Lds.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Lds.Tests/Properties/AssemblyInfo.cs index 3121eb55a9..2b9848014c 100644 --- a/tests/Opc.Ua.Lds.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Lds.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Lds.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.MigrationAnalyzer.Core.Tests/Opc.Ua.MigrationAnalyzer.Core.Tests.csproj b/tests/Opc.Ua.MigrationAnalyzer.Core.Tests/Opc.Ua.MigrationAnalyzer.Core.Tests.csproj index bccfc5b165..7c7067a095 100644 --- a/tests/Opc.Ua.MigrationAnalyzer.Core.Tests/Opc.Ua.MigrationAnalyzer.Core.Tests.csproj +++ b/tests/Opc.Ua.MigrationAnalyzer.Core.Tests/Opc.Ua.MigrationAnalyzer.Core.Tests.csproj @@ -24,10 +24,10 @@ - - - - - + + + + + diff --git a/tests/Opc.Ua.MigrationAnalyzer.Core.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.MigrationAnalyzer.Core.Tests/Properties/AssemblyInfo.cs index fb5b23c442..2b9848014c 100644 --- a/tests/Opc.Ua.MigrationAnalyzer.Core.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.MigrationAnalyzer.Core.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.MigrationAnalyzer.Core.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.MigrationAnalyzer.Tests/Opc.Ua.MigrationAnalyzer.Tests.csproj b/tests/Opc.Ua.MigrationAnalyzer.Tests/Opc.Ua.MigrationAnalyzer.Tests.csproj index 43478a9ba7..44eae22585 100644 --- a/tests/Opc.Ua.MigrationAnalyzer.Tests/Opc.Ua.MigrationAnalyzer.Tests.csproj +++ b/tests/Opc.Ua.MigrationAnalyzer.Tests/Opc.Ua.MigrationAnalyzer.Tests.csproj @@ -31,8 +31,8 @@ - - - + + + diff --git a/tests/Opc.Ua.MigrationAnalyzer.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.MigrationAnalyzer.Tests/Properties/AssemblyInfo.cs index c0533aaa6a..2b9848014c 100644 --- a/tests/Opc.Ua.MigrationAnalyzer.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.MigrationAnalyzer.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.MigrationAnalyzer.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.PubSub.Adapter.Tests/Opc.Ua.PubSub.Adapter.Tests.csproj b/tests/Opc.Ua.PubSub.Adapter.Tests/Opc.Ua.PubSub.Adapter.Tests.csproj index 6dbb082af2..b652b26c66 100644 --- a/tests/Opc.Ua.PubSub.Adapter.Tests/Opc.Ua.PubSub.Adapter.Tests.csproj +++ b/tests/Opc.Ua.PubSub.Adapter.Tests/Opc.Ua.PubSub.Adapter.Tests.csproj @@ -33,13 +33,13 @@ - - - - - - - + + + + + + + diff --git a/tests/Opc.Ua.PubSub.Diagnostics.Tests/Opc.Ua.PubSub.Diagnostics.Tests.csproj b/tests/Opc.Ua.PubSub.Diagnostics.Tests/Opc.Ua.PubSub.Diagnostics.Tests.csproj index 022e0d118c..2d9f8be854 100644 --- a/tests/Opc.Ua.PubSub.Diagnostics.Tests/Opc.Ua.PubSub.Diagnostics.Tests.csproj +++ b/tests/Opc.Ua.PubSub.Diagnostics.Tests/Opc.Ua.PubSub.Diagnostics.Tests.csproj @@ -46,7 +46,7 @@ - - + + diff --git a/tests/Opc.Ua.PubSub.Eth.Tests/Opc.Ua.PubSub.Eth.Tests.csproj b/tests/Opc.Ua.PubSub.Eth.Tests/Opc.Ua.PubSub.Eth.Tests.csproj index 14a1e11aa0..513c614432 100644 --- a/tests/Opc.Ua.PubSub.Eth.Tests/Opc.Ua.PubSub.Eth.Tests.csproj +++ b/tests/Opc.Ua.PubSub.Eth.Tests/Opc.Ua.PubSub.Eth.Tests.csproj @@ -40,9 +40,9 @@ - - - + + + diff --git a/tests/Opc.Ua.PubSub.Kafka.Tests/Opc.Ua.PubSub.Kafka.Tests.csproj b/tests/Opc.Ua.PubSub.Kafka.Tests/Opc.Ua.PubSub.Kafka.Tests.csproj index e3d2da5e62..db39e962b9 100644 --- a/tests/Opc.Ua.PubSub.Kafka.Tests/Opc.Ua.PubSub.Kafka.Tests.csproj +++ b/tests/Opc.Ua.PubSub.Kafka.Tests/Opc.Ua.PubSub.Kafka.Tests.csproj @@ -34,9 +34,9 @@ - - - + + + diff --git a/tests/Opc.Ua.PubSub.Mqtt.Tests/Opc.Ua.PubSub.Mqtt.Tests.csproj b/tests/Opc.Ua.PubSub.Mqtt.Tests/Opc.Ua.PubSub.Mqtt.Tests.csproj index 341ca411e5..24702f7357 100644 --- a/tests/Opc.Ua.PubSub.Mqtt.Tests/Opc.Ua.PubSub.Mqtt.Tests.csproj +++ b/tests/Opc.Ua.PubSub.Mqtt.Tests/Opc.Ua.PubSub.Mqtt.Tests.csproj @@ -54,9 +54,9 @@ - - - + + + diff --git a/tests/Opc.Ua.PubSub.Schema.Tests/Opc.Ua.PubSub.Schema.Tests.csproj b/tests/Opc.Ua.PubSub.Schema.Tests/Opc.Ua.PubSub.Schema.Tests.csproj index 615b36b664..20bb9e9b52 100644 --- a/tests/Opc.Ua.PubSub.Schema.Tests/Opc.Ua.PubSub.Schema.Tests.csproj +++ b/tests/Opc.Ua.PubSub.Schema.Tests/Opc.Ua.PubSub.Schema.Tests.csproj @@ -1,38 +1,38 @@ - - - Exe - $(TestsTargetFrameworks) - Opc.Ua.PubSub.Schema.Tests - enable - false - false - $(NoWarn);CS1591;CA2007;CA2000;CA1014 - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - + + + Exe + $(TestsTargetFrameworks) + Opc.Ua.PubSub.Schema.Tests + enable + false + false + $(NoWarn);CS1591;CA2007;CA2000;CA1014 + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + diff --git a/tests/Opc.Ua.PubSub.Schema.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.PubSub.Schema.Tests/Properties/AssemblyInfo.cs index bb8599a8f4..2b9848014c 100644 --- a/tests/Opc.Ua.PubSub.Schema.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.PubSub.Schema.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.PubSub.Schema.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.PubSub.Server.Tests/Opc.Ua.PubSub.Server.Tests.csproj b/tests/Opc.Ua.PubSub.Server.Tests/Opc.Ua.PubSub.Server.Tests.csproj index c7f0ddd3a6..aa2dcaa3f1 100644 --- a/tests/Opc.Ua.PubSub.Server.Tests/Opc.Ua.PubSub.Server.Tests.csproj +++ b/tests/Opc.Ua.PubSub.Server.Tests/Opc.Ua.PubSub.Server.Tests.csproj @@ -30,11 +30,11 @@ - - - - - + + + + + diff --git a/tests/Opc.Ua.PubSub.Tests/Benchmarks/Baselines/baseline-net10-dry.md b/tests/Opc.Ua.PubSub.Tests/Benchmarks/Baselines/baseline-net10-dry.md index 02c46965ff..55ed2812bb 100644 --- a/tests/Opc.Ua.PubSub.Tests/Benchmarks/Baselines/baseline-net10-dry.md +++ b/tests/Opc.Ua.PubSub.Tests/Benchmarks/Baselines/baseline-net10-dry.md @@ -3,7 +3,7 @@ > **Generated:** Captured by: > > ```pwsh -> dotnet run -c Release -p Tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj -f net10.0 \ +> dotnet run -c Release -p tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj -f net10.0 \ > -- --job dry --filter '*' --inProcess > ``` > diff --git a/tests/Opc.Ua.PubSub.Tests/Benchmarks/BenchmarkContext.cs b/tests/Opc.Ua.PubSub.Tests/Benchmarks/BenchmarkContext.cs index d501bff5f1..cf5d0662e3 100644 --- a/tests/Opc.Ua.PubSub.Tests/Benchmarks/BenchmarkContext.cs +++ b/tests/Opc.Ua.PubSub.Tests/Benchmarks/BenchmarkContext.cs @@ -37,7 +37,7 @@ namespace Opc.Ua.PubSub.Tests.Benchmarks { /// /// Shared helpers used by the benchmark fixtures. Mirrors the - /// helpers in Tests/Opc.Ua.PubSub.Tests/Encoding/* but + /// helpers in tests/Opc.Ua.PubSub.Tests/Encoding/* but /// strips the test-framework dependencies so the benchmark host /// stays small. /// diff --git a/tests/Opc.Ua.PubSub.Tests/Benchmarks/README.md b/tests/Opc.Ua.PubSub.Tests/Benchmarks/README.md index e83a08a583..6bb03d31e0 100644 --- a/tests/Opc.Ua.PubSub.Tests/Benchmarks/README.md +++ b/tests/Opc.Ua.PubSub.Tests/Benchmarks/README.md @@ -11,7 +11,7 @@ once, and emits a summary table that can be diffed for catastrophic regressions: ```pwsh -dotnet run -c Release -p Tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj ` +dotnet run -c Release -p tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj ` -f net10.0 -- --job dry --filter '*' --inProcess ``` @@ -32,22 +32,22 @@ iteration). For real numbers use one of the longer jobs: ```pwsh # ~5 minutes total. Single launch, ~3 iterations per benchmark. -dotnet run -c Release -p Tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj ` +dotnet run -c Release -p tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj ` -f net10.0 -- --job short --filter '*' --inProcess # ~30 minutes total. Multiple launches, ~15 iterations each. -dotnet run -c Release -p Tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj ` +dotnet run -c Release -p tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj ` -f net10.0 -- --job medium --filter '*' --inProcess # ~3 hours total. The defaults — full statistical pipeline. -dotnet run -c Release -p Tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj ` +dotnet run -c Release -p tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj ` -f net10.0 -- --filter '*' --inProcess ``` Filter to one suite to iterate locally: ```pwsh -dotnet run -c Release -p Tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj ` +dotnet run -c Release -p tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj ` -f net10.0 -- --filter '*UadpEncoding*' --inProcess ``` @@ -55,7 +55,7 @@ Output lands under `BenchmarkDotNet.Artifacts/results/` next to the project. To save outside the repo: ```pwsh -dotnet run -c Release -p Tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj ` +dotnet run -c Release -p tests\Opc.Ua.PubSub.Tests\Opc.Ua.PubSub.Tests.csproj ` -f net10.0 -- --filter '*' --inProcess ` --artifacts $env:USERPROFILE\bench-results ``` diff --git a/tests/Opc.Ua.PubSub.Tests/Opc.Ua.PubSub.Tests.csproj b/tests/Opc.Ua.PubSub.Tests/Opc.Ua.PubSub.Tests.csproj index 5a1378dbd5..f265b85c13 100644 --- a/tests/Opc.Ua.PubSub.Tests/Opc.Ua.PubSub.Tests.csproj +++ b/tests/Opc.Ua.PubSub.Tests/Opc.Ua.PubSub.Tests.csproj @@ -33,12 +33,12 @@ - - - - - - + + + + + + diff --git a/tests/Opc.Ua.PubSub.Udp.Tests/Opc.Ua.PubSub.Udp.Tests.csproj b/tests/Opc.Ua.PubSub.Udp.Tests/Opc.Ua.PubSub.Udp.Tests.csproj index c7efc56387..eb9c4b5735 100644 --- a/tests/Opc.Ua.PubSub.Udp.Tests/Opc.Ua.PubSub.Udp.Tests.csproj +++ b/tests/Opc.Ua.PubSub.Udp.Tests/Opc.Ua.PubSub.Udp.Tests.csproj @@ -32,9 +32,9 @@ - - - + + + diff --git a/tests/Opc.Ua.Redundancy.Client.Tests/Opc.Ua.Redundancy.Client.Tests.csproj b/tests/Opc.Ua.Redundancy.Client.Tests/Opc.Ua.Redundancy.Client.Tests.csproj index 54b91b38d2..94607d8d3e 100644 --- a/tests/Opc.Ua.Redundancy.Client.Tests/Opc.Ua.Redundancy.Client.Tests.csproj +++ b/tests/Opc.Ua.Redundancy.Client.Tests/Opc.Ua.Redundancy.Client.Tests.csproj @@ -26,9 +26,9 @@ - - - + + + diff --git a/tests/Opc.Ua.Redundancy.Client.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Redundancy.Client.Tests/Properties/AssemblyInfo.cs index a99df05255..2b9848014c 100644 --- a/tests/Opc.Ua.Redundancy.Client.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Redundancy.Client.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Redundancy.Client.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Redundancy.Kubernetes.Tests/Opc.Ua.Redundancy.Kubernetes.Tests.csproj b/tests/Opc.Ua.Redundancy.Kubernetes.Tests/Opc.Ua.Redundancy.Kubernetes.Tests.csproj index a40c0a292b..dc030deaa9 100644 --- a/tests/Opc.Ua.Redundancy.Kubernetes.Tests/Opc.Ua.Redundancy.Kubernetes.Tests.csproj +++ b/tests/Opc.Ua.Redundancy.Kubernetes.Tests/Opc.Ua.Redundancy.Kubernetes.Tests.csproj @@ -33,9 +33,9 @@ - - - + + + diff --git a/tests/Opc.Ua.Redundancy.Kubernetes.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Redundancy.Kubernetes.Tests/Properties/AssemblyInfo.cs index 50b0619c23..2b9848014c 100644 --- a/tests/Opc.Ua.Redundancy.Kubernetes.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Redundancy.Kubernetes.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Redundancy.Kubernetes.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Redundancy.PubSub.Tests/Opc.Ua.Redundancy.PubSub.Tests.csproj b/tests/Opc.Ua.Redundancy.PubSub.Tests/Opc.Ua.Redundancy.PubSub.Tests.csproj index ad62e765bd..50e028d05e 100644 --- a/tests/Opc.Ua.Redundancy.PubSub.Tests/Opc.Ua.Redundancy.PubSub.Tests.csproj +++ b/tests/Opc.Ua.Redundancy.PubSub.Tests/Opc.Ua.Redundancy.PubSub.Tests.csproj @@ -29,9 +29,9 @@ - - - + + + diff --git a/tests/Opc.Ua.Redundancy.Samples.Tests/Opc.Ua.Redundancy.Samples.Tests.csproj b/tests/Opc.Ua.Redundancy.Samples.Tests/Opc.Ua.Redundancy.Samples.Tests.csproj index 39458d9c32..558994471c 100644 --- a/tests/Opc.Ua.Redundancy.Samples.Tests/Opc.Ua.Redundancy.Samples.Tests.csproj +++ b/tests/Opc.Ua.Redundancy.Samples.Tests/Opc.Ua.Redundancy.Samples.Tests.csproj @@ -24,7 +24,7 @@ --> $(NoWarn);CA1014 $(NoWarn);RCS0056;RCS1166;RCS1174;RCS1229;RCS1047;RCS1077;NUnit2023;NUnit2010;NUnit2045 @@ -61,11 +61,11 @@ into their assemblies directly. --> - - - diff --git a/tests/Opc.Ua.Redundancy.Samples.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Redundancy.Samples.Tests/Properties/AssemblyInfo.cs index 6021fc0252..7798c9bd57 100644 --- a/tests/Opc.Ua.Redundancy.Samples.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Redundancy.Samples.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Redundancy.Samples.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Redundancy.Samples.Tests/SampleAppProcess.cs b/tests/Opc.Ua.Redundancy.Samples.Tests/SampleAppProcess.cs index fa7a63386d..3733f36fd2 100644 --- a/tests/Opc.Ua.Redundancy.Samples.Tests/SampleAppProcess.cs +++ b/tests/Opc.Ua.Redundancy.Samples.Tests/SampleAppProcess.cs @@ -50,7 +50,7 @@ namespace Opc.Ua.Redundancy.Samples.Tests /// starts the sample application. /// /// A short, human-readable name used to prefix captured output. - /// The sample application directory name under Applications/. + /// The sample application directory name under samples/. /// The sample application assembly (dll) name without extension. /// The command-line arguments passed to the sample application. /// Additional environment variables set for the process. @@ -325,7 +325,7 @@ namespace Opc.Ua.Redundancy.Samples.Tests foreach (string config in new[] { configuration, "Release", "Debug" }) { probePaths.Add(Path.Combine( - repoRoot, "Applications", applicationDirectory, "bin", config, "net10.0", assemblyName + ".dll")); + repoRoot, "samples", applicationDirectory, "bin", config, "net10.0", assemblyName + ".dll")); } foreach (string path in probePaths) diff --git a/tests/Opc.Ua.Redundancy.Samples.Tests/SampleHaLongHaulTests.cs b/tests/Opc.Ua.Redundancy.Samples.Tests/SampleHaLongHaulTests.cs index 089e7054de..1616f6d369 100644 --- a/tests/Opc.Ua.Redundancy.Samples.Tests/SampleHaLongHaulTests.cs +++ b/tests/Opc.Ua.Redundancy.Samples.Tests/SampleHaLongHaulTests.cs @@ -48,8 +48,8 @@ namespace Opc.Ua.Redundancy.Samples.Tests /// /// The multi-replica leader-election failover topologies (strong Raft and eventual /// active/active) that require DNS-based endpoint indirection are demonstrated by the - /// docker-compose setups under Applications/RedundantServer and - /// Applications/RedundantClient; these process-level soak tests focus on the + /// docker-compose setups under samples/RedundantServer and + /// samples/RedundantClient; these process-level soak tests focus on the /// failover and data-loss-visibility behavior that runs deterministically inside a CI /// runner without container networking. /// diff --git a/tests/Opc.Ua.Redundancy.Server.Tests/Opc.Ua.Redundancy.Server.Tests.csproj b/tests/Opc.Ua.Redundancy.Server.Tests/Opc.Ua.Redundancy.Server.Tests.csproj index a8285ad49f..3a071ca8c4 100644 --- a/tests/Opc.Ua.Redundancy.Server.Tests/Opc.Ua.Redundancy.Server.Tests.csproj +++ b/tests/Opc.Ua.Redundancy.Server.Tests/Opc.Ua.Redundancy.Server.Tests.csproj @@ -29,12 +29,12 @@ - - - - - - + + + + + + diff --git a/tests/Opc.Ua.Redundancy.Server.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Redundancy.Server.Tests/Properties/AssemblyInfo.cs index 15106f1bf1..2b9848014c 100644 --- a/tests/Opc.Ua.Redundancy.Server.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Redundancy.Server.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Redundancy.Server.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Security.Certificates.Tests/Assets/Test_chain.pem b/tests/Opc.Ua.Security.Certificates.Tests/Assets/Test_chain.pem index 42a410b82b..c3d24a8eed 100644 --- a/tests/Opc.Ua.Security.Certificates.Tests/Assets/Test_chain.pem +++ b/tests/Opc.Ua.Security.Certificates.Tests/Assets/Test_chain.pem @@ -55,5 +55,3 @@ vch/oDtFXY1go1wlLy89eCFH7fQxSsYvkMvc78t+mLyxGLpwXI0KENgXvEAvcLKp ptG3iTMwJGRdjQ/SSJmyNfRjlQNT0Jm73v9XeOobra7g4kRzuorpBAt1kVwxbfqB nEAozeUTBWB/nDBXsX/ol+YFFbLtc30w6bUE+400/S2pi5J+ymuQPA== -----END CERTIFICATE----- - -# Repository move history marker: Tests/Opc.Ua.Security.Certificates.Tests/Assets/Test_chain.pem diff --git a/tests/Opc.Ua.Security.Certificates.Tests/Opc.Ua.Security.Certificates.Tests.csproj b/tests/Opc.Ua.Security.Certificates.Tests/Opc.Ua.Security.Certificates.Tests.csproj index a08d6091f4..08d6ab732b 100644 --- a/tests/Opc.Ua.Security.Certificates.Tests/Opc.Ua.Security.Certificates.Tests.csproj +++ b/tests/Opc.Ua.Security.Certificates.Tests/Opc.Ua.Security.Certificates.Tests.csproj @@ -30,8 +30,8 @@ - - + + diff --git a/tests/Opc.Ua.Security.Certificates.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Security.Certificates.Tests/Properties/AssemblyInfo.cs index 7d3cb450c4..2b9848014c 100644 --- a/tests/Opc.Ua.Security.Certificates.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Security.Certificates.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Security.Certificates.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Server.TestFramework/Opc.Ua.Server.TestFramework.csproj b/tests/Opc.Ua.Server.TestFramework/Opc.Ua.Server.TestFramework.csproj index f659379619..e71f225d16 100644 --- a/tests/Opc.Ua.Server.TestFramework/Opc.Ua.Server.TestFramework.csproj +++ b/tests/Opc.Ua.Server.TestFramework/Opc.Ua.Server.TestFramework.csproj @@ -18,10 +18,10 @@ - - - - + + + + \ No newline at end of file diff --git a/tests/Opc.Ua.Server.TestFramework/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Server.TestFramework/Properties/AssemblyInfo.cs index a919e45065..2b9848014c 100644 --- a/tests/Opc.Ua.Server.TestFramework/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Server.TestFramework/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Server.TestFramework/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Server.Tests/Opc.Ua.Server.Tests.csproj b/tests/Opc.Ua.Server.Tests/Opc.Ua.Server.Tests.csproj index d59123c101..d21101aed3 100644 --- a/tests/Opc.Ua.Server.Tests/Opc.Ua.Server.Tests.csproj +++ b/tests/Opc.Ua.Server.Tests/Opc.Ua.Server.Tests.csproj @@ -46,15 +46,15 @@ - - - - - - - - - + + + + + + + + + diff --git a/tests/Opc.Ua.Server.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Server.Tests/Properties/AssemblyInfo.cs index 6259c1ee5b..2b9848014c 100644 --- a/tests/Opc.Ua.Server.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Server.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Server.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Sessions.Tests/LoadTest.cs b/tests/Opc.Ua.Sessions.Tests/LoadTest.cs index f0c673bb51..505b25308d 100644 --- a/tests/Opc.Ua.Sessions.Tests/LoadTest.cs +++ b/tests/Opc.Ua.Sessions.Tests/LoadTest.cs @@ -812,7 +812,7 @@ namespace Opc.Ua.Sessions.Tests /// Load test the server with a selectable number of concurrent sessions, /// each holding a single slow-publishing subscription that monitors a value. /// This exercises the per-session and per-subscription scaling limits and is - /// the basis for the session-scalability notes in Docs/Benchmarks.md. + /// the basis for the session-scalability notes in docs/Benchmarks.md. /// 500 is the supported baseline; the higher cases (up to 10000) are stress /// cases that push steady-state publish delivery until it starts dropping /// sessions. Because the test is [Explicit], the case to run is diff --git a/tests/Opc.Ua.Sessions.Tests/Opc.Ua.Sessions.Tests.csproj b/tests/Opc.Ua.Sessions.Tests/Opc.Ua.Sessions.Tests.csproj index 66903b3e33..d418d02409 100644 --- a/tests/Opc.Ua.Sessions.Tests/Opc.Ua.Sessions.Tests.csproj +++ b/tests/Opc.Ua.Sessions.Tests/Opc.Ua.Sessions.Tests.csproj @@ -37,13 +37,13 @@ - - - - - - - + + + + + + + diff --git a/tests/Opc.Ua.Sessions.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Sessions.Tests/Properties/AssemblyInfo.cs index 6985a51e57..2b9848014c 100644 --- a/tests/Opc.Ua.Sessions.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Sessions.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Sessions.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Sessions.Tests/SecurityPolicyBenchmarks.cs b/tests/Opc.Ua.Sessions.Tests/SecurityPolicyBenchmarks.cs index 614f6c4e41..034e43e48b 100644 --- a/tests/Opc.Ua.Sessions.Tests/SecurityPolicyBenchmarks.cs +++ b/tests/Opc.Ua.Sessions.Tests/SecurityPolicyBenchmarks.cs @@ -61,7 +61,7 @@ namespace Opc.Ua.Sessions.Tests /// Total: 171 benchmarks (19 methods × 9 security policies - None is excluded) /// /// USAGE: - /// cd Tests/Opc.Ua.Client.Tests + /// cd tests/Opc.Ua.Client.Tests /// /// /// Run all 171 benchmarks (takes ~30+ minutes): diff --git a/tests/Opc.Ua.Sessions.Tests/SharedKestrelHostIntegrationTests.cs b/tests/Opc.Ua.Sessions.Tests/SharedKestrelHostIntegrationTests.cs index aef53503e6..22ade24e4f 100644 --- a/tests/Opc.Ua.Sessions.Tests/SharedKestrelHostIntegrationTests.cs +++ b/tests/Opc.Ua.Sessions.Tests/SharedKestrelHostIntegrationTests.cs @@ -51,7 +51,7 @@ namespace Opc.Ua.Sessions.Tests /// /// The TLS-cert-thumbprint mismatch, ref-count, and path-routing /// behaviours are covered by the registry's unit tests in - /// Tests/Opc.Ua.Core.Tests/Stack/Transport/SharedKestrelHostTests.cs; + /// tests/Opc.Ua.Core.Tests/Stack/Transport/SharedKestrelHostTests.cs; /// this fixture exists to prove the wiring path between /// / /// and the registry is diff --git a/tests/Opc.Ua.SourceGeneration.Core.Tests/Opc.Ua.SourceGeneration.Core.Tests.csproj b/tests/Opc.Ua.SourceGeneration.Core.Tests/Opc.Ua.SourceGeneration.Core.Tests.csproj index 02e150549c..9c63ed4b8b 100644 --- a/tests/Opc.Ua.SourceGeneration.Core.Tests/Opc.Ua.SourceGeneration.Core.Tests.csproj +++ b/tests/Opc.Ua.SourceGeneration.Core.Tests/Opc.Ua.SourceGeneration.Core.Tests.csproj @@ -56,6 +56,6 @@ - + diff --git a/tests/Opc.Ua.SourceGeneration.Core.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.SourceGeneration.Core.Tests/Properties/AssemblyInfo.cs index 567eb6fc07..2b9848014c 100644 --- a/tests/Opc.Ua.SourceGeneration.Core.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.SourceGeneration.Core.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.SourceGeneration.Core.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/TestDataDesign.csv b/tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/TestDataDesign.csv index ca94587bb1..f21636efff 100644 --- a/tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/TestDataDesign.csv +++ b/tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/TestDataDesign.csv @@ -2627,5 +2627,3 @@ MultipleVectors_Encoding_DefaultJson,3626,Object ArrayValueObjectType_MultipleVectorsValue,3627,Variable Data_Static_Array_MultipleVectorsValue,3628,Variable Data_Dynamic_Array_MultipleVectorsValue,3629,Variable - -# Repository move history marker: Tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/TestDataDesign.csv diff --git a/tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/WotConnection.csv b/tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/WotConnection.csv index 53f39706dd..be490cf903 100644 --- a/tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/WotConnection.csv +++ b/tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/WotConnection.csv @@ -170,5 +170,3 @@ WoTAssetConnectionManagementType_WoTAssetName_Placeholder_AssetEndpoint,169,Vari WoTAssetConnectionManagementType_CreateAssetForEndpoint_OutputArguments,170,Variable WoTAssetConnectionManagement_CreateAssetForEndpoint_OutputArguments,171,Variable CreateAssetForEndpointMethodType_OutputArguments,172,Variable - -# Repository move history marker: Tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/WotConnection.csv diff --git a/tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/WotConnection.xml b/tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/WotConnection.xml index 1cc793c6a8..bbdb4cea45 100644 --- a/tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/WotConnection.xml +++ b/tests/Opc.Ua.SourceGeneration.Core.Tests/Resources/WotConnection.xml @@ -186,5 +186,3 @@ - - diff --git a/tests/Opc.Ua.SourceGeneration.Stack.Tests/Opc.Ua.SourceGeneration.Stack.Tests.csproj b/tests/Opc.Ua.SourceGeneration.Stack.Tests/Opc.Ua.SourceGeneration.Stack.Tests.csproj index 7a10f7925b..33da1d7b5d 100644 --- a/tests/Opc.Ua.SourceGeneration.Stack.Tests/Opc.Ua.SourceGeneration.Stack.Tests.csproj +++ b/tests/Opc.Ua.SourceGeneration.Stack.Tests/Opc.Ua.SourceGeneration.Stack.Tests.csproj @@ -31,8 +31,8 @@ $(DefineConstants);NET_STANDARD_TESTS - - + + diff --git a/tests/Opc.Ua.SourceGeneration.Stack.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.SourceGeneration.Stack.Tests/Properties/AssemblyInfo.cs index 67fb456beb..2b9848014c 100644 --- a/tests/Opc.Ua.SourceGeneration.Stack.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.SourceGeneration.Stack.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.SourceGeneration.Stack.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.SourceGeneration.Tests/Opc.Ua.SourceGeneration.Tests.csproj b/tests/Opc.Ua.SourceGeneration.Tests/Opc.Ua.SourceGeneration.Tests.csproj index d8759042e8..bf06ba8e52 100644 --- a/tests/Opc.Ua.SourceGeneration.Tests/Opc.Ua.SourceGeneration.Tests.csproj +++ b/tests/Opc.Ua.SourceGeneration.Tests/Opc.Ua.SourceGeneration.Tests.csproj @@ -30,8 +30,8 @@ $(DefineConstants);NET_STANDARD_TESTS - - + + diff --git a/tests/Opc.Ua.SourceGeneration.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.SourceGeneration.Tests/Properties/AssemblyInfo.cs index f8b32bb7a5..2b9848014c 100644 --- a/tests/Opc.Ua.SourceGeneration.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.SourceGeneration.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.SourceGeneration.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Stress.Tests/Opc.Ua.Stress.Tests.csproj b/tests/Opc.Ua.Stress.Tests/Opc.Ua.Stress.Tests.csproj index a98711c532..96e369c813 100644 --- a/tests/Opc.Ua.Stress.Tests/Opc.Ua.Stress.Tests.csproj +++ b/tests/Opc.Ua.Stress.Tests/Opc.Ua.Stress.Tests.csproj @@ -44,7 +44,7 @@ false enable $(NoWarn);RCS0056;RCS1166;RCS1174;RCS1229;RCS1047;RCS1077;NUnit2023;NUnit2010;NUnit2045 @@ -76,10 +76,10 @@ - - - - + + + + diff --git a/tests/Opc.Ua.Stress.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Stress.Tests/Properties/AssemblyInfo.cs index 6b247db4da..7798c9bd57 100644 --- a/tests/Opc.Ua.Stress.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Stress.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Stress.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Stress.Tests/README.md b/tests/Opc.Ua.Stress.Tests/README.md index 6a20bbc49d..92494e8cc9 100644 --- a/tests/Opc.Ua.Stress.Tests/README.md +++ b/tests/Opc.Ua.Stress.Tests/README.md @@ -1,6 +1,6 @@ # Stress tests -`Tests/Opc.Ua.Stress.Tests` contains subscription stress tests plus layered stress and chaos coverage for +`tests/Opc.Ua.Stress.Tests` contains subscription stress tests plus layered stress and chaos coverage for `IClientChannelManager` and managed-channel reconnect behavior. ## Categories @@ -16,13 +16,13 @@ ```bash # Contract + Integration (default PR CI): -dotnet test Tests/Opc.Ua.Stress.Tests --filter "Category=Contract|Category=Integration" +dotnet test tests/Opc.Ua.Stress.Tests --filter "Category=Contract|Category=Integration" # ChaosTCP (nightly): -dotnet test Tests/Opc.Ua.Stress.Tests --filter "Category=ChaosTCP" --TestRunParameters.Parameter(Seed=) +dotnet test tests/Opc.Ua.Stress.Tests --filter "Category=ChaosTCP" --TestRunParameters.Parameter(Seed=) # Soak (manual): -dotnet test Tests/Opc.Ua.Stress.Tests --filter "Category=Soak" +dotnet test tests/Opc.Ua.Stress.Tests --filter "Category=Soak" ``` Every chaos test prints its seed at start. Re-run a failed chaos case with the printed seed by passing diff --git a/tests/Opc.Ua.Subscriptions.Classic.Tests/Opc.Ua.Subscriptions.Classic.Tests.csproj b/tests/Opc.Ua.Subscriptions.Classic.Tests/Opc.Ua.Subscriptions.Classic.Tests.csproj index d9a32f0d48..2b36fd9809 100644 --- a/tests/Opc.Ua.Subscriptions.Classic.Tests/Opc.Ua.Subscriptions.Classic.Tests.csproj +++ b/tests/Opc.Ua.Subscriptions.Classic.Tests/Opc.Ua.Subscriptions.Classic.Tests.csproj @@ -31,10 +31,10 @@ - - - - + + + + diff --git a/tests/Opc.Ua.Subscriptions.Classic.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Subscriptions.Classic.Tests/Properties/AssemblyInfo.cs index edf695876b..2b9848014c 100644 --- a/tests/Opc.Ua.Subscriptions.Classic.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Subscriptions.Classic.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Subscriptions.Classic.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Subscriptions.Durable.Tests/Opc.Ua.Subscriptions.Durable.Tests.csproj b/tests/Opc.Ua.Subscriptions.Durable.Tests/Opc.Ua.Subscriptions.Durable.Tests.csproj index 4abe8494d3..ed2267541d 100644 --- a/tests/Opc.Ua.Subscriptions.Durable.Tests/Opc.Ua.Subscriptions.Durable.Tests.csproj +++ b/tests/Opc.Ua.Subscriptions.Durable.Tests/Opc.Ua.Subscriptions.Durable.Tests.csproj @@ -31,10 +31,10 @@ - - - - + + + + diff --git a/tests/Opc.Ua.Subscriptions.Durable.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Subscriptions.Durable.Tests/Properties/AssemblyInfo.cs index ef32e1e522..7798c9bd57 100644 --- a/tests/Opc.Ua.Subscriptions.Durable.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Subscriptions.Durable.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Subscriptions.Durable.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Subscriptions.Tests/Opc.Ua.Subscriptions.Tests.csproj b/tests/Opc.Ua.Subscriptions.Tests/Opc.Ua.Subscriptions.Tests.csproj index 7470a633cf..32fc4af855 100644 --- a/tests/Opc.Ua.Subscriptions.Tests/Opc.Ua.Subscriptions.Tests.csproj +++ b/tests/Opc.Ua.Subscriptions.Tests/Opc.Ua.Subscriptions.Tests.csproj @@ -32,10 +32,10 @@ - - - - + + + + diff --git a/tests/Opc.Ua.Subscriptions.Tests/PooledNotificationBenchmarks.cs b/tests/Opc.Ua.Subscriptions.Tests/PooledNotificationBenchmarks.cs index dcf3e09569..71924600f9 100644 --- a/tests/Opc.Ua.Subscriptions.Tests/PooledNotificationBenchmarks.cs +++ b/tests/Opc.Ua.Subscriptions.Tests/PooledNotificationBenchmarks.cs @@ -51,7 +51,7 @@ namespace Opc.Ua.Client.Subscriptions /// /// To run interactively: /// - /// dotnet test Tests/Opc.Ua.Client.Tests --filter "FullyQualifiedName~PooledNotificationBenchmarks" + /// dotnet test tests/Opc.Ua.Client.Tests --filter "FullyQualifiedName~PooledNotificationBenchmarks" /// /// To run as a BenchmarkDotNet harness, invoke the test fixture's /// [GlobalSetup]/[Benchmark] via the standard BDN diff --git a/tests/Opc.Ua.Subscriptions.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Subscriptions.Tests/Properties/AssemblyInfo.cs index 6c612e683e..2b9848014c 100644 --- a/tests/Opc.Ua.Subscriptions.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Subscriptions.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Subscriptions.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Test.Common/Opc.Ua.Test.Common.csproj b/tests/Opc.Ua.Test.Common/Opc.Ua.Test.Common.csproj index ab158b7f7c..0f7151f3ac 100644 --- a/tests/Opc.Ua.Test.Common/Opc.Ua.Test.Common.csproj +++ b/tests/Opc.Ua.Test.Common/Opc.Ua.Test.Common.csproj @@ -11,6 +11,6 @@ - + \ No newline at end of file diff --git a/tests/Opc.Ua.Test.Common/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Test.Common/Properties/AssemblyInfo.cs index 51143ca381..2b9848014c 100644 --- a/tests/Opc.Ua.Test.Common/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Test.Common/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Test.Common/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.Types.Tests/Opc.Ua.Types.Tests.csproj b/tests/Opc.Ua.Types.Tests/Opc.Ua.Types.Tests.csproj index 6d535d3db6..5eb044bfae 100644 --- a/tests/Opc.Ua.Types.Tests/Opc.Ua.Types.Tests.csproj +++ b/tests/Opc.Ua.Types.Tests/Opc.Ua.Types.Tests.csproj @@ -40,11 +40,11 @@ - + - + diff --git a/tests/Opc.Ua.Types.Tests/Properties/AssemblyInfo.cs b/tests/Opc.Ua.Types.Tests/Properties/AssemblyInfo.cs index daa1de1b3f..2b9848014c 100644 --- a/tests/Opc.Ua.Types.Tests/Properties/AssemblyInfo.cs +++ b/tests/Opc.Ua.Types.Tests/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tests/Opc.Ua.Types.Tests/Properties/AssemblyInfo.cs diff --git a/tests/Opc.Ua.WotCon.Tests/Opc.Ua.WotCon.Tests.csproj b/tests/Opc.Ua.WotCon.Tests/Opc.Ua.WotCon.Tests.csproj index 90662ea3a9..ca9d37fdc7 100644 --- a/tests/Opc.Ua.WotCon.Tests/Opc.Ua.WotCon.Tests.csproj +++ b/tests/Opc.Ua.WotCon.Tests/Opc.Ua.WotCon.Tests.csproj @@ -29,12 +29,12 @@ - - - - - - - + + + + + + + diff --git a/tests/benchmarks.cmd b/tests/benchmarks.cmd index 8e6cab9ab8..99b5c7ca84 100644 --- a/tests/benchmarks.cmd +++ b/tests/benchmarks.cmd @@ -14,7 +14,7 @@ set filter=* cd %build_root% -cd Tests\Opc.Ua.Security.Certificates.Tests\ +cd tests\Opc.Ua.Security.Certificates.Tests\ dotnet run -v n --configuration Release --framework %framework% -- --filter %filter% --runtimes %runtimes% cd ..\Opc.Ua.Core.Tests dotnet run -v n --configuration Release --framework %framework% -- --filter %filter% --runtimes %runtimes% diff --git a/tests/codecoverage.cmd b/tests/codecoverage.cmd index 77b35932f5..73b09bc60a 100644 --- a/tests/codecoverage.cmd +++ b/tests/codecoverage.cmd @@ -14,7 +14,7 @@ cd %build_root% rd /s /Q .\CodeCoverage rd /s /Q .\TestResults -dotnet test "UA.slnx" -v n --configuration Release --framework %framework% --collect:"XPlat Code Coverage" --settings ./Tests/coverlet.runsettings.xml --results-directory ./TestResults +dotnet test "UA.slnx" -v n --configuration Release --framework %framework% --collect:"XPlat Code Coverage" --settings ./tests/coverlet.runsettings.xml --results-directory ./TestResults REM ensure latest report tool is installed dotnet tool uninstall -g dotnet-reportgenerator-globaltool diff --git a/tests/codecoverage.sh b/tests/codecoverage.sh index 642686d463..cf65ca159e 100755 --- a/tests/codecoverage.sh +++ b/tests/codecoverage.sh @@ -7,7 +7,7 @@ cd $BUILDROOT rm -r ./CodeCoverage rm -r ./TestResults -dotnet test "UA.slnx" -v n --configuration Release --framework net10.0 --collect:"XPlat Code Coverage" --settings ./Tests/coverlet.runsettings.xml --results-directory ./TestResults +dotnet test "UA.slnx" -v n --configuration Release --framework net10.0 --collect:"XPlat Code Coverage" --settings ./tests/coverlet.runsettings.xml --results-directory ./TestResults # ensure latest report tool is installed dotnet tool uninstall -g dotnet-reportgenerator-globaltool diff --git a/tools/MigrationAnalyzer.slnx b/tools/MigrationAnalyzer.slnx index 9431f60841..993bd3adfa 100644 --- a/tools/MigrationAnalyzer.slnx +++ b/tools/MigrationAnalyzer.slnx @@ -1,7 +1,7 @@ - - + + @@ -12,17 +12,15 @@ - - - - - - - - - - - + + + + + + + + + diff --git a/tools/Opc.Ua.Mcp/Dockerfile b/tools/Opc.Ua.Mcp/Dockerfile index 23ee3b56a3..7c3c061ad7 100644 --- a/tools/Opc.Ua.Mcp/Dockerfile +++ b/tools/Opc.Ua.Mcp/Dockerfile @@ -2,7 +2,7 @@ # # The build context must be the repository ROOT so the project references resolve. # Build directly: -# docker build -f Applications/McpServer/Dockerfile -t opcua-mcp-server . +# docker build -f tools/Opc.Ua.Mcp/Dockerfile -t opcua-mcp-server . # # Defaults to the stdio MCP transport (run with `docker run -i ...`). For the # HTTP/SSE transport run with `--transport sse --port 5100`. @@ -10,7 +10,7 @@ FROM mcr.microsoft.com/dotnet/sdk AS build WORKDIR /src ENV DOTNET_EnableWriteXorExecute=0 COPY . . -RUN dotnet publish "Applications/McpServer/Opc.Ua.Mcp.csproj" \ +RUN dotnet publish "tools/Opc.Ua.Mcp/Opc.Ua.Mcp.csproj" \ -c Release -f net10.0 -p:PublishAot=false -p:CustomTestTarget=net10.0 \ -o /app/publish diff --git a/tools/Opc.Ua.Mcp/McpREADME.md b/tools/Opc.Ua.Mcp/McpREADME.md index ae1d050fe4..faa0913537 100644 --- a/tools/Opc.Ua.Mcp/McpREADME.md +++ b/tools/Opc.Ua.Mcp/McpREADME.md @@ -34,4 +34,4 @@ opcua-mcp --transport sse --port 5100 ## Documentation -See the [full documentation](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/McpServer.md). +See the [full documentation](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/McpServer.md). diff --git a/tools/Opc.Ua.Mcp/Opc.Ua.Mcp.csproj b/tools/Opc.Ua.Mcp/Opc.Ua.Mcp.csproj index 7d8ede6136..e81dee6e3d 100644 --- a/tools/Opc.Ua.Mcp/Opc.Ua.Mcp.csproj +++ b/tools/Opc.Ua.Mcp/Opc.Ua.Mcp.csproj @@ -32,11 +32,11 @@ - - - - - + + + + + diff --git a/tools/Opc.Ua.Mcp/Properties/AssemblyInfo.cs b/tools/Opc.Ua.Mcp/Properties/AssemblyInfo.cs index 92d92e0694..2b9848014c 100644 --- a/tools/Opc.Ua.Mcp/Properties/AssemblyInfo.cs +++ b/tools/Opc.Ua.Mcp/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Applications/McpServer/Properties/AssemblyInfo.cs diff --git a/tools/Opc.Ua.Mcp/README.md b/tools/Opc.Ua.Mcp/README.md index 8681d16bd1..28bbf5ea5d 100644 --- a/tools/Opc.Ua.Mcp/README.md +++ b/tools/Opc.Ua.Mcp/README.md @@ -29,7 +29,7 @@ An MCP (Model Context Protocol) server that exposes OPC UA Part 4 service calls ## Documentation -See the [full documentation](../../Docs/McpServer.md) and [Nuget readme](McpServerREADME.md). +See the [full documentation](../../docs/McpServer.md) and [NuGet readme](McpREADME.md). ### Claude Desktop Configuration @@ -40,7 +40,7 @@ Add to your `claude_desktop_config.json`: "mcpServers": { "opcua": { "command": "dotnet", - "args": ["run", "--project", "/path/to/Applications/McpServer/Opc.Ua.Mcp.csproj"] + "args": ["run", "--project", "/path/to/tools/Opc.Ua.Mcp/Opc.Ua.Mcp.csproj"] } } } @@ -55,7 +55,7 @@ Add to `.vscode/mcp.json`: "servers": { "opcua": { "command": "dotnet", - "args": ["run", "--project", "/path/to/Applications/McpServer/Opc.Ua.Mcp.csproj"] + "args": ["run", "--project", "/path/to/tools/Opc.Ua.Mcp/Opc.Ua.Mcp.csproj"] } } } diff --git a/tools/Opc.Ua.MigrationAnalyzer.CodeFixer/Properties/AssemblyInfo.cs b/tools/Opc.Ua.MigrationAnalyzer.CodeFixer/Properties/AssemblyInfo.cs index f2ed51a57e..2b9848014c 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.CodeFixer/Properties/AssemblyInfo.cs +++ b/tools/Opc.Ua.MigrationAnalyzer.CodeFixer/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tools/Opc.Ua.MigrationAnalyzer.CodeFixer/Properties/AssemblyInfo.cs diff --git a/tools/Opc.Ua.MigrationAnalyzer.Core/Client/Session/Session.cs b/tools/Opc.Ua.MigrationAnalyzer.Core/Client/Session/Session.cs index 77923f77f9..649242034d 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.Core/Client/Session/Session.cs +++ b/tools/Opc.Ua.MigrationAnalyzer.Core/Client/Session/Session.cs @@ -810,7 +810,7 @@ namespace Opc.Ua.Client // ---------------------------------------------------------------- // The following static factory helpers were originally declared as // `public partial class Session` members on the Session type in - // Libraries/Opc.Ua.Client. Cross-assembly partial classes are not + // src/Opc.Ua.Client. Cross-assembly partial classes are not // supported, so when migrated into this shim assembly they are // hosted as static methods on SessionObsolete. Callers that // previously invoked `Session.Create(...)` / `Session.Recreate(...)` diff --git a/tools/Opc.Ua.MigrationAnalyzer.Core/Core/Security/Certificates/CertificateIdentifier.cs b/tools/Opc.Ua.MigrationAnalyzer.Core/Core/Security/Certificates/CertificateIdentifier.cs index 427c65c6d2..b511da8105 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.Core/Core/Security/Certificates/CertificateIdentifier.cs +++ b/tools/Opc.Ua.MigrationAnalyzer.Core/Core/Security/Certificates/CertificateIdentifier.cs @@ -52,7 +52,7 @@ namespace Opc.Ua [Obsolete("CertificateIdentifier.Certificate was removed in 1.6 because " + "resolution requires a registry/telemetry context. " + "Use CertificateIdentifierResolver.ResolveAsync(id, registry, needPrivateKey, applicationUri, telemetry, ct). " + - "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md#ua0018")] + "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md#ua0018")] [OpcUaShim("UA0018")] public X509Certificate2? Certificate => throw new NotSupportedException( diff --git a/tools/Opc.Ua.MigrationAnalyzer.Core/Core/Stack/Types/IUserIdentityTokenHandler.cs b/tools/Opc.Ua.MigrationAnalyzer.Core/Core/Stack/Types/IUserIdentityTokenHandler.cs index acd8b02c43..8c3cb4e345 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.Core/Core/Stack/Types/IUserIdentityTokenHandler.cs +++ b/tools/Opc.Ua.MigrationAnalyzer.Core/Core/Stack/Types/IUserIdentityTokenHandler.cs @@ -51,7 +51,7 @@ namespace Opc.Ua /// . /// [Obsolete("Synchronous Encrypt was removed in 1.6. Use EncryptAsync. " + - "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md#ua0011")] + "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md#ua0011")] [OpcUaShim("UA0011")] public void Encrypt( Certificate receiverCertificate, @@ -82,7 +82,7 @@ namespace Opc.Ua /// . /// [Obsolete("Synchronous Decrypt was removed in 1.6. Use DecryptAsync. " + - "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md#ua0011")] + "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md#ua0011")] [OpcUaShim("UA0011")] public void Decrypt( Certificate certificate, @@ -113,7 +113,7 @@ namespace Opc.Ua /// . /// [Obsolete("Synchronous Sign was removed in 1.6. Use SignAsync. " + - "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md#ua0011")] + "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md#ua0011")] [OpcUaShim("UA0011")] public SignatureData Sign(byte[] dataToSign, string securityPolicyUri) { @@ -128,7 +128,7 @@ namespace Opc.Ua /// for . /// [Obsolete("Synchronous Verify was removed in 1.6. Use VerifyAsync. " + - "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md#ua0011")] + "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md#ua0011")] [OpcUaShim("UA0011")] public bool Verify( byte[] dataToVerify, diff --git a/tools/Opc.Ua.MigrationAnalyzer.Core/Core/Types/Encoders/EncodeableFactory.cs b/tools/Opc.Ua.MigrationAnalyzer.Core/Core/Types/Encoders/EncodeableFactory.cs index 774ca1cd79..d2985b54e9 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.Core/Core/Types/Encoders/EncodeableFactory.cs +++ b/tools/Opc.Ua.MigrationAnalyzer.Core/Core/Types/Encoders/EncodeableFactory.cs @@ -46,7 +46,7 @@ namespace Opc.Ua /// [Obsolete("EncodeableFactory.GlobalFactory was removed in 1.6. " + "Use ServiceMessageContext.GlobalContext.Factory instead. " + - "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md#ua0020")] + "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md#ua0020")] [OpcUaShim("UA0020")] public static IEncodeableFactory GlobalFactory => ServiceMessageContext.GlobalContext.Factory; } diff --git a/tools/Opc.Ua.MigrationAnalyzer.Core/Gds.Client.Common/GlobalDiscoveryServerClient.cs b/tools/Opc.Ua.MigrationAnalyzer.Core/Gds.Client.Common/GlobalDiscoveryServerClient.cs index fa5061852b..6745505ec3 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.Core/Gds.Client.Common/GlobalDiscoveryServerClient.cs +++ b/tools/Opc.Ua.MigrationAnalyzer.Core/Gds.Client.Common/GlobalDiscoveryServerClient.cs @@ -44,7 +44,7 @@ namespace Opc.Ua.Gds.Client /// Registers the application synchronously. /// [Obsolete("Synchronous RegisterApplication was removed in 1.6. Use RegisterApplicationAsync. " + - "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md#ua0015")] + "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md#ua0015")] [OpcUaShim("UA0015")] public NodeId RegisterApplication(ApplicationRecordDataType application) { @@ -58,7 +58,7 @@ namespace Opc.Ua.Gds.Client /// Unregisters the application synchronously. /// [Obsolete("Synchronous UnregisterApplication was removed in 1.6. Use UnregisterApplicationAsync. " + - "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md#ua0015")] + "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md#ua0015")] [OpcUaShim("UA0015")] public void UnregisterApplication(NodeId applicationId) { diff --git a/tools/Opc.Ua.MigrationAnalyzer.Core/Gds.Client.Common/LocalDiscoveryServerClient.cs b/tools/Opc.Ua.MigrationAnalyzer.Core/Gds.Client.Common/LocalDiscoveryServerClient.cs index 12e94330df..c45bfd769c 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.Core/Gds.Client.Common/LocalDiscoveryServerClient.cs +++ b/tools/Opc.Ua.MigrationAnalyzer.Core/Gds.Client.Common/LocalDiscoveryServerClient.cs @@ -47,7 +47,7 @@ namespace Opc.Ua.Gds.Client /// classic Begin/End APM pattern. /// [Obsolete("BeginFindServers/EndFindServers were removed in 1.6. Use FindServersAsync. " + - "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md#ua0015")] + "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md#ua0015")] [OpcUaShim("UA0015")] public IAsyncResult BeginFindServers(AsyncCallback? callback, object? state) { @@ -79,7 +79,7 @@ namespace Opc.Ua.Gds.Client /// Completes the asynchronous FindServers call. /// [Obsolete("BeginFindServers/EndFindServers were removed in 1.6. Use FindServersAsync. " + - "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md#ua0015")] + "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md#ua0015")] [OpcUaShim("UA0015")] public ArrayOf EndFindServers(IAsyncResult result) { diff --git a/tools/Opc.Ua.MigrationAnalyzer.Core/Gds.Client.Common/ServerPushConfigurationClient.cs b/tools/Opc.Ua.MigrationAnalyzer.Core/Gds.Client.Common/ServerPushConfigurationClient.cs index f6c666c3e4..2bc416251a 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.Core/Gds.Client.Common/ServerPushConfigurationClient.cs +++ b/tools/Opc.Ua.MigrationAnalyzer.Core/Gds.Client.Common/ServerPushConfigurationClient.cs @@ -44,7 +44,7 @@ namespace Opc.Ua.Gds.Client /// Applies the staged configuration changes synchronously. /// [Obsolete("Synchronous ApplyChanges was removed in 1.6. Use ApplyChangesAsync. " + - "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md#ua0015")] + "See https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md#ua0015")] [OpcUaShim("UA0015")] public void ApplyChanges() { diff --git a/tools/Opc.Ua.MigrationAnalyzer.Core/Opc.Ua.MigrationAnalyzer.Core.csproj b/tools/Opc.Ua.MigrationAnalyzer.Core/Opc.Ua.MigrationAnalyzer.Core.csproj index 3c14459204..9b3c71471c 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.Core/Opc.Ua.MigrationAnalyzer.Core.csproj +++ b/tools/Opc.Ua.MigrationAnalyzer.Core/Opc.Ua.MigrationAnalyzer.Core.csproj @@ -14,12 +14,12 @@ $(NoWarn);CS0618;CS0419 - - - - - - + + + + + + diff --git a/tools/Opc.Ua.MigrationAnalyzer.Core/Properties/AssemblyInfo.cs b/tools/Opc.Ua.MigrationAnalyzer.Core/Properties/AssemblyInfo.cs index 7fcbb77748..2b9848014c 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.Core/Properties/AssemblyInfo.cs +++ b/tools/Opc.Ua.MigrationAnalyzer.Core/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tools/Opc.Ua.MigrationAnalyzer.Core/Properties/AssemblyInfo.cs diff --git a/tools/Opc.Ua.MigrationAnalyzer.Core/readme.md b/tools/Opc.Ua.MigrationAnalyzer.Core/readme.md index 252f9d037d..634e9f8a4a 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.Core/readme.md +++ b/tools/Opc.Ua.MigrationAnalyzer.Core/readme.md @@ -7,7 +7,7 @@ analyzer + code-fixer + source-generator DLLs. ## Directory convention -Source files mirror the project layout in `Stack/` and `Libraries/`, +Source files mirror the project layout in `src/` and `src/`, flattened directly under the project root. For example: | Source project | Shim path | @@ -21,7 +21,7 @@ flattened directly under the project root. For example: Within each top-level directory the file path mirrors the directory layout of the source project — e.g. the obsolete extension surface around -`Stack/Opc.Ua.Core/Stack/Server/ServerBase.cs` lives at +`src/Opc.Ua.Core/Stack/Server/ServerBase.cs` lives at `Core/Stack/Server/ServerBase.cs`. ## Conventions diff --git a/tools/Opc.Ua.MigrationAnalyzer.Generator/Diagnostics/GeneratorDiagnostics.cs b/tools/Opc.Ua.MigrationAnalyzer.Generator/Diagnostics/GeneratorDiagnostics.cs index 395405338c..f534890eb3 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.Generator/Diagnostics/GeneratorDiagnostics.cs +++ b/tools/Opc.Ua.MigrationAnalyzer.Generator/Diagnostics/GeneratorDiagnostics.cs @@ -66,7 +66,7 @@ namespace Opc.Ua.MigrationAnalyzer.Generator "wrapper the consumer references. When the element type can't be " + "uniquely resolved in the consumer compilation, the shim cannot be " + "synthesized.", - helpLinkUri: "https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/MigrationGuide.md#collection-type-migration", + helpLinkUri: "https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/MigrationGuide.md#collection-type-migration", customTags: WellKnownDiagnosticTags.Telemetry); } } diff --git a/tools/Opc.Ua.MigrationAnalyzer.Generator/Properties/AssemblyInfo.cs b/tools/Opc.Ua.MigrationAnalyzer.Generator/Properties/AssemblyInfo.cs index 1a21712f03..2b9848014c 100644 --- a/tools/Opc.Ua.MigrationAnalyzer.Generator/Properties/AssemblyInfo.cs +++ b/tools/Opc.Ua.MigrationAnalyzer.Generator/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tools/Opc.Ua.MigrationAnalyzer.Generator/Properties/AssemblyInfo.cs diff --git a/tools/Opc.Ua.MigrationAnalyzer/AnalyzerReleases.Shipped.md b/tools/Opc.Ua.MigrationAnalyzer/AnalyzerReleases.Shipped.md index c39b1675e2..5ccc9f037f 100644 --- a/tools/Opc.Ua.MigrationAnalyzer/AnalyzerReleases.Shipped.md +++ b/tools/Opc.Ua.MigrationAnalyzer/AnalyzerReleases.Shipped.md @@ -1,4 +1,2 @@ ; Shipped analyzer releases ; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md - - diff --git a/tools/Opc.Ua.MigrationAnalyzer/AnalyzerReleases.Unshipped.md b/tools/Opc.Ua.MigrationAnalyzer/AnalyzerReleases.Unshipped.md index bc3aff3046..3d953bc42c 100644 --- a/tools/Opc.Ua.MigrationAnalyzer/AnalyzerReleases.Unshipped.md +++ b/tools/Opc.Ua.MigrationAnalyzer/AnalyzerReleases.Unshipped.md @@ -22,6 +22,6 @@ UA0015 | Migration | Info | Replace sync/APM members on GDS/LDS clients wit UA0018 | Migration | Info | Replace `CertificateIdentifier.Certificate` getter with `CertificateIdentifierResolver.ResolveAsync(...)`. UA0019 | Migration | Warning | Replace `new DataValue(StatusCode[, ts])` with `DataValue.FromStatusCode(...)`. UA0020 | Migration | Warning | Replace `EncodeableFactory.GlobalFactory` / `EncodeableFactory.Create()` with `ServiceMessageContext.Factory` / `Fork()`. -UA0021 | Migration | Info | Replace `CertificateValidator` / `CertificateValidationEventArgs` with the 1.6 `ICertificateManager` / `ICertificateValidatorEx` / `CertificateValidationResult` pipeline. See Docs/migrate/2.0.x/certificates.md. +UA0021 | Migration | Info | Replace `CertificateValidator` / `CertificateValidationEventArgs` with the 1.6 `ICertificateManager` / `ICertificateValidatorEx` / `CertificateValidationResult` pipeline. See docs/migrate/2.0.x/certificates.md. UA0022 | Migration | Warning | Replace `ApplicationConfiguration.CertificateValidator` / `ServerBase.CertificateValidator` property access with `.CertificateManager`. -UA0023 | Migration | Warning | Replace the legacy 1.04 PubSub top-level types (`UaPubSubApplication`, `IUaPubSubConnection`, `UaPubSubConnection`, `IUaPublisher`, `UaPublisher`, `IUaPubSubDataStore`, `UaPubSubDataStore`, `UaPubSubConfigurator`) with the new `IPubSubApplication` / `PubSubApplicationBuilder` surface (or `AddPubSub()` / `AddUdpTransport()` / `AddMqttTransport()` on `IOpcUaBuilder`). See Docs/migrate/2.0.x/pubsub.md. +UA0023 | Migration | Warning | Replace the legacy 1.04 PubSub top-level types (`UaPubSubApplication`, `IUaPubSubConnection`, `UaPubSubConnection`, `IUaPublisher`, `UaPublisher`, `IUaPubSubDataStore`, `UaPubSubDataStore`, `UaPubSubConfigurator`) with the new `IPubSubApplication` / `PubSubApplicationBuilder` surface (or `AddPubSub()` / `AddUdpTransport()` / `AddMqttTransport()` on `IOpcUaBuilder`). See docs/migrate/2.0.x/pubsub.md. diff --git a/tools/Opc.Ua.MigrationAnalyzer/Analyzers/UA0021CertificateValidatorRenameAnalyzer.cs b/tools/Opc.Ua.MigrationAnalyzer/Analyzers/UA0021CertificateValidatorRenameAnalyzer.cs index b51404e325..381ed98cf5 100644 --- a/tools/Opc.Ua.MigrationAnalyzer/Analyzers/UA0021CertificateValidatorRenameAnalyzer.cs +++ b/tools/Opc.Ua.MigrationAnalyzer/Analyzers/UA0021CertificateValidatorRenameAnalyzer.cs @@ -51,7 +51,7 @@ namespace Opc.Ua.MigrationAnalyzer.Analyzers /// CertificateValidationResult, with per-error accept logic moving to /// CertificateValidationOptions.AcceptError). There is therefore no accompanying /// code-fix provider; consumers must perform the migration manually using - /// Docs/migrate/2.0.x/certificates.md#certificatemanager-and-segregated-interfaces. + /// docs/migrate/2.0.x/certificates.md#certificatemanager-and-segregated-interfaces. /// /// Detection strategy: /// diff --git a/tools/Opc.Ua.MigrationAnalyzer/Diagnostics/DiagnosticDescriptors.cs b/tools/Opc.Ua.MigrationAnalyzer/Diagnostics/DiagnosticDescriptors.cs index 5b18462ce0..9773c8a866 100644 --- a/tools/Opc.Ua.MigrationAnalyzer/Diagnostics/DiagnosticDescriptors.cs +++ b/tools/Opc.Ua.MigrationAnalyzer/Diagnostics/DiagnosticDescriptors.cs @@ -179,7 +179,7 @@ namespace Opc.Ua.MigrationAnalyzer.Diagnostics public static readonly DiagnosticDescriptor UA0021_CertificateValidatorRename = Create( DiagnosticIds.UA0021, "CertificateValidator / CertificateValidationEventArgs renamed in 1.6", - "'{0}' was replaced in 1.6 by the new CertificateManager pipeline (ICertificateManager / ICertificateValidatorEx / CertificateValidationResult). The migration is structural (event-based -> async result + AcceptError callback) — see Docs/migrate/2.0.x/certificates.md.", + "'{0}' was replaced in 1.6 by the new CertificateManager pipeline (ICertificateManager / ICertificateValidatorEx / CertificateValidationResult). The migration is structural (event-based -> async result + AcceptError callback) — see docs/migrate/2.0.x/certificates.md.", DiagnosticSeverity.Info, "The CertificateValidator class and CertificateValidationEventArgs were removed in 1.6. The new ICertificateManager (composed of ICertificateValidatorEx, ICertificateRegistry, ICertificateTrustListManager, ICertificateLifecycle) replaces them; per-error accept logic moves from the CertificateValidation event to CertificateValidationOptions.AcceptError. This rule is diagnostic-only because the migration changes the API shape (no mechanical rename)."); @@ -188,13 +188,13 @@ namespace Opc.Ua.MigrationAnalyzer.Diagnostics "ApplicationConfiguration.CertificateValidator / ServerBase.CertificateValidator renamed in 2.0", "'{0}.CertificateValidator' was removed in 2.0 — use '{0}.CertificateManager' (type ICertificateManager)", DiagnosticSeverity.Warning, - "Configure via CertificateManagerFactory.Create(securityConfiguration, telemetry, ...). See Docs/migrate/2.0.x/certificates.md."); + "Configure via CertificateManagerFactory.Create(securityConfiguration, telemetry, ...). See docs/migrate/2.0.x/certificates.md."); public static readonly DiagnosticDescriptor UA0023_PubSubTopLevelObsolete = Create( DiagnosticIds.UA0023, "PubSub top-level types replaced in 2.0", "'{0}' was replaced in 2.0 — use the new IPubSubApplication / PubSubApplicationBuilder surface (or AddPubSub() / AddUdpTransport() / AddMqttTransport() on IOpcUaBuilder)", DiagnosticSeverity.Warning, - "The 1.04-era PubSub top-level types (UaPubSubApplication, IUaPubSubConnection, IUaPublisher, UaPubSubDataStore, UaPubSubConfigurator) ship as obsolete shims in 2.0; the new top-level surface uses provider-model abstractions wired via PubSubApplicationBuilder or Microsoft.Extensions.DependencyInjection extensions (Docs/migrate/2.0.x/pubsub.md)."); + "The 1.04-era PubSub top-level types (UaPubSubApplication, IUaPubSubConnection, IUaPublisher, UaPubSubDataStore, UaPubSubConfigurator) ship as obsolete shims in 2.0; the new top-level surface uses provider-model abstractions wired via PubSubApplicationBuilder or Microsoft.Extensions.DependencyInjection extensions (docs/migrate/2.0.x/pubsub.md)."); } } diff --git a/tools/Opc.Ua.MigrationAnalyzer/Diagnostics/DiagnosticIds.cs b/tools/Opc.Ua.MigrationAnalyzer/Diagnostics/DiagnosticIds.cs index 52731146fe..0051dc0384 100644 --- a/tools/Opc.Ua.MigrationAnalyzer/Diagnostics/DiagnosticIds.cs +++ b/tools/Opc.Ua.MigrationAnalyzer/Diagnostics/DiagnosticIds.cs @@ -63,12 +63,12 @@ namespace Opc.Ua.MigrationAnalyzer.Diagnostics /// /// Base URL for per-rule help. Each rule appends its own ID. - /// Points at the 2.0 migration index (`Docs/migrate/2.0.x/README.md`) + /// Points at the 2.0 migration index (`docs/migrate/2.0.x/README.md`) /// which contains the symptom → sub-doc table that maps every UA00xx /// rule to the sub-doc that documents it in detail. /// public const string HelpLinkUriBase = - "https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/migrate/2.0.x/README.md#"; + "https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/migrate/2.0.x/README.md#"; /// Compose a per-rule help URL anchored at the rule ID. public static string HelpLinkFor(string id) diff --git a/tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md b/tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md index 843e5bdd3a..c3886bef10 100644 --- a/tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md +++ b/tools/Opc.Ua.MigrationAnalyzer/NugetREADME.md @@ -8,7 +8,7 @@ ships **three Roslyn components + a runtime shim** to help migrate from OPC UA - a Roslyn **analyzer + code-fixer** set (`UA0001`–`UA0022`) that flags every pattern covered by the - [2.0 migration guide](../../Docs/migrate/2.0.x/README.md) + [2.0 migration guide](../../docs/migrate/2.0.x/README.md) and, where safe, applies the fix automatically; - a Roslyn **source generator** (`Opc.Ua.MigrationAnalyzer.Generator.dll`) that emits per-consumer `internal sealed [Obsolete] class Collection : List` diff --git a/tools/Opc.Ua.MigrationAnalyzer/Properties/AssemblyInfo.cs b/tools/Opc.Ua.MigrationAnalyzer/Properties/AssemblyInfo.cs index 11a7ae7318..2b9848014c 100644 --- a/tools/Opc.Ua.MigrationAnalyzer/Properties/AssemblyInfo.cs +++ b/tools/Opc.Ua.MigrationAnalyzer/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tools/Opc.Ua.MigrationAnalyzer/Properties/AssemblyInfo.cs diff --git a/tools/Opc.Ua.SourceGeneration.Core/NugetREADME.md b/tools/Opc.Ua.SourceGeneration.Core/NugetREADME.md index db385dea90..58cd293aab 100644 --- a/tools/Opc.Ua.SourceGeneration.Core/NugetREADME.md +++ b/tools/Opc.Ua.SourceGeneration.Core/NugetREADME.md @@ -21,4 +21,4 @@ pipeline. See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) and the -[Source-Generated Data Types guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/SourceGeneratedDataTypes.md). +[Source-Generated Data Types guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/SourceGeneratedDataTypes.md). diff --git a/tools/Opc.Ua.SourceGeneration.Core/Opc.Ua.SourceGeneration.Core.csproj b/tools/Opc.Ua.SourceGeneration.Core/Opc.Ua.SourceGeneration.Core.csproj index d2573f5ff2..0fe4821dc4 100644 --- a/tools/Opc.Ua.SourceGeneration.Core/Opc.Ua.SourceGeneration.Core.csproj +++ b/tools/Opc.Ua.SourceGeneration.Core/Opc.Ua.SourceGeneration.Core.csproj @@ -31,7 +31,7 @@ $(PackageId).Debug - + diff --git a/tools/Opc.Ua.SourceGeneration.Core/Properties/AssemblyInfo.cs b/tools/Opc.Ua.SourceGeneration.Core/Properties/AssemblyInfo.cs index a089e5c3be..2b9848014c 100644 --- a/tools/Opc.Ua.SourceGeneration.Core/Properties/AssemblyInfo.cs +++ b/tools/Opc.Ua.SourceGeneration.Core/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tools/Opc.Ua.SourceGeneration.Core/Properties/AssemblyInfo.cs diff --git a/tools/Opc.Ua.SourceGeneration.Stack/AnalyzerReleases.Shipped.md b/tools/Opc.Ua.SourceGeneration.Stack/AnalyzerReleases.Shipped.md index e9091ba1ee..5ccc9f037f 100644 --- a/tools/Opc.Ua.SourceGeneration.Stack/AnalyzerReleases.Shipped.md +++ b/tools/Opc.Ua.SourceGeneration.Stack/AnalyzerReleases.Shipped.md @@ -1,4 +1,2 @@ ; Shipped analyzer releases ; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md - - diff --git a/tools/Opc.Ua.SourceGeneration.Stack/NugetREADME.md b/tools/Opc.Ua.SourceGeneration.Stack/NugetREADME.md index 6ce6d1af63..0a64455d34 100644 --- a/tools/Opc.Ua.SourceGeneration.Stack/NugetREADME.md +++ b/tools/Opc.Ua.SourceGeneration.Stack/NugetREADME.md @@ -23,4 +23,4 @@ just reference `Opc.Ua.Core` and `Opc.Ua.Types`). See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) and the -[Source-Generated Data Types guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/SourceGeneratedDataTypes.md). +[Source-Generated Data Types guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/SourceGeneratedDataTypes.md). diff --git a/tools/Opc.Ua.SourceGeneration.Stack/Properties/AssemblyInfo.cs b/tools/Opc.Ua.SourceGeneration.Stack/Properties/AssemblyInfo.cs index 32f78ff19f..2b9848014c 100644 --- a/tools/Opc.Ua.SourceGeneration.Stack/Properties/AssemblyInfo.cs +++ b/tools/Opc.Ua.SourceGeneration.Stack/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tools/Opc.Ua.SourceGeneration.Stack/Properties/AssemblyInfo.cs diff --git a/tools/Opc.Ua.SourceGeneration.Tester/Opc.Ua.SourceGeneration.Tester.csproj b/tools/Opc.Ua.SourceGeneration.Tester/Opc.Ua.SourceGeneration.Tester.csproj index 07dc2def8f..a180f1666e 100644 --- a/tools/Opc.Ua.SourceGeneration.Tester/Opc.Ua.SourceGeneration.Tester.csproj +++ b/tools/Opc.Ua.SourceGeneration.Tester/Opc.Ua.SourceGeneration.Tester.csproj @@ -12,19 +12,19 @@ - + PreserveNewest Resources\%(Filename)%(Extension) - + PreserveNewest Resources\%(Filename)%(Extension) - + PreserveNewest Resources\%(Filename)%(Extension) - + PreserveNewest Resources\%(Filename)%(Extension) diff --git a/tools/Opc.Ua.SourceGeneration/AnalyzerReleases.Shipped.md b/tools/Opc.Ua.SourceGeneration/AnalyzerReleases.Shipped.md index 225e8d4b8e..5ccc9f037f 100644 --- a/tools/Opc.Ua.SourceGeneration/AnalyzerReleases.Shipped.md +++ b/tools/Opc.Ua.SourceGeneration/AnalyzerReleases.Shipped.md @@ -1,4 +1,2 @@ ; Shipped analyzer releases ; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md - - diff --git a/tools/Opc.Ua.SourceGeneration/NugetREADME.md b/tools/Opc.Ua.SourceGeneration/NugetREADME.md index 575acbcef2..c2ab0103c0 100644 --- a/tools/Opc.Ua.SourceGeneration/NugetREADME.md +++ b/tools/Opc.Ua.SourceGeneration/NugetREADME.md @@ -36,4 +36,4 @@ Reference the generator as an **analyzer** (no runtime dependency): See the [main repository README](https://github.com/OPCFoundation/UA-.NETStandard) and the -[Source-Generated Data Types guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/Docs/SourceGeneratedDataTypes.md). +[Source-Generated Data Types guide](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/SourceGeneratedDataTypes.md). diff --git a/tools/Opc.Ua.SourceGeneration/Properties/AssemblyInfo.cs b/tools/Opc.Ua.SourceGeneration/Properties/AssemblyInfo.cs index 7e58308019..2b9848014c 100644 --- a/tools/Opc.Ua.SourceGeneration/Properties/AssemblyInfo.cs +++ b/tools/Opc.Ua.SourceGeneration/Properties/AssemblyInfo.cs @@ -30,5 +30,3 @@ using System; [assembly: CLSCompliant(false)] - -// Repository move history marker: Tools/Opc.Ua.SourceGeneration/Properties/AssemblyInfo.cs diff --git a/tools/Opc.Ua.SourceGeneration/readme.md b/tools/Opc.Ua.SourceGeneration/readme.md index 40233270f2..b05069f545 100644 --- a/tools/Opc.Ua.SourceGeneration/readme.md +++ b/tools/Opc.Ua.SourceGeneration/readme.md @@ -62,7 +62,7 @@ Per-file behaviour is controlled with `AdditionalFiles` metadata: ``` -See [Source-Generated NodeManagers](../../Docs/SourceGeneratedNodeManagers.md#mixing-modeldesign-and-nodeset2-in-one-project) +See [Source-Generated NodeManagers](../../docs/SourceGeneratedNodeManagers.md#mixing-modeldesign-and-nodeset2-in-one-project) for the end-to-end pattern. ## Using DataType Generators @@ -141,7 +141,7 @@ so downstream models can simply derive from them. For an ergonomic, `System.IO`-style async client built on top of the generated `FileTypeClient` / `FileDirectoryTypeClient` / `TemporaryFileTransferTypeClient` proxies, see -[`Docs/FileSystemClient.md`](../../Docs/FileSystemClient.md). +[`docs/FileSystemClient.md`](../../docs/FileSystemClient.md). ### Output namespace diff --git a/tools/SourceGeneration.slnx b/tools/SourceGeneration.slnx index 659a85f8dd..cf7a1ca639 100644 --- a/tools/SourceGeneration.slnx +++ b/tools/SourceGeneration.slnx @@ -1,7 +1,7 @@ - - + + @@ -17,11 +17,11 @@ - + - - + +