chore(build): OpcUaClient driver/browser on ITelemetryContext ctors, TreatWarningsAsErrors on remaining src projects (#621 #606)
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<RootNamespace>ZB.MOM.WW.OtOpcUa.Client.CLI</RootNamespace>
|
<RootNamespace>ZB.MOM.WW.OtOpcUa.Client.CLI</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -237,10 +237,8 @@ public sealed class OpcUaClientService : IOpcUaClientService
|
|||||||
hasChildren));
|
hasChildren));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (continuationPoint != null && continuationPoint.Length > 0)
|
if (continuationPoint is not { Length: > 0 } pending) break;
|
||||||
(continuationPoint, references) = await _session.BrowseNextAsync(continuationPoint, ct);
|
(continuationPoint, references) = await _session.BrowseNextAsync(pending, ct);
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<RootNamespace>ZB.MOM.WW.OtOpcUa.Client.Shared</RootNamespace>
|
<RootNamespace>ZB.MOM.WW.OtOpcUa.Client.Shared</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<RootNamespace>ZB.MOM.WW.OtOpcUa.Client.UI</RootNamespace>
|
<RootNamespace>ZB.MOM.WW.OtOpcUa.Client.UI</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
+11
-7
@@ -124,17 +124,13 @@ public sealed class OpcUaClientDriverBrowser : IDriverBrowser
|
|||||||
/// <param name="ct">Cancellation token for the configuration build.</param>
|
/// <param name="ct">Cancellation token for the configuration build.</param>
|
||||||
private static async Task<ApplicationConfiguration> BuildBrowseAppConfigurationAsync(CancellationToken ct)
|
private static async Task<ApplicationConfiguration> BuildBrowseAppConfigurationAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
// The default ctor is obsolete in favour of the ITelemetryContext overload; suppress
|
// The ITelemetryContext overload is the non-obsolete ctor; an empty builder keeps SDK
|
||||||
// locally rather than plumbing a telemetry context all the way through — the browser
|
// internals off any logging provider.
|
||||||
// emits no per-request telemetry of its own and the SDK's internal fallback is fine
|
var app = new ApplicationInstance(BrowseTelemetry.Context)
|
||||||
// for a transient picker session (mirrors the runtime driver's same suppression).
|
|
||||||
#pragma warning disable CS0618
|
|
||||||
var app = new ApplicationInstance
|
|
||||||
{
|
{
|
||||||
ApplicationName = "OtOpcUa AdminUI Browse",
|
ApplicationName = "OtOpcUa AdminUI Browse",
|
||||||
ApplicationType = ApplicationType.Client,
|
ApplicationType = ApplicationType.Client,
|
||||||
};
|
};
|
||||||
#pragma warning restore CS0618
|
|
||||||
|
|
||||||
var pkiRoot = Path.Combine(
|
var pkiRoot = Path.Combine(
|
||||||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||||
@@ -245,3 +241,11 @@ public sealed class OpcUaClientDriverBrowser : IDriverBrowser
|
|||||||
private static string ShortName(string uri) =>
|
private static string ShortName(string uri) =>
|
||||||
uri?.Substring(uri.LastIndexOf('#') + 1) ?? "(null)";
|
uri?.Substring(uri.LastIndexOf('#') + 1) ?? "(null)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static class BrowseTelemetry
|
||||||
|
{
|
||||||
|
private static readonly Lazy<Opc.Ua.ITelemetryContext> Instance = new(() => Opc.Ua.DefaultTelemetry.Create(_ => { }));
|
||||||
|
|
||||||
|
/// <summary>Gets the shared telemetry context.</summary>
|
||||||
|
public static Opc.Ua.ITelemetryContext Context => Instance.Value;
|
||||||
|
}
|
||||||
|
|||||||
@@ -294,17 +294,13 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task<ApplicationConfiguration> BuildApplicationConfigurationAsync(CancellationToken ct)
|
private async Task<ApplicationConfiguration> BuildApplicationConfigurationAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
// The default ctor is obsolete in favour of the ITelemetryContext overload; suppress
|
// The ITelemetryContext overload is the non-obsolete ctor; an empty builder keeps SDK
|
||||||
// locally rather than plumbing a telemetry context all the way through the driver
|
// internals off any logging provider (mirrors Client.Shared's ClientTelemetry).
|
||||||
// surface — the driver emits no per-request telemetry of its own and the SDK's
|
var app = new ApplicationInstance(SdkTelemetry.Context)
|
||||||
// internal fallback is fine for a gateway use case.
|
|
||||||
#pragma warning disable CS0618
|
|
||||||
var app = new ApplicationInstance
|
|
||||||
{
|
{
|
||||||
ApplicationName = _options.SessionName,
|
ApplicationName = _options.SessionName,
|
||||||
ApplicationType = ApplicationType.Client,
|
ApplicationType = ApplicationType.Client,
|
||||||
};
|
};
|
||||||
#pragma warning restore CS0618
|
|
||||||
|
|
||||||
var pkiRoot = Path.Combine(
|
var pkiRoot = Path.Combine(
|
||||||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||||
@@ -472,7 +468,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
|||||||
endpointConfig.OperationTimeout = (int)_options.Timeout.TotalMilliseconds;
|
endpointConfig.OperationTimeout = (int)_options.Timeout.TotalMilliseconds;
|
||||||
var endpoint = new ConfiguredEndpoint(null, selected, endpointConfig);
|
var endpoint = new ConfiguredEndpoint(null, selected, endpointConfig);
|
||||||
|
|
||||||
var session = await new DefaultSessionFactory(telemetry: null!).CreateAsync(
|
var session = await new DefaultSessionFactory(SdkTelemetry.Context).CreateAsync(
|
||||||
appConfig,
|
appConfig,
|
||||||
endpoint,
|
endpoint,
|
||||||
false, // updateBeforeConnect
|
false, // updateBeforeConnect
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using Opc.Ua;
|
||||||
|
|
||||||
|
namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The one <see cref="ITelemetryContext" /> the driver hands the SDK's non-obsolete (telemetry-taking)
|
||||||
|
/// overloads. An empty builder keeps SDK internals off any logging provider (mirrors Client.Shared's
|
||||||
|
/// <c>ClientTelemetry</c>).
|
||||||
|
/// </summary>
|
||||||
|
internal static class SdkTelemetry
|
||||||
|
{
|
||||||
|
private static readonly Lazy<ITelemetryContext> Instance = new(() => DefaultTelemetry.Create(_ => { }));
|
||||||
|
|
||||||
|
/// <summary>Gets the shared telemetry context.</summary>
|
||||||
|
public static ITelemetryContext Context => Instance.Value;
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
(which on .NET Framework 4.7.2 and .NET 6+ equally resolves netstandard2.0). -->
|
(which on .NET Framework 4.7.2 and .NET 6+ equally resolves netstandard2.0). -->
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<IsRoslynComponent>true</IsRoslynComponent>
|
<IsRoslynComponent>true</IsRoslynComponent>
|
||||||
|
|||||||
+2
-2
@@ -37,7 +37,7 @@ public sealed class OpcUaClientContinuationPointReleaseTests
|
|||||||
private static Mock<ISession> BuildCancellingSessionMock()
|
private static Mock<ISession> BuildCancellingSessionMock()
|
||||||
{
|
{
|
||||||
var mock = new Mock<ISession>(MockBehavior.Loose);
|
var mock = new Mock<ISession>(MockBehavior.Loose);
|
||||||
mock.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext());
|
mock.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext(ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.SdkTelemetry.Context));
|
||||||
mock.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable());
|
mock.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable());
|
||||||
|
|
||||||
// BrowseAsync — return one Object child plus a non-empty continuation point so
|
// BrowseAsync — return one Object child plus a non-empty continuation point so
|
||||||
@@ -148,7 +148,7 @@ public sealed class OpcUaClientContinuationPointReleaseTests
|
|||||||
using var drv = new OpcUaClientDriver(new OpcUaClientDriverOptions(), "opcua-cp-norelease");
|
using var drv = new OpcUaClientDriver(new OpcUaClientDriverOptions(), "opcua-cp-norelease");
|
||||||
|
|
||||||
var mock = new Mock<ISession>(MockBehavior.Loose);
|
var mock = new Mock<ISession>(MockBehavior.Loose);
|
||||||
mock.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext());
|
mock.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext(ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.SdkTelemetry.Context));
|
||||||
mock.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable());
|
mock.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable());
|
||||||
|
|
||||||
// BrowseAsync — return a result with a continuation point so the loop is entered.
|
// BrowseAsync — return a result with a continuation point so the loop is entered.
|
||||||
|
|||||||
+1
-1
@@ -53,7 +53,7 @@ public sealed class OpcUaClientStaleSessionRaceTests
|
|||||||
// MessageContext. This getter is read in the driver's synchronous prologue (before the
|
// MessageContext. This getter is read in the driver's synchronous prologue (before the
|
||||||
// gate), so signalling here proves the pre-gate capture path has run.
|
// gate), so signalling here proves the pre-gate capture path has run.
|
||||||
mock.SetupGet(s => s.MessageContext)
|
mock.SetupGet(s => s.MessageContext)
|
||||||
.Returns(new ServiceMessageContext())
|
.Returns(new ServiceMessageContext(ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.SdkTelemetry.Context))
|
||||||
.Callback(() => prologueReached?.TrySetResult());
|
.Callback(() => prologueReached?.TrySetResult());
|
||||||
mock.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable());
|
mock.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable());
|
||||||
mock.Setup(s => s.HistoryReadAsync(
|
mock.Setup(s => s.HistoryReadAsync(
|
||||||
|
|||||||
Reference in New Issue
Block a user