public async Task ProcessEventsAsync(IEnumerable <EventData> events)
        {
            Logger.LogInformation("Processing events from event hub.");

            if (events != null)
            {
                foreach (EventData eventData in events)
                {
                    eventData.Properties.TryGetValue(TestConstants.Message.TrackingIdPropertyName, out object trackingIdFromEvent);
                    eventData.SystemProperties.TryGetValue(DeviceIdPropertyName, out object deviceIdFromEvent);
                    eventData.SystemProperties.TryGetValue(ModuleIdPropertyName, out object moduleIdFromEvent);

                    Logger.LogDebug($"Received event from Event Hub: trackingId={(string)trackingIdFromEvent}, deviceId={(string)deviceIdFromEvent}, moduleId={(string)moduleIdFromEvent}");

                    if (!string.IsNullOrWhiteSpace((string)trackingIdFromEvent) &&
                        string.Equals(trackingIdFromEvent.ToString(), this.trackingId, StringComparison.OrdinalIgnoreCase) &&
                        !string.IsNullOrWhiteSpace((string)deviceIdFromEvent) &&
                        string.Equals(deviceIdFromEvent.ToString(), this.deviceId, StringComparison.OrdinalIgnoreCase) &&
                        !string.IsNullOrWhiteSpace((string)moduleIdFromEvent))
                    {
                        eventData.Properties.TryGetValue(TestConstants.Message.SequenceNumberPropertyName, out object sequenceNumberFromEvent);
                        eventData.Properties.TryGetValue(TestConstants.Message.BatchIdPropertyName, out object batchIdFromEvent);

                        Logger.LogDebug($"Received event from Event Hub: batchId={(string)batchIdFromEvent}, sequenceNumber={(string)sequenceNumberFromEvent}");

                        if (!string.IsNullOrWhiteSpace((string)sequenceNumberFromEvent) &&
                            !string.IsNullOrWhiteSpace((string)batchIdFromEvent))
                        {
                            if (long.TryParse(sequenceNumberFromEvent.ToString(), out long sequenceNumber))
                            {
                                DateTime enqueuedtime = GetEnqueuedTime(deviceIdFromEvent.ToString(), moduleIdFromEvent.ToString(), eventData);

                                // TODO: remove hardcoded eventHub string in next line
                                var testResult = new MessageTestResult((string)moduleIdFromEvent + ".eventHub", enqueuedtime)
                                {
                                    TrackingId     = (string)trackingIdFromEvent,
                                    BatchId        = (string)batchIdFromEvent,
                                    SequenceNumber = sequenceNumber.ToString()
                                };

                                await this.storage.AddResultAsync(testResult.ToTestOperationResult());

                                Logger.LogInformation($"Received event from Event Hub persisted to store: trackingId={(string)trackingIdFromEvent}, deviceId={(string)deviceIdFromEvent}, moduleId={(string)moduleIdFromEvent}, batchId={(string)batchIdFromEvent}, sequenceNumber={sequenceNumber}");
                            }
                            else
                            {
                                Logger.LogError($"Message for module [{moduleIdFromEvent}] and device [{this.deviceId}] contains invalid sequence number [{(string)sequenceNumberFromEvent}].");
                            }
                        }
                        else
                        {
                            Logger.LogDebug($"Message for module [{moduleIdFromEvent}] and device [{this.deviceId}] doesn't contain batch id and/or sequence number.");
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
 internal async Task ReportTestResult(Message message)
 {
     string trackingId         = message.Properties[TestConstants.Message.TrackingIdPropertyName];
     string batchId            = message.Properties[TestConstants.Message.BatchIdPropertyName];
     string sequenceNumber     = message.Properties[TestConstants.Message.SequenceNumberPropertyName];
     var    testResultReceived = new MessageTestResult(this.moduleId + ".receive", DateTime.UtcNow)
     {
         TrackingId     = trackingId,
         BatchId        = batchId,
         SequenceNumber = sequenceNumber
     };
     await ModuleUtil.ReportTestResultAsync(this.testResultReportingClient, this.logger, testResultReceived);
 }
Exemplo n.º 3
0
        static List <(long, TestOperationResult)> GetInvalidStoreData(
            string source,
            IEnumerable <string> resultValues,
            IEnumerable <DateTime> resultDates,
            int start = 0)
        {
            var storeData = new List <(long, TestOperationResult)>();
            int count     = start;

            for (int i = 0; i < resultValues.Count(); i++)
            {
                var networkControllerTestResult = new MessageTestResult(source, resultDates.ElementAt(i));
                storeData.Add((count, networkControllerTestResult.ToTestOperationResult()));
                count++;
            }

            return(storeData);
        }
Exemplo n.º 4
0
 protected async Task ReportResult(long messageIdCounter)
 {
     await Settings.Current.TestResultCoordinatorUrl.ForEachAsync(
         async trcUrl =>
     {
         var testResultCoordinatorUrl  = new Uri(trcUrl, UriKind.Absolute);
         var testResultReportingClient = new TestResultReportingClient {
             BaseUrl = testResultCoordinatorUrl.AbsoluteUri
         };
         var testResult = new MessageTestResult(Settings.Current.ModuleId + ".send", DateTime.UtcNow)
         {
             TrackingId     = this.TrackingId,
             BatchId        = this.BatchId.ToString(),
             SequenceNumber = messageIdCounter.ToString()
         };
         await ModuleUtil.ReportTestResultAsync(testResultReportingClient, this.Logger, testResult);
     });
 }
Exemplo n.º 5
0
        public async Task StartAsync(CancellationToken ct)
        {
            this.logger.LogInformation($"CloudToDeviceMessageTester in sender mode with delayed start for {this.testStartDelay}.");
            await Task.Delay(this.testStartDelay, ct);

            DateTime testStartAt = DateTime.UtcNow;

            this.serviceClient = ServiceClient.CreateFromConnectionString(this.iotHubConnectionString);
            await this.serviceClient.OpenAsync();

            Guid batchId = Guid.NewGuid();

            this.logger.LogInformation($"Batch Id={batchId}");

            while (!ct.IsCancellationRequested && this.IsTestTimeUp(testStartAt))
            {
                MessageTestResult testResult = await this.SendCloudToDeviceMessageAsync(batchId, this.trackingId);

                await ModuleUtil.ReportTestResultAsync(this.testResultReportingClient, this.logger, testResult);

                this.messageCount++;
                await Task.Delay(this.messageDelay, ct);
            }
        }
Exemplo n.º 6
0
        public async Task StartAsync(CancellationToken ct)
        {
            this.logger.LogInformation($"CloudToDeviceMessageTester in sender mode with delayed start for {this.testStartDelay}.");
            await Task.Delay(this.testStartDelay, ct);

            DateTime testStartAt = DateTime.UtcNow;

            this.serviceClient = ServiceClient.CreateFromConnectionString(this.iotHubConnectionString);
            await this.serviceClient.OpenAsync();

            Guid batchId = Guid.NewGuid();

            this.logger.LogInformation($"Batch Id={batchId}");

            while (!ct.IsCancellationRequested && this.IsTestTimeUp(testStartAt))
            {
                try
                {
                    MessageTestResult testResult = await this.SendCloudToDeviceMessageAsync(batchId, this.trackingId);

                    this.messageCount++;
                    await ModuleUtil.ReportTestResultAsync(this.testResultReportingClient, this.logger, testResult);

                    await Task.Delay(this.messageDelay, ct);
                }
                catch (DeviceMaximumQueueDepthExceededException ex)
                {
                    this.logger.LogInformation($"Too many messages in IoTHub Queue for Sequence Number: {this.messageCount}, batchId: {batchId}. Error message: {ex.Message}");
                }
                catch (Exception ex)
                {
                    this.logger.LogError($"Error occurred while sending Cloud to Device message for Sequence number: {this.messageCount}, batchId: {batchId}. Error message: {ex.Message}");
                    throw;
                }
            }
        }
Exemplo n.º 7
0
        static async Task <MessageResponse> ProcessAndSendMessageAsync(Message message, object userContext)
        {
            Uri testResultCoordinatorUrl = Settings.Current.TestResultCoordinatorUrl;

            try
            {
                if (!(userContext is ModuleClient moduleClient))
                {
                    throw new InvalidOperationException("UserContext doesn't contain expected value");
                }

                // Must make a new message instead of reusing the old message because of the way the SDK sends messages
                string trackingId        = string.Empty;
                string batchId           = string.Empty;
                string sequenceNumber    = string.Empty;
                var    messageProperties = new List <KeyValuePair <string, string> >();

                foreach (KeyValuePair <string, string> prop in message.Properties)
                {
                    switch (prop.Key)
                    {
                    case TestConstants.Message.TrackingIdPropertyName:
                        trackingId = prop.Value ?? string.Empty;
                        break;

                    case TestConstants.Message.BatchIdPropertyName:
                        batchId = prop.Value ?? string.Empty;
                        break;

                    case TestConstants.Message.SequenceNumberPropertyName:
                        sequenceNumber = prop.Value ?? string.Empty;
                        break;
                    }

                    messageProperties.Add(new KeyValuePair <string, string>(prop.Key, prop.Value));
                }

                if (string.IsNullOrWhiteSpace(trackingId) || string.IsNullOrWhiteSpace(batchId) || string.IsNullOrWhiteSpace(sequenceNumber))
                {
                    Logger.LogWarning($"Received message missing info: trackingid={trackingId}, batchId={batchId}, sequenceNumber={sequenceNumber}");
                    return(MessageResponse.Completed);
                }

                // Report receiving message successfully to Test Result Coordinator
                var testResultReportingClient = new TestResultReportingClient {
                    BaseUrl = testResultCoordinatorUrl.AbsoluteUri
                };
                var testResultReceived = new MessageTestResult(Settings.Current.ModuleId + ".receive", DateTime.UtcNow)
                {
                    TrackingId     = trackingId,
                    BatchId        = batchId,
                    SequenceNumber = sequenceNumber
                };
                await ModuleUtil.ReportTestResultAsync(testResultReportingClient, Logger, testResultReceived);

                Logger.LogInformation($"Successfully received message: trackingid={trackingId}, batchId={batchId}, sequenceNumber={sequenceNumber}");

                byte[] messageBytes = message.GetBytes();
                var    messageCopy  = new Message(messageBytes);
                messageProperties.ForEach(kvp => messageCopy.Properties.Add(kvp));
                await moduleClient.SendEventAsync(Settings.Current.OutputName, messageCopy);

                // Report sending message successfully to Test Result Coordinator
                var testResultSent = new MessageTestResult(Settings.Current.ModuleId + ".send", DateTime.UtcNow)
                {
                    TrackingId     = trackingId,
                    BatchId        = batchId,
                    SequenceNumber = sequenceNumber
                };
                await ModuleUtil.ReportTestResultAsync(testResultReportingClient, Logger, testResultSent);

                Logger.LogInformation($"Successfully sent message: trackingid={trackingId}, batchId={batchId}, sequenceNumber={sequenceNumber}");
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"Error in {nameof(ProcessAndSendMessageAsync)} method");
            }

            return(MessageResponse.Completed);
        }
Exemplo n.º 8
0
        static async Task Main()
        {
            Logger.LogInformation($"Starting load gen with the following settings:\r\n{Settings.Current}");

            ModuleClient moduleClient = null;

            try
            {
                (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger);

                Guid batchId = Guid.NewGuid();
                Logger.LogInformation($"Batch Id={batchId}");

                moduleClient = await ModuleUtil.CreateModuleClientAsync(
                    Settings.Current.TransportType,
                    ModuleUtil.DefaultTimeoutErrorDetectionStrategy,
                    ModuleUtil.DefaultTransientRetryStrategy,
                    Logger);

                Logger.LogInformation($"Load gen delay start for {Settings.Current.TestStartDelay}.");
                await Task.Delay(Settings.Current.TestStartDelay);

                DateTime testStartAt      = DateTime.UtcNow;
                long     messageIdCounter = 1;
                while (!cts.IsCancellationRequested &&
                       (Settings.Current.TestDuration == TimeSpan.Zero || DateTime.UtcNow - testStartAt < Settings.Current.TestDuration))
                {
                    try
                    {
                        await SendEventAsync(moduleClient, batchId, Settings.Current.TrackingId, messageIdCounter);

                        // Report sending message successfully to Test Result Coordinator
                        await Settings.Current.TestResultCoordinatorUrl.ForEachAsync(
                            async trcUrl =>
                        {
                            var testResultCoordinatorUrl  = new Uri(trcUrl, UriKind.Absolute);
                            var testResultReportingClient = new TestResultReportingClient {
                                BaseUrl = testResultCoordinatorUrl.AbsoluteUri
                            };
                            var testResult = new MessageTestResult(Settings.Current.ModuleId + ".send", DateTime.UtcNow)
                            {
                                TrackingId     = Settings.Current.TrackingId,
                                BatchId        = batchId.ToString(),
                                SequenceNumber = messageIdCounter.ToString()
                            };
                            await ModuleUtil.ReportTestResultAsync(testResultReportingClient, Logger, testResult);
                        });

                        if (messageIdCounter % 1000 == 0)
                        {
                            Logger.LogInformation($"Sent {messageIdCounter} messages.");
                        }

                        await Task.Delay(Settings.Current.MessageFrequency);

                        messageIdCounter++;
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError(ex, $"[SendEventAsync] Sequence number {messageIdCounter}, BatchId: {batchId.ToString()};");
                    }
                }

                Logger.LogInformation("Finish sending messages.");
                await cts.Token.WhenCanceled();

                completed.Set();
                handler.ForEach(h => GC.KeepAlive(h));
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Error occurred during load gen.");
            }
            finally
            {
                Logger.LogInformation("Closing connection to Edge Hub.");
                moduleClient?.CloseAsync();
                moduleClient?.Dispose();
            }

            Logger.LogInformation("Load Gen complete. Exiting.");
        }
Exemplo n.º 9
0
        static async Task <MessageResponse> ProcessAndSendMessageAsync(Message message, object userContext)
        {
            Logger.LogInformation($"Received message from device: {message.ConnectionDeviceId}, module: {message.ConnectionModuleId}");

            var testResultCoordinatorUrl = Option.None <Uri>();

            if (Settings.Current.EnableTrcReporting)
            {
                var builder = new UriBuilder(Settings.Current.TestResultCoordinatorUrl);
                builder.Host             = Dns.GetHostEntry(Settings.Current.TestResultCoordinatorUrl.Host).AddressList[0].ToString();
                testResultCoordinatorUrl = Option.Some(builder.Uri);
            }

            try
            {
                if (!(userContext is MessageHandlerContext messageHandlerContext))
                {
                    throw new InvalidOperationException("UserContext doesn't contain expected value");
                }

                ModuleClient            moduleClient            = messageHandlerContext.ModuleClient;
                DuplicateMessageAuditor duplicateMessageAuditor = messageHandlerContext.DuplicateMessageAuditor;

                // Must make a new message instead of reusing the old message because of the way the SDK sends messages
                string trackingId                = string.Empty;
                string batchId                   = string.Empty;
                string sequenceNumber            = string.Empty;
                var    messageProperties         = new List <KeyValuePair <string, string> >();
                var    testResultReportingClient = Option.None <TestResultReportingClient>();

                if (Settings.Current.EnableTrcReporting)
                {
                    foreach (KeyValuePair <string, string> prop in message.Properties)
                    {
                        switch (prop.Key)
                        {
                        case TestConstants.Message.TrackingIdPropertyName:
                            trackingId = prop.Value ?? string.Empty;
                            break;

                        case TestConstants.Message.BatchIdPropertyName:
                            batchId = prop.Value ?? string.Empty;
                            break;

                        case TestConstants.Message.SequenceNumberPropertyName:
                            sequenceNumber = prop.Value ?? string.Empty;
                            break;
                        }

                        messageProperties.Add(new KeyValuePair <string, string>(prop.Key, prop.Value));
                    }

                    if (string.IsNullOrWhiteSpace(trackingId) || string.IsNullOrWhiteSpace(batchId) || string.IsNullOrWhiteSpace(sequenceNumber))
                    {
                        Logger.LogWarning($"Received message missing info: trackingid={trackingId}, batchId={batchId}, sequenceNumber={sequenceNumber}");
                        return(MessageResponse.Completed);
                    }

                    if (duplicateMessageAuditor.ShouldFilterMessage(sequenceNumber))
                    {
                        return(MessageResponse.Completed);
                    }

                    // Report receiving message successfully to Test Result Coordinator
                    testResultReportingClient = Option.Some(new TestResultReportingClient {
                        BaseUrl = testResultCoordinatorUrl.OrDefault().AbsoluteUri
                    });
                    var testResultReceived = new MessageTestResult(Settings.Current.ModuleId + ".receive", DateTime.UtcNow)
                    {
                        TrackingId     = trackingId,
                        BatchId        = batchId,
                        SequenceNumber = sequenceNumber
                    };

                    await ModuleUtil.ReportTestResultAsync(testResultReportingClient.OrDefault(), Logger, testResultReceived);

                    Logger.LogInformation($"Successfully received message: trackingid={trackingId}, batchId={batchId}, sequenceNumber={sequenceNumber}");
                }

                if (!Settings.Current.ReceiveOnly)
                {
                    byte[] messageBytes = message.GetBytes();
                    var    messageCopy  = new Message(messageBytes);
                    messageProperties.ForEach(kvp => messageCopy.Properties.Add(kvp));
                    await moduleClient.SendEventAsync(Settings.Current.OutputName, messageCopy);

                    Logger.LogInformation($"Message relayed upstream for device: {message.ConnectionDeviceId}, module: {message.ConnectionModuleId}");

                    if (Settings.Current.EnableTrcReporting)
                    {
                        // Report sending message successfully to Test Result Coordinator
                        var testResultSent = new MessageTestResult(Settings.Current.ModuleId + ".send", DateTime.UtcNow)
                        {
                            TrackingId     = trackingId,
                            BatchId        = batchId,
                            SequenceNumber = sequenceNumber
                        };

                        await ModuleUtil.ReportTestResultAsync(testResultReportingClient.OrDefault(), Logger, testResultSent);

                        Logger.LogInformation($"Successfully reported message: trackingid={trackingId}, batchId={batchId}, sequenceNumber={sequenceNumber}");
                    }
                }
                else
                {
                    int uniqueResultsExpected = Settings.Current.UniqueResultsExpected.Expect <ArgumentException>(() => throw new ArgumentException("Must supply this value if in ReceiveOnly mode"));
                    if (!resultsReceived.Contains(sequenceNumber))
                    {
                        resultsReceived.Add(sequenceNumber);
                    }

                    if (resultsReceived.Count == uniqueResultsExpected)
                    {
                        isFinished = true;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"Error in {nameof(ProcessAndSendMessageAsync)} method");
            }

            return(MessageResponse.Completed);
        }