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."); } } } } }
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); }
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); }
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); }); }
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); } }
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; } } }
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); }
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."); }
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); }