/* ======================================================================== * 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; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using Opc.Ua.Security.Certificates; namespace Opc.Ua.Client { /// /// Manages a session with a server. /// public static class SessionObsolete { extension(ISession session) { /// /// Gets the TickCount in ms of the last keep alive based on /// . /// [Obsolete("Use LastKeepAliveTimestamp + TimeProvider.GetElapsedTime. " + "LastKeepAliveTickCount is a 32-bit value that wraps every ~49.7 days.")] public int LastKeepAliveTickCount => unchecked((int)(session.LastKeepAliveTimestamp * 1000L / TimeProvider.System.TimestampFrequency)); } /// /// Reconnects to the server after a network failure. /// [Obsolete("Use ReconnectAsync instead.")] public static void Reconnect(this ISession session) { session.ReconnectAsync().GetAwaiter().GetResult(); } /// /// Reconnects to the server after a network failure using a waiting connection. /// [Obsolete("Use ReconnectAsync instead.")] public static void Reconnect(this ISession session, ITransportWaitingConnection connection) { session.ReconnectAsync(connection).GetAwaiter().GetResult(); } /// /// Reconnects to the server using a new channel. /// [Obsolete("Use ReconnectAsync instead.")] public static void Reconnect(this ISession session, ITransportChannel channel) { session.ReconnectAsync(channel).GetAwaiter().GetResult(); } /// /// Updates the local copy of the server's namespace uri and server uri tables. /// [Obsolete("Use FetchNamespaceTablesAsync instead.")] public static void FetchNamespaceTables(this ISession session) { session.FetchNamespaceTablesAsync().GetAwaiter().GetResult(); } /// /// Updates the cache with the type and its subtypes. /// [Obsolete("Use FetchTypeTreeAsync instead.")] public static void FetchTypeTree(this ISession session, ExpandedNodeId typeId) { session.FetchTypeTreeAsync(typeId).GetAwaiter().GetResult(); } /// /// Updates the cache with the types and its subtypes. /// [Obsolete("Use FetchTypeTreeAsync instead.")] public static void FetchTypeTree(this ISession session, ArrayOf typeIds) { session.FetchTypeTreeAsync(typeIds).GetAwaiter().GetResult(); } /// /// Returns the available encodings for a node /// [Obsolete("Use ReadAvailableEncodingsAsync instead.")] public static ArrayOf ReadAvailableEncodings( this ISession session, NodeId variableId) { return session.ReadAvailableEncodingsAsync(variableId).GetAwaiter().GetResult(); } /// /// Returns the data description for the encoding. /// [Obsolete("Use FindDataDescriptionAsync instead.")] public static ReferenceDescription FindDataDescription( this ISession session, NodeId encodingId) { return session.FindDataDescriptionAsync(encodingId).GetAwaiter().GetResult(); } /// /// Reads the values for the node attributes and returns a node object. /// [Obsolete("Use ReadNodeAsync instead.")] public static Node ReadNode(this ISession session, NodeId nodeId) { return session.ReadNodeAsync(nodeId).GetAwaiter().GetResult(); } /// /// Reads the values for the node attributes and returns a node object. /// [Obsolete("Use ReadNodeAsync instead.")] public static Node ReadNode( this ISession session, NodeId nodeId, NodeClass nodeClass, bool optionalAttributes = true) { return session.ReadNodeAsync( nodeId, nodeClass, optionalAttributes).GetAwaiter().GetResult(); } /// /// Reads the values for the node attributes and returns a node object. /// [Obsolete("Use ReadNodesAsync instead.")] public static void ReadNodes( this ISession session, ArrayOf nodeIds, out ArrayOf nodeCollection, out ArrayOf errors, bool optionalAttributes = false) { (nodeCollection, errors) = session.ReadNodesAsync( nodeIds, optionalAttributes).GetAwaiter().GetResult(); } /// /// Reads the values for the node attributes and returns a node object collection. /// /// /// If the nodeclass for the nodes in nodeIdCollection is already known, /// and passed as nodeClass, reads only values of required attributes. /// Otherwise NodeClass.Unspecified should be used. /// [Obsolete("Use ReadNodesAsync instead.")] public static void ReadNodes( this ISession session, ArrayOf nodeIds, NodeClass nodeClass, out ArrayOf nodeCollection, out ArrayOf errors, bool optionalAttributes = false) { (nodeCollection, errors) = session.ReadNodesAsync( nodeIds, nodeClass, optionalAttributes).GetAwaiter().GetResult(); } /// /// Reads the value for a node. /// [Obsolete("Use ReadValueAsync instead.")] public static DataValue ReadValue(this ISession session, NodeId nodeId) { return session.ReadValueAsync(nodeId).GetAwaiter().GetResult(); } /// /// Reads the values for a set of variables. /// [Obsolete("Use ReadValuesAsync returning Variant Array")] public static async ValueTask<( ArrayOf, ArrayOf )> ReadValuesAsync( this ISessionClient session, ArrayOf variableIds, ArrayOf expectedTypes, CancellationToken ct = default) { (ArrayOf dataValues, ArrayOf errorValues) = await session.ReadValuesAsync(variableIds, ct).ConfigureAwait(false); var errors = new ServiceResult[errorValues.Count]; object?[] values = new object?[dataValues.Count]; for (int ii = 0; ii < variableIds.Count; ii++) { object? value = dataValues[ii].Value; // extract the body from extension objects. if (value is ExtensionObject extension && extension.TryGetValue(out IEncodeable? encodeable)) { value = encodeable; } // check expected type. Type? expectedType = expectedTypes[ii]; if (expectedType != null && !expectedType.IsInstanceOfType(value)) { errors[ii] = ServiceResult.Create( StatusCodes.BadTypeMismatch, "Value {0} does not have expected type: {1}.", value!, expectedType.Name); continue; } // suitable value found. errors[ii] = errorValues[ii]; values[ii] = value; } return (values, errors); } /// /// Reads the value for a node an checks that it is the specified type. /// /// [Obsolete("Use ReadValueAsync instead.")] public static object? ReadValue(this ISession session, NodeId nodeId, Type? expectedType) { DataValue dataValue = session.ReadValueAsync(nodeId).GetAwaiter().GetResult(); object? value = dataValue.Value; if (expectedType != null) { if (dataValue.WrappedValue.TryGetValue(out ExtensionObject extension) && extension.TryGetValue(out IEncodeable? encodeable)) { value = encodeable; } if (!expectedType.IsInstanceOfType(value)) { throw ServiceResultException.Create( StatusCodes.BadTypeMismatch, "Server returned value unexpected type: {0}", value != null ? value.GetType().Name : "(null)"); } } return value; } /// /// Reads the values for a node collection. Returns diagnostic errors. /// [Obsolete("Use ReadValuesAsync instead.")] public static void ReadValues( this ISession session, ArrayOf nodeIds, out ArrayOf values, out ArrayOf errors) { (values, errors) = session.ReadValuesAsync( nodeIds).GetAwaiter().GetResult(); } /// /// Reads a byte string which is too large for the (server side) encoder to handle. /// /// [Obsolete("Use ReadByteStringInChunksAsync instead.")] public static ByteString ReadByteStringInChunks( this ISession session, NodeId nodeId) { return session.ReadByteStringInChunksAsync(nodeId).GetAwaiter().GetResult(); } /// /// Fetches all references for the specified node. /// [Obsolete("Use FetchReferencesAsync instead.")] public static ArrayOf FetchReferences( this ISession session, NodeId nodeId) { return session.FetchReferencesAsync(nodeId).GetAwaiter().GetResult(); } /// /// Fetches all references for the specified nodes. /// [Obsolete("Use FetchReferencesAsync instead.")] public static void FetchReferences( this ISession session, ArrayOf nodeIds, out ArrayOf> referenceDescriptions, out ArrayOf errors) { (referenceDescriptions, errors) = session.FetchReferencesAsync( nodeIds).GetAwaiter().GetResult(); } /// /// Establishes a session with the server. /// [Obsolete("Use OpenAsync instead.")] public static void Open( this ISession session, string sessionName, IUserIdentity identity) { session.OpenAsync(sessionName, identity).GetAwaiter().GetResult(); } /// /// Establishes a session with the server. /// [Obsolete("Use OpenAsync instead.")] public static void Open( this ISession session, string sessionName, uint sessionTimeout, IUserIdentity identity, ArrayOf preferredLocales) { session.OpenAsync( sessionName, sessionTimeout, identity, preferredLocales).GetAwaiter().GetResult(); } /// /// Establishes a session with the server. /// [Obsolete("Use OpenAsync instead.")] public static void Open( this ISession session, string sessionName, uint sessionTimeout, IUserIdentity identity, ArrayOf preferredLocales, bool checkDomain) { session.OpenAsync( sessionName, sessionTimeout, identity, preferredLocales, checkDomain).GetAwaiter().GetResult(); } /// /// Establishes a session with the server. /// [Obsolete("Use OpenAsync instead.")] public static void Open( this ISession session, string sessionName, uint sessionTimeout, IUserIdentity identity, ArrayOf preferredLocales, bool checkDomain, bool closeChannel) { session.OpenAsync( sessionName, sessionTimeout, identity, preferredLocales, checkDomain, closeChannel).GetAwaiter().GetResult(); } /// /// Updates the preferred locales used for the session. /// [Obsolete("Use ChangePreferredLocalesAsync instead.")] public static void ChangePreferredLocales( this ISession session, ArrayOf preferredLocales) { session.ChangePreferredLocalesAsync(preferredLocales) .GetAwaiter() .GetResult(); } /// /// Updates the user identity and/or locales used for the session. /// [Obsolete("Use UpdateSessionAsync instead.")] public static void UpdateSession( this ISession session, IUserIdentity identity, ArrayOf preferredLocales) { session.UpdateSessionAsync(identity, preferredLocales) .GetAwaiter() .GetResult(); } /// /// Finds the NodeIds for the components for an instance. /// [Obsolete("Use FindComponentIdsAsync instead.")] public static void FindComponentIds(this ISession session, NodeId instanceId, IList componentPaths, out ArrayOf componentIds, out ArrayOf errors) { (componentIds, errors) = session.FindComponentIdsAsync( instanceId, componentPaths) .GetAwaiter() .GetResult(); } /// /// Reads the values for a set of variables. /// [Obsolete("Use Use ReadValuesAsync instead.")] public static void ReadValues(this ISession session, ArrayOf variableIds, ArrayOf expectedTypes, out ArrayOf values, out ArrayOf errors) { (ArrayOf dataValues, ArrayOf errorValues) = session.ReadValuesAsync( variableIds) .GetAwaiter() .GetResult(); object?[] valuesBuffer = new object?[dataValues.Count]; var errorsBuffer = new ServiceResult[errorValues.Count]; for (int ii = 0; ii < variableIds.Count; ii++) { object? value = dataValues[ii].Value; // extract the body from extension objects. if (dataValues[ii].WrappedValue.TryGetValue(out ExtensionObject extension) && extension.TryGetValue(out IEncodeable? encodeable)) { value = encodeable; } // check expected type. Type? expectedType = expectedTypes[ii]; if (expectedType != null && !expectedType.IsInstanceOfType(value)) { errorsBuffer[ii] = ServiceResult.Create( StatusCodes.BadTypeMismatch, "Value {0} does not have expected type: {1}.", value!, expectedType.Name); continue; } // suitable value found. valuesBuffer[ii] = value; errorsBuffer[ii] = errorValues[ii]; } values = valuesBuffer; errors = errorsBuffer; } /// /// Reads the display name for a set of Nodes. /// [Obsolete("Use Use ReadValuesAsync instead.")] public static void ReadDisplayName(this ISession session, ArrayOf nodeIds, out ArrayOf displayNames, out ArrayOf errors) { (displayNames, errors) = session.ReadDisplayNameAsync(nodeIds) .GetAwaiter() .GetResult(); } /// /// Closes the client object and the underlying channel. /// [Obsolete("Use CloseAsync instead.")] public static StatusCode Close(this IClientBase client) { return client.CloseAsync().GetAwaiter().GetResult(); } /// /// Disconnects from the server and frees any network resources /// with the specified timeout. /// [Obsolete("Use CloseAsync instead.")] public static StatusCode Close(this ISession session, int timeout) { return session.CloseAsync(timeout).GetAwaiter().GetResult(); } /// /// Close the session with the server and optionally closes the channel. /// [Obsolete("Use CloseAsync instead.")] public static StatusCode Close(this ISession session, bool closeChannel) { return session.CloseAsync(closeChannel) .GetAwaiter() .GetResult(); } /// /// Disconnects from the server and frees any network resources /// with the specified timeout. /// [Obsolete("Use CloseAsync instead.")] public static StatusCode Close( this ISession session, int timeout, bool closeChannel) { return session.CloseAsync(timeout, closeChannel) .GetAwaiter() .GetResult(); } /// /// Removes a subscription from the session. /// [Obsolete("Use RemoveSubscriptionAsync instead.")] public static bool RemoveSubscription( this ISession session, Subscription subscription) { return session.RemoveSubscriptionAsync(subscription) .GetAwaiter() .GetResult(); } /// /// Remove a list of subscriptions from the session. /// [Obsolete("Use RemoveSubscriptionsAsync instead.")] public static bool RemoveSubscriptions( this ISession session, IEnumerable subscriptions) { return session.RemoveSubscriptionsAsync(subscriptions) .GetAwaiter() .GetResult(); } /// /// Reactivates a list of subscriptions loaded from storage. /// [Obsolete("Use ReactivateSubscriptionsAsync instead.")] public static bool ReactivateSubscriptions( this ISession session, SubscriptionCollection subscriptions, bool sendInitialValues) { return session.ReactivateSubscriptionsAsync( subscriptions, sendInitialValues) .GetAwaiter() .GetResult(); } /// /// Transfers a list of subscriptions from another session. /// [Obsolete("Use TransferSubscriptionsAsync instead.")] public static bool TransferSubscriptions( this ISession session, SubscriptionCollection subscriptions, bool sendInitialValues) { return session.TransferSubscriptionsAsync( subscriptions, sendInitialValues).GetAwaiter().GetResult(); } /// /// Invokes the Browse service. /// /// [Obsolete("Use BrowseAsync instead.")] public static ResponseHeader Browse( this ISession session, RequestHeader requestHeader, ViewDescription view, NodeId nodeToBrowse, uint maxResultsToReturn, BrowseDirection browseDirection, NodeId referenceTypeId, bool includeSubtypes, uint nodeClassMask, out ByteString continuationPoint, out ArrayOf references) { ( ResponseHeader responseHeader, ArrayOf continuationPoints, ArrayOf> referencesList, ArrayOf errors ) = session.BrowseAsync( requestHeader, view, [nodeToBrowse], maxResultsToReturn, browseDirection, referenceTypeId, includeSubtypes, nodeClassMask) .GetAwaiter() .GetResult(); Debug.Assert(errors.Count <= 1); if (errors.Count > 0 && StatusCode.IsBad(errors[0].StatusCode)) { throw new ServiceResultException(errors[0]); } Debug.Assert(referencesList.Count == 1); Debug.Assert(continuationPoints.Count == 1); references = referencesList[0]; continuationPoint = continuationPoints[0]; return responseHeader; } /// /// Invokes the BrowseNext service. /// /// [Obsolete("Use BrowseNextAsync instead.")] public static ResponseHeader BrowseNext( this ISession session, RequestHeader requestHeader, bool releaseContinuationPoint, ByteString continuationPoint, out ByteString revisedContinuationPoint, out ArrayOf references) { ( ResponseHeader responseHeader, ArrayOf revisedContinuationPoints, ArrayOf> referencesList, ArrayOf errors ) = session.BrowseNextAsync( requestHeader, [continuationPoint], releaseContinuationPoint) .GetAwaiter() .GetResult(); Debug.Assert(errors.Count <= 1); if (errors.Count > 0 && StatusCode.IsBad(errors[0].StatusCode)) { throw new ServiceResultException(errors[0]); } Debug.Assert(referencesList.Count == 1); Debug.Assert(revisedContinuationPoints.Count == 1); references = referencesList[0]; revisedContinuationPoint = revisedContinuationPoints[0]; return responseHeader; } /// /// Execute browse and, if necessary, browse next in one service call. /// Takes care of BadNoContinuationPoint and BadInvalidContinuationPoint status codes. /// [Obsolete("Use ManagedBrowseAsync instead.")] public static void ManagedBrowse( this ISession session, RequestHeader requestHeader, ViewDescription view, ArrayOf nodesToBrowse, uint maxResultsToReturn, BrowseDirection browseDirection, NodeId referenceTypeId, bool includeSubtypes, uint nodeClassMask, out ArrayOf> result, out ArrayOf errors) { (result, errors) = session.ManagedBrowseAsync( requestHeader, view, nodesToBrowse, maxResultsToReturn, browseDirection, referenceTypeId, includeSubtypes, nodeClassMask) .GetAwaiter() .GetResult(); } /// /// Calls the specified method and returns the output arguments. /// [Obsolete("Use CallAsync instead.")] public static ArrayOf Call( this ISession session, NodeId objectId, NodeId methodId, params Variant[] args) { return session.CallAsync( objectId, methodId, default, args) .GetAwaiter() .GetResult(); } /// /// Sends a republish request. /// [Obsolete("Use RepublishAsync instead.")] public static bool Republish( this ISession session, uint subscriptionId, uint sequenceNumber, out ServiceResult error) { (bool result, error) = session.RepublishAsync( subscriptionId, sequenceNumber) .GetAwaiter() .GetResult(); return result; } /// /// Call the ResendData method on the server for all subscriptions. /// [Obsolete("Use ResendDataAsync instead.")] public static bool ResendData( this ISession session, IEnumerable subscriptions, out ArrayOf errors) { (bool success, errors) = session.ResendDataAsync(subscriptions) .GetAwaiter() .GetResult(); return success; } /// /// Call the ResendData method on the server for all subscriptions. /// [Obsolete("Use ResendDataAsync using subscription ids instead.")] public static async Task<(bool, ArrayOf)> ResendDataAsync( this ISession session, IEnumerable subscriptions, CancellationToken ct = default) { try { ArrayOf errorsRo = await session.ResendDataAsync( subscriptions.Select(s => s.Id).ToArrayOf(), ct).ConfigureAwait(false); return (true, errorsRo); } catch { return (false, Array.Empty()); } } // ---------------------------------------------------------------- // 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 // supported, so when migrated into this shim assembly they are // hosted as static methods on SessionObsolete. Callers that // previously invoked `Session.Create(...)` / `Session.Recreate(...)` // must now call `SessionObsolete.Create(...)` / `SessionObsolete.Recreate(...)`. // ---------------------------------------------------------------- /// /// Creates a new communication session with a server by invoking the CreateSession service /// [Obsolete("Use ISessionFactory.CreateAsync")] public static Task Create( ApplicationConfiguration configuration, ConfiguredEndpoint endpoint, bool updateBeforeConnect, string sessionName, uint sessionTimeout, IUserIdentity identity, ArrayOf preferredLocales, CancellationToken ct = default) { return Create( configuration, endpoint, updateBeforeConnect, false, sessionName, sessionTimeout, identity, preferredLocales, ct); } /// /// Creates a new communication session with a server by invoking the CreateSession service /// [Obsolete("Use ISessionFactory.CreateAsync")] public static Task Create( ApplicationConfiguration configuration, ConfiguredEndpoint endpoint, bool updateBeforeConnect, bool checkDomain, string sessionName, uint sessionTimeout, IUserIdentity identity, ArrayOf preferredLocales, CancellationToken ct = default) { return Create( configuration, // No reverse-connect transport in this overload; the modern API requires // a non-nullable parameter so this obsolete bridge forwards null!. (ITransportWaitingConnection)null!, endpoint, updateBeforeConnect, checkDomain, sessionName, sessionTimeout, identity, preferredLocales, ct); } /// /// Creates a new session with a server using the specified channel /// [Obsolete("Use ISessionFactory.CreateAsync")] public static Session Create( ApplicationConfiguration configuration, ITransportChannel channel, ConfiguredEndpoint endpoint, Certificate clientCertificate, ArrayOf availableEndpoints = default, ArrayOf discoveryProfileUris = default) { return Create( // Telemetry context is nullable on this obsolete bridge but required by the // modern API; null! preserves the pre-nullable lookup behavior. null!, configuration, channel, endpoint, clientCertificate, availableEndpoints, discoveryProfileUris); } /// /// Recreates a session based on a specified template. /// /// The Session object to use as template /// The new session object. [Obsolete("Use ISessionFactory.RecreateAsync")] public static Session Recreate(Session template) { return RecreateAsync(template).GetAwaiter().GetResult(); } /// /// Recreates a session based on a specified template. /// /// The Session object to use as template /// The waiting reverse connection. /// The new session object. [Obsolete("Use ISessionFactory.RecreateAsync")] public static Session Recreate(Session template, ITransportWaitingConnection connection) { return RecreateAsync(template, connection).GetAwaiter().GetResult(); } /// /// Recreates a session based on a specified template using the provided channel. /// /// The Session object to use as template /// The waiting reverse connection. /// The new session object. [Obsolete("Use ISessionFactory.RecreateAsync")] public static Session Recreate(Session template, ITransportChannel transportChannel) { return RecreateAsync(template, transportChannel).GetAwaiter().GetResult(); } /// /// Recreates a session based on a specified template. /// [Obsolete("Use ISessionFactory.RecreateAsync")] public static async Task RecreateAsync( Session sessionTemplate, CancellationToken ct = default) { var factory = new DefaultSessionFactory(sessionTemplate.MessageContext.Telemetry) { ReturnDiagnostics = sessionTemplate.ReturnDiagnostics }; return (Session)await factory.RecreateAsync( sessionTemplate, ct).ConfigureAwait(false); } /// /// Recreates a session based on a specified template. /// [Obsolete("Use ISessionFactory.RecreateAsync")] public static async Task RecreateAsync( Session sessionTemplate, ITransportWaitingConnection connection, CancellationToken ct = default) { var factory = new DefaultSessionFactory(sessionTemplate.MessageContext.Telemetry) { ReturnDiagnostics = sessionTemplate.ReturnDiagnostics }; return (Session)await factory.RecreateAsync( sessionTemplate, connection, ct).ConfigureAwait(false); } /// /// Recreates a session based on a specified template using the provided channel. /// [Obsolete("Use ISessionFactory.RecreateAsync")] public static async Task RecreateAsync( Session sessionTemplate, ITransportChannel transportChannel, CancellationToken ct = default) { var factory = new DefaultSessionFactory(sessionTemplate.MessageContext.Telemetry) { ReturnDiagnostics = sessionTemplate.ReturnDiagnostics }; return (Session)await factory.RecreateAsync( sessionTemplate, transportChannel, ct).ConfigureAwait(false); } /// /// Creates a new communication session with a server using a reverse connection. /// [Obsolete("Use ISessionFactory.CreateAsync")] public static Task Create( ApplicationConfiguration configuration, ITransportWaitingConnection connection, ConfiguredEndpoint endpoint, bool updateBeforeConnect, bool checkDomain, string sessionName, uint sessionTimeout, IUserIdentity identity, ArrayOf preferredLocales, CancellationToken ct = default) { return CreateAsync( // Telemetry context is nullable on this obsolete bridge but required by the // modern API; null! preserves the pre-nullable lookup behavior. null!, configuration, connection, endpoint, updateBeforeConnect, checkDomain, sessionName, sessionTimeout, identity, preferredLocales, DiagnosticsMasks.None, ct); } /// /// Create a session /// [Obsolete("Use ISessionFactory.CreateAsync")] public static Task Create( ISessionInstantiator sessionInstantiator, ApplicationConfiguration configuration, ITransportWaitingConnection connection, ConfiguredEndpoint endpoint, bool updateBeforeConnect, bool checkDomain, string sessionName, uint sessionTimeout, IUserIdentity identity, ArrayOf preferredLocales, CancellationToken ct = default) { return CreateAsync( sessionInstantiator, configuration, connection, endpoint, updateBeforeConnect, checkDomain, sessionName, sessionTimeout, identity, preferredLocales, DiagnosticsMasks.None, ct); } /// /// Create a session /// [Obsolete("Use ISessionFactory.CreateAsync")] public static Task Create( ISessionInstantiator sessionInstantiator, ApplicationConfiguration configuration, ReverseConnectManager reverseConnectManager, ConfiguredEndpoint endpoint, bool updateBeforeConnect, bool checkDomain, string sessionName, uint sessionTimeout, IUserIdentity userIdentity, ArrayOf preferredLocales, CancellationToken ct = default) { return CreateAsync( sessionInstantiator, configuration, reverseConnectManager, endpoint, updateBeforeConnect, checkDomain, sessionName, sessionTimeout, userIdentity, preferredLocales, DiagnosticsMasks.None, ct); } /// /// Create a session /// [Obsolete("Use ISessionFactory.CreateAsync")] public static Task Create( ApplicationConfiguration configuration, ReverseConnectManager reverseConnectManager, ConfiguredEndpoint endpoint, bool updateBeforeConnect, bool checkDomain, string sessionName, uint sessionTimeout, IUserIdentity userIdentity, ArrayOf preferredLocales, CancellationToken ct = default) { return CreateAsync( configuration, reverseConnectManager, endpoint, updateBeforeConnect, checkDomain, sessionName, sessionTimeout, userIdentity, preferredLocales, ct); } /// /// Creates a new session. /// [Obsolete("Use ISessionFactory.Create")] public static Session Create( ISessionInstantiator sessionInstantiator, ApplicationConfiguration configuration, ITransportChannel channel, ConfiguredEndpoint endpoint, Certificate clientCertificate, ArrayOf availableEndpoints = default, ArrayOf discoveryProfileUris = default) { ServiceMessageContext context = configuration.CreateMessageContext(false); var factory = new DefaultSessionFactory(context.Telemetry); return (Session)factory.Create( channel, configuration, endpoint, clientCertificate, null, availableEndpoints, discoveryProfileUris); } /// /// Creates a secure channel to the specified endpoint. /// [Obsolete("Use ISessionFactory.CreateChannelAsync")] public static Task CreateChannelAsync( ApplicationConfiguration configuration, ITransportWaitingConnection connection, ConfiguredEndpoint endpoint, bool updateBeforeConnect, bool checkDomain, CancellationToken ct = default) { ServiceMessageContext context = configuration.CreateMessageContext(false); var factory = new DefaultSessionFactory(context.Telemetry); return factory.CreateChannelAsync( configuration, connection, endpoint, updateBeforeConnect, checkDomain, ct); } /// /// Creates a new communication session with a server using a reverse connection. /// [Obsolete("Use ISessionFactory.CreateAsync")] public static async Task CreateAsync( ISessionInstantiator sessionInstantiator, ApplicationConfiguration configuration, ITransportWaitingConnection connection, ConfiguredEndpoint endpoint, bool updateBeforeConnect, bool checkDomain, string sessionName, uint sessionTimeout, IUserIdentity identity, ArrayOf preferredLocales, DiagnosticsMasks returnDiagnostics, CancellationToken ct = default) { ServiceMessageContext context = configuration.CreateMessageContext(false); var factory = new DefaultSessionFactory(context.Telemetry) { ReturnDiagnostics = returnDiagnostics }; return (Session)await factory.CreateAsync( configuration, connection, endpoint, updateBeforeConnect, checkDomain, sessionName, sessionTimeout, identity, preferredLocales, ct).ConfigureAwait(false); } /// /// Creates a new communication session with a server using a reverse connect manager. /// [Obsolete("Use ISessionFactory.CreateAsync")] public static async Task CreateAsync( ApplicationConfiguration configuration, ReverseConnectManager reverseConnectManager, ConfiguredEndpoint endpoint, bool updateBeforeConnect, bool checkDomain, string sessionName, uint sessionTimeout, IUserIdentity userIdentity, ArrayOf preferredLocales, CancellationToken ct = default) { ServiceMessageContext context = configuration.CreateMessageContext(false); var factory = new DefaultSessionFactory(context.Telemetry); return (Session)await factory.CreateAsync( configuration, reverseConnectManager, endpoint, updateBeforeConnect, checkDomain, sessionName, sessionTimeout, userIdentity, preferredLocales, ct).ConfigureAwait(false); } /// /// Creates a new communication session with a server using a reverse connect manager. /// [Obsolete("Use ISessionFactory.CreateAsync")] public static async Task CreateAsync( ISessionInstantiator sessionInstantiator, ApplicationConfiguration configuration, ReverseConnectManager reverseConnectManager, ConfiguredEndpoint endpoint, bool updateBeforeConnect, bool checkDomain, string sessionName, uint sessionTimeout, IUserIdentity userIdentity, ArrayOf preferredLocales, DiagnosticsMasks returnDiagnostics, CancellationToken ct = default) { ServiceMessageContext context = configuration.CreateMessageContext(false); var factory = new DefaultSessionFactory(context.Telemetry) { ReturnDiagnostics = returnDiagnostics }; return (Session)await factory.CreateAsync( configuration, reverseConnectManager, endpoint, updateBeforeConnect, checkDomain, sessionName, sessionTimeout, userIdentity, preferredLocales, ct).ConfigureAwait(false); } } /// /// Obsolete traceable session, which now is supported by session /// [Obsolete("Use Session which also provides tracing")] public class TraceableSession : Session { /// /// Create session /// public TraceableSession( ISessionChannel channel, ApplicationConfiguration configuration, ConfiguredEndpoint endpoint) : base(channel, configuration, endpoint) { } /// /// Create session /// public TraceableSession( ITransportChannel channel, Session template, bool copyEventHandlers) : base(channel, template, copyEventHandlers) { } /// /// Create session /// public TraceableSession( ITransportChannel channel, ApplicationConfiguration configuration, ConfiguredEndpoint endpoint, Certificate clientCertificate, ArrayOf availableEndpoints = default, ArrayOf discoveryProfileUris = default) : base( channel, configuration, endpoint, clientCertificate, null, availableEndpoints, discoveryProfileUris) { } /// /// Object that creates instances of a session /// [Obsolete("Use DefaultSessionFactory which also provides tracing capabilities.")] public class TraceableSessionFactory : DefaultSessionFactory { /// /// The default instance of the factory. /// public static new readonly TraceableSessionFactory Instance = new(); /// /// Obsolete default constructor /// public TraceableSessionFactory() // Telemetry is required by the base ctor; this obsolete parameterless ctor // forwards null! to preserve the pre-nullable instantiation pattern. : base(null!) { } } } /// /// Object that creates an instance of a Session object. /// [Obsolete("Use ISessionFactory instead. This interface will be removed in a future release.")] public interface ISessionInstantiator : ISessionFactory; /// /// Obsolete session factory api /// public static class SessionFactoryObsolete { /// /// Create session /// [Obsolete("Use Create with channel and configuration reversed")] public static ISession Create( this ISessionFactory factory, ApplicationConfiguration configuration, ITransportChannel channel, ConfiguredEndpoint endpoint, Certificate clientCertificate, ArrayOf availableEndpoints = default, ArrayOf discoveryProfileUris = default) { return factory.Create( channel, configuration, endpoint, clientCertificate, null, availableEndpoints, discoveryProfileUris); } } }