fix: initialize SDK telemetry and preserve ByteString boundaries

This commit is contained in:
Joseph Doherty
2026-11-10 10:11:07 -05:00
parent 52a4476b21
commit f9a006dab4
3 changed files with 7 additions and 4 deletions
@@ -173,6 +173,7 @@ public sealed class OpcUaApplicationHost : IAsyncDisposable
private readonly ILogger<OpcUaApplicationHost> _logger;
private ApplicationInstance? _application;
private StandardServer? _server;
private readonly ITelemetryContext _telemetry = DefaultTelemetry.Create(_ => { });
private readonly List<IUserTokenAuthenticator> _identityAuthenticators = [];
/// <summary>Initializes a new instance of the OPC UA application host.</summary>
@@ -205,7 +206,7 @@ public sealed class OpcUaApplicationHost : IAsyncDisposable
// 1.5.378 requires an ITelemetryContext on the ApplicationInstance ctor (the parameterless ctor
// is obsolete). DefaultTelemetry.Create wires the SDK's internal logging; an empty builder keeps
// the SDK's trace off our ILogger (the host keeps its own _logger) — sufficient for the bootstrap.
_application = new ApplicationInstance(DefaultTelemetry.Create(_ => { }))
_application = new ApplicationInstance(_telemetry)
{
ApplicationName = _options.ApplicationName,
ApplicationType = ApplicationType.Server,
@@ -487,7 +488,7 @@ public sealed class OpcUaApplicationHost : IAsyncDisposable
serverConfig.SecurityPolicies = BuildSecurityPolicies(_options.EnabledSecurityProfiles).ToArray();
serverConfig.UserTokenPolicies = BuildUserTokenPolicies(_options.AllowAnonymous).ToArray();
var config = new ApplicationConfiguration
var config = new ApplicationConfiguration(_telemetry)
{
ApplicationName = _options.ApplicationName,
ApplicationUri = _options.ApplicationUri,
@@ -6574,7 +6574,7 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
return leaf switch
{
// BaseEventType/EventId is a ByteString — encode the driver-specific string id as UTF-8 bytes.
"EventId" => new Variant(System.Text.Encoding.UTF8.GetBytes(evt.EventId ?? string.Empty)),
"EventId" => Variant.From(ByteString.From(System.Text.Encoding.UTF8.GetBytes(evt.EventId ?? string.Empty))),
"EventType" => new Variant(eventType),
"SourceName" => evt.SourceName is null ? Variant.Null : new Variant(evt.SourceName),
"SourceNode" => SourceNodeOf(evt) is { } source ? new Variant(source) : Variant.Null,
@@ -14,7 +14,9 @@ internal static class SdkValueBoundary
if (array.Rank != 1) throw new ArgumentException("Only one-dimensional values are supported.", nameof(value));
value = array.Clone();
}
if (byteArray && value is byte[] bytes) return Variant.From((ArrayOf<byte>)bytes);
if (value is byte[] bytes) return byteArray
? Variant.From((ArrayOf<byte>)bytes)
: Variant.From(ByteString.From(bytes));
if (VariantHelper.TryCastFrom(value, out var variant)) return variant;
throw new ArgumentException("Unsupported OPC UA value type.", nameof(value));
}