/* ======================================================================== * 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 { /// /// Factory that creates the GDS ApplicationsNodeManager for the reference server. /// The node manager automatically wires handlers for: /// /// CertificateDirectoryType (Part 12 §7.6) /// KeyCredentialServiceType (Part 12 §8) /// AuthorizationServiceType (Part 12 §9) /// /// public sealed class GdsNodeManagerFactory : IAsyncNodeManagerFactory { private readonly GlobalDiscoveryServerConfiguration m_gdsConfiguration; /// /// Initializes a new instance of the class. /// /// The GDS configuration. public GdsNodeManagerFactory(GlobalDiscoveryServerConfiguration gdsConfiguration) { m_gdsConfiguration = gdsConfiguration; } /// public ArrayOf NamespacesUris => [ "http://opcfoundation.org/UA/GDS/applications/", Opc.Ua.Gds.Namespaces.OpcUaGds ]; /// public ValueTask 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( new ApplicationsNodeManager( server, configuration, database, database, new CertificateGroup(server.Telemetry), autoApprove: true)); #pragma warning restore CA2000 } } }