internal static async Task RecordDeviceBackfillRequest(Types.BackfillRequest request, ILogger logger) { try { using (SqlConnection connection = new SqlConnection(Environment.GetEnvironmentVariable("SQLConnectionString"))) { await connection.OpenAsync(); using (SqlCommand command = new SqlCommand(SqlHelpers.SQL_INSERT_BACKFILL_REQUEST, connection)) { command.Parameters.AddWithValue("@startWindow", request.StartWindow.ToUniversalTime().ToString("o")); command.Parameters.AddWithValue("@endWindow", request.EndWindow.ToUniversalTime().ToString("o")); command.Parameters.AddWithValue("@batchId", request.BatchId); command.Parameters.AddWithValue("@created", request.Created.ToUniversalTime().ToString("o")); if (await command.ExecuteNonQueryAsync() != 1) { throw new Exception($"Cannot insert new backfill request in SQL:{JsonConvert.SerializeObject(request)}"); } } } } catch (SqlException e) { logger.LogError($"Error when reading sql database: {e.ToString()}"); throw; } return; }
internal static async Task InvokeDirectMethod(Types.BackfillRequest request, ILogger logger) { try { logger.LogInformation("Calling BackfillMethod"); // This call should be non blocking. The back-fill might take a long time on the device. // The device needs to ack back and start the back-fill. var methodInvocation = new CloudToDeviceMethod(Environment.GetEnvironmentVariable("BackfillMethodName")) { ResponseTimeout = TimeSpan.FromSeconds(Int32.Parse(Environment.GetEnvironmentVariable("DirectMethodResponseTimeoutSeconds"))) }; methodInvocation.SetPayloadJson(JsonConvert.SerializeObject(request)); using (var serviceClient = ServiceClient.CreateFromConnectionString(Environment.GetEnvironmentVariable("IoTHubConnectionString"))) { // Invoke the direct method asynchronously and get the response from the simulated device. logger.LogInformation("Calling BackfillMethod"); var response = await serviceClient.InvokeDeviceMethodAsync( Environment.GetEnvironmentVariable("IoTDeviceId"), Environment.GetEnvironmentVariable("IoTModuleId"), methodInvocation); logger.LogInformation($"Response status: {response.Status}, payload: {response.GetPayloadAsJson()}"); } } catch (Exception ex) { logger.LogError($"Error when calling the backfill direct method: {ex.ToString()}"); } return; }
internal static Types.BackfillRequest CreateDeviceBackfillRequest(Types.DataGap dataGap, ILogger logger) { Types.BackfillRequest backfillRequest = new Types.BackfillRequest() { BatchId = dataGap.BatchId, EndWindow = dataGap.EndWindow, StartWindow = dataGap.StartWindow, Created = DateTime.UtcNow }; return(backfillRequest); }
public static async Task RunAsync( [QueueTrigger("%StorageQueueName%", Connection = "StorageConnectionString")] string backfillRequest, [EventHub("%ExecutionEventHubName%", Connection = "EventHubConnectionString")] IAsyncCollector <string> outputEvents, ILogger log, ExecutionContext context) { try { log.LogInformation($"{context.FunctionName}: {backfillRequest}"); Types.DataGap request = JsonConvert.DeserializeObject <Types.DataGap>(backfillRequest); Types.BackfillRequest existingDeviceBackfillRequest = await Helpers.SqlHelpers.GetExistingDeviceBackfillRequest(request, log); if (existingDeviceBackfillRequest != null) { log.LogInformation($"{context.FunctionName}: Found existing backfill request {JsonConvert.SerializeObject(existingDeviceBackfillRequest)}"); return; } List <Types.DataGap> latestGaps = await Helpers.SqlHelpers.CalculateActualGaps(request, log); foreach (Types.DataGap gap in latestGaps) { existingDeviceBackfillRequest = await Helpers.SqlHelpers.GetExistingDeviceBackfillRequest(request, log); if (existingDeviceBackfillRequest != null) { log.LogInformation($"{context.FunctionName}: Found existing backfill request {JsonConvert.SerializeObject(existingDeviceBackfillRequest)}"); continue; } Types.BackfillRequest requestSection = Helpers.SqlHelpers.CreateDeviceBackfillRequest(gap, log); string requestSectionString = JsonConvert.SerializeObject(requestSection); await outputEvents.AddAsync(requestSectionString); log.LogInformation($"{context.FunctionName}: Created backfill request {requestSectionString}"); } } catch (Exception e) { log.LogError($"Error in {context.FunctionName}: {e.ToString()}"); throw; } }