public async Task <IActionResult> Post([FromBody] PayloadV5 payload) { string payloadFieldsUnpacked = string.Empty; // Check that the post data is good if (!this.ModelState.IsValid) { log.WarnFormat("QueuedController validation failed {0}", this.ModelState.Messages()); return(this.BadRequest(this.ModelState)); } try { QueueClient queueClient = new QueueClient(storageConnectionString, queueName); await queueClient.CreateIfNotExistsAsync(); await queueClient.SendMessageAsync(Convert.ToBase64String(JsonSerializer.SerializeToUtf8Bytes(payload))); } catch (Exception ex) { log.Error("Unable to open/create queue or send message", ex); return(this.Problem("Unable to open queue (creating if it doesn't exist) or send message", statusCode: 500, title: "Uplink payload not sent")); } return(this.Ok()); }
public static async Task Run( [QueueTrigger("%UplinkQueueName%", Connection = "AzureStorageConnectionString")] PayloadV5 payloadObject, ILogger log) { DeviceClient deviceClient = null; // I worry about threading for this and configuration if (Log == null) { Log = log; } // Quick n dirty hack to see what difference (if any) not processing retries makes if (payloadObject.is_retry) { Log.LogInformation("DevID:{dev_id} AppID:{app_id} Counter:{counter} Uplink message retry", payloadObject.dev_id, payloadObject.app_id, payloadObject.counter); return; } // Check that KeyVault URI is configured in environment variables. Not a lot we can do if it isn't.... if (Configuration == null) { string keyVaultUri = Environment.GetEnvironmentVariable("KeyVaultURI"); if (string.IsNullOrEmpty(keyVaultUri)) { Log.LogError("KeyVaultURI environment variable not set"); throw new ApplicationException("KeyVaultURI environment variable not set"); } // Load configuration from KeyVault try { Configuration = new ConfigurationBuilder() .AddEnvironmentVariables() .AddAzureKeyVault(keyVaultUri) .Build(); } catch (Exception ex) { Log.LogError(ex, $"Configuration loading failed"); throw; } } Log.LogInformation("DevID:{dev_id} AppID:{app_id} Counter:{counter} Uplink message device processing start", payloadObject.dev_id, payloadObject.app_id, payloadObject.counter); deviceClient = await DeviceClientCreate( Configuration.GetSection("DPSGlobaDeviceEndpoint").Value, Configuration.GetSection("DPSIDScope").Value, payloadObject.app_id, payloadObject.dev_id); await DeviceTelemetrySend(deviceClient, payloadObject); Log.LogInformation("DevID:{dev_id} AppID:{app_id} Counter:{counter} Uplink message device processing completed", payloadObject.dev_id, payloadObject.app_id, payloadObject.counter); }
static async Task DeviceTelemetrySend(DeviceClient deviceClient, PayloadV5 payloadObject) { // Assemble the JSON payload to send to Azure IoT Hub/Central. Log.LogInformation("DevID:{dev_id} AppID:{app_id} Payload assembly start", payloadObject.dev_id, payloadObject.app_id); JObject telemetryEvent = new JObject(); try { JObject payloadFields = (JObject)payloadObject.payload_fields; telemetryEvent.Add("HardwareSerial", payloadObject.hardware_serial); telemetryEvent.Add("Retry", payloadObject.is_retry); telemetryEvent.Add("Counter", payloadObject.counter); telemetryEvent.Add("DeviceID", payloadObject.dev_id); telemetryEvent.Add("ApplicationID", payloadObject.app_id); telemetryEvent.Add("Port", payloadObject.port); telemetryEvent.Add("PayloadRaw", payloadObject.payload_raw); telemetryEvent.Add("ReceivedAtUTC", payloadObject.metadata.time); // If the payload has been unpacked in TTN backend add fields to telemetry event payload if (payloadFields != null) { foreach (JProperty child in payloadFields.Children()) { EnumerateChildren(telemetryEvent, child); } } } catch (Exception ex) { Log.LogError(ex, "DevID:{dev_id} AppID:{app_id} Payload processing or Telemetry event assembly failed", payloadObject.dev_id, payloadObject.app_id); throw; } // Send the message to Azure IoT Hub/Azure IoT Central Log.LogInformation("DevID:{dev_id} AppID:{app_id} Payload SendEventAsync start", payloadObject.dev_id, payloadObject.app_id); try { using (Message ioTHubmessage = new Message(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(telemetryEvent)))) { // Ensure the displayed time is the acquired time rather than the uploaded time. esp. important for when messages that ended up // in poison queue are returned to the processing queue. ioTHubmessage.Properties.Add("iothub-creation-time-utc", payloadObject.metadata.time.ToString("s", CultureInfo.InvariantCulture)); await deviceClient.SendEventAsync(ioTHubmessage); } } catch (Exception ex) { if (!DeviceClients.TryRemove(payloadObject.dev_id, out deviceClient)) { Log.LogWarning("DevID:{dev_id} AppID:{app_id} Payload SendEventAsync TryRemove failed", payloadObject.dev_id, payloadObject.app_id); } Log.LogError(ex, "DevID:{dev_id} AppID:{app_id} SendEventAsync failed", payloadObject.dev_id, payloadObject.app_id); throw; } }