Ejemplo n.º 1
0
 public ResponseHeader DeleteSubscriptions(
     RequestHeader requestHeader,
     UInt32Collection subscriptionIds,
     out StatusCodeCollection results,
     out DiagnosticInfoCollection diagnosticInfos)
 {
     return(m_session.DeleteSubscriptions(requestHeader, subscriptionIds, out results, out diagnosticInfos));
 }
Ejemplo n.º 2
0
        } // Read

        public static unsafe uint Read(this NativeReader reader, uint offset, out UInt32Collection values)
        {
            values = new UInt32Collection(reader, offset);
            uint count;

            offset = reader.DecodeUnsigned(offset, out count);
            offset = checked (offset + count * sizeof(UInt32));
            return(offset);
        } // Read
Ejemplo n.º 3
0
 public ResponseHeader TransferSubscriptions(
     RequestHeader requestHeader,
     UInt32Collection subscriptionIds,
     bool sendInitialValues,
     out TransferResultCollection results,
     out DiagnosticInfoCollection diagnosticInfos)
 {
     return(m_session.TransferSubscriptions(requestHeader, subscriptionIds, sendInitialValues, out results, out diagnosticInfos));
 }
Ejemplo n.º 4
0
 public ResponseHeader SetPublishingMode(
     RequestHeader requestHeader,
     bool publishingEnabled,
     UInt32Collection subscriptionIds,
     out StatusCodeCollection results,
     out DiagnosticInfoCollection diagnosticInfos)
 {
     return(m_session.SetPublishingMode(requestHeader, publishingEnabled, subscriptionIds, out results, out diagnosticInfos));
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Set monitoring mode of items.
        /// </summary>
        public async Task <List <ServiceResult> > SetMonitoringModeAsync(
            MonitoringMode monitoringMode,
            IList <MonitoredItem> monitoredItems,
            CancellationToken ct = default)
        {
            if (monitoredItems == null)
            {
                throw new ArgumentNullException(nameof(monitoredItems));
            }

            VerifySubscriptionState(true);

            if (monitoredItems.Count == 0)
            {
                return(null);
            }

            // get list of items to update.
            UInt32Collection monitoredItemIds = new UInt32Collection();

            foreach (MonitoredItem monitoredItem in monitoredItems)
            {
                monitoredItemIds.Add(monitoredItem.Status.Id);
            }

            var response = await m_session.SetMonitoringModeAsync(
                null,
                m_id,
                monitoringMode,
                monitoredItemIds,
                ct).ConfigureAwait(false);

            StatusCodeCollection results = response.Results;

            ClientBase.ValidateResponse(results, monitoredItemIds);
            ClientBase.ValidateDiagnosticInfos(response.DiagnosticInfos, monitoredItemIds);

            // update results.
            List <ServiceResult> errors = new List <ServiceResult>();
            bool noErrors = UpdateMonitoringMode(
                monitoredItems, errors, results,
                response.DiagnosticInfos, response.ResponseHeader,
                monitoringMode);

            // raise state changed event.
            m_changeMask |= SubscriptionChangeMask.ItemsModified;
            ChangesCompleted();

            // return null list if no errors occurred.
            if (noErrors)
            {
                return(null);
            }

            return(errors);
        }
        /// <summary>
        /// Display current attribute values.
        /// </summary>
        /// <param name="nodeToRead"></param>
        /// <param name="attrIds"></param>
        /// <param name="results"></param>
        /// /// <param name="response"></param>
        private void updateAttributes(
            NodeId nodeToRead,
            UInt32Collection attrIds,
            DataValueCollection results,
            ResponseHeader response)
        {
            if (attrIds.Count != results.Count)
            {
                // Error case.
                return;
            }

            try
            {
                for (int i = 0; i < attrIds.Count; i++)
                {
                    string attributeName  = (string)attrIds[i].ToString();
                    string attributeValue = results[i].ToString();
                    string attributeStatus;

                    // Add the attribute name / value to the list view.
                    ListViewItem item = new ListViewItem(attributeName);

                    // Add the value
                    item.SubItems.Add(attributeValue);

                    if (attrIds[i] == Attributes.Value)
                    {
                        m_CurrentWriteValue             = new WriteValue();
                        m_CurrentWriteValue.AttributeId = Attributes.Value;
                        m_CurrentWriteValue.NodeId      = nodeToRead;
                        m_CurrentWriteNodeName          = nodeToRead.ToString();
                        m_CurrentValue = results[i].Value;
                    }

                    // Add status.
                    attributeStatus = results[i].StatusCode.ToString();
                    if (StatusCode.IsBad(results[i].StatusCode))
                    {
                        item.SubItems[0].Text      = (String)attributeStatus;
                        item.SubItems[0].ForeColor = Color.Red;
                    }

                    // Add item to listview.
                    this.lvAttributes.Items.Add(item);

                    // Fit the width of the nodeid column to the size of the header.
                    this.lvAttributes.Columns[0].Width = -2;
                }
            }
            catch (Exception e)
            {
                // Update status label.
                OnUpdateStatusLabel("Error while processing read results: " + e.Message, false);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Worker method to test Transfer of subscriptions to new session.
        /// </summary>
        public static void TransferSubscriptionTest(
            IServerTestServices services,
            RequestHeader requestHeader,
            UInt32Collection subscriptionIds,
            bool sendInitialData,
            bool expectAccessDenied)
        {
            Assert.AreEqual(1, subscriptionIds.Count);

            requestHeader.Timestamp = DateTime.UtcNow;
            var response = services.TransferSubscriptions(requestHeader, subscriptionIds, sendInitialData,
                                                          out TransferResultCollection transferResults, out DiagnosticInfoCollection diagnosticInfos);

            Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code);
            Assert.AreEqual(subscriptionIds.Count, transferResults.Count);
            ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, subscriptionIds);

            foreach (var transferResult in transferResults)
            {
                TestContext.Out.WriteLine("TransferResult: {0}", transferResult.StatusCode);
                if (expectAccessDenied)
                {
                    Assert.AreEqual(StatusCodes.BadUserAccessDenied, transferResult.StatusCode.Code);
                }
                else
                {
                    Assert.IsTrue(StatusCode.IsGood(transferResult.StatusCode));
                    Assert.AreEqual(1, transferResult.AvailableSequenceNumbers.Count);
                }
            }

            if (expectAccessDenied)
            {
                return;
            }

            requestHeader.Timestamp = DateTime.UtcNow;
            var acknoledgements = new SubscriptionAcknowledgementCollection();

            response = services.Publish(requestHeader, acknoledgements,
                                        out uint publishedId, out UInt32Collection availableSequenceNumbers,
                                        out bool moreNotifications, out NotificationMessage notificationMessage,
                                        out StatusCodeCollection _, out diagnosticInfos);
            Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code);
            ServerFixtureUtils.ValidateResponse(response);
            ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements);
            Assert.AreEqual(subscriptionIds[0], publishedId);
            Assert.AreEqual(sendInitialData ? 1 : 0, notificationMessage.NotificationData.Count);
            //Assert.AreEqual(0, availableSequenceNumbers.Count);

            requestHeader.Timestamp = DateTime.UtcNow;
            response = services.DeleteSubscriptions(requestHeader, subscriptionIds, out StatusCodeCollection statusResults, out diagnosticInfos);
            Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code);
        }
Ejemplo n.º 8
0
 public KinectFaceMeshJig()
 {
     _displayFaceMesh     = false;
     _polygonPoints       = new Point3dCollection();
     _polygonPositions    = new Point3dCollection();
     _numPolygonPositions = new UInt32Collection();
     _numPolygonPoints    = new UInt32Collection();
     _outlineColors       = new EntityColorCollection();
     _fillColors          = new EntityColorCollection();
     _outlineTypes        = new LinetypeCollection();
     _fillOpacities       = new TransparencyCollection();
 }
Ejemplo n.º 9
0
 public ResponseHeader Publish(
     RequestHeader requestHeader,
     SubscriptionAcknowledgementCollection subscriptionAcknowledgements,
     out uint subscriptionId,
     out UInt32Collection availableSequenceNumbers,
     out bool moreNotifications,
     out NotificationMessage notificationMessage,
     out StatusCodeCollection results,
     out DiagnosticInfoCollection diagnosticInfos)
 {
     return(m_session.Publish(requestHeader, subscriptionAcknowledgements, out subscriptionId, out availableSequenceNumbers,
                              out moreNotifications, out notificationMessage, out results, out diagnosticInfos));
 }
        /// <summary>
        /// Worker method to test TransferSubscriptions of a server.
        /// </summary>
        public static UInt32Collection CreateSubscriptionForTransfer(
            IServerTestServices services,
            RequestHeader requestHeader,
            NodeId[] testNodes,
            uint queueSize       = DefaultMonitoredItemsQueueSize,
            int samplingInterval = DefaultMonitoredItemsSamplingInterval)
        {
            // start time

            requestHeader.Timestamp = DateTime.UtcNow;
            uint subscriptionId = CreateSubscription(services, requestHeader);
            uint clientHandle   = 1;

            foreach (NodeId testNode in testNodes)
            {
                CreateMonitoredItem(services, requestHeader, subscriptionId, testNode, clientHandle++, queueSize, samplingInterval);
            }

            var subscriptionIds = new UInt32Collection();

            subscriptionIds.Add(subscriptionId);

            // enable publishing
            var response = services.SetPublishingMode(requestHeader, true, subscriptionIds,
                                                      out var statuses, out var diagnosticInfos);

            ServerFixtureUtils.ValidateResponse(response);
            ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, subscriptionIds);

            // wait some time to settle
            Thread.Sleep(1000);

            // publish request
            var acknoledgements = new SubscriptionAcknowledgementCollection();

            response = services.Publish(requestHeader, acknoledgements,
                                        out uint publishedId, out UInt32Collection availableSequenceNumbers,
                                        out bool moreNotifications, out NotificationMessage notificationMessage,
                                        out StatusCodeCollection _, out diagnosticInfos);
            ServerFixtureUtils.ValidateResponse(response);
            ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements);
            Assert.AreEqual(subscriptionId, publishedId);

            // static node, do not acknoledge
            Assert.AreEqual(1, availableSequenceNumbers.Count);

            return(subscriptionIds);
        }
Ejemplo n.º 11
0
 public static Entry For(UInt32Collection collection)
 {
     if (collection == null)
     {
         return(new NullEntry());
     }
     else
     {
         ArrayEntry array = new ArrayEntry();
         UInt32Collection.Enumerator e = collection.GetEnumerator();
         while (e.MoveNext())
         {
             array.Add(For(e.Current));
         }
         return(array);
     }
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Deletes all items that have been marked for deletion.
        /// </summary>
        public async Task <IList <MonitoredItem> > DeleteItemsAsync(CancellationToken ct)
        {
            VerifySubscriptionState(true);

            if (m_deletedItems.Count == 0)
            {
                return(new List <MonitoredItem>());
            }

            List <MonitoredItem> itemsToDelete = m_deletedItems;

            m_deletedItems = new List <MonitoredItem>();

            UInt32Collection monitoredItemIds = new UInt32Collection();

            foreach (MonitoredItem monitoredItem in itemsToDelete)
            {
                monitoredItemIds.Add(monitoredItem.Status.Id);
            }

            var response = await m_session.DeleteMonitoredItemsAsync(
                null,
                m_id,
                monitoredItemIds,
                ct).ConfigureAwait(false);

            StatusCodeCollection results = response.Results;

            ClientBase.ValidateResponse(results, monitoredItemIds);
            ClientBase.ValidateDiagnosticInfos(response.DiagnosticInfos, monitoredItemIds);

            // update results.
            for (int ii = 0; ii < results.Count; ii++)
            {
                itemsToDelete[ii].SetDeleteResult(results[ii], ii, response.DiagnosticInfos, response.ResponseHeader);
            }

            m_changeMask |= SubscriptionChangeMask.ItemsDeleted;
            ChangesCompleted();

            // return the list of items affected by the change.
            return(itemsToDelete);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Convert value rank and dimensions to stack values
        /// </summary>
        /// <param name="valueRank"></param>
        /// <param name="arrayDimensions"></param>
        /// <returns></returns>
        public static (int, UInt32Collection) ToStackValue(this ValueRank valueRank,
                                                           string arrayDimensions)
        {
            switch (valueRank)
            {
            case ValueRank.Array:
                return(ValueRanks.OneDimension, null);

            case ValueRank.Scalar:
                return(ValueRanks.Scalar, null);

            case ValueRank.ScalarOrArray:
                return(ValueRanks.ScalarOrOneDimension, null);

            case ValueRank.OneOrMoreDimensions:
                if (string.IsNullOrEmpty(arrayDimensions))
                {
                    return(ValueRanks.OneOrMoreDimensions, null);
                }
                var tokens = arrayDimensions.Split(
                    new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                if (tokens == null || tokens.Length < 1)
                {
                    return(ValueRanks.OneOrMoreDimensions, null);
                }
                var dimensions = new UInt32Collection();
                foreach (var dim in tokens)
                {
                    try {
                        dimensions.Add(Convert.ToUInt32(dim));
                    }
                    catch {
                        dimensions.Add(0);
                    }
                }
                return(dimensions.Count, dimensions);

            default:
                return(ValueRanks.Any, null);
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Worker method to verify the SubscriptionTransferred message of a server.
        /// </summary>
        public static void VerifySubscriptionTransferred(
            IServerTestServices services,
            RequestHeader requestHeader,
            UInt32Collection subscriptionIds,
            bool deleteSubscriptions)
        {
            // start time
            requestHeader.Timestamp = DateTime.UtcNow;

            // wait some time to settle
            Thread.Sleep(100);

            // publish request
            var acknoledgements = new SubscriptionAcknowledgementCollection();
            var response        = services.Publish(requestHeader, acknoledgements,
                                                   out uint publishedId, out UInt32Collection availableSequenceNumbers,
                                                   out bool moreNotifications, out NotificationMessage notificationMessage,
                                                   out StatusCodeCollection _, out var diagnosticInfos);

            ServerFixtureUtils.ValidateResponse(response);
            ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements);
            Assert.IsFalse(moreNotifications);
            Assert.IsTrue(subscriptionIds.Contains(publishedId));
            Assert.AreEqual(1, notificationMessage.NotificationData.Count);
            var statusMessage = notificationMessage.NotificationData[0].ToString();

            Assert.IsTrue(statusMessage.Contains("GoodSubscriptionTransferred"));

            // static node, do not acknoledge
            if (availableSequenceNumbers != null)
            {
                Assert.AreEqual(0, availableSequenceNumbers.Count);
            }

            if (deleteSubscriptions)
            {
                response = services.DeleteSubscriptions(requestHeader, subscriptionIds, out var _, out diagnosticInfos);
                ServerFixtureUtils.ValidateResponse(response);
                ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, subscriptionIds);
            }
        }
Ejemplo n.º 15
0
        public static uint[] ToArray(this UInt32Collection collection, Type enumType = null)
        {
            int count = collection.Count;

            uint[] result;
            if (enumType != null)
            {
                Debug.Assert(enumType.IsEnum);
                result = (uint[])Array.CreateInstance(enumType, count);
            }
            else
            {
                result = new uint[count];
            }
            int i = 0;

            foreach (uint element in collection)
            {
                result[i++] = element;
            }
            Debug.Assert(i == count);
            return(result);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Updates the triggers for the monitored item.
        /// </summary>
        public void SetTriggering(
            OperationContext context,
            uint triggeringItemId,
            UInt32Collection linksToAdd,
            UInt32Collection linksToRemove,
            out StatusCodeCollection addResults,
            out DiagnosticInfoCollection addDiagnosticInfos,
            out StatusCodeCollection removeResults,
            out DiagnosticInfoCollection removeDiagnosticInfos)
        {
            if (context == null) throw new ArgumentNullException("context");
            if (linksToAdd == null) throw new ArgumentNullException("linksToAdd");
            if (linksToRemove == null) throw new ArgumentNullException("linksToRemove");

            // allocate results.
            bool diagnosticsExist = false;
            addResults = new StatusCodeCollection();
            addDiagnosticInfos = null;
            removeResults = new StatusCodeCollection();
            removeDiagnosticInfos = null;

            if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
            {
                addDiagnosticInfos = new DiagnosticInfoCollection();
                removeDiagnosticInfos = new DiagnosticInfoCollection();
            }

            // build list of items to modify.
            lock (m_lock)
            {
                // check session.
                VerifySession(context);

                // clear lifetime counter.
                ResetLifetimeCount();

                // look up triggering item.
                LinkedListNode<IMonitoredItem> triggerNode = null;

                if (!m_monitoredItems.TryGetValue(triggeringItemId, out triggerNode))
                {
                    throw new ServiceResultException(StatusCodes.BadMonitoredItemIdInvalid);
                }

                // lookup existing list.
                List<ITriggeredMonitoredItem> triggeredItems = null;

                if (!m_itemsToTrigger.TryGetValue(triggeringItemId, out triggeredItems))
                {
                    m_itemsToTrigger[triggeringItemId] = triggeredItems = new List<ITriggeredMonitoredItem>();
                }

                // remove old links.
                for (int ii = 0; ii < linksToRemove.Count; ii++)
                {
                    removeResults.Add(StatusCodes.Good);

                    bool found = false;

                    for (int jj = 0; jj < triggeredItems.Count; jj++)
                    {
                        if (triggeredItems[jj].Id == linksToRemove[ii])
                        {
                            found = true;
                            triggeredItems.RemoveAt(jj);
                            break;
                        }
                    }

                    if (!found)
                    {
                        removeResults[ii] = StatusCodes.BadMonitoredItemIdInvalid;

                        // update diagnostics.
                        if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                        {
                            DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, removeResults[ii]);
                            diagnosticsExist = true;
                            removeDiagnosticInfos.Add(diagnosticInfo);
                        }

                        continue;
                    }

                    // update diagnostics.
                    if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        removeDiagnosticInfos.Add(null);
                    }
                }

                // add new links.
                for (int ii = 0; ii < linksToAdd.Count; ii++)
                {
                    addResults.Add(StatusCodes.Good);

                    LinkedListNode<IMonitoredItem> node = null;

                    if (!m_monitoredItems.TryGetValue(linksToAdd[ii], out node))
                    {
                        addResults[ii] = StatusCodes.BadMonitoredItemIdInvalid;

                        // update diagnostics.
                        if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                        {
                            DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, addResults[ii]);
                            diagnosticsExist = true;
                            addDiagnosticInfos.Add(diagnosticInfo);
                        }

                        continue;
                    }

                    // check if triggering interface is supported.
                    ITriggeredMonitoredItem triggeredItem = node.Value as ITriggeredMonitoredItem;

                    if (triggeredItem == null)
                    {
                        addResults[ii] = StatusCodes.BadNotSupported;

                        // update diagnostics.
                        if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                        {
                            DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, addResults[ii]);
                            diagnosticsExist = true;
                            addDiagnosticInfos.Add(diagnosticInfo);
                        }

                        continue;
                    }

                    // add value if not already in list.
                    bool found = false;

                    for (int jj = 0; jj < triggeredItems.Count; jj++)
                    {
                        if (triggeredItems[jj].Id == triggeredItem.Id)
                        {
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        triggeredItems.Add(triggeredItem);
                    }

                    // update diagnostics.
                    if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        addDiagnosticInfos.Add(null);
                    }
                }

                // remove an empty list.
                if (triggeredItems.Count == 0)
                {
                    m_itemsToTrigger.Remove(triggeringItemId);
                }

                // clear diagnostics if not required.
                if (!diagnosticsExist)
                {
                    if (addDiagnosticInfos != null) addDiagnosticInfos.Clear();
                    if (removeDiagnosticInfos != null) removeDiagnosticInfos.Clear();
                }
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Invokes the DeleteSubscriptions service.
        /// </summary>
        public virtual ResponseHeader DeleteSubscriptions(
            RequestHeader                requestHeader,
            UInt32Collection             subscriptionIds,
            out StatusCodeCollection     results,
            out DiagnosticInfoCollection diagnosticInfos)
        {
            results = null;
            diagnosticInfos = null;

            ValidateRequest(requestHeader);

            // Insert implementation.

            return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Invokes the SetTriggering service.
        /// </summary>
        public virtual ResponseHeader SetTriggering(
            RequestHeader                requestHeader,
            uint                         subscriptionId,
            uint                         triggeringItemId,
            UInt32Collection             linksToAdd,
            UInt32Collection             linksToRemove,
            out StatusCodeCollection     addResults,
            out DiagnosticInfoCollection addDiagnosticInfos,
            out StatusCodeCollection     removeResults,
            out DiagnosticInfoCollection removeDiagnosticInfos)
        {
            addResults = null;
            addDiagnosticInfos = null;
            removeResults = null;
            removeDiagnosticInfos = null;

            ValidateRequest(requestHeader);

            // Insert implementation.

            return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Reads a uint array from the stream.
        /// </summary>
        public UInt32Collection ReadUInt32Array(string fieldName)
        {
            bool isNil = false;

            UInt32Collection values = new UInt32Collection();
                                    
            if (BeginField(fieldName, true, out isNil))
            {                                
                PushNamespace(Namespaces.OpcUaXsd);
                
                while (MoveToElement("UInt32"))
                {
                    values.Add(ReadUInt32("UInt32"));
                }

                // check the length.
                if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
                {
                    throw new ServiceResultException(StatusCodes.BadEncodingLimitsExceeded);
                }

                PopNamespace();

                EndField(fieldName);
                return values;
            }

            if (isNil)
            {
                return null;
            }

            return values;
        }
        /// <summary>
        /// Invokes the SetTriggering service.
        /// </summary>
        /// <param name="requestHeader">The request header.</param>
        /// <param name="subscriptionId">The subscription id.</param>
        /// <param name="triggeringItemId">The id for the MonitoredItem used as the triggering item.</param>
        /// <param name="linksToAdd">The list of ids of the items to report that are to be added as triggering links.</param>
        /// <param name="linksToRemove">The list of ids of the items to report for the triggering links to be deleted.</param>
        /// <param name="addResults">The list of StatusCodes for the items to add.</param>
        /// <param name="addDiagnosticInfos">The list of diagnostic information for the links to add.</param>
        /// <param name="removeResults">The list of StatusCodes for the items to delete.</param>
        /// <param name="removeDiagnosticInfos">The list of diagnostic information for the links to delete.</param>
        /// <returns>
        /// Returns a <see cref="ResponseHeader"/> object 
        /// </returns>
        public override ResponseHeader SetTriggering(
            RequestHeader requestHeader,
            uint subscriptionId,
            uint triggeringItemId,
            UInt32Collection linksToAdd,
            UInt32Collection linksToRemove,
            out StatusCodeCollection addResults,
            out DiagnosticInfoCollection addDiagnosticInfos,
            out StatusCodeCollection removeResults,
            out DiagnosticInfoCollection removeDiagnosticInfos)
        {
            addResults = null;
            addDiagnosticInfos = null;
            removeResults = null;
            removeDiagnosticInfos = null;

            OperationContext context = ValidateRequest(requestHeader, RequestType.SetTriggering);

            try
            {
                if ((linksToAdd == null || linksToAdd.Count == 0) && (linksToRemove == null || linksToRemove.Count == 0))
                {
                    throw new ServiceResultException(StatusCodes.BadNothingToDo);
                }

                ServerInternal.SubscriptionManager.SetTriggering(
                    context,
                    subscriptionId,
                    triggeringItemId,
                    linksToAdd,
                    linksToRemove,
                    out addResults,
                    out addDiagnosticInfos,
                    out removeResults,
                    out removeDiagnosticInfos);

                return CreateResponse(requestHeader, context.StringTable);
            }
            catch (ServiceResultException e)
            {
                lock (ServerInternal.DiagnosticsLock)
                {
                    ServerInternal.ServerDiagnostics.RejectedRequestsCount++;

                    if (IsSecurityError(e.StatusCode))
                    {
                        ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++;
                    }
                }

                throw TranslateException(context, e);
            }
            finally
            {
                OnRequestComplete(context);
            }  
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Writes the value of an attribute.
        /// </summary>
        /// <param name="attributeId">The attribute id.</param>
        /// <param name="value">The value.</param>
        /// <returns>The result of write operation.</returns>
        protected override ServiceResult Write(uint attributeId, object value)
        {
            switch (attributeId)
            {
                case Attributes.AccessLevel:             { m_accessLevel             = (byte)value;   return ServiceResult.Good; } 
                case Attributes.UserAccessLevel:         { m_userAccessLevel         = (byte)value;   return ServiceResult.Good; } 
                case Attributes.MinimumSamplingInterval: { m_minimumSamplingInterval = (int)value;    return ServiceResult.Good; } 
                case Attributes.Historizing:             { m_historizing             = (bool)value;   return ServiceResult.Good; } 
                    
                // values are copied when the are written so then can be safely returned on read.
                case Attributes.Value:
                {
                    m_value.Value = Utils.Clone(value);
                    return ServiceResult.Good;
                }

                case Attributes.DataType: 
                { 
                    NodeId dataType = (NodeId)value;

                    // must ensure the value is of the correct datatype.
                    if (dataType != m_dataType)
                    {
                        m_value.Value = TypeInfo.GetDefaultValue(dataType, m_valueRank);
                    }

                    m_dataType = dataType;
                    return ServiceResult.Good;
                }
 
                case Attributes.ValueRank:
                {
                    int valueRank = (int)value;

                    if (valueRank != m_valueRank)
                    {
                        m_value.Value = TypeInfo.GetDefaultValue(m_dataType, valueRank);
                    }

                    m_valueRank = valueRank;
                    
                    return ServiceResult.Good;
                }
                    
                case Attributes.ArrayDimensions:
                {
                    m_arrayDimensions = new UInt32Collection((uint[])value);

                    // ensure number of dimensions is correct.
                    if (m_arrayDimensions.Count > 0)
                    {
                        if (m_arrayDimensions.Count != m_valueRank)
                        {
                            m_valueRank = m_arrayDimensions.Count;
                            m_value.Value = TypeInfo.GetDefaultValue(m_dataType, m_valueRank);
                        }
                    }

                    return ServiceResult.Good;
                }
            }

            return base.Write(attributeId, value);
        }        
Ejemplo n.º 22
0
        /// <summary>
        /// Processes the response from a publish request.
        /// </summary>
        private void ProcessPublishResponse(
            ResponseHeader      responseHeader,
            uint                subscriptionId,
            UInt32Collection    availableSequenceNumbers,
            bool                moreNotifications,
            NotificationMessage notificationMessage)
        {
            Subscription subscription = null;
            
            // send notification that the server is alive.
            OnKeepAlive(m_serverState, responseHeader.Timestamp);

            // collect the current set if acknowledgements.
            lock (SyncRoot)
            {
                // clear out acknowledgements for messages that the server does not have any more.
                SubscriptionAcknowledgementCollection acknowledgementsToSend = new SubscriptionAcknowledgementCollection();

                for (int ii = 0; ii < m_acknowledgementsToSend.Count; ii++)
                {
                    SubscriptionAcknowledgement acknowledgement = m_acknowledgementsToSend[ii];

                    if (acknowledgement.SubscriptionId != subscriptionId)
                    {
                        acknowledgementsToSend.Add(acknowledgement);
                    }
                    else
                    {
                        if (availableSequenceNumbers == null || availableSequenceNumbers.Contains(acknowledgement.SequenceNumber))
                        {
                            acknowledgementsToSend.Add(acknowledgement);
                        }
                    }
                }

                // create an acknowledgement to be sent back to the server.
                if (notificationMessage.NotificationData.Count > 0)
                {
                    SubscriptionAcknowledgement acknowledgement = new SubscriptionAcknowledgement();

                    acknowledgement.SubscriptionId = subscriptionId;
                    acknowledgement.SequenceNumber = notificationMessage.SequenceNumber;

                    acknowledgementsToSend.Add(acknowledgement);
                }

                uint lastSentSequenceNumber = 0;
                if (availableSequenceNumbers != null)
                {
                    foreach (uint availableSequenceNumber in availableSequenceNumbers)
                    {
                        if (m_latestAcknowledgementsSent.ContainsKey(subscriptionId))
                        {
                            lastSentSequenceNumber = m_latestAcknowledgementsSent[subscriptionId];

                            // If the last sent sequence number is uint.Max do not display the warning; the counter rolled over
                            // If the last sent sequence number is greater or equal to the available sequence number (returned by the publish), a warning must be logged.
                            if (((lastSentSequenceNumber >= availableSequenceNumber) && (lastSentSequenceNumber != uint.MaxValue)) || (lastSentSequenceNumber == availableSequenceNumber) && (lastSentSequenceNumber == uint.MaxValue))
                            {
                                Utils.Trace("Received sequence number which was already acknowledged={0}", availableSequenceNumber);
                            }
                        }
                    }
                }

                if (m_latestAcknowledgementsSent.ContainsKey(subscriptionId))
                {
                    lastSentSequenceNumber = m_latestAcknowledgementsSent[subscriptionId];

                    // If the last sent sequence number is uint.Max do not display the warning; the counter rolled over
                    // If the last sent sequence number is greater or equal to the notificationMessage's sequence number (returned by the publish), a warning must be logged.
                    if (((lastSentSequenceNumber >= notificationMessage.SequenceNumber) && (lastSentSequenceNumber != uint.MaxValue)) || (lastSentSequenceNumber == notificationMessage.SequenceNumber) && (lastSentSequenceNumber == uint.MaxValue))
                    {
                        Utils.Trace("Received sequence number which was already acknowledged={0}", notificationMessage.SequenceNumber);
                    }
                }

                if (availableSequenceNumbers != null)
                {
                    foreach (var acknowledgement in acknowledgementsToSend)
                    {
                        if (acknowledgement.SubscriptionId == subscriptionId && !availableSequenceNumbers.Contains(acknowledgement.SequenceNumber))
                        {
                            Utils.Trace("Sequence number={0} was not received in the available sequence numbers.", acknowledgement.SequenceNumber);
                        }
                    }
                }

                m_acknowledgementsToSend = acknowledgementsToSend;

                if (notificationMessage.IsEmpty)
                {
                    Utils.Trace("Empty notification message received for SessionId {0} with PublishTime {1}", SessionId, notificationMessage.PublishTime.ToLocalTime());
                }

                // find the subscription.
                foreach (Subscription current in m_subscriptions)
                {
                    if (current.Id == subscriptionId)
                    {
                        subscription = current;                            
                        break;
                    }
                }                    
            }

            // ignore messages with a subscription that has been deleted.
            if (subscription != null)
            {
                // Validate publish time and reject old values.
                if (notificationMessage.PublishTime.AddMilliseconds(subscription.CurrentPublishingInterval * subscription.CurrentLifetimeCount) < DateTime.UtcNow)
                {
                    Utils.Trace("PublishTime {0} in publish response is too old for SubscriptionId {1}.", notificationMessage.PublishTime.ToLocalTime(), subscription.Id);
                }

                // Validate publish time and reject old values.
                if (notificationMessage.PublishTime > DateTime.UtcNow.AddMilliseconds(subscription.CurrentPublishingInterval * subscription.CurrentLifetimeCount))
                {
                    Utils.Trace("PublishTime {0} in publish response is newer than actual time for SubscriptionId {1}.", notificationMessage.PublishTime.ToLocalTime(), subscription.Id);
                }

                // update subscription cache.                                 
                subscription.SaveMessageInCache(
                    availableSequenceNumbers, 
                    notificationMessage, 
                    responseHeader.StringTable);

                // raise the notification.
                lock (m_eventLock)
                {
                    NotificationEventArgs args = new NotificationEventArgs(subscription, notificationMessage, responseHeader.StringTable);

                    if (m_Publish != null)
                    {
                        ThreadPool.QueueUserWorkItem(OnRaisePublishNotification, args);
                    }
                }
            }
            else
            {
                Utils.Trace("Received Publish Response for Unknown SubscriptionId={0}", subscriptionId);
            }
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Worker method to test subscriptions of a server.
        /// </summary>
        /// <param name="services"></param>
        /// <param name="requestHeader"></param>
        public static void SubscriptionTest(
            IServerTestServices services,
            RequestHeader requestHeader)
        {
            // start time
            requestHeader.Timestamp = DateTime.UtcNow;

            // create subscription
            double publishingInterval        = 1000.0;
            uint   lifetimeCount             = 60;
            uint   maxKeepAliveCount         = 2;
            uint   maxNotificationPerPublish = 0;
            byte   priority  = 128;
            bool   enabled   = false;
            uint   queueSize = 5;

            var response = services.CreateSubscription(requestHeader,
                                                       publishingInterval, lifetimeCount, maxKeepAliveCount,
                                                       maxNotificationPerPublish, enabled, priority,
                                                       out uint id, out double revisedPublishingInterval, out uint revisedLifetimeCount, out uint revisedMaxKeepAliveCount);

            Assert.AreEqual(publishingInterval, revisedPublishingInterval);
            Assert.AreEqual(lifetimeCount, revisedLifetimeCount);
            Assert.AreEqual(maxKeepAliveCount, revisedMaxKeepAliveCount);
            ServerFixtureUtils.ValidateResponse(response);

            MonitoredItemCreateRequestCollection itemsToCreate = new MonitoredItemCreateRequestCollection();
            // check badnothingtodo
            var sre = Assert.Throws <ServiceResultException>(() =>
                                                             services.CreateMonitoredItems(requestHeader, id, TimestampsToReturn.Neither, itemsToCreate,
                                                                                           out MonitoredItemCreateResultCollection mockResults, out DiagnosticInfoCollection mockInfos));

            Assert.AreEqual(StatusCodes.BadNothingToDo, sre.StatusCode);

            // add item
            uint handleCounter = 1;

            itemsToCreate.Add(new MonitoredItemCreateRequest()
            {
                ItemToMonitor = new ReadValueId()
                {
                    AttributeId = Attributes.Value,
                    NodeId      = VariableIds.Server_ServerStatus_CurrentTime
                },
                MonitoringMode      = MonitoringMode.Reporting,
                RequestedParameters = new MonitoringParameters()
                {
                    ClientHandle     = ++handleCounter,
                    SamplingInterval = -1,
                    Filter           = null,
                    DiscardOldest    = true,
                    QueueSize        = queueSize
                }
            });
            response = services.CreateMonitoredItems(requestHeader, id, TimestampsToReturn.Neither, itemsToCreate,
                                                     out MonitoredItemCreateResultCollection itemCreateResults, out DiagnosticInfoCollection diagnosticInfos);
            ServerFixtureUtils.ValidateResponse(response);
            ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, itemsToCreate);

            // modify subscription
            response = services.ModifySubscription(requestHeader, id,
                                                   publishingInterval, lifetimeCount, maxKeepAliveCount,
                                                   maxNotificationPerPublish, priority,
                                                   out revisedPublishingInterval, out revisedLifetimeCount, out revisedMaxKeepAliveCount);
            Assert.AreEqual(publishingInterval, revisedPublishingInterval);
            Assert.AreEqual(lifetimeCount, revisedLifetimeCount);
            Assert.AreEqual(maxKeepAliveCount, revisedMaxKeepAliveCount);
            ServerFixtureUtils.ValidateResponse(response);

            // modify monitored item, just timestamps to return
            var itemsToModify = new MonitoredItemModifyRequestCollection();

            foreach (var itemCreated in itemCreateResults)
            {
                itemsToModify.Add(
                    new MonitoredItemModifyRequest()
                {
                    MonitoredItemId = itemCreated.MonitoredItemId
                });
            }
            ;
            response = services.ModifyMonitoredItems(requestHeader, id, TimestampsToReturn.Both, itemsToModify,
                                                     out MonitoredItemModifyResultCollection modifyResults, out diagnosticInfos);
            ServerFixtureUtils.ValidateResponse(response);
            ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, itemsToModify);

            // publish request
            var acknoledgements = new SubscriptionAcknowledgementCollection();

            response = services.Publish(requestHeader, acknoledgements,
                                        out uint subscriptionId, out UInt32Collection availableSequenceNumbers,
                                        out bool moreNotifications, out NotificationMessage notificationMessage,
                                        out StatusCodeCollection statuses, out diagnosticInfos);
            ServerFixtureUtils.ValidateResponse(response);
            ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements);
            Assert.AreEqual(id, subscriptionId);
            Assert.AreEqual(0, availableSequenceNumbers.Count);

            // enable publishing
            enabled = true;
            var subscriptions = new UInt32Collection()
            {
                id
            };

            response = services.SetPublishingMode(requestHeader, enabled, subscriptions,
                                                  out statuses, out diagnosticInfos);
            ServerFixtureUtils.ValidateResponse(response);
            ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, subscriptions);

            // wait some time to fill queue
            int loopCounter = (int)queueSize;

            Thread.Sleep(loopCounter * 1000);

            acknoledgements = new SubscriptionAcknowledgementCollection();
            do
            {
                // get publish responses
                response = services.Publish(requestHeader, acknoledgements,
                                            out subscriptionId, out availableSequenceNumbers,
                                            out moreNotifications, out notificationMessage,
                                            out statuses, out diagnosticInfos);
                ServerFixtureUtils.ValidateResponse(response);
                ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements);
                Assert.AreEqual(id, subscriptionId);

                var dataChangeNotification = notificationMessage.NotificationData[0].Body as DataChangeNotification;
                TestContext.Out.WriteLine("Notification: {0} {1} {2}",
                                          notificationMessage.SequenceNumber,
                                          dataChangeNotification?.MonitoredItems[0].Value.ToString(),
                                          notificationMessage.PublishTime);

                acknoledgements.Clear();
                acknoledgements.Add(new SubscriptionAcknowledgement()
                {
                    SubscriptionId = id,
                    SequenceNumber = notificationMessage.SequenceNumber
                });
            } while (acknoledgements.Count > 0 && --loopCounter > 0);

            // republish
            response = services.Republish(requestHeader, subscriptionId, notificationMessage.SequenceNumber, out notificationMessage);
            ServerFixtureUtils.ValidateResponse(response);

            // disable publishing
            enabled  = false;
            response = services.SetPublishingMode(requestHeader, enabled, subscriptions,
                                                  out statuses, out diagnosticInfos);
            ServerFixtureUtils.ValidateResponse(response);
            ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, subscriptions);

            // delete subscription
            response = services.DeleteSubscriptions(requestHeader, subscriptions, out statuses, out diagnosticInfos);
            ServerFixtureUtils.ValidateResponse(response);
            ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, subscriptions);
        }
Ejemplo n.º 24
0
        } // Read

        public static unsafe uint Read(this NativeReader reader, uint offset, out UInt32Collection values)
        {
            values = new UInt32Collection(reader, offset);
            uint count;
            offset = reader.DecodeUnsigned(offset, out count);
            offset = checked(offset + count * sizeof(UInt32));
            return offset;
        } // Read
Ejemplo n.º 25
0
        /// <summary>
        /// Reads a uint array from the stream.
        /// </summary>
        public UInt32Collection ReadUInt32Array(string fieldName)
        {
            int length = ReadArrayLength();

            if (length == -1)
            {
                return null;
            }

            UInt32Collection values = new UInt32Collection(length);

            for (int ii = 0; ii < length; ii++)
            {
                values.Add(ReadUInt32(null));
            }

            return values;
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Invokes the Publish service.
        /// </summary>
        public virtual ResponseHeader Publish(
            RequestHeader                         requestHeader,
            SubscriptionAcknowledgementCollection subscriptionAcknowledgements,
            out uint                              subscriptionId,
            out UInt32Collection                  availableSequenceNumbers,
            out bool                              moreNotifications,
            out NotificationMessage               notificationMessage,
            out StatusCodeCollection              results,
            out DiagnosticInfoCollection          diagnosticInfos)
        {
            PublishRequest request = new PublishRequest();
            PublishResponse response = null;

            request.RequestHeader                = requestHeader;
            request.SubscriptionAcknowledgements = subscriptionAcknowledgements;

            UpdateRequestHeader(request, requestHeader == null, "Publish");

            try
            {
                if (UseTransportChannel)
                {
                    IServiceResponse genericResponse = TransportChannel.SendRequest(request);

                    if (genericResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    ValidateResponse(genericResponse.ResponseHeader);
                    response = (PublishResponse)genericResponse;
                }
                else
                {
                    PublishResponseMessage responseMessage = InnerChannel.Publish(new PublishMessage(request));

                    if (responseMessage == null || responseMessage.PublishResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    response = responseMessage.PublishResponse;
                    ValidateResponse(response.ResponseHeader);
                }

                subscriptionId           = response.SubscriptionId;
                availableSequenceNumbers = response.AvailableSequenceNumbers;
                moreNotifications        = response.MoreNotifications;
                notificationMessage      = response.NotificationMessage;
                results                  = response.Results;
                diagnosticInfos          = response.DiagnosticInfos;
            }
            finally
            {
                RequestCompleted(request, response, "Publish");
            }

            return response.ResponseHeader;
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Begins an asynchronous invocation of the DeleteSubscriptions service.
        /// </summary>
        public IAsyncResult BeginDeleteSubscriptions(
            RequestHeader    requestHeader,
            UInt32Collection subscriptionIds,
            AsyncCallback    callback,
            object           asyncState)
        {
            DeleteSubscriptionsRequest request = new DeleteSubscriptionsRequest();

            request.RequestHeader   = requestHeader;
            request.SubscriptionIds = subscriptionIds;

            UpdateRequestHeader(request, requestHeader == null, "DeleteSubscriptions");

            if (UseTransportChannel)
            {
                return TransportChannel.BeginSendRequest(request, callback, asyncState);
            }

            return InnerChannel.BeginDeleteSubscriptions(new DeleteSubscriptionsMessage(request), callback, asyncState);
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Invokes the DeleteSubscriptions service.
        /// </summary>
        public virtual ResponseHeader DeleteSubscriptions(
            RequestHeader                requestHeader,
            UInt32Collection             subscriptionIds,
            out StatusCodeCollection     results,
            out DiagnosticInfoCollection diagnosticInfos)
        {
            DeleteSubscriptionsRequest request = new DeleteSubscriptionsRequest();
            DeleteSubscriptionsResponse response = null;

            request.RequestHeader   = requestHeader;
            request.SubscriptionIds = subscriptionIds;

            UpdateRequestHeader(request, requestHeader == null, "DeleteSubscriptions");

            try
            {
                if (UseTransportChannel)
                {
                    IServiceResponse genericResponse = TransportChannel.SendRequest(request);

                    if (genericResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    ValidateResponse(genericResponse.ResponseHeader);
                    response = (DeleteSubscriptionsResponse)genericResponse;
                }
                else
                {
                    DeleteSubscriptionsResponseMessage responseMessage = InnerChannel.DeleteSubscriptions(new DeleteSubscriptionsMessage(request));

                    if (responseMessage == null || responseMessage.DeleteSubscriptionsResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    response = responseMessage.DeleteSubscriptionsResponse;
                    ValidateResponse(response.ResponseHeader);
                }

                results         = response.Results;
                diagnosticInfos = response.DiagnosticInfos;
            }
            finally
            {
                RequestCompleted(request, response, "DeleteSubscriptions");
            }

            return response.ResponseHeader;
        }
Ejemplo n.º 29
0
		/// <summary>
		/// Deletes the monitored items in a subscription.
		/// </summary>
		private void DeleteMonitoredItems(
			OperationContext             context,
            UInt32Collection             monitoredItemIds,
            bool                         doNotCheckSession,
            out StatusCodeCollection     results,
            out DiagnosticInfoCollection diagnosticInfos)
        {
            if (context == null)          throw new ArgumentNullException("context");
            if (monitoredItemIds == null) throw new ArgumentNullException("monitoredItemIds");

            int count = monitoredItemIds.Count;

            bool diagnosticsExist = false;
            results = new StatusCodeCollection(count);
            diagnosticInfos = null;

            if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
            {
                diagnosticInfos = new DiagnosticInfoCollection(count);
            }
            
            // build list of items to modify.
            List<IMonitoredItem> monitoredItems = new List<IMonitoredItem>(count);
            List<ServiceResult> errors = new List<ServiceResult>(count);
            double[] originalSamplingIntervals = new double[count];
            MonitoringMode[] originalMonitoringModes = new MonitoringMode[count];

            bool validItems = false;

            lock (m_lock)
            {
                // check session.
                if (!doNotCheckSession)
                {
                    VerifySession(context);
                }

                // clear lifetime counter.
                ResetLifetimeCount();
                
                for (int ii = 0; ii < count; ii++)
                {
                    LinkedListNode<IMonitoredItem> node = null;

                    if (!m_monitoredItems.TryGetValue(monitoredItemIds[ii], out node))
                    {
                        monitoredItems.Add(null);
                        errors.Add(StatusCodes.BadMonitoredItemIdInvalid);

                        // update diagnostics.
                        if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                        {
                            DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, errors[ii]);
                            diagnosticsExist = true;
                            diagnosticInfos.Add(diagnosticInfo);
                        }

                        continue;
                    }
                    
                    IMonitoredItem monitoredItem = node.Value;
                    monitoredItems.Add(monitoredItem);

                    // remove the item from the internal lists.
                    m_monitoredItems.Remove(monitoredItemIds[ii]);
                    m_itemsToTrigger.Remove(monitoredItemIds[ii]);

                    //remove the links towards the deleted monitored item
                    List<ITriggeredMonitoredItem> triggeredItems = null;
                    foreach (KeyValuePair<uint, List<ITriggeredMonitoredItem>> item in m_itemsToTrigger)
                    {
                        triggeredItems = item.Value;
                        for (int jj = 0; jj < triggeredItems.Count; jj++)
                        {
                            if (triggeredItems[jj].Id == monitoredItemIds[ii])
                            {
                                triggeredItems.RemoveAt(jj);
                                break;
                            }
                        }
                    }
                    
                    if (node.List != null)
                    {
                        node.List.Remove(node);
                    }

                    originalSamplingIntervals[ii] = monitoredItem.SamplingInterval;
                    originalMonitoringModes[ii] = monitoredItem.MonitoringMode;

                    errors.Add(null);
                    validItems = true;

                    // update diagnostics.
                    if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        diagnosticInfos.Add(null);
                    }
                }
            }
   
            // update items.
            if (validItems)
            {
                m_server.NodeManager.DeleteMonitoredItems(
                    context,
                    m_id,
                    monitoredItems,
                    errors);
            }
            
            lock (m_lock)
            {
                // update diagnostics.
                for (int ii = 0; ii < errors.Count; ii++)
                {
                    ServiceResult error = errors[ii];

                    if (error == null)
                    {
                        results.Add(StatusCodes.Good);
                    }
                    else
                    {
                        results.Add(error.StatusCode);
                    }

                    // update diagnostics.
                    if (ServiceResult.IsGood(error))
                    {
                        RemoveItemToSamplingInterval(originalSamplingIntervals[ii], originalMonitoringModes[ii]);
                    }

                    if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        if (error != null && error.Code != StatusCodes.Good)
                        {
                            diagnosticInfos[ii] = ServerUtils.CreateDiagnosticInfo(m_server, context, error);
                            diagnosticsExist = true;
                        }
                    }
                }

                // clear diagnostics if not required.
                if (!diagnosticsExist && diagnosticInfos != null)
                {
                    diagnosticInfos.Clear();
                }

                // update diagnostics.
                lock (m_diagnostics)
                {
                    m_diagnostics.MonitoredItemCount = 0;
                    m_diagnostics.DisabledMonitoredItemCount = 0;
                }

                // TraceState("ITEMS DELETED");
            }
        }
Ejemplo n.º 30
0
        //This test doesn't deterministically prove sequential publishing, but rather relies on a subscription not being able to handle the message load.
        //This test should be re-implemented with a Session that deterministically provides the wrong order of messages to Subscription.
        public void SequentialPublishingSubscription(bool enabled)
        {
            var       subscriptionList              = new List <Subscription>();
            var       sequenceBroken                = new AutoResetEvent(false);
            var       numOfNotifications            = 0L;
            const int TestWaitTime                  = 10000;
            const int MonitoredItemsPerSubscription = 500;
            const int Subscriptions                 = 10;

            for (int i = 0; i < Subscriptions; i++)
            {
                var subscription = new Subscription(m_session.DefaultSubscription)
                {
                    SequentialPublishing      = enabled,
                    PublishingInterval        = 0,
                    DisableMonitoredItemCache = true, //Not needed
                    PublishingEnabled         = false
                };
                subscriptionList.Add(subscription);

                //Create many monitored items on the server status current time, and track the last reported source timestamp
                var list = Enumerable.Range(1, MonitoredItemsPerSubscription).Select(_ => new MonitoredItem(subscription.DefaultItem)
                {
                    StartNodeId      = new NodeId("Scalar_Simulation_Int32", 2),
                    SamplingInterval = 0,
                }).ToList();
                var dict = list.ToDictionary(item => item.ClientHandle, _ => DateTime.MinValue);

                subscription.AddItems(list);
                var result = m_session.AddSubscription(subscription);
                Assert.True(result);
                subscription.Create();
                var publishInterval = (int)subscription.CurrentPublishingInterval;
                TestContext.Out.WriteLine($"CurrentPublishingInterval: {publishInterval}");

                //Need to realize test failed, assert needs to be brought to this thread
                subscription.FastDataChangeCallback = (_, notification, __) => {
                    notification.MonitoredItems.ForEach(item => {
                        Interlocked.Increment(ref numOfNotifications);
                        if (dict[item.ClientHandle] > item.Value.SourceTimestamp)
                        {
                            sequenceBroken.Set(); //Out of order encountered
                        }

                        dict[item.ClientHandle] = item.Value.SourceTimestamp;
                    });
                };
            }

            UInt32Collection subscriptionIds = new UInt32Collection();

            foreach (var subscription in subscriptionList)
            {
                subscriptionIds.Add(subscription.Id);
            }

            var stopwatch = Stopwatch.StartNew();

            // start
            m_session.SetPublishingMode(null, true, subscriptionIds, out var results, out var diagnosticInfos);

            // Wait for out-of-order to occur
            var failed = sequenceBroken.WaitOne(TestWaitTime);

            // stop
            m_session.SetPublishingMode(null, false, subscriptionIds, out results, out diagnosticInfos);

            //Log information
            var elapsed = stopwatch.Elapsed.TotalMilliseconds / 1000.0;

            TestContext.Out.WriteLine($"Ran for: {elapsed:N} seconds");
            long   totalNotifications = Interlocked.Read(ref numOfNotifications);
            double notificationRate   = totalNotifications / elapsed;

            foreach (var subscription in subscriptionList)
            {
                int outstandingMessageWorkers = subscription.OutstandingMessageWorkers;
                TestContext.Out.WriteLine($"Id: {subscription.Id} Outstanding workers: {outstandingMessageWorkers}");
            }
            TestContext.Out.WriteLine($"Number of notifications: {totalNotifications:N0}");
            TestContext.Out.WriteLine($"Notifications rate: {notificationRate:N} per second"); //How fast it processed notifications.

            Assert.NotZero(totalNotifications);                                                //No notifications means nothing worked
            if (enabled)
            {
                //catch if Out-of-sequence occurred
                Assert.False(failed);
            }

            var notificationsPerSecond = Subscriptions * MonitoredItemsPerSubscription;

            Assert.AreEqual(notificationsPerSecond * (elapsed + 0.5), totalNotifications, notificationsPerSecond);

            foreach (var subscription in subscriptionList)
            {
                var result = m_session.RemoveSubscription(subscription);
                Assert.True(result);
            }
        }
Ejemplo n.º 31
0
        /// <summary>
        /// Returns all available notifications.
        /// </summary>
        public NotificationMessage Publish(
            OperationContext      context, 
            out UInt32Collection  availableSequenceNumbers, 
            out bool              moreNotifications)
        {   
            if (context == null) throw new ArgumentNullException("context");
            
            NotificationMessage message = null;

            lock (m_lock)
            {
                moreNotifications = false;
                availableSequenceNumbers = null;

                // check if expired.
                if (m_expired)
                {
                    return null;
                }

                try
                {
                    // update diagnostics.
                    lock (m_diagnostics)
                    {
                        m_diagnostics.PublishRequestCount++;
                    }

                    message = InnerPublish(context, out availableSequenceNumbers, out moreNotifications);
                    
                    lock (m_diagnostics)
                    {
                        m_diagnostics.UnacknowledgedMessageCount = (uint)availableSequenceNumbers.Count;
                    }
                }
                finally
                {
                    // clear counters on success.
                    if (message != null)
                    {
                        // TraceState(Utils.Format("PUBLISH #{0}", message.SequenceNumber));
                        ResetKeepaliveCount();
                        m_waitingForPublish = moreNotifications;
                        ResetLifetimeCount();
                    }
                }
            }

            return message;
        }
Ejemplo n.º 32
0
        /// <summary>
        /// Writes the value of an attribute.
        /// </summary>
        /// <param name="attributeId">The attribute id.</param>
        /// <param name="value">The value.</param>
        /// <returns>The result of write operation.</returns>
        protected override ServiceResult Write(uint attributeId, object value)
        {
            switch (attributeId)
            {                    
                // values are copied when the are written so then can be safely returned on read.
                case Attributes.Value:
                {
                    m_value.Value = Utils.Clone(value);
                    return ServiceResult.Good;
                }

                case Attributes.DataType: 
                { 
                    NodeId dataType = (NodeId)value;

                    // must ensure the value is of the correct datatype.
                    if (dataType != m_dataType)
                    {
                        m_value.Value = null;
                    }

                    m_dataType = dataType;
                    return ServiceResult.Good;
                }
 
                case Attributes.ValueRank:
                {
                    int valueRank = (int)value;

                    if (valueRank != m_valueRank)
                    {
                        m_value.Value = null;
                    }

                    m_valueRank = valueRank;

                    return ServiceResult.Good;
                }
                    
                case Attributes.ArrayDimensions:
                {
                    m_arrayDimensions = new UInt32Collection((uint[])value);

                    // ensure number of dimensions is correct.
                    if (m_arrayDimensions.Count > 0)
                    {
                        if (m_valueRank != m_arrayDimensions.Count)
                        {                        
                            m_valueRank = m_arrayDimensions.Count;   
                            m_value.Value = null;
                        }
                    }

                    return ServiceResult.Good;
                }
            }

            return base.Write(attributeId, value);
        }
Ejemplo n.º 33
0
        /// <summary>
        /// Begins an asynchronous invocation of the SetPublishingMode service.
        /// </summary>
        public IAsyncResult BeginSetPublishingMode(
            RequestHeader    requestHeader,
            bool             publishingEnabled,
            UInt32Collection subscriptionIds,
            AsyncCallback    callback,
            object           asyncState)
        {
            SetPublishingModeRequest request = new SetPublishingModeRequest();

            request.RequestHeader     = requestHeader;
            request.PublishingEnabled = publishingEnabled;
            request.SubscriptionIds   = subscriptionIds;

            UpdateRequestHeader(request, requestHeader == null, "SetPublishingMode");

            if (UseTransportChannel)
            {
                return TransportChannel.BeginSendRequest(request, callback, asyncState);
            }

            return InnerChannel.BeginSetPublishingMode(new SetPublishingModeMessage(request), callback, asyncState);
        }
        /// <summary>
        /// Invokes the Publish service.
        /// </summary>
        /// <param name="requestHeader">The request header.</param>
        /// <param name="subscriptionAcknowledgements">The list of acknowledgements for one or more Subscriptions.</param>
        /// <param name="subscriptionId">The subscription identifier.</param>
        /// <param name="availableSequenceNumbers">The available sequence numbers.</param>
        /// <param name="moreNotifications">If set to <c>true</c> the number of Notifications that were ready to be sent could not be sent in a single response.</param>
        /// <param name="notificationMessage">The NotificationMessage that contains the list of Notifications.</param>
        /// <param name="results">The list of results for the acknowledgements.</param>
        /// <param name="diagnosticInfos">The diagnostic information for the results.</param>
        /// <returns>
        /// Returns a <see cref="ResponseHeader"/> object 
        /// </returns>
        public override ResponseHeader Publish(
            RequestHeader                         requestHeader, 
            SubscriptionAcknowledgementCollection subscriptionAcknowledgements, 
            out uint                              subscriptionId, 
            out UInt32Collection                  availableSequenceNumbers, 
            out bool                              moreNotifications, 
            out NotificationMessage               notificationMessage, 
            out StatusCodeCollection              results, 
            out DiagnosticInfoCollection          diagnosticInfos)
        {
            OperationContext context = ValidateRequest(requestHeader, RequestType.Publish);

            try
            {
                /*
                // check if there is an odd delay.
                if (DateTime.UtcNow > requestHeader.Timestamp.AddMilliseconds(100))
                {
                    Utils.Trace(
                        "WARNING. Unexpected delay receiving Publish request. Time={0:hh:mm:ss.fff}, ReceiveTime={1:hh:mm:ss.fff}",
                        DateTime.UtcNow,
                        requestHeader.Timestamp);
                }
                */
                
                Utils.Trace("PUBLISH #{0} RECIEVED. TIME={1:hh:hh:ss.fff}", requestHeader.RequestHandle, requestHeader.Timestamp);
                
                notificationMessage = ServerInternal.SubscriptionManager.Publish(
                    context,
                    subscriptionAcknowledgements,
                    null,
                    out subscriptionId,
                    out availableSequenceNumbers,
                    out moreNotifications,
                    out results,
                    out diagnosticInfos);

                /*
                if (notificationMessage != null)
                {
                    Utils.Trace(
                        "PublishResponse: SubId={0} SeqNo={1}, PublishTime={2:mm:ss.fff}, Time={3:mm:ss.fff}",
                        subscriptionId,
                        notificationMessage.SequenceNumber,
                        notificationMessage.PublishTime,
                        DateTime.UtcNow);
                }
                */

                return CreateResponse(requestHeader, context.StringTable);      
            }
            catch (ServiceResultException e)
            {
                lock (ServerInternal.DiagnosticsLock)
                {
                    ServerInternal.ServerDiagnostics.RejectedRequestsCount++;

                    if (IsSecurityError(e.StatusCode))
                    {
                        ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++;
                    }
                }

                throw TranslateException(context, e);
            }  
            finally
            {
                OnRequestComplete(context);
            }
        }
Ejemplo n.º 35
0
        /// <summary>
        /// Deletes all of the active subscriptions.
        /// </summary>
        private bool DeleteSubscriptions()
        {   
            try
            {
                UInt32Collection subscriptionIds = new UInt32Collection();

                lock (m_subscriptions)
                {
                    for (int ii = 0; ii < m_subscriptions.Count; ii++)
                    {
                        Subscription subscription = m_subscriptions[ii];

                        lock (subscription)
                        {
                            subscriptionIds.Add(subscription.SubscriptionId);
                            subscription.Deleted = true;
                        }
                    }
                }
                    
                RequestHeader requestHeader = new RequestHeader();
                requestHeader.ReturnDiagnostics = 0;

                StatusCodeCollection results;
                DiagnosticInfoCollection diagnosticInfos;

                ResponseHeader responseHeader = Session.DeleteSubscriptions(
                    requestHeader,
                    subscriptionIds,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, subscriptionIds);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, subscriptionIds);
                                
                if (diagnosticInfos != null && diagnosticInfos.Count > 0)
                {
                    Log("Returned non-empty DiagnosticInfos array during DeleteSubscriptions.");
                    return false;
                }

                bool success = true;

                lock (m_subscriptions)
                {
                    for (int ii = 0; ii < m_subscriptions.Count; ii++)
                    {
                        if (StatusCode.IsBad(results[ii]))
                        {
                            Log(
                                "Unexpected error deleting subscription {0}. StatusCode = {1}",
                                subscriptionIds[ii],
                                subscriptionIds);

                            success = false;
                        }

                        Subscription subscription = m_subscriptions[ii];

                        lock (subscription)
                        {
                            subscription.States[subscription.States.Count - 1].End = responseHeader.Timestamp;
                        }
                    }
                }

                // let the queue empty.
                Thread.Sleep(1000);

                return success;
            }
            catch (Exception e)
            {
                Log(e, "DeleteSubscriptions Failed.");
                return false;
            } 
        }
        /// <summary>
        /// Invokes the SetMonitoringMode service.
        /// </summary>
        /// <param name="requestHeader">The request header.</param>
        /// <param name="subscriptionId">The subscription id.</param>
        /// <param name="monitoringMode">The monitoring mode to be set for the MonitoredItems.</param>
        /// <param name="monitoredItemIds">The list of MonitoredItems to modify.</param>
        /// <param name="results">The list of results for the MonitoredItems to modify.</param>
        /// <param name="diagnosticInfos">The diagnostic information for the results.</param>
        /// <returns>
        /// Returns a <see cref="ResponseHeader"/> object
        /// </returns>
        public override ResponseHeader SetMonitoringMode(
            RequestHeader                requestHeader,
            uint                         subscriptionId, 
            MonitoringMode               monitoringMode,
            UInt32Collection             monitoredItemIds,
            out StatusCodeCollection     results, 
            out DiagnosticInfoCollection diagnosticInfos)
        {
            OperationContext context = ValidateRequest(requestHeader, RequestType.SetMonitoringMode);
                
            try
            {
                if (monitoredItemIds == null || monitoredItemIds.Count == 0)
                {
                    throw new ServiceResultException(StatusCodes.BadNothingToDo);
                }         

                ServerInternal.SubscriptionManager.SetMonitoringMode(
                    context,
                    subscriptionId,
                    monitoringMode,
                    monitoredItemIds,
                    out results,
                    out diagnosticInfos);

                return CreateResponse(requestHeader, context.StringTable);
            }
            catch (ServiceResultException e)
            {
                lock (ServerInternal.DiagnosticsLock)
                {
                    ServerInternal.ServerDiagnostics.RejectedRequestsCount++;

                    if (IsSecurityError(e.StatusCode))
                    {
                        ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++;
                    }
                }

                throw TranslateException(context, e);
            }  
            finally
            {
                OnRequestComplete(context);
            }
        }
Ejemplo n.º 37
0
        /// <summary>
        /// Sets the publishing enable state for the subscriptions.
        /// </summary>
        private bool SetPublishingEnabled(bool enabled)
        {   
            try
            {
                UInt32Collection subscriptionIds = new UInt32Collection();

                lock (m_subscriptions)
                {
                    for (int ii = 0; ii < m_subscriptions.Count; ii++)
                    {
                        subscriptionIds.Add(m_subscriptions[ii].SubscriptionId);
                        m_subscriptions[ii].PublishingEnabled = enabled;
                    }
                }
                    
                RequestHeader requestHeader = new RequestHeader();
                requestHeader.ReturnDiagnostics = 0;

                StatusCodeCollection results;
                DiagnosticInfoCollection diagnosticInfos;

                Session.SetPublishingMode(
                    requestHeader,
                    enabled,
                    subscriptionIds,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, subscriptionIds);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, subscriptionIds);
                                
                if (diagnosticInfos != null && diagnosticInfos.Count > 0)
                {
                    Log("Returned non-empty DiagnosticInfos array during SetPublishingMode.");
                    return false;
                }

                bool success = true;
                
                for  (int ii = 0; ii < results.Count; ii++)
                {
                    if (StatusCode.IsBad(results[ii]))
                    {
                        Log(
                            "Unexpected error setting publish enable state for subscription {0}. StatusCode = {1}", 
                            subscriptionIds[ii],
                            subscriptionIds);

                        success = false;
                    }
                }

                return success;
            }
            catch (Exception e)
            {
                Log(e, "SetPublishingMode Failed.");
                return false;
            } 
        }
Ejemplo n.º 38
0
        /// <summary>
        /// Invokes the SetMonitoringMode service.
        /// </summary>
        public virtual ResponseHeader SetMonitoringMode(
            RequestHeader                requestHeader,
            uint                         subscriptionId,
            MonitoringMode               monitoringMode,
            UInt32Collection             monitoredItemIds,
            out StatusCodeCollection     results,
            out DiagnosticInfoCollection diagnosticInfos)
        {
            results = null;
            diagnosticInfos = null;

            ValidateRequest(requestHeader);

            // Insert implementation.

            return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported);
        }
Ejemplo n.º 39
0
        /// <summary>
        /// Verifies the result of a publish
        /// </summary>
        private bool VerifyPublishResponse(
            ResponseHeader responseHeader,
            Subscription subscription,
            UInt32Collection availableSequenceNumbers,
            bool moreNotifications,
            NotificationMessage notificationMessage,
            StatusCodeCollection results,
            DiagnosticInfoCollection diagnosticInfos)
        {
            /*
            Utils.Trace(
                "PublishReceived: SubId={0} SeqNo={1}, PublishTime={2:mm:ss.fff}, Time={3:mm:ss.fff}",
                subscription.SubscriptionId,
                notificationMessage.SequenceNumber,
                notificationMessage.PublishTime,
                DateTime.UtcNow);
            */

            // check if there is an odd delay.
            if (responseHeader.Timestamp > notificationMessage.PublishTime.AddMilliseconds(100))
            {
                Log(
                    "WARNING. Unexpected delay between PublishTime and ResponseTime. SeqNo={0}, PublishTime={1:hh:mm:ss.fff}, ResponseTime={2:hh:mm:ss.fff}",
                    notificationMessage.SequenceNumber,
                    notificationMessage.PublishTime,
                    responseHeader.Timestamp);
            }

            // save results.
            subscription.AvailableSequenceNumbers = availableSequenceNumbers;

            if (notificationMessage.NotificationData.Count == 0)
            {
                // keep alives do not increment the sequence number.
                if (subscription.NextExpectedSequenceNumber != notificationMessage.SequenceNumber)
                {
                    Log(
                        "Incorrect sequence number for keep alive. SubscriptionId = {0}, Actual = {1}, Expected = {2}", 
                        subscription.SubscriptionId,
                        notificationMessage.SequenceNumber,
                        subscription.NextExpectedSequenceNumber);

                    subscription.Failed = true;
                    return false;
                }

                // save the message.                
                DateTime timestamp = responseHeader.Timestamp;
                DateTime start = subscription.States[subscription.States.Count - 1].Start;

                // check if this is an old request being processed late.
                if (start > timestamp && subscription.States.Count > 1)
                {
                    subscription.States[subscription.States.Count - 2].KeepAlives.Add(timestamp);
                }
                else
                {
                    subscription.States[subscription.States.Count - 1].KeepAlives.Add(timestamp);
                }
            }
            else
            {
                // check for replays.
                if (subscription.NextExpectedSequenceNumber > notificationMessage.SequenceNumber)
                {
                    // check for out of order responses.
                    bool found = false;

                    for (int ii = 0; ii < subscription.MissingSequenceNumbers.Count; ii++)
                    {
                        if (subscription.MissingSequenceNumbers[ii] == notificationMessage.SequenceNumber)
                        {
                            subscription.MissingSequenceNumbers.RemoveAt(ii);
                            found = true;
                            break;
                        }
                    }

                    // oops - duplicate.
                    if (!found)
                    {
                        Log(
                            "Duplicate sequence number for message. SubscriptionId = {0}, Actual = {1}, Expected = {2}",
                            subscription.SubscriptionId,
                            notificationMessage.SequenceNumber,
                            subscription.NextExpectedSequenceNumber);

                        subscription.Failed = true;
                        return false;
                    }
                }
                
                // increment message counter.
                if (notificationMessage.SequenceNumber >= subscription.NextExpectedSequenceNumber)
                {
                    for (uint ii = subscription.NextExpectedSequenceNumber; ii < notificationMessage.SequenceNumber; ii++)
                    {
                        if (!subscription.MissingSequenceNumbers.Contains(ii))
                        {
                            subscription.MissingSequenceNumbers.Add(ii);
                        }
                    }

                    subscription.NextExpectedSequenceNumber = notificationMessage.SequenceNumber+1;
                }
                                                        
                // save the largest received message number (gap exist because of client side threading issues).
                if (subscription.LastReceivedSequenceNumber < notificationMessage.SequenceNumber)
                {
                    subscription.LastReceivedSequenceNumber = notificationMessage.SequenceNumber;
                }

                // save the message.                
                DateTime timestamp = responseHeader.Timestamp;
                DateTime start = subscription.States[subscription.States.Count-1].Start;

                // check if this is an old request being processed late.
                if (start > timestamp && subscription.States.Count > 1)
                {
                    subscription.States[subscription.States.Count - 2].KeepAlives.Add(timestamp);
                }
                else
                {
                    subscription.States[subscription.States.Count - 1].KeepAlives.Add(timestamp);
                }

                subscription.NotificationMessages.Add(notificationMessage);
                subscription.ReceiveTimes.Add(responseHeader.Timestamp);

                // change to keep alive mode.
                if (subscription.StaticData)
                {
                    PublishingState state = new PublishingState();

                    state.KeepAliveCount = subscription.KeepAliveCount;
                    state.PublishingInterval = subscription.PublishingInterval;
                    state.Start = timestamp;
                    state.KeepAliveMode = true;

                    subscription.States[subscription.States.Count-1].End = state.Start;
                    subscription.States.Add(state);
                }

                // save the acknowlegements.
                SaveAcknowledgement(subscription.SubscriptionId, notificationMessage.SequenceNumber);
            }

            return true;
        }
Ejemplo n.º 40
0
        /// <summary>
        /// Invokes the Publish service.
        /// </summary>
        public virtual ResponseHeader Publish(
            RequestHeader                         requestHeader,
            SubscriptionAcknowledgementCollection subscriptionAcknowledgements,
            out uint                              subscriptionId,
            out UInt32Collection                  availableSequenceNumbers,
            out bool                              moreNotifications,
            out NotificationMessage               notificationMessage,
            out StatusCodeCollection              results,
            out DiagnosticInfoCollection          diagnosticInfos)
        {
            subscriptionId = 0;
            availableSequenceNumbers = null;
            moreNotifications = false;
            notificationMessage = null;
            results = null;
            diagnosticInfos = null;

            ValidateRequest(requestHeader);

            // Insert implementation.

            return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported);
        }
Ejemplo n.º 41
0
        /// <summary>
        /// Toggles the monitoring mode for the items.
        /// </summary>
        private bool ToogleDisabledState(Subscription subscription, List<MonitoredItem> monitoredItems)
        {
            UInt32Collection monitoredItemIds = new UInt32Collection();

            lock (subscription)
            {
                subscription.NotificationMessages.Clear();
                subscription.ReceiveTimes.Clear();

                for (int ii = 0; ii < monitoredItems.Count; ii++)
                {
                    monitoredItemIds.Add(monitoredItems[ii].MonitoredItemId);
                    monitoredItems[ii].Value = null;
                }
            }

            StatusCodeCollection results = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            Session.SetMonitoringMode(
                null,
                subscription.SubscriptionId,
                MonitoringMode.Disabled,
                monitoredItemIds,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, monitoredItemIds);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, monitoredItemIds);
            
            lock (subscription)
            {
                for (int ii = 0; ii < results.Count; ii++)
                {
                    if (StatusCode.IsBad(results[ii]))
                    {
                        Log(
                            "Error disabling MonitoredItem. ClientHandle = {0}, Node = {1}, Attribute = {2}, StatusCode = {3}", 
                            monitoredItems[ii].MonitoredItemId,
                            monitoredItems[ii].Node,
                            Attributes.GetBrowseName(monitoredItems[ii].AttributeId),
                            results[ii]);

                        return false;
                    }
                }
            }

            ResponseHeader responseHeader = Session.SetMonitoringMode(
                null,
                subscription.SubscriptionId,
                MonitoringMode.Reporting,
                monitoredItemIds,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, monitoredItemIds);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, monitoredItemIds);
            
            lock (subscription)
            {
                for (int ii = 0; ii < results.Count; ii++)
                {
                    if (StatusCode.IsBad(results[ii]))
                    {
                        Log(
                            "Error enabling MonitoredItem. ClientHandle = {0}, Node = {1}, Attribute = {2}, StatusCode = {3}", 
                            monitoredItems[ii].MonitoredItemId,
                            monitoredItems[ii].Node,
                            Attributes.GetBrowseName(monitoredItems[ii].AttributeId),
                            results[ii]);

                        return false;
                    }

                    monitoredItems[ii].UpdateTime = responseHeader.Timestamp;
                }
            }

            return true;
        }
Ejemplo n.º 42
0
        /// <remarks>
        /// This test doesn't deterministically prove sequential publishing,
        /// but rather relies on a subscription not being able to handle the message load.
        /// This test should be re-implemented with a Session that deterministically
        /// provides the wrong order of messages to Subscription.
        ///</remarks>
        public void SequentialPublishingSubscription(bool enabled)
        {
            var       subscriptionList              = new List <Subscription>();
            var       subscriptionIds               = new UInt32Collection();
            var       sequenceBroken                = new AutoResetEvent(false);
            var       numOfNotifications            = 0L;
            const int TestWaitTime                  = 10000;
            const int MonitoredItemsPerSubscription = 500;
            const int Subscriptions                 = 10;

            // multiple Subscriptions to enforce multiple queued publish requests
            for (int i = 0; i < Subscriptions; i++)
            {
                var s = new Subscription(m_session.DefaultSubscription)
                {
                    SequentialPublishing      = enabled,
                    PublishingInterval        = 0,
                    DisableMonitoredItemCache = true, //Not needed
                    PublishingEnabled         = false
                };
                subscriptionList.Add(s);
            }

            var subscription = subscriptionList[0];

            // Create monitored items on the server
            // and track the last reported source timestamp
            var list = Enumerable.Range(1, MonitoredItemsPerSubscription).Select(_ => new MonitoredItem(subscription.DefaultItem)
            {
                StartNodeId      = new NodeId("Scalar_Simulation_Int32", 2),
                SamplingInterval = 0,
            }).ToList();
            var dict = list.ToDictionary(item => item.ClientHandle, _ => DateTime.MinValue);

            subscription.AddItems(list);

            foreach (var s in subscriptionList)
            {
                var boolResult = m_session.AddSubscription(s);
                Assert.True(boolResult);
                s.Create();
                var publishInterval = (int)s.CurrentPublishingInterval;
                TestContext.Out.WriteLine($"CurrentPublishingInterval: {publishInterval}");
                subscriptionIds.Add(s.Id);
            }

            //Need to realize test failed, assert needs to be brought to this thread
            subscription.FastDataChangeCallback = (_, notification, __) => {
                notification.MonitoredItems.ForEach(item => {
                    Interlocked.Increment(ref numOfNotifications);
                    if (dict[item.ClientHandle] > item.Value.SourceTimestamp)
                    {
                        TestContext.Out.WriteLine("Out of order encountered");
                        sequenceBroken.Set();
                        return;
                    }
                    dict[item.ClientHandle] = item.Value.SourceTimestamp;
                    Thread.Sleep(10);
                });
            };

            var stopwatch = Stopwatch.StartNew();

            // start
            m_session.SetPublishingMode(null, true, subscriptionIds, out var results, out var diagnosticInfos);

            // Wait for out-of-order to occur
            var failed = sequenceBroken.WaitOne(TestWaitTime);

            // stop
            m_session.SetPublishingMode(null, false, subscriptionIds, out results, out diagnosticInfos);

            //Log information
            var elapsed = stopwatch.Elapsed.TotalMilliseconds / 1000.0;

            TestContext.Out.WriteLine($"Ran for: {elapsed:N} seconds");
            long   totalNotifications        = Interlocked.Read(ref numOfNotifications);
            double notificationRate          = totalNotifications / elapsed;
            int    outstandingMessageWorkers = subscription.OutstandingMessageWorkers;

            TestContext.Out.WriteLine($"Id: {subscription.Id} Outstanding workers: {outstandingMessageWorkers}");

            // clean up before validating conditions
            foreach (var s in subscriptionList)
            {
                var result = m_session.RemoveSubscription(s);
                Assert.True(result);
            }

            TestContext.Out.WriteLine($"Number of notifications: {totalNotifications:N0}");
            //How fast it processed notifications.
            TestContext.Out.WriteLine($"Notifications rate: {notificationRate:N} per second");
            //No notifications means nothing worked
            Assert.NotZero(totalNotifications);

            // The issue more unlikely seem to appear on .NET 6 in the given timeframe
            if (!enabled && !failed)
            {
                Assert.Inconclusive("The test couldn't validate the issue on this platform");
            }

            // catch if expected/unexpected Out-of-sequence occurred
            Assert.AreEqual(enabled, !failed);
        }
Ejemplo n.º 43
0
        /// <summary>
        /// Begins an asynchronous invocation of the SetTriggering service.
        /// </summary>
        public IAsyncResult BeginSetTriggering(
            RequestHeader    requestHeader,
            uint             subscriptionId,
            uint             triggeringItemId,
            UInt32Collection linksToAdd,
            UInt32Collection linksToRemove,
            AsyncCallback    callback,
            object           asyncState)
        {
            SetTriggeringRequest request = new SetTriggeringRequest();

            request.RequestHeader    = requestHeader;
            request.SubscriptionId   = subscriptionId;
            request.TriggeringItemId = triggeringItemId;
            request.LinksToAdd       = linksToAdd;
            request.LinksToRemove    = linksToRemove;

            UpdateRequestHeader(request, requestHeader == null, "SetTriggering");

            if (UseTransportChannel)
            {
                return TransportChannel.BeginSendRequest(request, callback, asyncState);
            }

            return InnerChannel.BeginSetTriggering(new SetTriggeringMessage(request), callback, asyncState);
        }
Ejemplo n.º 44
0
		/// <summary>
		/// Deletes the monitored items in a subscription.
		/// </summary>
        public void DeleteMonitoredItems(
            OperationContext context,
            UInt32Collection monitoredItemIds,
            out StatusCodeCollection results,
            out DiagnosticInfoCollection diagnosticInfos)
        {
            DeleteMonitoredItems(context, monitoredItemIds, false, out results, out diagnosticInfos);
        }
Ejemplo n.º 45
0
        /// <summary>
        /// Finishes an asynchronous invocation of the Publish service.
        /// </summary>
        public ResponseHeader EndPublish(
            IAsyncResult                 result,
            out uint                     subscriptionId,
            out UInt32Collection         availableSequenceNumbers,
            out bool                     moreNotifications,
            out NotificationMessage      notificationMessage,
            out StatusCodeCollection     results,
            out DiagnosticInfoCollection diagnosticInfos)
        {
            PublishResponse response = null;

            try
            {
                if (UseTransportChannel)
                {
                    IServiceResponse genericResponse = TransportChannel.EndSendRequest(result);

                    if (genericResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    ValidateResponse(genericResponse.ResponseHeader);
                    response = (PublishResponse)genericResponse;
                }
                else
                {
                    PublishResponseMessage responseMessage = InnerChannel.EndPublish(result);

                    if (responseMessage == null || responseMessage.PublishResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    response = responseMessage.PublishResponse;
                    ValidateResponse(response.ResponseHeader);
                }

                subscriptionId           = response.SubscriptionId;
                availableSequenceNumbers = response.AvailableSequenceNumbers;
                moreNotifications        = response.MoreNotifications;
                notificationMessage      = response.NotificationMessage;
                results                  = response.Results;
                diagnosticInfos          = response.DiagnosticInfos;
            }
            finally
            {
                RequestCompleted(null, response, "Publish");
            }

            return response.ResponseHeader;
        }
Ejemplo n.º 46
0
		/// <summary>
		/// Changes the monitoring mode for a set of items.
		/// </summary>
        public void SetMonitoringMode(
            OperationContext             context,
            MonitoringMode               monitoringMode,
            UInt32Collection             monitoredItemIds,
            out StatusCodeCollection     results, 
            out DiagnosticInfoCollection diagnosticInfos)
        {  
            if (context == null)          throw new ArgumentNullException("context");
            if (monitoredItemIds == null) throw new ArgumentNullException("monitoredItemIds");

            int count = monitoredItemIds.Count;

            bool diagnosticsExist = false;
            results = new StatusCodeCollection(count);
            diagnosticInfos = null;

            if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
            {
                diagnosticInfos = new DiagnosticInfoCollection(count);
            }
        
            // build list of items to modify.
            List<IMonitoredItem> monitoredItems = new List<IMonitoredItem>(count);
            List<ServiceResult> errors = new List<ServiceResult>(count);
            MonitoringMode[] originalMonitoringModes = new MonitoringMode[count];

            bool validItems = false;

            lock (m_lock)
            {
                // check session.
                VerifySession(context);

                // clear lifetime counter.
                ResetLifetimeCount();

                for (int ii = 0; ii < count; ii++)
                {
                    LinkedListNode<IMonitoredItem> node = null;

                    if (!m_monitoredItems.TryGetValue(monitoredItemIds[ii], out node))
                    {
                        monitoredItems.Add(null);
                        errors.Add(StatusCodes.BadMonitoredItemIdInvalid);

                        // update diagnostics.
                        if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                        {
                            DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, errors[ii]);
                            diagnosticsExist = true;
                            diagnosticInfos.Add(diagnosticInfo);
                        }

                        continue;
                    }
                    
                    IMonitoredItem monitoredItem = node.Value;
                    monitoredItems.Add(monitoredItem);
                    originalMonitoringModes[ii] = monitoredItem.MonitoringMode;

                    errors.Add(null);
                    validItems = true;

                    // update diagnostics.
                    if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        diagnosticInfos.Add(null);
                    }
                }
            }

            // update items.
            if (validItems)
            {
                m_server.NodeManager.SetMonitoringMode(
                    context,
                    monitoringMode,
                    monitoredItems,
                    errors);
            }
                
            lock (m_lock)
            {
                // update diagnostics.
                for (int ii = 0; ii < errors.Count; ii++)
                {
                    ServiceResult error = errors[ii];

                    if (error == null)
                    {
                        results.Add(StatusCodes.Good);
                    }
                    else
                    {
                        results.Add(error.StatusCode);
                    }
                    
                    // update diagnostics.
                    if (ServiceResult.IsGood(error))
                    {
                        ModifyItemMonitoringMode(monitoredItems[ii].SamplingInterval, originalMonitoringModes[ii], monitoringMode);
                    }

                    if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        if (error != null && error.Code != StatusCodes.Good)
                        {
                            diagnosticInfos[ii] = ServerUtils.CreateDiagnosticInfo(m_server, context, error);
                            diagnosticsExist = true;
                        }
                    }
                }

                // clear diagnostics if not required.
                if (!diagnosticsExist && diagnosticInfos != null)
                {
                    diagnosticInfos.Clear();
                }

                // update diagnostics.
                lock (m_diagnostics)
                {
                    m_diagnostics.MonitoredItemCount = 0;
                    m_diagnostics.DisabledMonitoredItemCount = 0;
                }

                if (monitoringMode == MonitoringMode.Disabled)
                {
                    // TraceState("ITEMS DISABLED");
                }
                else if (monitoringMode == MonitoringMode.Reporting)
                {
                    // TraceState("ITEMS REPORTING ENABLED");
                }
                else
                {
                    // TraceState("ITEMS SAMPLING ENABLED");
                }
            }
        }
Ejemplo n.º 47
0
        /// <summary>
        /// Deletes the monitored items.
        /// </summary>
        private bool DeleteMonitoredItems(
            Subscription subscription, 
            List<MonitoredItem> monitoredItems)
        {   
            try
            {
                RequestHeader requestHeader = new RequestHeader();
                requestHeader.ReturnDiagnostics = 0;

                UInt32Collection monitoredItemIds = new UInt32Collection();
                
                for (int ii = 0; ii < monitoredItems.Count; ii++)
                {
                    monitoredItemIds.Add(monitoredItems[ii].MonitoredItemId);
                }

                StatusCodeCollection results;
                DiagnosticInfoCollection diagnosticInfos;

                Session.DeleteMonitoredItems(
                    requestHeader,
                    subscription.SubscriptionId,
                    monitoredItemIds,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, monitoredItemIds);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, monitoredItemIds);
                                
                if (diagnosticInfos != null && diagnosticInfos.Count > 0)
                {
                    Log("Returned non-empty DiagnosticInfos array during DeleteMonitoredItems.");
                    return false;
                }

                bool success = true;
                
                for (int ii = 0; ii < monitoredItems.Count; ii++)
                {
                    if (StatusCode.IsBad(results[ii]))
                    {
                        Log(
                            "Delete monitored item failed for Node '{0}', NodeId = {1}, AttributeId = {2}, StatusCode = {3}",
                            monitoredItems[ii].Node,
                            monitoredItems[ii].Node.NodeId,
                            Attributes.GetBrowseName(monitoredItems[ii].AttributeId),
                            results[ii]);

                        success = false;
                        continue;
                    }
                }
                
                return success;              
            }
            catch (Exception e)
            {
                Log(e, "DeleteMonitoredItems Failed.");
                return false;
            } 
        }
Ejemplo n.º 48
0
        /// <summary>
        /// Returns all available notifications.
        /// </summary>
        private NotificationMessage InnerPublish(
            OperationContext      context, 
            out UInt32Collection  availableSequenceNumbers, 
            out bool              moreNotifications)
        {   
            // check session.
            VerifySession(context);

            // TraceState("PUBLISH");

            // check if a keep alive should be sent if there is no data.
            bool keepAliveIfNoData = (m_keepAliveCounter >= m_maxKeepAliveCount);

            availableSequenceNumbers = new UInt32Collection();

            moreNotifications = false;

            if (m_lastSentMessage < m_sentMessages.Count)
            {
                // return the available sequence numbers.
                for (int ii = 0; ii <= m_lastSentMessage && ii < m_sentMessages.Count; ii++)
                {
                    availableSequenceNumbers.Add(m_sentMessages[ii].SequenceNumber);
                }
                
                moreNotifications = m_waitingForPublish = m_lastSentMessage < m_sentMessages.Count-1;

                // TraceState("PUBLISH QUEUED MESSAGE");
                return m_sentMessages[m_lastSentMessage++];
            }
            
            List<NotificationMessage> messages = new List<NotificationMessage>();

            if (m_publishingEnabled)
            {                
                DateTime start1 = DateTime.UtcNow;

                // collect notifications to publish.
                Queue<EventFieldList> events = new Queue<EventFieldList>();
                Queue<MonitoredItemNotification> datachanges = new Queue<MonitoredItemNotification>();
                Queue<DiagnosticInfo> datachangeDiagnostics = new Queue<DiagnosticInfo>();
                
                // check for monitored items that are ready to publish.
                LinkedListNode<IMonitoredItem> current = m_itemsToPublish.First;
                
                while (current != null)
                {
                    LinkedListNode<IMonitoredItem> next = current.Next;
                    IMonitoredItem monitoredItem = current.Value;

                    if ((monitoredItem.MonitoredItemType & MonitoredItemTypeMask.DataChange) != 0)
                    {
                        ((IDataChangeMonitoredItem)monitoredItem).Publish(context, datachanges, datachangeDiagnostics);
                    }
                    else
                    {
                        ((IEventMonitoredItem)monitoredItem).Publish(context, events);                        
                    }

                    // add back to list to check.
                    m_itemsToPublish.Remove(current);
                    m_itemsToCheck.AddLast(current);
                                    
                    // check there are enough notifications for a message.
                    if (m_maxNotificationsPerPublish > 0 && events.Count + datachanges.Count > m_maxNotificationsPerPublish)
                    {
                        // construct message.
                        int notificationCount;
                        int eventCount = events.Count;
                        int dataChangeCount = datachanges.Count;
                                           
                        NotificationMessage message = ConstructMessage(
                             events, 
                             datachanges, 
                             datachangeDiagnostics, 
                             out notificationCount);

                        // add to list of messages to send.
                        messages.Add(message);

                        lock (m_diagnostics)
                        {
                            m_diagnostics.DataChangeNotificationsCount += (uint)(dataChangeCount - datachanges.Count);
                            m_diagnostics.EventNotificationsCount += (uint)(eventCount - events.Count);
                            m_diagnostics.NotificationsCount += (uint)notificationCount;
                        }
                    }
                                        
                    current = next;
                }
                    
                // pubish the remaining notifications.
                while (events.Count + datachanges.Count > 0)
                {
                    // construct message.
                    int notificationCount;
                    int eventCount = events.Count;
                    int dataChangeCount = datachanges.Count;   
                                       
                     NotificationMessage message = ConstructMessage(
                         events, 
                         datachanges, 
                         datachangeDiagnostics, 
                         out notificationCount);

                    // add to list of messages to send.
                    messages.Add(message);

                    lock (m_diagnostics)
                    {
                        m_diagnostics.DataChangeNotificationsCount += (uint)(dataChangeCount - datachanges.Count);
                        m_diagnostics.EventNotificationsCount += (uint)(eventCount - events.Count);
                        m_diagnostics.NotificationsCount += (uint)notificationCount;
                    }
                }

                // check for missing notifications.
                if (!keepAliveIfNoData && messages.Count == 0)
                {
                    Utils.Trace(
                        (int)Utils.TraceMasks.Error,
                        "Oops! MonitoredItems queued but no notifications availabled.");
               
                    m_waitingForPublish = false;

                    return null;
                }
                
                DateTime end1 = DateTime.UtcNow;
                
                double delta1 = ((double)(end1.Ticks-start1.Ticks))/TimeSpan.TicksPerMillisecond;

                if (delta1 > 200)
                {
                    TraceState(Utils.Format("PUBLISHING DELAY ({0}ms)", delta1));
                }
            }

            if (messages.Count == 0)
            {
                // create a keep alive message.
                NotificationMessage message = new NotificationMessage();

                // use the sequence number for the next message.                    
                message.SequenceNumber = (uint)m_sequenceNumber; 
                message.PublishTime    = DateTime.UtcNow;

                // return the available sequence numbers.
                for (int ii = 0; ii <= m_lastSentMessage && ii < m_sentMessages.Count; ii++)
                {
                    availableSequenceNumbers.Add(m_sentMessages[ii].SequenceNumber);
                }

                // TraceState("PUBLISH KEEPALIVE");
                return message;
            }

            // have to drop unsent messages if out of queue space.
            if (messages.Count > m_maxMessageCount)
            {
                Utils.Trace(
                    "WARNING: QUEUE OVERFLOW. Dropping {2} Messages. Increase MaxMessageQueueSize. SubId={0}, MaxMessageQueueSize={1}", 
                    m_id,
                    m_maxMessageCount,
                    messages.Count - (int)m_maxMessageCount);

                messages.RemoveRange(0, messages.Count - (int)m_maxMessageCount);
            }

            // remove old messages if queue is full.
            if (m_sentMessages.Count > m_maxMessageCount - messages.Count)
            {
                lock (m_diagnostics)
                {
                    m_diagnostics.UnacknowledgedMessageCount += (uint)messages.Count;
                }

                if (m_maxMessageCount <= messages.Count)
                {
                    m_sentMessages.Clear();
                }
                else
                {
                    m_sentMessages.RemoveRange(0, messages.Count);
                }
            }

            // save new message
            m_lastSentMessage = m_sentMessages.Count;
            m_sentMessages.AddRange(messages);
            
            // check if there are more notifications to send.
            moreNotifications = m_waitingForPublish = messages.Count > 1;

            // return the available sequence numbers.
            for (int ii = 0; ii <= m_lastSentMessage && ii < m_sentMessages.Count; ii++)
            {
                availableSequenceNumbers.Add(m_sentMessages[ii].SequenceNumber);
            }

            // TraceState("PUBLISH NEW MESSAGE");
            return m_sentMessages[m_lastSentMessage++];
        }
Ejemplo n.º 49
0
        private CallMethodRequestCollection ResendDataCall(StatusCode expectedStatus, UInt32Collection subscriptionIds)
        {
            // Find the ResendData method
            var nodesToCall = new CallMethodRequestCollection();

            foreach (var subscriptionId in subscriptionIds)
            {
                nodesToCall.Add(new CallMethodRequest()
                {
                    ObjectId       = ObjectIds.Server,
                    MethodId       = MethodIds.Server_ResendData,
                    InputArguments = new VariantCollection()
                    {
                        new Variant(subscriptionId)
                    }
                });
            }

            //call ResendData method with subscription ids
            m_requestHeader.Timestamp = DateTime.UtcNow;
            var response = m_server.Call(m_requestHeader,
                                         nodesToCall,
                                         out var results,
                                         out var diagnosticInfos);

            Assert.AreEqual(expectedStatus, results[0].StatusCode.Code);
            ServerFixtureUtils.ValidateResponse(response);

            return(nodesToCall);
        }