Files
Copilot 5dd53ff9d0 [Server] Migrate all NodeManagers to AsyncCustomNodeManager (#3817)
Migrate all NodeManagers to IAsyncNodeManager
Add more Tests

## Related Issues

Issue linking is handled automatically by the system.

## Types of changes

What types of changes does your code introduce?  
_Put an `x` in the boxes that apply. You can also fill these out after
creating the PR._

- [x] Bugfix (non-breaking change which fixes an issue)
- [ ] Enhancement (non-breaking change which adds functionality)
- [ ] Test enhancement (non-breaking change to increase test coverage)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected, requires version increase of
Nuget packages)
- [ ] Documentation Update (if none of the other choices apply)

## Checklist

_Put an `x` in the boxes that apply. You can also fill these out after
creating the PR. If you're unsure about any of them, don't hesitate to
ask. We're here to help! This is simply a reminder of what we are going
to look for before merging your code._

- [ ] I have read the
[CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md)
doc.
- [ ] I have signed the
[CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf).
- [x] I ran tests locally with my changes, all passed.
- [x] I fixed all failing tests in the CI pipelines. 
- [x] I fixed all introduced issues with CodeQL and LGTM.
- [ ] I have added tests that prove my fix is effective or that my
feature works and increased code coverage.
- [ ] I have added necessary documentation (if appropriate).
- [ ] Any dependent changes have been merged and published in downstream
modules.

## Further comments

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: romanett <romanett98@gmail.com>
Co-authored-by: Marc Schier <marcschier@users.noreply.github.com>
2026-05-28 20:24:22 +02:00

112 lines
4.5 KiB
C#

/* ========================================================================
* Copyright (c) 2005-2025 The OPC Foundation, Inc. All rights reserved.
*
* OPC Foundation MIT License 1.00
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* The complete license agreement can be found here:
* http://opcfoundation.org/License/MIT/1.00/
* ======================================================================*/
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Opc.Ua;
using Opc.Ua.Gds;
using Opc.Ua.Gds.Server;
using Opc.Ua.Gds.Server.Database.Linq;
using Opc.Ua.Server;
namespace Quickstarts.ReferenceServer
{
/// <summary>
/// Factory that creates the GDS ApplicationsNodeManager for the reference server.
/// The node manager automatically wires handlers for:
/// <list type="bullet">
/// <item><description>CertificateDirectoryType (Part 12 §7.6)</description></item>
/// <item><description>KeyCredentialServiceType (Part 12 §8)</description></item>
/// <item><description>AuthorizationServiceType (Part 12 §9)</description></item>
/// </list>
/// </summary>
public sealed class GdsNodeManagerFactory : IAsyncNodeManagerFactory
{
private readonly GlobalDiscoveryServerConfiguration m_gdsConfiguration;
/// <summary>
/// Initializes a new instance of the <see cref="GdsNodeManagerFactory"/> class.
/// </summary>
/// <param name="gdsConfiguration">The GDS configuration.</param>
public GdsNodeManagerFactory(GlobalDiscoveryServerConfiguration gdsConfiguration)
{
m_gdsConfiguration = gdsConfiguration;
}
/// <inheritdoc/>
public ArrayOf<string> NamespacesUris =>
[
"http://opcfoundation.org/UA/GDS/applications/",
Opc.Ua.Gds.Namespaces.OpcUaGds
];
/// <inheritdoc/>
public ValueTask<IAsyncNodeManager> CreateAsync(
IServerInternal server,
ApplicationConfiguration configuration,
CancellationToken cancellationToken = default)
{
// Ensure the GDS data types are registered in the message context
if (!server.MessageContext.Factory.ContainsEncodeableType(
Opc.Ua.Gds.DataTypeIds.ApplicationRecordDataType))
{
server.MessageContext.Factory.Builder
.AddOpcUaGds()
.Commit();
}
string? databaseStorePath = Utils.ReplaceSpecialFolderNames(
m_gdsConfiguration.DatabaseStorePath);
// Ensure the directory exists
string? databaseDir = Path.GetDirectoryName(databaseStorePath);
if (!string.IsNullOrEmpty(databaseDir))
{
Directory.CreateDirectory(databaseDir);
}
LinqApplicationsDatabase database = string.IsNullOrEmpty(databaseDir)
? new LinqApplicationsDatabase()
: JsonApplicationsDatabase.Load(databaseStorePath!);
#pragma warning disable CA2000 // Ownership is transferred to the server via returned node manager instance.
return new ValueTask<IAsyncNodeManager>(
new ApplicationsNodeManager(
server,
configuration,
database,
database,
new CertificateGroup(server.Telemetry),
autoApprove: true));
#pragma warning restore CA2000
}
}
}