public static async Task<KustoOperations> GetClientAsync()
 {
     await semaphoreSlim.WaitAsync();
     try
     {
         return instance ?? (instance = CreateInstance());
     }
     finally
     {
         semaphoreSlim.Release();
     }
 }
예제 #2
0
        public async Task SaveDeviceTwinOperationAsync(string eventData, ILogger log, string tenant, string deviceId, string operationType, TelemetryTimestamp timeStamp, EventHubHelper eventHubHelper)
        {
            try
            {
                string  deviceTwin     = eventData;
                Twin    twin           = null;
                JObject deviceTwinJson = new JObject();
                deviceTwinJson.Add(DeviceTelemetryKeyConstants.DeviceId, deviceId.ToString());
                deviceTwinJson.Add(DeviceTelemetryKeyConstants.TimeStamp, timeStamp.DateTime);
                deviceTwinJson.Add(DeviceTelemetryKeyConstants.TimeReceived, timeStamp.EpochTimestamp);
                deviceTwinJson.Add(DeviceTelemetryKeyConstants.EventOpType, operationType);
                deviceTwinJson.Add(DeviceTelemetryKeyConstants.IsDeleted, false);

                if (operationType.ToString().Equals("createDeviceIdentity"))
                {
                    deviceTwinJson.Add(DeviceTelemetryKeyConstants.DeviceCreatedDate, timeStamp.DateTime);

                    try
                    {
                        twin = await TenantConnectionHelper.GetRegistry(Convert.ToString(tenant)).GetTwinAsync(deviceId.ToString());

                        deviceTwin = twin.ToJson();
                    }
                    catch (Exception e)
                    {
                        log.LogError($"Unable to fetch DeviceId: {deviceId} device twin from iothub of tenant: {tenant}.", e);
                    }
                }
                else
                {
                    JObject         previousTwin = null;
                    KustoOperations kustoClient  = await KustoOperations.GetClientAsync();

                    string kustoQuery     = $"DeviceTwin | where DeviceId == \"{deviceId}\" | summarize arg_max(TimeStamp, *) by DeviceId | where IsDeleted == false";
                    var    deviceTwinList = await kustoClient.QueryAsync <DeviceTwinModel>($"IoT-{tenant}", kustoQuery, null);

                    DeviceTwinModel preDeviceTwin = deviceTwinList.FirstOrDefault();

                    if (preDeviceTwin != null)
                    {
                        previousTwin = preDeviceTwin.Twin;
                        deviceTwinJson.Add(DeviceTelemetryKeyConstants.DeviceCreatedDate, preDeviceTwin.DeviceCreatedDate);
                    }
                    else
                    {
                        deviceTwinJson.Add(DeviceTelemetryKeyConstants.DeviceCreatedDate, default(DateTime)); // Set Device Created Date to Default if twin is not present in storage.

                        try
                        {
                            twin = await TenantConnectionHelper.GetRegistry(Convert.ToString(tenant)).GetTwinAsync(deviceId.ToString());

                            if (twin != null)
                            {
                                previousTwin = JObject.Parse(twin.ToJson());
                            }
                        }
                        catch (Exception e)
                        {
                            log.LogError($"Unable to fetch DeviceId: {deviceId} device twin from iothub of tenant: {tenant}.", e);
                        }
                    }

                    switch (operationType)
                    {
                    case "deviceConnected":
                        if (preDeviceTwin != null)
                        {
                            previousTwin["connectionState"]  = "Connected";
                            previousTwin["lastActivityTime"] = timeStamp.DateTime;
                        }

                        break;

                    case "deviceDisconnected":
                        if (preDeviceTwin != null)
                        {
                            previousTwin["connectionState"]  = "Disconnected";
                            previousTwin["lastActivityTime"] = timeStamp.DateTime;
                        }

                        break;

                    case "updateTwin":
                        if (preDeviceTwin != null)
                        {
                            JObject twinFragment = JObject.Parse(eventData);
                            previousTwin = previousTwin.UpdateJson(twinFragment);
                        }
                        else
                        {
                            previousTwin = JObject.Parse(eventData);
                        }

                        break;

                    case "deleteDeviceIdentity":
                        deviceTwinJson[DeviceTelemetryKeyConstants.IsDeleted] = true;
                        break;

                    default:
                        break;
                    }

                    deviceTwin = previousTwin?.ToString();
                }

                deviceTwinJson.Add(DeviceTelemetryKeyConstants.Data, deviceTwin);

                // Save the Device Twin Data to EventHub for further processing
                var byteMessage         = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(deviceTwinJson));
                var eventDeviceTwinData = new Azure.Messaging.EventHubs.EventData(byteMessage);
                eventDeviceTwinData.Properties.Add("deviceid", deviceId.ToString());

                await eventHubHelper.SendMessageToEventHub($"{tenant}-devicetwin", new Azure.Messaging.EventHubs.EventData[] { eventDeviceTwinData });
            }
            catch (Exception exception)
            {
                throw new ApplicationException($"Save Device Twin operation failed: {exception}, operation type: {operationType}, tenant: {tenant}, deviceId {deviceId}");
            }
        }