/// <summary>
        /// Subscribes or unsubscribes to events produced an event source.
        /// </summary>
        public override ServiceResult SubscribeToEvents(
            OperationContext context,
            object sourceId,
            uint subscriptionId,
            IEventMonitoredItem monitoredItem,
            bool unsubscribe)
        {
            ServerSystemContext systemContext = SystemContext.Copy(context);

            // send request to external system.
            try
            {
                MonitoredItem localItem = monitoredItem as MonitoredItem;

                if (localItem == null)
                {
                    return ServiceResult.Good;
                }

                Opc.Ua.Client.Session client = GetClientSession(systemContext);


                if (unsubscribe)
                {
                    lock (client)
                    {
                        // get the subscription.
                        Opc.Ua.Client.Subscription target = null;

                        foreach (Opc.Ua.Client.Subscription current in client.Subscriptions)
                        {
                            target = current;
                            break;
                        }

                        if (target == null)
                        {
                            return ServiceResult.Good;
                        }

                        // find matching item.
                        Opc.Ua.Client.MonitoredItem remoteItem = target.FindItemByClientHandle(monitoredItem.Id);

                        if (remoteItem == null)
                        {
                            return ServiceResult.Good;
                        }

                        // apply changes.
                        target.RemoveItem(remoteItem);
                        target.ApplyChanges();

                        if (target.MonitoredItemCount == 0)
                        {
                            target.Session.RemoveSubscription(target);
                        }
                    }

                    return ServiceResult.Good;
                }
                
                // create a request.
                Opc.Ua.Client.MonitoredItem request = new Opc.Ua.Client.MonitoredItem(localItem.Id);

                if (localItem.NodeId == ObjectIds.Server || localItem.NodeId == m_root.NodeId)
                {
                    request.StartNodeId = ObjectIds.Server;
                }
                else
                {
                    request.StartNodeId = m_mapper.ToRemoteId(localItem.NodeId);
                }

                request.AttributeId = Attributes.EventNotifier;
                request.MonitoringMode = localItem.MonitoringMode;
                request.SamplingInterval = (int)localItem.SamplingInterval;
                request.QueueSize = localItem.QueueSize;
                request.DiscardOldest = true;
                request.Filter = localItem.Filter;
                request.Handle = localItem;

                lock (client)
                {
                    // create subscription.
                    if (client.SubscriptionCount == 0)
                    {
                        Opc.Ua.Client.Subscription subscription = new Opc.Ua.Client.Subscription();

                        subscription.PublishingInterval = 250;
                        subscription.KeepAliveCount = 100;
                        subscription.LifetimeCount = 1000;
                        subscription.MaxNotificationsPerPublish = 10000;
                        subscription.Priority = 1;
                        subscription.PublishingEnabled = true;
                        subscription.TimestampsToReturn = TimestampsToReturn.Both;
                        subscription.DisableMonitoredItemCache = true;
                        subscription.FastDataChangeCallback = OnDataChangeNotification;
                        subscription.FastEventCallback = OnEventNotification;

                        client.AddSubscription(subscription);
                        subscription.Create();
                    }

                    // get the subscription.
                    Opc.Ua.Client.Subscription target = null;

                    foreach (Opc.Ua.Client.Subscription current in client.Subscriptions)
                    {
                        target = current;
                        break;
                    }

                    if (target == null)
                    {
                        return ServiceResult.Good;
                    }

                    target.AddItem(request);
                    target.ApplyChanges();

                    if (ServiceResult.IsBad(request.Status.Error))
                    {
                        Utils.Trace((int)Utils.TraceMasks.Error, "Could not create event item. {0}", request.Status.Error.ToLongString());
                    }
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Could not access external system.");
            }

            return ServiceResult.Good;
        }
Example #2
0
        /// <summary>
        /// Reports an event produced by the object.
        /// </summary>
        public virtual void ReportEvent(BaseEvent e)
        {
            lock (DataLock)
            {
                if (m_reportEventsToParent)
                {
                    ObjectSource parent = Parent as ObjectSource;

                    if (parent != null)
                    {
                        parent.ReportEvent(e);
                    }
                }

                List <IEventMonitoredItem> monitoredItems = new List <IEventMonitoredItem>();

                if (MonitoredItems != null)
                {
                    foreach (IMonitoredItem monitoredItem in MonitoredItems)
                    {
                        IEventMonitoredItem eventItem = monitoredItem as IEventMonitoredItem;

                        if (eventItem != null)
                        {
                            monitoredItems.Add(eventItem);
                        }
                    }

                    if (monitoredItems.Count > 0)
                    {
                        EventManager.ReportEvent(e, monitoredItems);
                    }
                }
            }
        }
        /// <summary>
        /// Called when a Node produces an event.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="node">The affected node.</param>
        /// <param name="e">The event.</param>
        public void OnReportEvent(ISystemContext context, NodeState node, IFilterTarget e)
        {
            List <IEventMonitoredItem> eventMonitoredItems = new List <IEventMonitoredItem>();

            lock (NodeManager.Lock)
            {
                if (EventMonitoredItems == null)
                {
                    return;
                }

                for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
                {
                    IEventMonitoredItem monitoredItem = EventMonitoredItems[ii];
                    // enqueue event for role permission validation
                    eventMonitoredItems.Add(monitoredItem);
                }
            }

            for (int ii = 0; ii < eventMonitoredItems.Count; ii++)
            {
                IEventMonitoredItem monitoredItem = eventMonitoredItems[ii];

                #region  Filter out audit events in case the Server_Auditing values is false or the channel is not encrypted

                if (e is AuditEventState)
                {
                    // check Server.Auditing flag and skip if false
                    if (!NodeManager.Server.Auditing)
                    {
                        continue;
                    }
                    else
                    {
                        // check if channel is not encrypted and skip if so
                        if (monitoredItem?.Session?.EndpointDescription?.SecurityMode != MessageSecurityMode.SignAndEncrypt &&
                            monitoredItem?.Session?.EndpointDescription?.TransportProfileUri != Profiles.HttpsBinaryTransport)
                        {
                            continue;
                        }
                    }
                }
                #endregion

                // validate if the monitored item has the required role permissions to receive the event
                ServiceResult validationResult = NodeManager.ValidateEventRolePermissions(monitoredItem, e);

                if (ServiceResult.IsBad(validationResult))
                {
                    // skip event reporting for EventType without permissions
                    continue;
                }

                lock (NodeManager.Lock)
                {
                    // enqueue event
                    monitoredItem?.QueueEvent(e);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Modifies a monitored item.
        /// </summary>
        public void ModifyMonitoredItem(
            OperationContext context,
            IEventMonitoredItem monitoredItem,
            TimestampsToReturn timestampsToReturn,
            MonitoredItemModifyRequest itemToModify,
            EventFilter filter)
        {
            lock (m_lock) {
                // should never be called with items that it does not own.
                if (!m_monitoredItems.ContainsKey(monitoredItem.Id))
                {
                    return;
                }

                // limit the queue size.
                uint queueSize = itemToModify.RequestedParameters.QueueSize;

                if (queueSize > m_maxEventQueueSize)
                {
                    queueSize = m_maxEventQueueSize;
                }

                // modify the attributes.
                monitoredItem.ModifyAttributes(
                    context.DiagnosticsMask,
                    timestampsToReturn,
                    itemToModify.RequestedParameters.ClientHandle,
                    filter,
                    filter,
                    null,
                    itemToModify.RequestedParameters.SamplingInterval,
                    queueSize,
                    itemToModify.RequestedParameters.DiscardOldest);
            }
        }
Example #5
0
        /// <summary>
        /// Resends the events for any conditions belonging to the node or its children.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="monitoredItem">The item to refresh.</param>
        public void ConditionRefresh(
            ISystemContext context,
            IEventMonitoredItem monitoredItem)
        {
            if (m_eventSubscriptions != null)
            {
                for (int ii = 0; ii < m_eventSubscriptions.Count; ii++)
                {
                    // only process items monitoring this node.
                    if (!Object.ReferenceEquals(monitoredItem, m_eventSubscriptions[ii]))
                    {
                        continue;
                    }

                    // get the set of condition events for the node and its children.
                    List <IFilterTarget> events = new List <IFilterTarget>();
                    m_node.ConditionRefresh(context, events, true);

                    // report the events to the monitored item.
                    for (int jj = 0; jj < events.Count; jj++)
                    {
                        monitoredItem.QueueEvent(events[jj]);
                    }
                }
            }
        }
        /// <summary>
        /// Adds the specified event monitored item.
        /// </summary>
        /// <param name="eventItem">The monitored item.</param>
        public void Add(IEventMonitoredItem eventItem)
        {
            if (EventMonitoredItems == null)
            {
                EventMonitoredItems = new List <IEventMonitoredItem>();
                Node.OnReportEvent  = OnReportEvent;
            }

            EventMonitoredItems.Add(eventItem);
        }
 /// <summary>
 /// Called when a Node produces an event.
 /// </summary>
 /// <param name="context">The system context.</param>
 /// <param name="node">The affected node.</param>
 /// <param name="e">The event.</param>
 public void OnReportEvent(ISystemContext context, NodeState node, IFilterTarget e)
 {
     lock (NodeManager.Lock)
     {
         for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
         {
             IEventMonitoredItem monitoredItem = EventMonitoredItems[ii];
             monitoredItem.QueueEvent(e);
         }
     }
 }
Example #8
0
        /// <summary>
        /// Called when a Node produces an event.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="node">The affected node.</param>
        /// <param name="e">The event.</param>
        public void OnReportEvent(ISystemContext context, NodeState node, IFilterTarget e)
        {
            List <IEventMonitoredItem> eventMonitoredItems = new List <IEventMonitoredItem>();

            lock (NodeManager.Lock)
            {
                if (EventMonitoredItems == null)
                {
                    return;
                }

                for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
                {
                    IEventMonitoredItem monitoredItem = EventMonitoredItems[ii];
                    // enqueue event for role permission validation
                    eventMonitoredItems.Add(monitoredItem);
                }
            }

            for (int ii = 0; ii < eventMonitoredItems.Count; ii++)
            {
                IEventMonitoredItem monitoredItem  = eventMonitoredItems[ii];
                BaseEventState      baseEventState = e as BaseEventState;

                if (baseEventState != null)
                {
                    ServiceResult validationResult = NodeManager.ValidateRolePermissions(new OperationContext(monitoredItem),
                                                                                         baseEventState?.EventType?.Value, PermissionType.ReceiveEvents);

                    if (ServiceResult.IsBad(validationResult))
                    {
                        // skip event reporting for EventType without permissions
                        continue;
                    }

                    validationResult = NodeManager.ValidateRolePermissions(new OperationContext(monitoredItem),
                                                                           baseEventState?.SourceNode?.Value, PermissionType.ReceiveEvents);

                    if (ServiceResult.IsBad(validationResult))
                    {
                        // skip event reporting for SourceNode without permissions
                        continue;
                    }
                }

                lock (NodeManager.Lock)
                {
                    // enqueue event
                    monitoredItem?.QueueEvent(e);
                }
            }
        }
        /// <summary>
        /// Removes the specified event monitored item.
        /// </summary>
        /// <param name="eventItem">The monitored item.</param>
        public void Remove(IEventMonitoredItem eventItem)
        {
            for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
            {
                if (Object.ReferenceEquals(EventMonitoredItems[ii], eventItem))
                {
                    EventMonitoredItems.RemoveAt(ii);
                    break;
                }
            }

            if (EventMonitoredItems.Count == 0)
            {
                EventMonitoredItems = null;
                Node.OnReportEvent  = null;
            }
        }
Example #10
0
 /// <summary cref="IEventSource.SubscribeToEvents" />
 public void SubscribeToEvents(
     OperationContext context,
     object notifier,
     uint subscriptionId,
     IEventMonitoredItem monitoredItem,
     bool unsubscribe)
 {
     lock (DataLock)
     {
         if (unsubscribe)
         {
             Unsubscribe(monitoredItem);
         }
         else
         {
             Subscribe(monitoredItem);
         }
     }
 }
Example #11
0
        /// <summary>
        /// Unsubscribes to events produced by the node.
        /// </summary>
        public void UnsubscribeToEvents(ISystemContext context, IEventMonitoredItem eventSubscription)
        {
            if (m_eventSubscriptions != null)
            {
                for (int ii = 0; ii < m_eventSubscriptions.Count; ii++)
                {
                    if (Object.ReferenceEquals(eventSubscription, m_eventSubscriptions[ii]))
                    {
                        m_eventSubscriptions.RemoveAt(ii);

                        if (m_eventSubscriptions.Count == 0)
                        {
                            m_node.SetAreEventsMonitored(context, false, true);
                            m_node.OnReportEvent = null;
                        }

                        break;
                    }
                }
            }
        }
Example #12
0
        /// <summary>
        /// Subscribes to events produced by the node.
        /// </summary>
        public void SubscribeToEvents(ISystemContext context, IEventMonitoredItem eventSubscription)
        {
            if (m_eventSubscriptions == null)
            {
                m_eventSubscriptions = new List <IEventMonitoredItem>();
            }

            if (m_eventSubscriptions.Count == 0)
            {
                m_node.OnReportEvent = OnReportEvent;
                m_node.SetAreEventsMonitored(context, true, true);
            }

            for (int ii = 0; ii < m_eventSubscriptions.Count; ii++)
            {
                if (Object.ReferenceEquals(eventSubscription, m_eventSubscriptions[ii]))
                {
                    return;
                }
            }

            m_eventSubscriptions.Add(eventSubscription);
        }
Example #13
0
        /// <summary cref="IEventSource.SubscribeToAllEvents" />
        public void SubscribeToAllEvents(
            OperationContext context,
            uint subscriptionId,
            IEventMonitoredItem monitoredItem,
            bool unsubscribe)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            lock (DataLock)
            {
                if (unsubscribe)
                {
                    Unsubscribe(monitoredItem);
                }
                else
                {
                    Subscribe(monitoredItem);
                }
            }
        }
Example #14
0
        /// <summary>
        /// Subscribes to events produced by the node.
        /// </summary>
        public void SubscribeToEvents(ISystemContext context, IEventMonitoredItem eventSubscription)
        {
            if (_eventSubscriptions == null)
            {
                _eventSubscriptions = new List <IEventMonitoredItem>();
            }

            if (_eventSubscriptions.Count == 0)
            {
                Node.OnReportEvent = OnReportEvent;
                Node.SetAreEventsMonitored(context, true, true);
            }

            for (var ii = 0; ii < _eventSubscriptions.Count; ii++)
            {
                if (ReferenceEquals(eventSubscription, _eventSubscriptions[ii]))
                {
                    return;
                }
            }

            _eventSubscriptions.Add(eventSubscription);
        }
Example #15
0
        /// <summary>
        /// Called when a Node produces an event.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="node">The affected node.</param>
        /// <param name="e">The event.</param>
        public void OnReportEvent(ISystemContext context, NodeState node, IFilterTarget e)
        {
            lock (NodeManager.Lock)
            {
                if (EventMonitoredItems == null)
                {
                    return;
                }

                for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
                {
                    IEventMonitoredItem monitoredItem  = EventMonitoredItems[ii];
                    BaseEventState      baseEventState = e as BaseEventState;
                    if (baseEventState != null)
                    {
                        ServiceResult validationResult = NodeManager.ValidateRolePermissions(new OperationContext(monitoredItem),
                                                                                             baseEventState?.EventType?.Value, PermissionType.ReceiveEvents);
                        if (ServiceResult.IsBad(validationResult))
                        {
                            // ignore invalid permission type events
                            continue;
                        }

                        validationResult = NodeManager.ValidateRolePermissions(new OperationContext(monitoredItem),
                                                                               baseEventState?.SourceNode?.Value, PermissionType.ReceiveEvents);
                        if (ServiceResult.IsBad(validationResult))
                        {
                            // ignore invalid permission type events
                            continue;
                        }

                        // enque event
                        monitoredItem.QueueEvent(e);
                    }
                }
            }
        }
Example #16
0
        /// <summary>
        /// Subscribes or unsubscribes to events produced by all event sources.
        /// </summary>
        /// <remarks>
        /// This method is called when a event subscription is created or deleted. The node
        /// manager must start/stop reporting events for all objects that it manages.
        /// </remarks>
        public override ServiceResult SubscribeToAllEvents(
            Opc.Ua.Server.OperationContext context,
            uint subscriptionId,
            IEventMonitoredItem monitoredItem,
            bool unsubscribe)
        {
            ServerSystemContext serverSystemContext = SystemContext.Copy(context);

            lock (Lock)
            {
                // A client has subscribed to the Server object which means all events produced
                // by this manager must be reported. This is done by incrementing the monitoring
                // reference count for all root notifiers.
                if (_rootNotifiers != null)
                {
                    for (int ii = 0; ii < _rootNotifiers.Count; ii++)
                    {
                        SubscribeToEvents(serverSystemContext, _rootNotifiers[ii], monitoredItem, unsubscribe);
                    }
                }

                return(ServiceResult.Good);
            }
        }
Example #17
0
        /// <summary>
        /// Adds the specified event monitored item.
        /// </summary>
        /// <param name="eventItem">The monitored item.</param>
        public void Add(IEventMonitoredItem eventItem)
        {
            if (EventMonitoredItems == null)
            {
                EventMonitoredItems = new List<IEventMonitoredItem>();
                Node.OnReportEvent = OnReportEvent;
            }

            EventMonitoredItems.Add(eventItem);
        }
Example #18
0
        /// <summary>
        /// Removes the specified event monitored item.
        /// </summary>
        /// <param name="eventItem">The monitored item.</param>
        public void Remove(IEventMonitoredItem eventItem)
        {
            for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
            {
                if (Object.ReferenceEquals(EventMonitoredItems[ii], eventItem))
                {
                    EventMonitoredItems.RemoveAt(ii);
                    break;
                }
            }

            if (EventMonitoredItems.Count == 0)
            {
                EventMonitoredItems = null;
                Node.OnReportEvent = null;
            }
        }
        /// <summary>
        /// Resends the events for any conditions belonging to the node or its children.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="monitoredItem">The item to refresh.</param>
        public void ConditionRefresh(
            ISystemContext context, 
            IEventMonitoredItem monitoredItem)
        {
            if (m_eventSubscriptions != null)
            {
                for (int ii = 0; ii < m_eventSubscriptions.Count; ii++)
                {
                    // only process items monitoring this node.
                    if (!Object.ReferenceEquals(monitoredItem, m_eventSubscriptions[ii]))
                    {
                        continue;
                    }
                    
                    // get the set of condition events for the node and its children.
                    List<IFilterTarget> events = new List<IFilterTarget>();
                    m_node.ConditionRefresh(context, events, true);

                    // report the events to the monitored item.
                    for (int jj = 0; jj < events.Count; jj++)
                    {
                        monitoredItem.QueueEvent(events[jj]);
                    }
                }
            }
        }
Example #20
0
        /// <summary cref="IEventSource.SubscribeToAllEvents" /> 
        public void SubscribeToAllEvents(
            OperationContext    context, 
            uint                subscriptionId,
            IEventMonitoredItem monitoredItem,
            bool                unsubscribe)
        {
            if (context == null)  throw new ArgumentNullException("context");

            lock (DataLock)
            {
                if (unsubscribe)
                {
                    Unsubscribe(monitoredItem);
                }
                else
                {
                    Subscribe(monitoredItem);
                }
            }
        }
        /// <summary>
        /// Subscribes to events.
        /// </summary>
        protected override ServiceResult SubscribeToEvents(
            ServerSystemContext context,
            NodeState source,
            IEventMonitoredItem monitoredItem,
            bool unsubscribe)
        {
            ComAeClientManager system = (ComAeClientManager)this.SystemContext.SystemHandle;
            ComAeClient client = (ComAeClient)system.SelectClient(context, false);

            // need to wait until the cache is refreshed for the first time.
            if (!WaitForTypeCache())
            {
                return StatusCodes.BadOutOfService;
            }

            lock (Lock)
            {
                SubscriptionIndex index = new SubscriptionIndex();
                index.NodeId = source.NodeId;
                index.LocaleId = client.LocaleId;

                if (unsubscribe)
                {
                    ComAeSubscriptionClient subscription = null;

                    if (!m_monitoredItems.TryGetValue(monitoredItem.Id, out subscription))
                    {
                        return ServiceResult.Good;
                    }

                    m_monitoredItems.Remove(monitoredItem.Id);
                    // Utils.Trace("REMOVED ITEM {0}", monitoredItem.Id);

                    if (subscription.RemoveItem(monitoredItem as MonitoredItem) == 0)
                    {
                        subscription.Delete();
                        m_subscriptions.Remove(index);
                        // Utils.Trace("DELETED SUBSCRIPTION {0}", index.NodeId);
                    }
                }
                else
                {
                    ComAeSubscriptionClient subscription = null;

                    if (!m_subscriptions.TryGetValue(index, out subscription))
                    {
                        subscription = new ComAeSubscriptionClient(context, m_configuration, m_typeCache, NamespaceIndex, system, monitoredItem as MonitoredItem);
                        m_subscriptions.Add(index, subscription);
                        subscription.Create();
                        // Utils.Trace("ADDED NEW SUBSCRIPTION {0}", index.NodeId);
                    }
                    else
                    {
                        subscription.AddItem(monitoredItem as MonitoredItem);
                    }

                    m_monitoredItems[monitoredItem.Id] = subscription;
                    // Utils.Trace("ADDED NEW ITEM {0}", monitoredItem.Id);
                }
            }

            // all done.
            return ServiceResult.Good;
        }
 /// <summary>
 /// Does any processing after a monitored item is subscribed to.
 /// </summary>
 protected virtual void OnUnsubscribeToEvents(
     ISystemContext systemContext,
     MonitoredNode monitoredNode,
     IEventMonitoredItem monitoredItem)
 {
     // does nothing.
 }
        /// <summary>
        /// Subscribes or unsubscribes to events produced by all event sources.
        /// </summary>
        /// <remarks>
        /// This method is called when a event subscription is created or deleted. The node 
        /// manager must start/stop reporting events for all objects that it manages.
        /// </remarks>
        public virtual ServiceResult SubscribeToAllEvents(
            OperationContext    context, 
            uint                subscriptionId, 
            IEventMonitoredItem monitoredItem, 
            bool                unsubscribe)
        {
            ServerSystemContext systemContext = m_systemContext.Copy(context);
            IDictionary<NodeId,NodeState> operationCache = new NodeIdDictionary<NodeState>();

            lock (Lock)
            {
                // update root notifiers.
                for (int ii = 0; ii < m_rootNotifiers.Count; ii++)
                {
                    SubscribeToAllEvents(
                        systemContext,
                        monitoredItem,
                        unsubscribe,
                        m_rootNotifiers[ii]);
                }

                return ServiceResult.Good;
            }
        }
        /// <summary>
        /// Subscribes or unsubscribes to events produced by the specified source.
        /// </summary>
        /// <remarks>
        /// This method is called when a event subscription is created or deletes. The node manager 
        /// must  start/stop reporting events for the specified object and all objects below it in 
        /// the notifier hierarchy.
        /// </remarks>
        public virtual ServiceResult SubscribeToEvents(
            OperationContext    context, 
            object              sourceId, 
            uint                subscriptionId, 
            IEventMonitoredItem monitoredItem, 
            bool                unsubscribe)
        {
            ServerSystemContext systemContext = SystemContext.Copy(context);

            lock (Lock)
            {
                // check for valid handle.
                NodeHandle handle = IsHandleInNamespace(sourceId);

                if (handle == null)
                {
                    return StatusCodes.BadNodeIdInvalid;
                }

                // check for valid node.
                NodeState source = ValidateNode(systemContext, handle, null);

                if (source == null)
                {
                    return StatusCodes.BadNodeIdUnknown;
                }

                // subscribe to events.
                return SubscribeToEvents(systemContext, source, monitoredItem, unsubscribe);
            }
        }
Example #25
0
        /// <summary>
        /// Modifies a monitored item.
        /// </summary>
        public void ModifyMonitoredItem(
            OperationContext           context,
            IEventMonitoredItem        monitoredItem,
            TimestampsToReturn         timestampsToReturn,
            MonitoredItemModifyRequest itemToModify,
            EventFilter                filter)
        {
            lock (m_lock)
            {
                // should never be called with items that it does not own.
                if (!m_monitoredItems.ContainsKey(monitoredItem.Id))
                {
                    return;
                }

                // limit the queue size.
                uint queueSize = itemToModify.RequestedParameters.QueueSize;

                if (queueSize > m_maxEventQueueSize)
                {
                    queueSize = m_maxEventQueueSize;
                }

                // modify the attributes.
                monitoredItem.ModifyAttributes(
                    context.DiagnosticsMask,
                    timestampsToReturn,
                    itemToModify.RequestedParameters.ClientHandle,
                    filter,
                    filter,
                    null,
                    itemToModify.RequestedParameters.SamplingInterval,
                    queueSize,
                    itemToModify.RequestedParameters.DiscardOldest);
            }           
        }
 /// <summary>
 /// Subscribes or unsubscribes to events produced by all event sources.
 /// </summary>
 public override ServiceResult SubscribeToAllEvents(
     OperationContext context,
     uint subscriptionId,
     IEventMonitoredItem monitoredItem,
     bool unsubscribe)
 {
     return SubscribeToEvents(context, null, subscriptionId, monitoredItem, unsubscribe);
 }
        /// <summary>
        /// Subscribes to events.
        /// </summary>
        protected override ServiceResult SubscribeToEvents(
            ServerSystemContext context,
            NodeState source,
            IEventMonitoredItem monitoredItem,
            bool unsubscribe)
        {
            ComAeClientManager system = (ComAeClientManager)this.SystemContext.SystemHandle;
            ComAeClient        client = (ComAeClient)system.SelectClient(context, false);

            // need to wait until the cache is refreshed for the first time.
            if (!WaitForTypeCache())
            {
                return(StatusCodes.BadOutOfService);
            }

            lock (Lock)
            {
                SubscriptionIndex index = new SubscriptionIndex();
                index.NodeId   = source.NodeId;
                index.LocaleId = client.LocaleId;

                if (unsubscribe)
                {
                    ComAeSubscriptionClient subscription = null;

                    if (!m_monitoredItems.TryGetValue(monitoredItem.Id, out subscription))
                    {
                        return(ServiceResult.Good);
                    }

                    m_monitoredItems.Remove(monitoredItem.Id);
                    // Utils.Trace("REMOVED ITEM {0}", monitoredItem.Id);

                    if (subscription.RemoveItem(monitoredItem as MonitoredItem) == 0)
                    {
                        subscription.Delete();
                        m_subscriptions.Remove(index);
                        // Utils.Trace("DELETED SUBSCRIPTION {0}", index.NodeId);
                    }
                }
                else
                {
                    ComAeSubscriptionClient subscription = null;

                    if (!m_subscriptions.TryGetValue(index, out subscription))
                    {
                        subscription = new ComAeSubscriptionClient(context, m_configuration, m_typeCache, NamespaceIndex, system, monitoredItem as MonitoredItem);
                        m_subscriptions.Add(index, subscription);
                        subscription.Create();
                        // Utils.Trace("ADDED NEW SUBSCRIPTION {0}", index.NodeId);
                    }
                    else
                    {
                        subscription.AddItem(monitoredItem as MonitoredItem);
                    }

                    m_monitoredItems[monitoredItem.Id] = subscription;
                    // Utils.Trace("ADDED NEW ITEM {0}", monitoredItem.Id);
                }
            }

            // all done.
            return(ServiceResult.Good);
        }
Example #28
0
        /// <summary>
        /// Called when a Node produces an event.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="node">The affected node.</param>
        /// <param name="e">The event.</param>
        public void OnReportEvent(ISystemContext context, NodeState node, IFilterTarget e)
        {
            List <IEventMonitoredItem> eventMonitoredItems = new List <IEventMonitoredItem>();

            lock (NodeManager.Lock)
            {
                if (EventMonitoredItems == null)
                {
                    return;
                }

                for (int ii = 0; ii < EventMonitoredItems.Count; ii++)
                {
                    IEventMonitoredItem monitoredItem = EventMonitoredItems[ii];
                    // enqueue event for role permission validation
                    eventMonitoredItems.Add(monitoredItem);
                }
            }

            for (int ii = 0; ii < eventMonitoredItems.Count; ii++)
            {
                IEventMonitoredItem monitoredItem  = eventMonitoredItems[ii];
                BaseEventState      baseEventState = e as BaseEventState;

                if (baseEventState != null)
                {
                    #region  Filter out audit events in case the Server_Auditing values is false or the channel is not encrypted

                    if (e is AuditEventState)
                    {
                        // check Server.Auditing flag and skip if false
                        if (!NodeManager.Server.EventManager.ServerAuditing)
                        {
                            continue;
                        }
                        else
                        {
                            // check if channel is not encrypted and skip if so
                            OperationContext operationContext = (context as SystemContext)?.OperationContext as OperationContext;
                            if (operationContext != null &&
                                operationContext.ChannelContext.EndpointDescription.SecurityMode != MessageSecurityMode.SignAndEncrypt &&
                                operationContext.ChannelContext.EndpointDescription.TransportProfileUri != Profiles.HttpsBinaryTransport)
                            {
                                continue;
                            }
                        }
                    }
                    #endregion

                    ServiceResult validationResult = NodeManager.ValidateRolePermissions(new OperationContext(monitoredItem),
                                                                                         baseEventState?.EventType?.Value, PermissionType.ReceiveEvents);


                    if (ServiceResult.IsBad(validationResult))
                    {
                        // skip event reporting for EventType without permissions
                        continue;
                    }

                    validationResult = NodeManager.ValidateRolePermissions(new OperationContext(monitoredItem),
                                                                           baseEventState?.SourceNode?.Value, PermissionType.ReceiveEvents);

                    if (ServiceResult.IsBad(validationResult))
                    {
                        // skip event reporting for SourceNode without permissions
                        continue;
                    }
                }

                lock (NodeManager.Lock)
                {
                    // enqueue event
                    monitoredItem?.QueueEvent(e);
                }
            }
        }
        /// <see cref="INodeManager.SubscribeToAllEvents" />
        public ServiceResult SubscribeToAllEvents(
            OperationContext    context,
            uint                subscriptionId,
            IEventMonitoredItem monitoredItem,
            bool                unsubscribe)
        {  
            if (context == null)  throw new ArgumentNullException("context");
            if (monitoredItem == null)  throw new ArgumentNullException("monitoredItem");
            
            #if LEGACY_CORENODEMANAGER
            try
            {
                m_lock.Enter();
                
                foreach (IEventSource eventSource in m_eventSources.Values)
                {
                    eventSource.SubscribeToAllEvents(context, subscriptionId, monitoredItem, unsubscribe);
                }

                return ServiceResult.Good;
            }
            finally
            {
                m_lock.Exit();
            }    
            #else
            return ServiceResult.Good;
            #endif 
        }
        /// <see cref="INodeManager.SubscribeToEvents" />
        public ServiceResult SubscribeToEvents(
            OperationContext    context,
            object              sourceId,
            uint                subscriptionId,
            IEventMonitoredItem monitoredItem,
            bool                unsubscribe)
        {
            if (context == null)  throw new ArgumentNullException("context");
            if (sourceId == null) throw new ArgumentNullException("sourceId");
            if (monitoredItem == null) throw new ArgumentNullException("monitoredItem");

            lock (m_lock)
            {
                // validate the node.
                NodeMetadata metadata = GetNodeMetadata(context, sourceId, BrowseResultMask.NodeClass);

                if (metadata == null)
                {
                    return StatusCodes.BadNodeIdUnknown;
                }

                // validate the node class.
                if (((metadata.NodeClass & NodeClass.Object | NodeClass.View)) == 0)
                {
                    return StatusCodes.BadNotSupported;
                }

                // check that it supports events.
                if ((metadata.EventNotifier & EventNotifiers.SubscribeToEvents) == 0)
                {
                    return StatusCodes.BadNotSupported;
                }
                
                #if LEGACY_CORENODEMANAGER  
                // subscribe to all notifiers below the notifier.
                SubscribeToEvents(
                    context, 
                    metadata.Handle as ILocalNode, 
                    subscriptionId, 
                    monitoredItem, 
                    unsubscribe);
                #endif
                
                return ServiceResult.Good;
            }
        }
Example #31
0
        /// <summary>
        /// Subscribes to events.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="source">The source.</param>
        /// <param name="monitoredItem">The monitored item.</param>
        /// <param name="unsubscribe">if set to <c>true</c> [unsubscribe].</param>
        /// <returns>Any error code.</returns>
        protected override ServiceResult SubscribeToEvents(
            ServerSystemContext context,
            NodeState source,
            IEventMonitoredItem monitoredItem,
            bool unsubscribe)
        {
            // handle unsubscribe.
            if (unsubscribe)
            {
                // check for existing monitored node.
                if (!MonitoredNodes.TryGetValue(source.NodeId, out MonitoredNode2 monitoredNode2))
                {
                    return(StatusCodes.BadNodeIdUnknown);
                }

                monitoredNode2.Remove(monitoredItem);

                // check if node is no longer being monitored.
                if (!monitoredNode2.HasMonitoredItems)
                {
                    MonitoredNodes.Remove(source.NodeId);
                }

                // update flag.
                source.SetAreEventsMonitored(context, !unsubscribe, true);

                // call subclass.
                OnSubscribeToEvents(context, monitoredNode2, unsubscribe);

                // all done.
                return(ServiceResult.Good);
            }

            // only objects or views can be subscribed to.
            BaseObjectState instance = source as BaseObjectState;

            if (instance == null || (instance.EventNotifier & EventNotifiers.SubscribeToEvents) == 0)
            {
                ViewState view = source as ViewState;

                if (view == null || (view.EventNotifier & EventNotifiers.SubscribeToEvents) == 0)
                {
                    return(StatusCodes.BadNotSupported);
                }
            }

            // check for existing monitored node.
            if (!MonitoredNodes.TryGetValue(source.NodeId, out MonitoredNode2 monitoredNode))
            {
                MonitoredNodes[source.NodeId] = monitoredNode = new MonitoredNode2(this, source);
            }

            // this links the node to specified monitored item and ensures all events
            // reported by the node are added to the monitored item's queue.
            monitoredNode.Add(monitoredItem);

            // This call recursively updates a reference count all nodes in the notifier
            // hierarchy below the area. Sources with a reference count of 0 do not have
            // any active subscriptions so they do not need to report events.
            source.SetAreEventsMonitored(context, !unsubscribe, true);

            // signal update.
            OnSubscribeToEvents(context, monitoredNode, unsubscribe);

            // all done.
            return(ServiceResult.Good);
        }
        /// <summary>
        /// Subscribes or unsubscribes to events produced by the specified source.
        /// </summary>
        /// <remarks>
        /// This method is called when a event subscription is created or deletes. The node manager 
        /// must  start/stop reporting events for the specified object and all objects below it in 
        /// the notifier hierarchy.
        /// </remarks>
        public virtual ServiceResult SubscribeToEvents(
            OperationContext    context, 
            object              sourceId, 
            uint                subscriptionId, 
            IEventMonitoredItem monitoredItem, 
            bool                unsubscribe)
        {
            ServerSystemContext systemContext = m_systemContext.Copy(context);
            IDictionary<NodeId,NodeState> operationCache = new NodeIdDictionary<NodeState>();

            lock (Lock)
            {
                // check for valid handle.
                NodeState source = IsHandleInNamespace(sourceId);

                if (source == null)
                {
                    return StatusCodes.BadNodeIdInvalid;
                }

                // check if the object supports subscritions.
                BaseObjectState instance = sourceId as BaseObjectState;

                if (instance == null || instance.EventNotifier != EventNotifiers.SubscribeToEvents)
                {
                    return StatusCodes.BadNotSupported;
                }

                MonitoredNode monitoredNode = instance.Handle as MonitoredNode;

                // handle unsubscribe.
                if (unsubscribe)
                {
                    if (monitoredNode != null)
                    {
                        monitoredNode.UnsubscribeToEvents(systemContext, monitoredItem);

                        // do any post processing.
                        OnUnsubscribeToEvents(systemContext, monitoredNode, monitoredItem);
                    }

                    return ServiceResult.Good;
                }

                // subscribe to events.
                if (monitoredNode == null)
                {
                    instance.Handle = monitoredNode = new MonitoredNode(m_server, this, source);
                }

                monitoredNode.SubscribeToEvents(systemContext, monitoredItem);

                // do any post processing.
                OnSubscribeToEvents(systemContext, monitoredNode, monitoredItem);

                return ServiceResult.Good;
            }
        }
        /// <summary>
        /// Subscribes or unsubscribes to events produced by all event sources.
        /// </summary>
        /// <remarks>
        /// This method is called when a event subscription is created or deleted. The node 
        /// manager must start/stop reporting events for all objects that it manages.
        /// </remarks>
        public virtual ServiceResult SubscribeToAllEvents(
            OperationContext    context, 
            uint                subscriptionId, 
            IEventMonitoredItem monitoredItem, 
            bool                unsubscribe)
        {
            ServerSystemContext systemContext = SystemContext.Copy(context);

            lock (Lock)
            {
                // A client has subscribed to the Server object which means all events produced
                // by this manager must be reported. This is done by incrementing the monitoring
                // reference count for all root notifiers.
                if (m_rootNotifiers != null)
                {
                    for (int ii = 0; ii < m_rootNotifiers.Count; ii++)
                    {
                        SubscribeToEvents(systemContext, m_rootNotifiers[ii], monitoredItem, unsubscribe);
                    }
                }

                return ServiceResult.Good;
            }
        }
        /// <summary>
        /// Subscribes/unsubscribes to all events produced by the specified node.
        /// </summary>
        protected void SubscribeToAllEvents(
            ISystemContext      systemContext, 
            IEventMonitoredItem monitoredItem, 
            bool                unsubscribe,
            NodeState           source)
        {
            MonitoredNode monitoredNode = source.Handle as MonitoredNode;

            // handle unsubscribe.
            if (unsubscribe)
            {
                if (monitoredNode != null)
                {
                    monitoredNode.UnsubscribeToEvents(systemContext, monitoredItem);

                    // do any post processing.
                    OnUnsubscribeToEvents(systemContext, monitoredNode, monitoredItem);
                }

                return;
            }

            // subscribe to events.
            if (monitoredNode == null)
            {
                source.Handle = monitoredNode = new MonitoredNode(m_server, this, source);
            }

            monitoredNode.SubscribeToEvents(systemContext, monitoredItem);

            // do any post processing.
            OnSubscribeToEvents(systemContext, monitoredNode, monitoredItem);
        }
        /// <summary>
        /// Subscribes to events.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="source">The source.</param>
        /// <param name="monitoredItem">The monitored item.</param>
        /// <param name="unsubscribe">if set to <c>true</c> [unsubscribe].</param>
        /// <returns>Any error code.</returns>
        protected virtual ServiceResult SubscribeToEvents(
            ServerSystemContext context, 
            NodeState           source,
            IEventMonitoredItem monitoredItem, 
            bool                unsubscribe)
        {
            MonitoredNode monitoredNode = null;

            // handle unsubscribe.
            if (unsubscribe)
            {
                // check for existing monitored node.
                if (!MonitoredNodes.TryGetValue(source.NodeId, out monitoredNode))
                {
                    return StatusCodes.BadNodeIdUnknown;
                }

                monitoredNode.Remove(monitoredItem);

                // check if node is no longer being monitored.
                if (!monitoredNode.HasMonitoredItems)
                {
                    MonitoredNodes.Remove(source.NodeId);
                }

                // update flag.
                source.SetAreEventsMonitored(context, !unsubscribe, true);

                // call subclass.
                OnSubscribeToEvents(context, monitoredNode, unsubscribe);

                // all done.
                return ServiceResult.Good;
            }

            // only objects or views can be subscribed to.
            BaseObjectState instance = source as BaseObjectState;

            if (instance == null || (instance.EventNotifier & EventNotifiers.SubscribeToEvents) == 0)
            {
                ViewState view = source as ViewState;

                if (view == null || (view.EventNotifier & EventNotifiers.SubscribeToEvents) == 0)
                {
                    return StatusCodes.BadNotSupported;
                }
            }

            // check for existing monitored node.
            if (!MonitoredNodes.TryGetValue(source.NodeId, out monitoredNode))
            {
                MonitoredNodes[source.NodeId] = monitoredNode = new MonitoredNode(this, source);
            }

            // this links the node to specified monitored item and ensures all events
            // reported by the node are added to the monitored item's queue.
            monitoredNode.Add(monitoredItem);

            // This call recursively updates a reference count all nodes in the notifier
            // hierarchy below the area. Sources with a reference count of 0 do not have 
            // any active subscriptions so they do not need to report events.
            source.SetAreEventsMonitored(context, !unsubscribe, true);

            // signal update.
            OnSubscribeToEvents(context, monitoredNode, unsubscribe);
 
            // all done.
            return ServiceResult.Good;
        }
        /// <summary>
        /// Subscribes to events produced by the node.
        /// </summary>
        public void SubscribeToEvents(ISystemContext context, IEventMonitoredItem eventSubscription)
        {
            if (m_eventSubscriptions == null)
            {
                m_eventSubscriptions = new List<IEventMonitoredItem>();
            }

            if (m_eventSubscriptions.Count == 0)
            {
                m_node.OnReportEvent = OnReportEvent;
                m_node.SetAreEventsMonitored(context, true, true);
            }
            
            for (int ii = 0; ii < m_eventSubscriptions.Count; ii++)
            {
                if (Object.ReferenceEquals(eventSubscription, m_eventSubscriptions[ii]))
                {
                    return;
                }
            }

            m_eventSubscriptions.Add(eventSubscription);
        }
        /// <summary>
        /// Unsubscribes to events produced by the node.
        /// </summary>
        public void UnsubscribeToEvents(ISystemContext context, IEventMonitoredItem eventSubscription)
        {
            if (m_eventSubscriptions != null)
            {
                for (int ii = 0; ii < m_eventSubscriptions.Count; ii++)
                {
                    if (Object.ReferenceEquals(eventSubscription, m_eventSubscriptions[ii]))
                    {
                        m_eventSubscriptions.RemoveAt(ii);

                        if (m_eventSubscriptions.Count == 0)
                        {
                            m_node.SetAreEventsMonitored(context, false, true);
                            m_node.OnReportEvent = null;
                        }

                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Recursively subscribes to events for the notifiers in the tree.
        /// </summary>
        private void SubscribeToEvents(
            OperationContext    context,
            ILocalNode          node,
            uint                subscriptionId,
            IEventMonitoredItem monitoredItem,
            bool                unsubscribe)
        {
            // find handle associated with the node.
            IEventSource eventSource = node as IEventSource;
            SourceHandle handle = node.Handle as SourceHandle;

            if (handle != null)
            {
                eventSource = handle.Source as IEventSource;            
            }
            
            if (eventSource != null)
            {
                try
                {
                    eventSource.SubscribeToEvents(context, (handle != null)?handle.Handle:null, subscriptionId, monitoredItem, unsubscribe);
                }
                catch (Exception e)
                {
                    Utils.Trace(e, "Unexpected error calling SubscribeToEvents on an EventSource.");
                }
            }
    
            // find the child notifiers.
            IList<IReference> references = node.References.Find(ReferenceTypes.HasNotifier, false, true, m_server.TypeTree);

            for (int ii = 0; ii < references.Count; ii++)
            {
                if (!references[ii].TargetId.IsAbsolute)
                {
                    ILocalNode target = GetManagerHandle(references[ii].TargetId) as ILocalNode;

                    if (target == null)
                    {
                        continue;
                    }
                    
                    // only object or views can produce events.
                    if ((target.NodeClass & (NodeClass.Object | NodeClass.View)) == 0)
                    {
                        continue;
                    }

                    SubscribeToEvents(context, target, subscriptionId, monitoredItem, unsubscribe);
                }
            }       
        }
Example #39
0
 /// <summary cref="IEventSource.SubscribeToEvents" /> 
 public void SubscribeToEvents(
     OperationContext    context, 
     object              notifier, 
     uint                subscriptionId,
     IEventMonitoredItem monitoredItem,
     bool                unsubscribe)
 {
     lock (DataLock)
     {
         if (unsubscribe)
         {
             Unsubscribe(monitoredItem);
         }
         else
         {
             Subscribe(monitoredItem);
         }
     }
 }