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); }
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); }
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); }