private async Task SaveDeviceProperties(string tenantId, string deploymentId, List <TwinServiceModel> deviceTwins)
        {
            if (deviceTwins != null)
            {
                TwinServiceListModel existingDeviceTwins = await this.GetTwins(tenantId, string.Format(DeploymentDevicePropertiesCollection, deploymentId));

                if (existingDeviceTwins == null || (existingDeviceTwins != null && existingDeviceTwins.Items.Count == 0))
                {
                    await this.SaveDeviceTwins(tenantId, deploymentId, deviceTwins);
                }
                else
                {
                    foreach (var deviceTwin in deviceTwins)
                    {
                        CosmosOperations storageClient = await CosmosOperations.GetClientAsync();

                        var existingDeviceTwin = existingDeviceTwins.Items.FirstOrDefault(x => x.DeviceId == deviceTwin.DeviceId);
                        var value = JsonConvert.SerializeObject(
                            deviceTwin,
                            Formatting.Indented,
                            new JsonSerializerSettings
                        {
                            NullValueHandling = NullValueHandling.Ignore,
                        });

                        try
                        {
                            await storageClient.SaveDocumentAsync(string.Format(DeploymentDevicePropertiesCollection, deploymentId), deviceTwin.DeviceId, new ValueServiceModel()
                            {
                                Data = value, ETag = existingDeviceTwin.ETag
                            }, this.GenerateCollectionLink(tenantId));
                        }
                        catch (Exception)
                        {
                        }

                        // archive exisiting Device Twin
                        var archiveDeviceTwinValue = JsonConvert.SerializeObject(
                            existingDeviceTwin,
                            Formatting.Indented,
                            new JsonSerializerSettings
                        {
                            NullValueHandling = NullValueHandling.Ignore,
                        });
                        await storageClient.SaveDocumentAsync(string.Format(DeploymentHistoryPropertiesCollection, deploymentId, Guid.NewGuid().ToString()), deviceTwin.DeviceId, new ValueServiceModel()
                        {
                            Data = archiveDeviceTwinValue
                        }, this.GenerateCollectionLink(tenantId));
                    }
                }
            }
        }
        private async Task SaveDeviceTwins(string tenantId, string deploymentId, List <TwinServiceModel> deviceTwins)
        {
            if (deviceTwins != null)
            {
                CosmosOperations storageClient = await CosmosOperations.GetClientAsync();

                foreach (var deviceTwin in deviceTwins)
                {
                    var value = JsonConvert.SerializeObject(
                        deviceTwin,
                        Formatting.Indented,
                        new JsonSerializerSettings
                    {
                        NullValueHandling = NullValueHandling.Ignore,
                    });

                    try
                    {
                        await storageClient.SaveDocumentAsync(string.Format(DeploymentDevicePropertiesCollection, deploymentId), deviceTwin.DeviceId, new ValueServiceModel()
                        {
                            Data = value
                        }, this.GenerateCollectionLink(tenantId));
                    }
                    catch (Exception)
                    {
                    }
                }
            }
        }
        public async Task SaveDeploymentFromHub(string tenantId, DeploymentServiceModel deploymentModel, List <TwinServiceModel> deviceTwins)
        {
            CosmosOperations storageClient = await CosmosOperations.GetClientAsync();

            foreach (TwinServiceModel deviceTwin in deviceTwins)
            {
                DeploymentHistoryModel modelToSave = new DeploymentHistoryModel
                {
                    DeploymentId           = deploymentModel.Id,
                    DeploymentName         = deploymentModel.Name,
                    DeviceId               = deviceTwin.DeviceId,
                    PreviousFirmwareTwin   = null,
                    LastUpdatedDateTimeUtc = DateTime.UtcNow,
                    Twin = deviceTwin,
                };

                var value = JsonConvert.SerializeObject(
                    modelToSave,
                    Formatting.None,
                    new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore,
                });

                await storageClient.SaveDocumentAsync(string.Format(DeploymentHistoryCollection, deviceTwin.DeviceId), deploymentModel.Id, new ValueServiceModel()
                {
                    Data = value
                }, this.GenerateCollectionLink(tenantId), Guid.NewGuid());
            }
        }
        private async Task SaveModuleTwin(string tenantId, string deploymentId, TwinServiceModel moduleTwin)
        {
            CosmosOperations storageClient = await CosmosOperations.GetClientAsync();

            var value = JsonConvert.SerializeObject(
                moduleTwin,
                Formatting.Indented,
                new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
            });

            await storageClient.SaveDocumentAsync(string.Format(DeploymentEdgeModulePropertiesCollection, deploymentId), $"{moduleTwin.DeviceId}-{this.RemoveSpecialCharacters(moduleTwin.ModuleId)}", new ValueServiceModel()
            {
                Data = value
            }, this.GenerateCollectionLink(tenantId));
        }
        private async Task SaveDeployment(DeploymentServiceModel deployment, string tenantId)
        {
            CosmosOperations storageClient = await CosmosOperations.GetClientAsync();

            var value = JsonConvert.SerializeObject(
                deployment,
                Formatting.Indented,
                new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
            });

            await storageClient.SaveDocumentAsync(DeploymentsCollection, deployment.Id, new ValueServiceModel()
            {
                Data = value, ETag = deployment.ETag
            }, this.GenerateCollectionLink(tenantId));
        }
        private async Task SaveDeviceStatuses(IDictionary <string, DeploymentStatus> deviceStatuses, string deploymentId, string tenantId)
        {
            CosmosOperations storageClient = await CosmosOperations.GetClientAsync();

            var sql = CosmosOperations.GetDocumentsByCollectionId("CollectionId", string.Format(DeviceStatusesCollection, deploymentId));

            var existingDeviceStatuses = await storageClient.QueryAllDocumentsAsync(
                "pcs-storage",
                $"pcs-{tenantId}",
                this.DefaultQueryOptions,
                sql);

            if (existingDeviceStatuses != null && existingDeviceStatuses.Count > 0)
            {
                foreach (var item in existingDeviceStatuses)
                {
                    await storageClient.DeleteDocumentAsync(item.Id, this.GenerateCollectionLink(tenantId));
                }
            }

            if (deviceStatuses != null)
            {
                for (int i = 0; i < deviceStatuses.Count; i = i + DeviceStatusLength)
                {
                    var items = deviceStatuses.Skip(i).Take(DeviceStatusLength).ToDictionary(p => p.Key, p => p.Value);
                    var value = JsonConvert.SerializeObject(
                        new DeviceStatusServiceModel
                    {
                        DeviceStatuses = items,
                        DeploymentId   = deploymentId,
                    },
                        Formatting.Indented,
                        new JsonSerializerSettings
                    {
                        NullValueHandling = NullValueHandling.Ignore,
                    });
                    await storageClient.SaveDocumentAsync(string.Format(DeviceStatusesCollection, deploymentId), Guid.NewGuid().ToString(), new ValueServiceModel()
                    {
                        Data = value
                    }, this.GenerateCollectionLink(tenantId));
                }
            }
        }
        private async Task StoreModuleTwinsInStorage(string tenantId, List <TwinServiceModel> moduleTwins, string deploymentId)
        {
            if (moduleTwins != null && moduleTwins.Count > 0)
            {
                TwinServiceListModel existingModuleTwins = await this.GetTwins(tenantId, string.Format(DeploymentEdgeModulePropertiesCollection, deploymentId));

                if (existingModuleTwins == null || (existingModuleTwins != null && existingModuleTwins.Items.Count == 0))
                {
                    foreach (var moduleTwin in moduleTwins)
                    {
                        await this.SaveModuleTwin(tenantId, deploymentId, moduleTwin);
                    }
                }
                else
                {
                    foreach (var moduleTwin in moduleTwins)
                    {
                        var existingModuleTwin         = existingModuleTwins.Items.FirstOrDefault(x => x.ModuleId == moduleTwin.ModuleId && x.DeviceId == moduleTwin.DeviceId);
                        CosmosOperations storageClient = await CosmosOperations.GetClientAsync();

                        var value = JsonConvert.SerializeObject(
                            moduleTwin,
                            Formatting.Indented,
                            new JsonSerializerSettings
                        {
                            NullValueHandling = NullValueHandling.Ignore,
                        });

                        try
                        {
                            await storageClient.SaveDocumentAsync(string.Format(DeploymentEdgeModulePropertiesCollection, deploymentId), $"{moduleTwin.DeviceId}-{this.RemoveSpecialCharacters(moduleTwin.ModuleId)}", new ValueServiceModel()
                            {
                                Data = value, ETag = existingModuleTwin.ETag
                            }, this.GenerateCollectionLink(tenantId));
                        }
                        catch (Exception)
                        {
                        }

                        // archive exisiting Device Twin
                        var archiveModuleTwinValue = JsonConvert.SerializeObject(
                            existingModuleTwin,
                            Formatting.Indented,
                            new JsonSerializerSettings
                        {
                            NullValueHandling = NullValueHandling.Ignore,
                        });
                        try
                        {
                            await storageClient.SaveDocumentAsync(string.Format(DeploymentModuleHistoryPropertiesCollection, deploymentId, Guid.NewGuid().ToString()), $"{moduleTwin.DeviceId}-{this.RemoveSpecialCharacters(moduleTwin.ModuleId)}", new ValueServiceModel()
                            {
                                Data = archiveModuleTwinValue
                            }, this.GenerateCollectionLink(tenantId));
                        }
                        catch (Exception)
                        {
                        }
                    }
                }
            }
        }