static async Task Main(string[] args) { Logger.LogInformation($"Starting Deployment Tester with the following settings: \r\n{Settings.Current}"); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger); var testResultReportingClient = new TestResultReportingClient { BaseUrl = Settings.Current.TestResultCoordinatorUrl.AbsoluteUri }; try { if (Settings.Current.TestMode == DeploymentTesterMode.Receiver) { await ReportDeploymentEnvironmentVariablesAsync(testResultReportingClient); } else { await Task.Delay(Settings.Current.TestStartDelay); await UpdateDeploymentEnvironmentVariablesAsync(testResultReportingClient, cts); } } catch (Exception ex) { Logger.LogError(ex, "Unexpected exception found."); await ModuleUtil.ReportTestResultAsync(testResultReportingClient, Logger, new ErrorTestResult(Settings.Current.TrackingId, Settings.Current.ModuleId, ex)); } await cts.Token.WhenCanceled(); completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); Logger.LogInformation("DeploymentTester Main() finished."); }
public async Task StartAsync( DateTime runExpirationTime, DateTime edgeHubRestartedTime, CancellationToken cancellationToken) { (DateTime dmCompletedTime, HttpStatusCode dmStatusCode) = await this.SendDirectMethodAsync( Settings.Current.DeviceId, this.directMethodTargetModuleId, Settings.Current.DirectMethodName, runExpirationTime, cancellationToken); TestResultBase dmTestResult = new EdgeHubRestartDirectMethodResult( this.GetSource(), DateTime.UtcNow, Settings.Current.TrackingId, this.batchId, this.directMethodCount, edgeHubRestartedTime, dmCompletedTime, dmStatusCode); await ModuleUtil.ReportTestResultAsync( this.GetReportClient(), this.logger, dmTestResult, cancellationToken); }
static async Task ReportTestInfoAsync() { var testInfoResults = new string[] { $"Network Run Profile={Settings.Current.NetworkRunProfile}", $"Network Network Id={Settings.Current.NetworkId}", $"Network Frequencies={string.Join(",", Settings.Current.Frequencies.Select(f => $"[offline:{f.OfflineFrequency},Online:{f.OnlineFrequency},Runs:{f.RunsCount}]"))}" }; var testResultReportingClient = new TestResultReportingClient() { BaseUrl = Settings.Current.TestResultCoordinatorEndpoint.AbsoluteUri }; foreach (string testInfo in testInfoResults) { await ModuleUtil.ReportTestResultAsync( testResultReportingClient, Log, new TestInfoResult( Settings.Current.TrackingId, Settings.Current.ModuleId, testInfo, DateTime.UtcNow)); } }
async Task SendStatus(string status) { var result = new LegacyTwinTestResult(this.moduleId, DateTime.UtcNow, status); Logger.LogDebug($"Sending report {result.GetFormattedResult()}"); await ModuleUtil.ReportTestResultAsync(this.testResultReportingClient, Logger, result); }
public async Task StartAsync( DateTime runExpirationTime, DateTime edgeHubRestartedTime, CancellationToken cancellationToken) { (DateTime msgCompletedTime, HttpStatusCode mgsStatusCode) = await this.SendMessageAsync( Settings.Current.TrackingId, this.batchId, Settings.Current.MessageOutputEndpoint, runExpirationTime, cancellationToken); TestResultBase msgTestResult = new EdgeHubRestartMessageResult( this.GetSource(), DateTime.UtcNow, Settings.Current.TrackingId, this.batchId.ToString(), this.messageCount.ToString(), edgeHubRestartedTime, msgCompletedTime, mgsStatusCode); await ModuleUtil.ReportTestResultAsync( this.GetReportClient(), this.logger, msgTestResult, cancellationToken); }
static async Task UpdateDeploymentEnvironmentVariablesAsync(TestResultReportingClient apiClient, CancellationTokenSource cts) { RegistryManager registryManager = null; try { registryManager = RegistryManager.CreateFromConnectionString(Settings.Current.IoTHubConnectionString.OrDefault()); JObject deploymentJson = await GetEdgeAgentDeploymentManifestJsonAsync(registryManager, Settings.Current.DeviceId); DateTime testStartAt = DateTime.UtcNow; long count = 1; var envVars = new Dictionary <string, string>(); while (!cts.IsCancellationRequested && DateTime.UtcNow - testStartAt < Settings.Current.TestDuration) { KeyValuePair <string, string> newEnvVar = AddEnvironmentValue(deploymentJson, Settings.Current.TargetModuleId.OrDefault(), count); ConfigurationContent configContent = JsonConvert.DeserializeObject <ConfigurationContent>(deploymentJson.ToString()); await registryManager.ApplyConfigurationContentOnDeviceAsync(Settings.Current.DeviceId, configContent); envVars.Add(newEnvVar.Key, newEnvVar.Value); var testResult = new DeploymentTestResult(Settings.Current.TrackingId, Settings.Current.ModuleId + ".send", envVars, DateTime.UtcNow); await ModuleUtil.ReportTestResultAsync(apiClient, Logger, testResult); Logger.LogInformation($"Successfully report to TRC for new deployment: tracking id={Settings.Current.TrackingId}, new environment variable={newEnvVar.Key}:{newEnvVar.Value}, EnvVars Count={envVars.Count}."); await Task.Delay(Settings.Current.DeploymentUpdatePeriod, cts.Token); count++; } } finally { registryManager?.Dispose(); } }
static async Task <DateTime> RestartEdgeHubAsync( ServiceClient iotHubServiceClient, CancellationToken cancellationToken) { DateTime startAttemptTime = DateTime.UtcNow; CloudToDeviceMethod c2dMethod = new CloudToDeviceMethod("RestartModule"); string payloadSchema = "{{ \"SchemaVersion\": \"1.0\", \"Id\": \"{0}\" }}"; string payload = string.Format(payloadSchema, "edgeHub"); Logger.LogInformation("RestartModule Method Payload: {0}", payload); c2dMethod.SetPayloadJson(payload); while (true) { try { // TODO: Introduce the offline scenario to use docker command. CloudToDeviceMethodResult response = await iotHubServiceClient.InvokeDeviceMethodAsync(Settings.Current.DeviceId, "$edgeAgent", c2dMethod); if ((HttpStatusCode)response.Status != HttpStatusCode.OK) { Logger.LogError($"Calling EdgeHub restart failed with status code {response.Status} : {response.GetPayloadAsJson()}."); } else { Logger.LogInformation($"Calling EdgeHub restart succeeded with status code {response.Status}."); } return(DateTime.UtcNow); } catch (Exception e) { Logger.LogError($"Exception caught for payload {payload}: {e}"); if (Settings.Current.RestartPeriod < DateTime.UtcNow - startAttemptTime) { string errorMessage = $"Failed to restart EdgeHub from {startAttemptTime} to {DateTime.UtcNow}:\n\n{e}\n\nPayload: {payload}"; TestResultBase errorResult = new ErrorTestResult( Settings.Current.TrackingId, GetSource(), errorMessage, DateTime.UtcNow); var reportClient = new TestResultReportingClient { BaseUrl = Settings.Current.ReportingEndpointUrl.AbsoluteUri }; await ModuleUtil.ReportTestResultAsync( reportClient, Logger, errorResult, cancellationToken); throw; } } } }
async Task <Tuple <DateTime, HttpStatusCode> > SendMessageAsync( string trackingId, Guid batchId, string msgOutputEndpoint, DateTime runExpirationTime, CancellationToken cancellationToken) { ModuleClient moduleClient = await this.GetModuleClientAsync(); this.messageCount++; while ((!cancellationToken.IsCancellationRequested) && (DateTime.UtcNow < runExpirationTime)) { Message message = new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new { data = DateTime.UtcNow.ToString() }))); message.Properties.Add("sequenceNumber", this.messageCount.ToString()); message.Properties.Add("batchId", batchId.ToString()); message.Properties.Add("trackingId", trackingId); try { // Sending the result via edgeHub await moduleClient.SendEventAsync(msgOutputEndpoint, message); this.logger.LogInformation($"[SendMessageAsync] Send Message with count {this.messageCount}: finished."); return(new Tuple <DateTime, HttpStatusCode>(DateTime.UtcNow, HttpStatusCode.OK)); } catch (Exception ex) { if (ex is TimeoutException) { // TimeoutException is expected to happen while the EdgeHub is down. // Let's log the attempt and retry the message send until successful this.logger.LogDebug(ex, $"[SendMessageAsync] Exception caught with SequenceNumber {this.messageCount}, BatchId: {batchId.ToString()}"); } else { string errorMessage = $"[SendMessageAsync] Exception caught with SequenceNumber {this.messageCount}, BatchId: {batchId.ToString()}"; this.logger.LogError(ex, errorMessage); TestResultBase errorResult = new ErrorTestResult( Settings.Current.TrackingId, this.GetSource(), errorMessage, DateTime.UtcNow); await ModuleUtil.ReportTestResultAsync( this.GetReportClient(), this.logger, errorResult, cancellationToken); } } } return(new Tuple <DateTime, HttpStatusCode>(DateTime.UtcNow, HttpStatusCode.InternalServerError)); }
async Task SendReportAsync(string source, StatusCode statusCode, TwinCollection details, string exception = "") { var result = new TwinTestResult(source, DateTime.UtcNow) { Operation = statusCode.ToString(), Properties = details, ErrorMessage = exception, TrackingId = this.trackingId }; Logger.LogDebug($"Sending report {result.GetFormattedResult()}"); await ModuleUtil.ReportTestResultAsync(this.testResultReportingClient, Logger, result); }
public Task ReportNetworkStatusAsync(NetworkControllerOperation operation, NetworkControllerStatus networkControllerStatus, NetworkControllerType networkControllerType, bool success = true) { var testResult = new NetworkControllerTestResult(this.moduleId, DateTime.UtcNow) { Operation = operation.ToString(), OperationStatus = success ? "Success" : "Failed", NetworkControllerType = networkControllerType, NetworkControllerStatus = networkControllerStatus, TrackingId = this.trackingId }; return(ModuleUtil.ReportTestResultAsync(this.testResultReportingClient, Log, testResult)); }
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); }
public async Task ReportTestResult() { await this.testResultReportingClient.ForEachAsync( async (TestResultReportingClient testResultReportingClient) => { DirectMethodTestResult testResult = new DirectMethodTestResult(this.configuration.GetValue <string>("IOTEDGE_MODULEID") + ".receive", DateTime.UtcNow) { TrackingId = this.trackingId.GetOrElse(string.Empty), BatchId = this.batchId.ToString(), SequenceNumber = this.directMethodCount.ToString(), Result = HttpStatusCode.OK.ToString() }; await ModuleUtil.ReportTestResultAsync(testResultReportingClient, this.logger, testResult); }); }
public async Task ReportTestResult(string directMethodCount) { await this.testResultReportingClient.ForEachAsync( async (TestResultReportingClient testResultReportingClient) => { DirectMethodTestResult testResult = new DirectMethodTestResult( this.configuration.GetValue <string>("IOTEDGE_MODULEID") + ".receive", DateTime.UtcNow, this.trackingId.GetOrElse(string.Empty), this.batchId, ulong.Parse(directMethodCount), HttpStatusCode.OK); await ModuleUtil.ReportTestResultAsync(testResultReportingClient, this.logger, testResult); }); }
static async Task ReportDeploymentEnvironmentVariablesAsync(TestResultReportingClient trcClient) { // Report all environment variable with predefined prefix to Test Result Coordinator var envVars = new Dictionary <string, string>(); foreach (DictionaryEntry envVariable in Environment.GetEnvironmentVariables()) { if (envVariable.Key.ToString().StartsWith(Settings.EnvironmentVariablePrefix, StringComparison.OrdinalIgnoreCase)) { envVars.Add(envVariable.Key.ToString(), envVariable.Value.ToString()); } } var testResult = new DeploymentTestResult(Settings.Current.TrackingId, Settings.Current.ModuleId + ".receive", envVars, DateTime.UtcNow); await ModuleUtil.ReportTestResultAsync(trcClient, Logger, testResult); Logger.LogInformation($"Successfully report to TRC for new deployment: tracking id={Settings.Current.TrackingId}, environment variable count={testResult.EnvironmentVariables.Count}."); }
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; } } }
public static async Task <int> MainAsync() { Logger.LogInformation($"Starting DirectMethodSender with the following settings:\r\n{Settings.Current}"); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger); DirectMethodSenderBase directMethodClient = null; ModuleClient reportClient = null; Option <Uri> analyzerUrl = Settings.Current.AnalyzerUrl; Option <Uri> testReportCoordinatorUrl = Settings.Current.TestResultCoordinatorUrl; try { Guid batchId = Guid.NewGuid(); Logger.LogInformation($"Batch Id={batchId}"); directMethodClient = await CreateClientAsync(Settings.Current.InvocationSource); reportClient = 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, cts.Token); DateTime testStartAt = DateTime.UtcNow; while (!cts.Token.IsCancellationRequested && IsTestTimeUp(testStartAt)) { (HttpStatusCode result, long dmCounter) = await directMethodClient.InvokeDirectMethodAsync(cts); // TODO: Create an abstract class to handle the reporting client generation if (testReportCoordinatorUrl.HasValue) { await testReportCoordinatorUrl.ForEachAsync( async (Uri uri) => { var testResult = new DirectMethodTestResult(Settings.Current.ModuleId + ".send", DateTime.UtcNow) { TrackingId = Settings.Current.TrackingId.Expect(() => new ArgumentException("TrackingId is empty")), BatchId = batchId.ToString(), SequenceNumber = dmCounter.ToString(), Result = result.ToString() }; var testResultReportingClient = new TestResultReportingClient { BaseUrl = uri.AbsoluteUri }; await ModuleUtil.ReportTestResultAsync(testResultReportingClient, Logger, testResult); }); } else { await analyzerUrl.ForEachAsync( async (Uri uri) => { var testResult = new LegacyDirectMethodTestResult(Settings.Current.TargetModuleId, DateTime.UtcNow) { Result = result.ToString() }; var testResultReportingClient = new TestResultReportingClient { BaseUrl = uri.AbsoluteUri }; await ModuleUtil.ReportTestResultAsync(testResultReportingClient, Logger, testResult); }, async() => { await reportClient.SendEventAsync("AnyOutput", new Message(Encoding.UTF8.GetBytes("Direct Method call succeeded."))); }); } await Task.Delay(Settings.Current.DirectMethodDelay, cts.Token); } await cts.Token.WhenCanceled(); } catch (Exception e) { Logger.LogError(e, "Error occurred during direct method sender test setup"); } finally { // Implicit CloseAsync() directMethodClient?.Dispose(); reportClient?.Dispose(); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); Logger.LogInformation("DirectMethodSender Main() finished."); return(0); }
async Task <Tuple <DateTime, HttpStatusCode> > SendDirectMethodAsync( string deviceId, string targetModuleId, string directMethodName, DateTime runExpirationTime, CancellationToken cancellationToken) { while ((!cancellationToken.IsCancellationRequested) && (DateTime.UtcNow < runExpirationTime)) { try { // Direct Method sequence number is always increasing regardless of sending result. this.directMethodCount++; MethodRequest request = new MethodRequest( directMethodName, Encoding.UTF8.GetBytes($"{{ \"Message\": \"Hello\", \"DirectMethodCount\": \"{this.directMethodCount}\" }}"), TimeSpan.FromSeconds(5), // Minimum value accepted by SDK Settings.Current.SdkOperationTimeout); MethodResponse result = await this.dmModuleClient.InvokeMethodAsync(deviceId, targetModuleId, request); this.logger.LogInformation($"[DirectMethodEdgeHubConnector] Invoke DirectMethod with count {this.directMethodCount}"); if ((HttpStatusCode)result.Status == HttpStatusCode.OK) { this.logger.LogDebug(result.ResultAsJson); } else { this.logger.LogError(result.ResultAsJson); } return(new Tuple <DateTime, HttpStatusCode>(DateTime.UtcNow, (HttpStatusCode)result.Status)); } catch (Exception e) { // Only handle the exception that relevant to our test case; otherwise, re-throw it. if (this.IsEdgeHubDownDuringDirectMethodSend(e) || this.IsDirectMethodReceiverNotConnected(e)) { // swallow exeception and retry until success this.logger.LogDebug($"[DirectMethodEdgeHubConnector] Expected exception caught with SequenceNumber {this.directMethodCount}"); } else { // something is wrong, Log and send report to TRC string errorMessage = $"[DirectMethodEdgeHubConnector] Exception caught with SequenceNumber {this.directMethodCount}"; this.logger.LogError(e, errorMessage); TestResultBase errorResult = new ErrorTestResult( Settings.Current.TrackingId, this.GetSource(), errorMessage, DateTime.UtcNow); await ModuleUtil.ReportTestResultAsync( this.GetReportClient(), this.logger, errorResult, cancellationToken); } } } return(new Tuple <DateTime, HttpStatusCode>(DateTime.UtcNow, HttpStatusCode.InternalServerError)); }
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); }
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) { 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); }