public async Task ConvertAsyncReturnsExpectedModel()
        {
            string tenantId = this.rand.NextString();
            List <ValueApiModel> deviceGroupsList = new List <ValueApiModel>
            {
                this.entityHelper.CreateDeviceGroup(),
                this.entityHelper.CreateDeviceGroup(),
            };
            ValueListApiModel deviceGroups = new ValueListApiModel
            {
                Items = deviceGroupsList,
            };

            this.mockStorageAdapterClient
            .Setup(c => c.GetAllAsync(
                       It.Is <string>(s => s == this.converter.Entity)))
            .ReturnsAsync(deviceGroups);

            this.mockBlobStorageClient
            .Setup(c => c.CreateBlobAsync(
                       It.IsAny <string>(),
                       It.IsAny <string>(),
                       It.IsAny <string>()))
            .Returns(Task.CompletedTask);

            this.mockIotHubManagerClient
            .Setup(c => c.GetListAsync(
                       It.IsAny <IEnumerable <DeviceGroupConditionModel> >(),
                       It.Is <string>(s => s == tenantId)))
            .ReturnsAsync(new DeviceListModel {
                Items = new List <DeviceModel> {
                    this.entityHelper.CreateDevice(), this.entityHelper.CreateDevice()
                }
            });                                                                                                                                               // return a device for each device group

            ConversionApiModel conversionResponse = await this.converter.ConvertAsync(tenantId);

            this.mockStorageAdapterClient
            .Verify(
                c => c.GetAllAsync(
                    It.Is <string>(s => s == this.converter.Entity)),
                Times.Once);
            this.mockBlobStorageClient
            .Verify(
                c => c.CreateBlobAsync(
                    It.IsAny <string>(),
                    It.IsAny <string>(),
                    It.IsAny <string>()),
                Times.Once);
            this.mockIotHubManagerClient
            .Verify(
                c => c.GetListAsync(
                    It.IsAny <IEnumerable <DeviceGroupConditionModel> >(),
                    It.Is <string>(s => s == tenantId)),
                Times.Exactly(deviceGroups.Items.Count));

            Assert.Equal(conversionResponse.Entities, deviceGroups);
            Assert.Equal(conversionResponse.TenantId, tenantId);
        }
コード例 #2
0
        public async Task ConvertAsyncReturnsExpectedModel()
        {
            string tenantId = this.rand.NextString();
            List <ValueApiModel> rulesList = new List <ValueApiModel>
            {
                this.entityHelper.CreateRule(),
                this.entityHelper.CreateRule(),
            };
            ValueListApiModel rules = new ValueListApiModel
            {
                Items = rulesList,
            };

            this.mockStorageAdapterClient
            .Setup(c => c.GetAllAsync(
                       It.Is <string>(s => s == this.converter.Entity),
                       It.IsAny <string>()))
            .ReturnsAsync(rules);

            this.mockBlobStorageClient
            .Setup(c => c.CreateBlobAsync(
                       It.IsAny <string>(),
                       It.IsAny <string>(),
                       It.IsAny <string>()))
            .Returns(Task.CompletedTask);

            ConversionApiModel conversionResponse = await this.converter.ConvertAsync(tenantId);

            this.mockStorageAdapterClient
            .Verify(
                c => c.GetAllAsync(
                    It.Is <string>(s => s == this.converter.Entity),
                    It.IsAny <string>()),
                Times.Once);
            this.mockBlobStorageClient
            .Verify(
                c => c.CreateBlobAsync(
                    It.IsAny <string>(),
                    It.IsAny <string>(),
                    It.IsAny <string>()),
                Times.Once);

            Assert.Equal(conversionResponse.Entities, rules);
            Assert.Equal(conversionResponse.TenantId, tenantId);
        }
コード例 #3
0
        public override async Task <ConversionApiModel> ConvertAsync(string tenantId, string operationId = null)
        {
            ValueListApiModel rules = null;

            try
            {
                rules = await this.StorageAdapterClient.GetAllAsync(this.Entity);
            }
            catch (Exception e)
            {
                this.Logger.LogError(e, "Unable to query {entity} using storage adapter. OperationId: {operationId}. TenantId: {tenantId}", this.Entity, operationId, tenantId);
                throw e;
            }

            if (rules.Items.Count() == 0 || rules == null)
            {
                string errorMessage = $"No entities were receieved from storage adapter to convert to {this.Entity}. OperationId: {operationId}. TenantId: {tenantId}";
                this.Logger.LogError(new Exception(errorMessage), errorMessage);
                throw new ResourceNotFoundException("No entities were receieved from storage adapter to convert to rules.");
            }

            List <RuleReferenceDataModel> jsonRulesList = new List <RuleReferenceDataModel>();

            try
            {
                foreach (ValueApiModel item in rules.Items)
                {
                    try
                    {
                        RuleDataModel dataModel = JsonConvert.DeserializeObject <RuleDataModel>(item.Data);
                        RuleModel     ruleModel = new RuleModel(item.Key, dataModel);

                        // return a RuleReferenceModel which is a conversion from the RuleModel into a SAjob readable format with additional metadata
                        RuleReferenceDataModel referenceModel = new RuleReferenceDataModel(ruleModel);
                        jsonRulesList.Add(referenceModel);
                    }
                    catch (Exception)
                    {
                        this.Logger.LogInformation("Unable to convert a rule to the proper reference data model for {entity}. OperationId: {operationId}. TenantId: {tenantId}", this.Entity, operationId, tenantId);
                    }
                }

                if (jsonRulesList.Count() == 0)
                {
                    throw new ResourceNotSupportedException("No rules were able to be converted to the proper rule reference data model.");
                }
            }
            catch (Exception e)
            {
                this.Logger.LogError(e, "Unable to convert {entity} queried from storage adapter to appropriate data model. OperationId: {operationId}. TenantId: {tenantId}", this.Entity, operationId, tenantId);
                throw e;
            }

            string fileContent = null;

            try
            {
                fileContent = JsonConvert.SerializeObject(jsonRulesList, Formatting.Indented);
            }
            catch (Exception e)
            {
                this.Logger.LogError(e, "Unable to serialize the IEnumerable of {entity} data models for the temporary file content. OperationId: {operationId}. TenantId: {tenantId}", this.Entity, operationId, tenantId);
                throw e;
            }

            string blobFilePath = await this.WriteFileContentToBlobAsync(fileContent, tenantId, operationId);

            ConversionApiModel conversionResponse = new ConversionApiModel
            {
                TenantId     = tenantId,
                BlobFilePath = blobFilePath,
                Entities     = rules,
                OperationId  = operationId,
            };

            this.Logger.LogInformation("Successfully Completed {entity} conversion\n{model}", this.Entity, JsonConvert.SerializeObject(conversionResponse));
            return(conversionResponse);
        }
        public override async Task <ConversionApiModel> ConvertAsync(string tenantId, string operationId = null)
        {
            ValueListApiModel deviceGroups = null;

            try
            {
                deviceGroups = await this.StorageAdapterClient.GetAllAsync(this.Entity, tenantId);
            }
            catch (Exception e)
            {
                this.Logger.LogError(e, "Unable to query {entity} using storage adapter. OperationId: {operationId}. TenantId: {tenantId}", this.Entity, operationId, tenantId);
                throw e;
            }

            if (deviceGroups.Items.Count() == 0 || deviceGroups == null)
            {
                string errorMessage = $"No entities were receieved from storage adapter to convert to {this.Entity}. OperationId: {operationId}. TenantId: {tenantId}";
                this.Logger.LogError(new Exception(errorMessage), errorMessage);
                throw new ResourceNotFoundException("No entities were receieved from storage adapter to convert to rules.");
            }

            DeviceGroupListModel deviceGroupModels = new DeviceGroupListModel();

            try
            {
                List <DeviceGroupModel> items = new List <DeviceGroupModel>();
                foreach (ValueApiModel group in deviceGroups.Items)
                {
                    try
                    {
                        DeviceGroupDataModel dataModel       = JsonConvert.DeserializeObject <DeviceGroupDataModel>(group.Data);
                        DeviceGroupModel     individualModel = new DeviceGroupModel(group.Key, group.ETag, dataModel);
                        items.Add(individualModel);
                    }
                    catch (Exception)
                    {
                        this.Logger.LogInformation("Unable to convert a device group to the proper reference data model for {entity}. OperationId: {operationId}. TenantId: {tenantId}", this.Entity, operationId, tenantId);
                    }
                }

                if (items.Count() == 0)
                {
                    throw new ResourceNotSupportedException("No device groups were able to be converted to the proper rule reference data model.");
                }

                deviceGroupModels.Items = items;
            }
            catch (Exception e)
            {
                this.Logger.LogError(e, "Unable to convert {entity} queried from storage adapter to appropriate data model. OperationId: {operationId}. TenantId: {tenantId}", this.Entity, operationId, tenantId);
                throw e;
            }

            Dictionary <DeviceGroupModel, DeviceListModel> deviceMapping = new Dictionary <DeviceGroupModel, DeviceListModel>();

            foreach (DeviceGroupModel deviceGroup in deviceGroupModels.Items)
            {
                try
                {
                    DeviceListModel devicesList = await this.iotHubManager.GetListAsync(deviceGroup.Conditions, tenantId);

                    if (devicesList.Items.Count() > 0)
                    {
                        deviceMapping.Add(deviceGroup, devicesList);
                    }
                }
                catch (Exception e)
                {
                    // Do not throw an exception here, attempt to query other device groups instead to get as much data as possible
                    // Log all device groups that could not be retreived
                    this.Logger.LogError(e, "Unable to get list of devices for devicegroup {deviceGroup} from IotHubManager. OperationId: {operationId}. TenantId: {tenantId}", deviceGroup.Id, operationId, tenantId);
                }
            }

            if (deviceMapping.Count() == 0)
            {
                string groups       = $"[{string.Join(", ", deviceGroupModels.Items.Select(group => group.Id))}]";
                string errorMessage = $"No Devices were found for any {this.Entity}. OperationId: {operationId}. TenantId: {tenantId}\n{groups}";
                this.Logger.LogError(new Exception(errorMessage), errorMessage);
                throw new ResourceNotFoundException($"No Devices were found for any {this.Entity}.");
            }

            string fileContent = null;

            try
            {
                // Write a file in csv format:
                // deviceId,groupId
                // mapping contains devices groups, and a list model of all devices within each device group
                // create a new csv row for each device and device group combination
                string fileContentRows = string.Join("\n", deviceMapping.Select(mapping =>
                {
                    return(string.Join("\n", mapping.Value.Items.Select(device => $"{device.Id},{mapping.Key.Id}")));
                }));

                // Add the rows and the header together to complete the csv file content
                fileContent = $"{CsvHeader}\n{fileContentRows}";
            }
            catch (Exception e)
            {
                this.Logger.LogError(e, "Unable to serialize the {entity} data models for the temporary file content. OperationId: {operationId}. TenantId: {tenantId}", this.Entity, operationId, tenantId);
                throw e;
            }

            string blobFilePath = await this.WriteFileContentToBlobAsync(fileContent, tenantId, operationId);

            ConversionApiModel conversionResponse = new ConversionApiModel
            {
                TenantId     = tenantId,
                BlobFilePath = blobFilePath,
                Entities     = deviceGroups,
                OperationId  = operationId,
            };

            this.Logger.LogInformation("Successfully Completed {entity} conversion\n{model}", this.Entity, JsonConvert.SerializeObject(conversionResponse));
            return(conversionResponse);
        }