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