Esempio n. 1
0
        /// <summary>
        /// Analyze payload of IoTHub message, adding timestamp and related sequence numbers into temporary
        /// </summary>
        /// <param name="arg"></param>
        /// <returns>Task that run until token is canceled</returns>
        private Task Client_ProcessEventAsync(ProcessEventArgs arg)
        {
            var eventReceivedTimestamp = DateTime.UtcNow;

            // Check if already stopped.
            if (_cancellationTokenSource == null)
            {
                _logger.LogWarning("Received Events but nothing to do, because already stopped");
                return(Task.CompletedTask);
            }

            if (!arg.HasEvent)
            {
                _logger.LogWarning("Received partition event without content");
                return(Task.CompletedTask);
            }

            var     body              = arg.Data.Body.ToArray();
            var     content           = Encoding.UTF8.GetString(body);
            dynamic json              = JsonConvert.DeserializeObject(content);
            var     valueChangesCount = 0;

            // TODO build variant that works with PubSub

            foreach (dynamic entry in json)
            {
                DateTime entrySourceTimestamp;
                string   entryNodeId = null;
                object   entryValue;

                try
                {
                    entrySourceTimestamp = (DateTime)entry.Value.SourceTimestamp;
                    entryNodeId          = entry.NodeId;
                    entryValue           = entry.Value.Value;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Could not read sequence number, nodeId and/or timestamp from " +
                                     "message. Please make sure that publisher is running with samples format and with " +
                                     "--fm parameter set.");
                    continue;
                }

                // Feed data to checkers.
                _missingTimestampsChecker.ProcessEvent(entryNodeId, entrySourceTimestamp, entryValue);
                _messageProcessingDelayChecker.ProcessEvent(entrySourceTimestamp, eventReceivedTimestamp);
                _messageDeliveryDelayChecker.ProcessEvent(entrySourceTimestamp, arg.Data.EnqueuedTime.UtcDateTime);
                _valueChangeCounterPerNodeId.ProcessEvent(entryNodeId, entrySourceTimestamp, entryValue);
                _missingValueChangesChecker.ProcessEvent(entrySourceTimestamp);
                _incrementalIntValueChecker.ProcessEvent(entryNodeId, entryValue);

                Interlocked.Increment(ref _totalValueChangesCount);
                valueChangesCount++;
            }

            _logger.LogDebug("Received {NumberOfValueChanges} messages from IoT Hub, partition {PartitionId}.",
                             valueChangesCount, arg.Partition.PartitionId);
            return(Task.CompletedTask);
        }
        /// <summary>
        /// Feed the checkers for the Value Change (single Node value) within the reveived event
        /// </summary>
        /// <param name="nodeId">Identifeir of the data source.</param>
        /// <param name="sourceTimestamp">Timestamp at the Data Source.</param>
        /// <param name="enqueuedTimestamp">IoT Hub message enqueue timestamp.</param>
        /// <param name="receivedTimestamp">Timestamp of arrival in the telemetry processor.</param>
        /// <param name="value">The actual value of the data change.</param>
        private void FeedDataCheckers(
            string nodeId,
            DateTime sourceTimestamp,
            DateTime enqueuedTimestamp,
            DateTime receivedTimestamp,
            object value)
        {
            // OPC PLC contains bad fast and slow nodes that drop messages by design.
            // We will ignore entries that do not have a value.
            if (value is null)
            {
                return;
            }

            // Feed data to checkers.
            _missingTimestampsChecker.ProcessEvent(nodeId, sourceTimestamp, value);
            _messageProcessingDelayChecker.ProcessEvent(nodeId, sourceTimestamp, receivedTimestamp);
            _messageDeliveryDelayChecker.ProcessEvent(nodeId, sourceTimestamp, enqueuedTimestamp);
            _valueChangeCounterPerNodeId.ProcessEvent(nodeId, sourceTimestamp, value);
            _missingValueChangesChecker.ProcessEvent(sourceTimestamp);
            _incrementalIntValueChecker.ProcessEvent(nodeId, sourceTimestamp, value);

            Interlocked.Increment(ref _totalValueChangesCount);
        }