コード例 #1
0
        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.");
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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));
            }
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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();
            }
        }
コード例 #7
0
        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;
                    }
                }
            }
        }
コード例 #8
0
        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));
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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));
        }
コード例 #11
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);
 }
コード例 #12
0
 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);
     });
 }
コード例 #13
0
        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);
            });
        }
コード例 #14
0
        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}.");
        }
コード例 #15
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);
     });
 }
コード例 #16
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);
            }
        }
コード例 #17
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;
                }
            }
        }
コード例 #18
0
ファイル: Program.cs プロジェクト: mabubaker1947/iotedge
        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);
        }
コード例 #19
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));
        }
コード例 #20
0
ファイル: Program.cs プロジェクト: nlcamp/iotedge
        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);
        }
コード例 #21
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.");
        }
コード例 #22
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);
        }