/* ======================================================================== * 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.Threading; using System.Threading.Tasks; namespace Opc.Ua.Server { /// /// An interface to an object that creates a INodeManager object. /// public interface INodeManagerFactory { /// /// The INodeManager factory. /// /// The server instance. /// The application configuration. INodeManager Create(IServerInternal server, ApplicationConfiguration configuration); /// /// The namespace table of the NodeManager. /// ArrayOf NamespacesUris { get; } } /// /// An interface to an object that manages a set of nodes in the address space. /// public interface INodeManager { /// /// Returns the NamespaceUris for the Nodes belonging to the NodeManager. /// /// /// By default the MasterNodeManager uses the namespaceIndex to determine who owns an Node. /// /// Servers that do not wish to partition their address space this way must provide their own /// implementation of MasterNodeManager.GetManagerHandle(). /// /// NodeManagers which depend on a custom partitioning scheme must return a null value. /// IEnumerable NamespaceUris { get; } /// /// Creates the address space by loading any configuration information an connecting to an underlying system (if applicable). /// /// A table of references that need to be added to other node managers. /// /// A node manager owns a set of nodes. These nodes may be known in advance or they may be stored in an /// external system are retrived on demand. These nodes may have two way references to nodes that are owned /// by other node managers. In these cases, the node managers only manage one half of those references. The /// other half of the reference should be returned to the MasterNodeManager. /// void CreateAddressSpace(IDictionary> externalReferences); /// /// Deletes the address by releasing all resources and disconnecting from any underlying system. /// void DeleteAddressSpace(); /// /// Returns an opaque handle identifying to the node to the node manager. /// /// A node handle, null if the node manager does not recognize the node id. /// /// The method must not block by querying an underlying system. If the node manager wraps an /// underlying system then it must check to see if it recognizes the syntax of the node id. /// The handle in this case may simply be a partially parsed version of the node id. /// object? GetManagerHandle(NodeId nodeId); /// /// Adds references to the node manager. /// /// /// The node manager checks the dictionary for nodes that it owns and ensures the associated references exist. /// void AddReferences(IDictionary> references); /// /// Deletes a reference. /// ServiceResult DeleteReference( object sourceHandle, NodeId referenceTypeId, bool isInverse, ExpandedNodeId targetId, bool deleteBidirectional); /// /// Returns the metadata associated with the node. /// /// /// Returns null if the node does not exist. /// NodeMetadata? GetNodeMetadata( OperationContext context, object targetHandle, BrowseResultMask resultMask); /// /// Returns the set of references that meet the filter criteria. /// /// The context to used when processing the request. /// The continuation point that stores the state of the Browse operation. /// The list of references that meet the filter criteria. /// /// NodeManagers will likely have references to other NodeManagers which means they will not be able /// to apply the NodeClassMask or fill in the attributes for the target Node. In these cases the /// NodeManager must return a ReferenceDescription with the NodeId and ReferenceTypeId set. The caller will /// be responsible for filling in the target attributes. /// The references parameter may already contain references when the method is called. The implementer must /// include these references when calculating whether a continuation point must be returned. /// /// Thrown if the context, continuationPoint or references parameters are null. /// Thrown if an error occurs during processing. void Browse( OperationContext context, ref ContinuationPoint continuationPoint, IList references); /// /// Finds the targets of the relative path from the source node. /// /// The context to used when processing the request. /// The handle for the source node. /// The relative path to follow. /// The NodeIds for any target at the end of the relative path. /// The NodeIds for any local target that is in another NodeManager. /// /// A null context indicates that the server's internal logic is making the call. /// The first target in the list must be the target that matches the instance declaration (if applicable). /// Any local targets that belong to other NodeManagers are returned as unresolvedTargetIds. /// The caller must check the BrowseName to determine if it matches the relativePath. /// The implementor must not throw an exception if the source or target nodes do not exist. /// /// Thrown if the sourceHandle, relativePath or targetIds parameters are null. void TranslateBrowsePath( OperationContext context, object sourceHandle, RelativePathElement relativePath, IList targetIds, IList unresolvedTargetIds); /// /// Reads the attribute values for a set of nodes. /// /// /// /// The MasterNodeManager pre-processes the nodesToRead and ensures that: /// - the AttributeId is a known attribute. /// - the IndexRange, if specified, is valid. /// - the DataEncoding and the IndexRange are not specified if the AttributeId is not Value. /// /// /// The MasterNodeManager post-processes the values by: /// - sets values[ii].StatusCode to the value of errors[ii].Code /// - creates a instance of DataValue if one does not exist and an errors[ii] is bad. /// - removes timestamps from the DataValue if the client does not want them. /// /// /// The node manager must ignore ReadValueId with the Processed flag set to true. /// The node manager must set the Processed flag for any ReadValueId that it processes. /// /// void Read( OperationContext context, double maxAge, ArrayOf nodesToRead, IList values, IList errors); /// /// Reads the history of a set of items. /// void HistoryRead( OperationContext context, HistoryReadDetails details, TimestampsToReturn timestampsToReturn, bool releaseContinuationPoints, ArrayOf nodesToRead, IList results, IList errors); /// /// Writes a set of values. /// /// /// Each node manager should only process node ids that it recognizes. If it processes a value it /// must set the Processed flag in the WriteValue structure. /// void Write( OperationContext context, ArrayOf nodesToWrite, IList errors); /// /// Updates the history for a set of nodes. /// void HistoryUpdate( OperationContext context, Type detailsType, ArrayOf nodesToUpdate, IList results, IList errors); /// /// Calls a method defined on an object. /// void Call( OperationContext context, ArrayOf methodsToCall, IList results, IList errors); /// /// Tells the NodeManager to report events from the specified notifier. /// /// /// This method may be called multiple times for the name monitoredItemId if the /// context for that MonitoredItem changes (i.e. UserIdentity and/or Locales). /// ServiceResult SubscribeToEvents( OperationContext context, object sourceId, uint subscriptionId, IEventMonitoredItem monitoredItem, bool unsubscribe); /// /// Tells the NodeManager to report events all events from all sources. /// /// /// This method may be called multiple times for the name monitoredItemId if the /// context for that MonitoredItem changes (i.e. UserIdentity and/or Locales). /// ServiceResult SubscribeToAllEvents( OperationContext context, uint subscriptionId, IEventMonitoredItem monitoredItem, bool unsubscribe); /// /// Tells the NodeManager to refresh any conditions. /// ServiceResult ConditionRefresh( OperationContext context, IList monitoredItems); /// /// Creates a set of monitored items. /// void CreateMonitoredItems( OperationContext context, uint subscriptionId, double publishingInterval, TimestampsToReturn timestampsToReturn, ArrayOf itemsToCreate, IList errors, IList filterErrors, IList monitoredItems, bool createDurable, MonitoredItemIdFactory monitoredItemIdFactory); /// /// Restore a set of monitored items after a restart. /// void RestoreMonitoredItems( IList itemsToRestore, IList monitoredItems, IUserIdentity savedOwnerIdentity); /// /// Modifies a set of monitored items. /// void ModifyMonitoredItems( OperationContext context, TimestampsToReturn timestampsToReturn, IList monitoredItems, ArrayOf itemsToModify, IList errors, IList filterErrors); /// /// Deletes a set of monitored items. /// void DeleteMonitoredItems( OperationContext context, IList monitoredItems, IList processedItems, IList errors); /// /// Transfers a set of monitored items. /// /// /// Queue initial values from monitored items in the node managers. /// void TransferMonitoredItems( OperationContext context, bool sendInitialValues, IList monitoredItems, IList processedItems, IList errors); /// /// Changes the monitoring mode for a set of monitored items. /// void SetMonitoringMode( OperationContext context, MonitoringMode monitoringMode, IList monitoredItems, IList processedItems, IList errors); } /// /// An interface to an object that manages a set of nodes in the address space. /// public interface INodeManager2 : INodeManager { /// /// Called when the session is closed. /// void SessionClosing(OperationContext context, NodeId sessionId, bool deleteSubscriptions); /// /// Returns true if the node is in the view. /// bool IsNodeInView(OperationContext context, NodeId viewId, object nodeHandle); /// /// Returns the metadata needed for validating permissions, associated with the node with /// the option to optimize services by using a cache. /// /// /// Returns null if the node does not exist. /// It should return null in case the implementation wishes to handover the task to the parent INodeManager.GetNodeMetadata /// NodeMetadata? GetPermissionMetadata( OperationContext context, object targetHandle, BrowseResultMask resultMask, Dictionary uniqueNodesServiceAttributesCache, bool permissionsOnly); } /// /// An interface to an object that manages a set of nodes in the address space. /// public interface INodeManager3 : INodeManager2 { /// /// Validates if the specified event monitored item has enough permissions to receive the specified event /// ServiceResult ValidateEventRolePermissions( IEventMonitoredItem monitoredItem, IFilterTarget filterTarget); /// /// Validates Role permissions for the specified NodeId /// ServiceResult ValidateRolePermissions( OperationContext operationContext, NodeId nodeId, PermissionType requestedPermission); /// /// Called when a session is activated and the user identity has changed. /// Implementations should invalidate any cached role permissions for monitored items /// belonging to the session so that permissions are re-evaluated on the next data change. /// void SessionActivated(OperationContext context, NodeId sessionId); /// /// Resolves the effective for a call request. /// MethodState FindMethodState( OperationContext context, CallMethodRequest methodToCall); } /// /// An asynchronous version of the "Call" method defined on the interface. /// public interface ICallAsyncNodeManager { /// /// Asynchronously calls a method defined on an object. /// ValueTask CallAsync( OperationContext context, ArrayOf methodsToCall, IList results, IList errors, CancellationToken cancellationToken = default); } /// /// An asynchronous version of the "Read" method defined on the interface. /// public interface IReadAsyncNodeManager { /// /// Reads the attribute values for a set of nodes. /// /// /// /// The MasterNodeManager pre-processes the nodesToRead and ensures that: /// - the AttributeId is a known attribute. /// - the IndexRange, if specified, is valid. /// - the DataEncoding and the IndexRange are not specified if the AttributeId is not Value. /// /// /// The MasterNodeManager post-processes the values by: /// - sets values[ii].StatusCode to the value of errors[ii].Code /// - creates a instance of DataValue if one does not exist and an errors[ii] is bad. /// - removes timestamps from the DataValue if the client does not want them. /// /// /// The node manager must ignore ReadValueId with the Processed flag set to true. /// The node manager must set the Processed flag for any ReadValueId that it processes. /// /// ValueTask ReadAsync( OperationContext context, double maxAge, ArrayOf nodesToRead, IList values, IList errors, CancellationToken cancellationToken = default); } /// /// An asynchronous version of the "Write" method defined on the interface. /// public interface IWriteAsyncNodeManager { /// /// Writes a set of values. /// /// /// Each node manager should only process node ids that it recognizes. If it processes a value it /// must set the Processed flag in the WriteValue structure. /// ValueTask WriteAsync( OperationContext context, ArrayOf nodesToWrite, IList errors, CancellationToken cancellationToken = default); } /// /// An asynchronous version of the "HistoryRead" method defined on the interface. /// public interface IHistoryReadAsyncNodeManager { /// /// Reads the history of a set of items. /// ValueTask HistoryReadAsync( OperationContext context, HistoryReadDetails details, TimestampsToReturn timestampsToReturn, bool releaseContinuationPoints, ArrayOf nodesToRead, IList results, IList errors, CancellationToken cancellationToken = default); } /// /// An asynchronous version of the "HistoryUpdate" method defined on the interface. /// public interface IHistoryUpdateAsyncNodeManager { /// /// Updates the history for a set of nodes. /// ValueTask HistoryUpdateAsync( OperationContext context, Type detailsType, ArrayOf nodesToUpdate, IList results, IList errors, CancellationToken cancellationToken = default); } /// /// An asynchronous version of the "ConditionRefresh" method defined on the interface. /// public interface IConditionRefreshAsyncNodeManager { /// /// Tells the NodeManager to refresh any conditions. /// ValueTask ConditionRefreshAsync( OperationContext context, IList monitoredItems, CancellationToken cancellationToken = default); } /// /// An asynchronous version of the "TranslateBrowsePath" method defined on the interface. /// public interface ITranslateBrowsePathAsyncNodeManager { /// /// Finds the targets of the relative path from the source node. /// /// The context to used when processing the request. /// The handle for the source node. /// The relative path to follow. /// The NodeIds for any target at the end of the relative path. /// The NodeIds for any local target that is in another NodeManager. /// The cancellation token /// /// A null context indicates that the server's internal logic is making the call. /// The first target in the list must be the target that matches the instance declaration (if applicable). /// Any local targets that belong to other NodeManagers are returned as unresolvedTargetIds. /// The caller must check the BrowseName to determine if it matches the relativePath. /// The implementor must not throw an exception if the source or target nodes do not exist. /// /// Thrown if the sourceHandle, relativePath or targetIds parameters are null. ValueTask TranslateBrowsePathAsync( OperationContext context, object sourceHandle, RelativePathElement relativePath, IList targetIds, IList unresolvedTargetIds, CancellationToken cancellationToken = default); } /// /// An asynchronous version of the "Browse" method defined on the interface. /// public interface IBrowseAsyncNodeManager { /// /// Returns the set of references that meet the filter criteria. /// /// The context to used when processing the request. /// The continuation point that stores the state of the Browse operation. /// The list of references that meet the filter criteria. /// The cancellation token /// /// NodeManagers will likely have references to other NodeManagers which means they will not be able /// to apply the NodeClassMask or fill in the attributes for the target Node. In these cases the /// NodeManager must return a ReferenceDescription with the NodeId and ReferenceTypeId set. The caller will /// be responsible for filling in the target attributes. /// The references parameter may already contain references when the method is called. The implementer must /// include these references when calculating whether a continuation point must be returned. /// /// The continuation point that stores the state of the Browse operation or null if there are no more references to return. /// Thrown if the context, continuationPoint or references parameters are null. /// Thrown if an error occurs during processing. ValueTask BrowseAsync( OperationContext context, ContinuationPoint continuationPoint, IList references, CancellationToken cancellationToken = default); } /// /// An asynchronous version of the "SetMonitoringMode" method defined on the interface. /// public interface ISetMonitoringModeAsyncNodeManager { /// /// Changes the monitoring mode for a set of monitored items. /// ValueTask SetMonitoringModeAsync( OperationContext context, MonitoringMode monitoringMode, IList monitoredItems, IList processedItems, IList errors, CancellationToken cancellationToken = default); } /// /// An asynchronous version of the "TransferMonitoredItems" method defined on the interface. /// public interface ITransferMonitoredItemsAsyncNodeManager { /// /// Transfers a set of monitored items. /// /// /// Queue initial values from monitored items in the node managers. /// ValueTask TransferMonitoredItemsAsync( OperationContext context, bool sendInitialValues, IList monitoredItems, IList processedItems, IList errors, CancellationToken cancellationToken = default); } /// /// An asynchronous version of the "DeleteMonitoredItems" method defined on the interface. /// public interface IDeleteMonitoredItemsAsyncNodeManager { /// /// Deletes a set of monitored items. /// ValueTask DeleteMonitoredItemsAsync( OperationContext context, IList monitoredItems, IList processedItems, IList errors, CancellationToken cancellationToken = default); } /// /// An asynchronous version of the "ModifyMonitoredItems" method defined on the interface. /// public interface IModifyMonitoredItemsAsyncNodeManager { /// /// Modifies a set of monitored items. /// ValueTask ModifyMonitoredItemsAsync( OperationContext context, TimestampsToReturn timestampsToReturn, IList monitoredItems, ArrayOf itemsToModify, IList errors, IList filterErrors, CancellationToken cancellationToken = default); } /// /// An asynchronous version of the "CreateMonitoredItems" method defined on the interface. /// public interface ICreateMonitoredItemsAsyncNodeManager { /// /// Creates a set of monitored items. /// ValueTask CreateMonitoredItemsAsync( OperationContext context, uint subscriptionId, double publishingInterval, TimestampsToReturn timestampsToReturn, ArrayOf itemsToCreate, IList errors, IList filterErrors, IList monitoredItems, bool createDurable, MonitoredItemIdFactory monitoredItemIdFactory, CancellationToken cancellationToken = default); } /// /// Opt-in facet implemented by node managers that allow clients to /// add/delete nodes and add/delete references at runtime via the OPC UA /// NodeManagement service set (Part 4 ยง5.8). /// /// /// /// Aggregated into the composite so every /// async node manager exposes the surface. /// short-circuits on before invoking the /// per-item methods, so node managers that opt out incur no overhead. /// /// /// Node managers must set to true to opt /// in. The default implementation returns /// false, so the service set returns /// when targeting nodes owned by managers that have not opted in. /// /// public interface INodeManagementAsyncNodeManager { /// /// Indicates whether this node manager accepts NodeManagement service /// requests. When false the master dispatcher rejects per-item /// requests routed to this manager with . /// bool AllowNodeManagement { get; } /// /// Adds a single node defined by . The implementation /// owns the parent node identified by . /// /// The operation context. /// The AddNodesItem to process. /// Cancellation token. /// A tuple containing the service result and the assigned NodeId /// (NodeId.Null on failure). ValueTask<(ServiceResult result, NodeId addedNodeId)> AddNodeAsync( OperationContext context, AddNodesItem item, CancellationToken cancellationToken = default); /// /// Deletes a single node defined by . The implementation /// owns the node identified by . /// /// The operation context. /// The DeleteNodesItem to process. /// Cancellation token. /// The service result. When /// is true, inverse references targeting the deleted node in other node /// managers are removed by the master dispatcher. ValueTask DeleteNodeAsync( OperationContext context, DeleteNodesItem item, CancellationToken cancellationToken = default); /// /// Adds a single forward reference whose source is owned by this node /// manager. The master dispatcher routes the complementary inverse edge /// to the target's owning node manager when the target is local. /// /// The operation context. /// The AddReferencesItem describing the edge to add. /// Cancellation token. ValueTask AddReferenceAsync( OperationContext context, AddReferencesItem item, CancellationToken cancellationToken = default); /// /// Deletes a single reference whose source is owned by this node manager. /// When is true /// the master dispatcher removes the complementary inverse edge from the /// target's owning node manager when the target is local. /// /// The operation context. /// The DeleteReferencesItem describing the edge to remove. /// Cancellation token. ValueTask DeleteReferenceAsync( OperationContext context, DeleteReferencesItem item, CancellationToken cancellationToken = default); } /// /// An interface to an object that creates a IAsyncNodeManager object. /// public interface IAsyncNodeManagerFactory { /// /// The IAsyncNodeManager factory. /// /// The server instance. /// The application configuration. /// The cancellation token ValueTask CreateAsync( IServerInternal server, ApplicationConfiguration configuration, CancellationToken cancellationToken = default); /// /// The namespace table of the NodeManager. /// ArrayOf NamespacesUris { get; } } /// /// An asynchronous verison of the interface. /// This interface is in active development and will be extended in future releases. /// Please use the sub interfaces to implement async support for specific service calls. /// public interface IAsyncNodeManager : ICallAsyncNodeManager, IReadAsyncNodeManager, IWriteAsyncNodeManager, IHistoryReadAsyncNodeManager, IHistoryUpdateAsyncNodeManager, IConditionRefreshAsyncNodeManager, ITranslateBrowsePathAsyncNodeManager, IBrowseAsyncNodeManager, ISetMonitoringModeAsyncNodeManager, ITransferMonitoredItemsAsyncNodeManager, IDeleteMonitoredItemsAsyncNodeManager, IModifyMonitoredItemsAsyncNodeManager, ICreateMonitoredItemsAsyncNodeManager, INodeManagementAsyncNodeManager { /// /// Resolves the effective for a call request. /// ValueTask FindMethodStateAsync( OperationContext context, CallMethodRequest methodToCall, CancellationToken cancellationToken = default); /// /// Returns the NamespaceUris for the Nodes belonging to the NodeManager. /// /// /// By default the MasterNodeManager uses the namespaceIndex to determine who owns an Node. /// /// Servers that do not wish to partition their address space this way must provide their own /// implementation of MasterNodeManager.GetManagerHandle(). /// /// NodeManagers which depend on a custom partitioning scheme must return a null value. /// IEnumerable NamespaceUris { get; } /// /// Shall never be null. /// Allows access to synchronous methods for compatibility /// If the NodeManager does not support synchronous calls natively use /// to wrap the async calls. /// INodeManager SyncNodeManager { get; } /// /// Creates the address space by loading any configuration information an connecting to an underlying system (if applicable). /// /// A table of references that need to be added to other node managers. /// /// A node manager owns a set of nodes. These nodes may be known in advance or they may be stored in an /// external system are retrived on demand. These nodes may have two way references to nodes that are owned /// by other node managers. In these cases, the node managers only manage one half of those references. The /// other half of the reference should be returned to the MasterNodeManager. /// ValueTask CreateAddressSpaceAsync( IDictionary> externalReferences, CancellationToken cancellationToken = default); /// /// Returns the metadata associated with the node. /// /// /// Returns null if the node does not exist. /// ValueTask GetNodeMetadataAsync( OperationContext context, object targetHandle, BrowseResultMask resultMask, CancellationToken cancellationToken = default); /// /// Deletes the address by releasing all resources and disconnecting from any underlying system. /// ValueTask DeleteAddressSpaceAsync(CancellationToken cancellationToken = default); /// /// Returns an opaque handle identifying to the node to the node manager. /// /// A node handle, null if the node manager does not recognize the node id. /// /// The method must not block by querying an underlying system. If the node manager wraps an /// underlying system then it must check to see if it recognizes the syntax of the node id. /// The handle in this case may simply be a partially parsed version of the node id. /// ValueTask GetManagerHandleAsync(NodeId nodeId, CancellationToken cancellationToken = default); /// /// Adds references to the node manager. /// /// /// The node manager checks the dictionary for nodes that it owns and ensures the associated references exist. /// ValueTask AddReferencesAsync( IDictionary> references, CancellationToken cancellationToken = default); /// /// Deletes a reference. /// ValueTask DeleteReferenceAsync( object sourceHandle, NodeId referenceTypeId, bool isInverse, ExpandedNodeId targetId, bool deleteBidirectional, CancellationToken cancellationToken = default); /// /// Called when the session is closed. /// ValueTask SessionClosingAsync( OperationContext context, NodeId sessionId, bool deleteSubscriptions, CancellationToken cancellationToken = default); /// /// Called when a session is activated and the user identity has changed. /// Implementations should invalidate any cached role permissions for monitored items /// belonging to the session so that permissions are re-evaluated on the next data change. /// ValueTask SessionActivatedAsync( OperationContext context, NodeId sessionId, CancellationToken cancellationToken = default); /// /// Returns true if the node is in the view. /// ValueTask IsNodeInViewAsync( OperationContext context, NodeId viewId, object nodeHandle, CancellationToken cancellationToken = default); /// /// Returns the metadata needed for validating permissions, associated with the node with /// the option to optimize services by using a cache. /// /// /// Returns null if the node does not exist. /// It should return null in case the implementation wishes to handover the task to the parent INodeManager.GetNodeMetadata /// ValueTask GetPermissionMetadataAsync( OperationContext context, object targetHandle, BrowseResultMask resultMask, Dictionary uniqueNodesServiceAttributesCache, bool permissionsOnly, CancellationToken cancellationToken = default); /// /// Tells the NodeManager to report events from the specified notifier. /// /// /// This method may be called multiple times for the name monitoredItemId if the /// context for that MonitoredItem changes (i.e. UserIdentity and/or Locales). /// ValueTask SubscribeToEventsAsync( OperationContext context, object sourceId, uint subscriptionId, IEventMonitoredItem monitoredItem, bool unsubscribe, CancellationToken cancellationToken = default); /// /// Tells the NodeManager to report events all events from all sources. /// /// /// This method may be called multiple times for the name monitoredItemId if the /// context for that MonitoredItem changes (i.e. UserIdentity and/or Locales). /// ValueTask SubscribeToAllEventsAsync( OperationContext context, uint subscriptionId, IEventMonitoredItem monitoredItem, bool unsubscribe, CancellationToken cancellationToken = default); /// /// Restore a set of monitored items after a restart. /// ValueTask RestoreMonitoredItemsAsync( IList itemsToRestore, IList monitoredItems, IUserIdentity savedOwnerIdentity, CancellationToken cancellationToken = default); /// /// Validates if the specified event monitored item has enough permissions to receive the specified event /// ValueTask ValidateEventRolePermissionsAsync( IEventMonitoredItem monitoredItem, IFilterTarget filterTarget, CancellationToken cancellationToken = default); /// /// Validates Role permissions for the specified NodeId /// ValueTask ValidateRolePermissionsAsync( OperationContext operationContext, NodeId nodeId, PermissionType requestedPermission, CancellationToken cancellationToken = default); /// /// Returns true if the specified node has opted into /// multiple event consumer task handling. /// /// The to check. bool IsMultipleEventConsumerNode(NodeId nodeId); } /// /// Stores metadata required to process requests related to a node. /// public class NodeMetadata { /// /// Initializes the object with its handle and NodeId. /// public NodeMetadata(object handle, NodeId nodeId) { Handle = handle; NodeId = nodeId; } /// /// The handle assigned by the NodeManager that owns the Node. /// public object Handle { get; } /// /// The canonical NodeId for the Node. /// public NodeId NodeId { get; } /// /// The NodeClass for the Node. /// public NodeClass NodeClass { get; set; } /// /// The BrowseName for the Node. /// public QualifiedName BrowseName { get; set; } /// /// The DisplayName for the Node. /// public LocalizedText DisplayName { get; set; } /// /// The type definition for the Node (if one exists). /// public ExpandedNodeId TypeDefinition { get; set; } /// /// The modelling for the Node (if one exists). /// public NodeId ModellingRule { get; set; } /// /// Specifies which attributes are writeable. /// public AttributeWriteMask WriteMask { get; set; } /// /// Whether the Node can be used with event subscriptions or for historial event queries. /// public byte EventNotifier { get; set; } /// /// Whether the Node can be use to read or write current or historical values. /// public byte AccessLevel { get; set; } /// /// Whether the Node is a Method that can be executed. /// public bool Executable { get; set; } /// /// The DataType of the Value attribute for Variable or VariableType nodes. /// public NodeId DataType { get; set; } /// /// The ValueRank for the Value attribute for Variable or VariableType nodes. /// public int ValueRank { get; set; } /// /// The ArrayDimensions for the Value attribute for Variable or VariableType nodes. /// public ArrayOf ArrayDimensions { get; set; } /// /// Specifies the AccessRestrictions that apply to a Node. /// public AccessRestrictionType AccessRestrictions { get; set; } /// /// The value reflects the DefaultAccessRestrictions Property of the NamespaceMetadata Object for the Namespace /// to which the Node belongs. /// public AccessRestrictionType DefaultAccessRestrictions { get; set; } /// /// The RolePermissions for the Node. /// Specifies the Permissions that apply to a Node for all Roles which have access to the Node. /// public ArrayOf RolePermissions { get; set; } /// /// The DefaultRolePermissions of the Node's name-space meta-data /// The value reflects the DefaultRolePermissions Property from the NamespaceMetadata Object associated with the Node. /// public ArrayOf DefaultRolePermissions { get; set; } /// /// The UserRolePermissions of the Node. /// Specifies the Permissions that apply to a Node for all Roles granted to current Session. /// public ArrayOf UserRolePermissions { get; set; } /// /// The DefaultUserRolePermissions of the Node. /// The value reflects the DefaultUserRolePermissions Property from the NamespaceMetadata Object associated with the Node. /// public ArrayOf DefaultUserRolePermissions { get; set; } /// /// Indicates this node is part of a type hierarchy (ObjectType/VariableType /// or a child thereof). Type hierarchy nodes bypass access restriction and /// role permission validation. /// public bool IsPartOfTypeHierarchy { get; set; } } }