public async Task <TableStorageResponse <DeviceRule> > DeleteDeviceRuleAsync(DeviceRule ruleToDelete) { DeviceRuleTableEntity incomingEntity = BuildTableEntityFromRule(ruleToDelete); TableStorageResponse <DeviceRule> result = await _azureTableStorageClient.DoDeleteAsync <DeviceRule, DeviceRuleTableEntity>(incomingEntity, BuildRuleFromTableEntity); if (result.Status == TableStorageResponseStatus.Successful) { // Build up a new blob to push up for ASA job ref data List <DeviceRuleBlobEntity> blobList = await BuildBlobEntityListFromTableRows(); await PersistRulesToBlobStorageAsync(blobList); } return(result); }
/// <summary> /// Updated the enabled state of a given rule. This method does not update any other properties on the rule /// </summary> /// <param name="deviceId"></param> /// <param name="ruleId"></param> /// <param name="enabled"></param> /// <returns></returns> public async Task <TableStorageResponse <LocationRule> > UpdateLocationRuleEnabledStateAsync(string regionId, string ruleId, bool enabled) { LocationRule found = await _locationRulesRepository.GetLocationRuleAsync(regionId, ruleId); if (found == null) { var response = new TableStorageResponse <LocationRule>(); response.Entity = found; response.Status = TableStorageResponseStatus.NotFound; return(response); } found.EnabledState = enabled; return(await _locationRulesRepository.SaveLocationRuleAsync(found)); }
/// <summary> /// Updated the enabled state of a given rule. This method does not update any other properties on the rule /// </summary> /// <param name="deviceId"></param> /// <param name="ruleId"></param> /// <param name="enabled"></param> /// <returns></returns> public async Task <TableStorageResponse <DeviceRule> > UpdateDeviceRuleEnabledStateAsync(string deviceId, string ruleId, bool enabled) { DeviceRule found = await _deviceRulesRepository.GetDeviceRuleAsync(deviceId, ruleId); if (found == null) { var response = new TableStorageResponse <DeviceRule>(); response.Entity = found; response.Status = TableStorageResponseStatus.NotFound; return(response); } found.EnabledState = enabled; return(await _deviceRulesRepository.SaveDeviceRuleAsync(found)); }
public async Task <TableStorageResponse <DeviceRule> > DeleteDeviceRuleAsync(DeviceRule ruleToDelete) { DeviceRuleTableEntity incomingEntity = BuildTableEntityFromRule(ruleToDelete); TableStorageResponse <DeviceRule> result = await AzureTableStorageHelper.DoDeleteAsync <DeviceRule, DeviceRuleTableEntity>(incomingEntity, BuildRuleFromTableEntity, _storageAccountConnectionString, _deviceRulesNormalizedTableName); if (result.Status == TableStorageResponseStatus.Successful) { // Build up a new blob to push up for ASA job ref data List <DeviceRuleBlobEntity> blobList = await BuildBlobEntityListFromTableRows(); await PersistRulesToBlobStorageAsync(blobList); } return(result); }
/// <summary> /// Save a rule to the data store. This method should be used for new rules as well as updating existing rules /// </summary> /// <param name="updatedRule"></param> /// <returns></returns> public async Task <TableStorageResponse <DeviceRule> > SaveDeviceRuleAsync(DeviceRule updatedRule) { //Enforce single instance of a rule for a data field for a given device List <DeviceRule> foundForDevice = await _deviceRulesRepository.GetAllRulesForDeviceAsync(updatedRule.DeviceID); foreach (DeviceRule rule in foundForDevice) { if (rule.DataField == updatedRule.DataField && rule.RuleId != updatedRule.RuleId) { var response = new TableStorageResponse <DeviceRule>(); response.Entity = rule; response.Status = TableStorageResponseStatus.DuplicateInsert; return(response); } } return(await _deviceRulesRepository.SaveDeviceRuleAsync(updatedRule)); }
/// <summary> /// Save a rule to the data store. This method should be used for new rules as well as updating existing rules /// </summary> /// <param name="updatedRule"></param> /// <returns></returns> public async Task<TableStorageResponse<DeviceRule>> SaveDeviceRuleAsync(DeviceRule updatedRule) { //Enforce single instance of a rule for a data field for a given device List<DeviceRule> foundForDevice = await _deviceRulesRepository.GetAllRulesForDeviceAsync(updatedRule.DeviceID); foreach(DeviceRule rule in foundForDevice) { if(rule.DataField == updatedRule.DataField && rule.RuleId != updatedRule.RuleId) { var response = new TableStorageResponse<DeviceRule>(); response.Entity = rule; response.Status = TableStorageResponseStatus.DuplicateInsert; return response; } } return await _deviceRulesRepository.SaveDeviceRuleAsync(updatedRule); }
private static async Task <TableStorageResponse <TResult> > PerformTableOperation <TResult, TInput>(CloudTable table, TableOperation operation, TInput incomingEntity, Func <TInput, TResult> tableEntityToModelConverter) where TInput : TableEntity { var result = new TableStorageResponse <TResult>(); try { await table.ExecuteAsync(operation); var nullModel = tableEntityToModelConverter((TInput)null); result.Entity = nullModel; result.Status = TableStorageResponseStatus.Successful; } catch (Exception ex) { TableOperation retrieveOperation = TableOperation.Retrieve <TInput>(incomingEntity.PartitionKey, incomingEntity.RowKey); TableResult retrievedEntity = table.Execute(retrieveOperation); if (retrievedEntity != null) { // Return the found version of this rule in case it had been modified by someone else since our last read. var retrievedModel = tableEntityToModelConverter((TInput)retrievedEntity.Result); result.Entity = retrievedModel; } else { // We didn't find an existing rule, probably creating new, so we'll just return what was sent in result.Entity = tableEntityToModelConverter(incomingEntity); } if (ex.GetType() == typeof(StorageException) && (((StorageException)ex).RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed || ((StorageException)ex).RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict)) { result.Status = TableStorageResponseStatus.ConflictError; } else { result.Status = TableStorageResponseStatus.UnknownError; } } return(result); }
public async Task <bool> RemoveAllRulesForDeviceAsync(string deviceId) { bool result = true; List <DeviceRule> deviceRules = await _deviceRulesRepository.GetAllRulesForDeviceAsync(deviceId); foreach (DeviceRule rule in deviceRules) { TableStorageResponse <DeviceRule> response = await _deviceRulesRepository.DeleteDeviceRuleAsync(rule); if (response.Status != TableStorageResponseStatus.Successful) { //Do nothing, just report that it failed. The client can then take other steps if needed/desired result = false; } } return(result); }
private async Task <UserSetting> SetUserSettingImplAsync(string userId, UserSetting setting) { var incomingEntity = new UserSettingTableEntity(userId, setting); if (!string.IsNullOrWhiteSpace(setting.Etag)) { incomingEntity.ETag = setting.Etag; } TableStorageResponse <UserSetting> result = await _azureTableStorageClient.DoTableInsertOrReplaceAsync <UserSetting, UserSettingTableEntity>(incomingEntity, (tableEntity) => { if (tableEntity == null) { return(null); } return(new UserSetting(tableEntity)); }); return(result.Entity); }
private JsonResult BuildRuleUpdateResponse(TableStorageResponse <DeviceRule> response) { switch (response.Status) { case TableStorageResponseStatus.Successful: return(Json(new { success = true })); case TableStorageResponseStatus.ConflictError: return(Json(new { error = Strings.TableDataSaveConflictErrorMessage })); case TableStorageResponseStatus.DuplicateInsert: return(Json(new { error = Strings.RuleAlreadyAddedError })); case TableStorageResponseStatus.NotFound: return(Json(new { error = Strings.UnableToRetrieveRuleFromService })); case TableStorageResponseStatus.UnknownError: default: return(Json(new { error = Strings.RuleUpdateError })); } }
public async Task DeleteNameAsyncTest() { var newNameCache = fixture.Create <NameCacheEntity>(); NameCacheTableEntity tableEntity = null; var resp = new TableStorageResponse <NameCacheEntity> { Entity = newNameCache, Status = TableStorageResponseStatus.Successful }; _tableStorageClientMock.Setup( x => x.DoDeleteAsync(It.IsNotNull <NameCacheTableEntity>(), It.IsNotNull <Func <NameCacheTableEntity, NameCacheEntity> >())) .Callback <NameCacheTableEntity, Func <NameCacheTableEntity, NameCacheEntity> >( (entity, func) => tableEntity = entity) .ReturnsAsync(resp); var ret = await nameCacheRepository.DeleteNameAsync(NameCacheEntityType.DesiredProperty, newNameCache.Name); Assert.True(ret); Assert.NotNull(tableEntity); Assert.Equal(newNameCache.Name, tableEntity.Name); }
public async Task DeleteNameAsyncFailureTest() { var newNameCache = fixture.Create <NameCacheEntity>(); NameCacheTableEntity tableEntity = null; var resp = new TableStorageResponse <NameCacheEntity> { Entity = newNameCache, Status = TableStorageResponseStatus.NotFound }; _tableStorageClientMock.Setup( x => x.DoDeleteAsync(It.IsNotNull <NameCacheTableEntity>(), It.IsNotNull <Func <NameCacheTableEntity, NameCacheEntity> >())) .Callback <NameCacheTableEntity, Func <NameCacheTableEntity, NameCacheEntity> >( (entity, func) => tableEntity = null) .ReturnsAsync(resp); var ret = await nameCacheRepository.DeleteNameAsync(NameCacheEntityType.DesiredProperty, newNameCache.Name); Assert.False(ret); Assert.Null(tableEntity); await Assert.ThrowsAsync <ArgumentException>(async() => await nameCacheRepository.DeleteNameAsync(NameCacheEntityType.All, newNameCache.Name)); }
/// <summary> /// Save a rule to the data store. This method should be used for new rules as well as updating existing rules /// </summary> /// <param name="newRule"></param> /// <returns></returns> public async Task <TableStorageResponse <LocationRule> > SaveLocationRuleAsync(LocationRule newRule) { if (newRule.RegionId == "default") { return(await _locationRulesRepository.SaveLocationRuleAsync(newRule)); } string regionId = $"{Math.Truncate(newRule.RegionLatitude * 10)/10}_{Math.Truncate(newRule.RegionLongitude *10)/10}"; if (newRule.RegionId != regionId || string.IsNullOrWhiteSpace(newRule.RuleId)) { var response = new TableStorageResponse <LocationRule>(); response.Entity = newRule; response.Status = TableStorageResponseStatus.IncorrectEntry; return(response); } //Enforce single instance of a rule for a data field for a given device List <LocationRule> foundForRegion = await _locationRulesRepository.GetAllRulesForRegionAsync(newRule.RegionId); foreach (LocationRule rule in foundForRegion) { if ((rule.RuleId != newRule.RuleId) && (rule.RegionLatitude == newRule.RegionLatitude) && (rule.RegionLongitude == newRule.RegionLongitude)) { var response = new TableStorageResponse <LocationRule>(); response.Entity = rule; response.Status = TableStorageResponseStatus.DuplicateInsert; return(response); } } return(await _locationRulesRepository.SaveLocationRuleAsync(newRule)); }
public async Task <ActionResult> DeleteLocationRule(string regionId, string ruleId) { TableStorageResponse <LocationRule> response = await _locationRulesLogic.DeleteLocationRuleAsync(regionId, ruleId); return(BuildRuleUpdateResponse(response)); }
public async Task <ActionResult> DeleteDeviceRule(string deviceId, string ruleId) { TableStorageResponse <DeviceRule> response = await _deviceRulesLogic.DeleteDeviceRuleAsync(deviceId, ruleId); return(BuildRuleUpdateResponse(response)); }
/// <summary> /// Updated the enabled state of a given rule. This method does not update any other properties on the rule /// </summary> /// <param name="deviceId"></param> /// <param name="ruleId"></param> /// <param name="enabled"></param> /// <returns></returns> public async Task<TableStorageResponse<DeviceRule>> UpdateDeviceRuleEnabledStateAsync(string deviceId, string ruleId, bool enabled) { DeviceRule found = await _deviceRulesRepository.GetDeviceRuleAsync(deviceId, ruleId); if(found == null) { var response = new TableStorageResponse<DeviceRule>(); response.Entity = found; response.Status = TableStorageResponseStatus.NotFound; return response; } found.EnabledState = enabled; return await _deviceRulesRepository.SaveDeviceRuleAsync(found); }
public static async Task <TableStorageResponse <TResult> > DoTableInsertOrReplace <TResult, TInput>(TInput incomingEntity, Func <TInput, TResult> tableEntityToModelConverter, string storageAccountConnectionString, string tableName) where TInput : TableEntity { var result = new TableStorageResponse <TResult>(); var deviceRulesTable = await AzureTableStorageHelper.GetTableAsync(storageAccountConnectionString, tableName); // Simply doing an InsertOrReplace will not do any concurrency checking, according to // http://azure.microsoft.com/en-us/blog/managing-concurrency-in-microsoft-azure-storage-2/ // So we will not use InsertOrReplace. Instead we will look to see if we have a rule like this // If so, then we'll do a concurrency-safe update, otherwise simply insert TableOperation retrieveOperation = TableOperation.Retrieve <TInput>(incomingEntity.PartitionKey, incomingEntity.RowKey); TableResult retrievedEntity = await deviceRulesTable.ExecuteAsync(retrieveOperation); try { TableOperation operation = null; if (retrievedEntity.Result != null) { operation = TableOperation.Replace(incomingEntity); } else { operation = TableOperation.Insert(incomingEntity); } await deviceRulesTable.ExecuteAsync(operation); //Get the new version of the entity out of the database // And set up the result to return to the caller retrievedEntity = await deviceRulesTable.ExecuteAsync(retrieveOperation); var updatedModel = tableEntityToModelConverter((TInput)retrievedEntity.Result); result.Entity = updatedModel; result.Status = TableStorageResponseStatus.Successful; } catch (Exception ex) { if (retrievedEntity != null) { // Return the found version of this rule in case it had been modified by someone else since our last read. var retrievedModel = tableEntityToModelConverter((TInput)retrievedEntity.Result); result.Entity = retrievedModel; } else { // We didn't find an existing rule, probably creating new, so we'll just return what was sent in result.Entity = tableEntityToModelConverter(incomingEntity); } if (ex.GetType() == typeof(StorageException) && (((StorageException)ex).RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed || ((StorageException)ex).RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict)) { result.Status = TableStorageResponseStatus.ConflictError; } else { result.Status = TableStorageResponseStatus.UnknownError; } } return(result); }
private JsonResult BuildRuleUpdateResponse(TableStorageResponse<DeviceRule> response) { switch (response.Status) { case TableStorageResponseStatus.Successful: return Json(new { success = true }); case TableStorageResponseStatus.ConflictError: return Json(new { error = Strings.TableDataSaveConflictErrorMessage, entity = JsonConvert.SerializeObject(response.Entity) }); case TableStorageResponseStatus.DuplicateInsert: return Json(new { error = Strings.RuleAlreadyAddedError, entity = JsonConvert.SerializeObject(response.Entity) }); case TableStorageResponseStatus.NotFound: return Json(new { error = Strings.UnableToRetrieveRuleFromService, entity = JsonConvert.SerializeObject(response.Entity) }); case TableStorageResponseStatus.UnknownError: default: return Json(new { error = Strings.RuleUpdateError, entity = JsonConvert.SerializeObject(response.Entity) }); } }
public async void SaveDeviceRuleAsyncTest() { var newRule = fixture.Create<DeviceRule>(); DeviceRuleTableEntity tableEntity = null; var resp = new TableStorageResponse<DeviceRule> { Entity = newRule, Status = TableStorageResponseStatus.Successful }; _tableStorageClientMock.Setup( x => x.DoTableInsertOrReplaceAsync(It.IsNotNull<DeviceRuleTableEntity>(), It.IsNotNull<Func<DeviceRuleTableEntity, DeviceRule>>())) .Callback<DeviceRuleTableEntity, Func<DeviceRuleTableEntity, DeviceRule>>( (entity, func) => tableEntity = entity) .ReturnsAsync(resp); var tableEntities = fixture.Create<List<DeviceRuleTableEntity>>(); _tableStorageClientMock.Setup(x => x.ExecuteQueryAsync(It.IsNotNull<TableQuery<DeviceRuleTableEntity>>())) .ReturnsAsync(tableEntities); string blobEntititesStr = null; _blobClientMock.Setup(x => x.UploadTextAsync(It.IsNotNull<string>(), It.IsNotNull<string>())) .Callback<string, string>((name, blob) => blobEntititesStr = blob) .Returns(Task.FromResult(true)); var ret = await deviceRulesRepository.SaveDeviceRuleAsync(newRule); Assert.NotNull(ret); Assert.Equal(resp, ret); Assert.NotNull(tableEntity); Assert.Equal(newRule.DeviceID, tableEntity.DeviceId); Assert.NotNull(blobEntititesStr); }
public async void SaveFilterAsyncTest() { var newFilter = fixture.Create <DeviceListFilter>(); var oldEntity = fixture.Create <DeviceListFilterTableEntity>(); DeviceListFilterTableEntity tableEntity = null; var tableEntities = new List <DeviceListFilterTableEntity>(); var resp = new TableStorageResponse <DeviceListFilter> { Entity = newFilter, Status = TableStorageResponseStatus.Successful }; _filterTableStorageClientMock.Setup(x => x.ExecuteQueryAsync(It.IsNotNull <TableQuery <DeviceListFilterTableEntity> >())) .ReturnsAsync(tableEntities); _filterTableStorageClientMock.Setup( x => x.DoTableInsertOrReplaceAsync(It.IsNotNull <DeviceListFilterTableEntity>(), It.IsNotNull <Func <DeviceListFilterTableEntity, DeviceListFilter> >())) .Callback <DeviceListFilterTableEntity, Func <DeviceListFilterTableEntity, DeviceListFilter> >( (entity, func) => { tableEntity = entity; tableEntities.Add(tableEntity); }) .ReturnsAsync(resp); var ret = await deviceListFilterRepository.SaveFilterAsync(newFilter, true); Assert.NotNull(ret); Assert.NotNull(tableEntity); _filterTableStorageClientMock.Setup(x => x.ExecuteQueryAsync(It.IsNotNull <TableQuery <DeviceListFilterTableEntity> >())) .ReturnsAsync(tableEntities); ret = await deviceListFilterRepository.SaveFilterAsync(newFilter, false); Assert.Equal(ret.Id, newFilter.Id); Assert.Equal(ret.Name, newFilter.Name); Assert.Equal(ret.Clauses.Count, newFilter.Clauses.Count); tableEntity.Name = "changedName"; _filterTableStorageClientMock.SetupSequence(x => x.ExecuteQueryAsync(It.IsNotNull <TableQuery <DeviceListFilterTableEntity> >())) .ReturnsAsync(tableEntities) .ReturnsAsync(new List <DeviceListFilterTableEntity>()); _filterTableStorageClientMock.Setup(x => x.DoDeleteAsync(It.IsNotNull <DeviceListFilterTableEntity>(), It.IsAny <Func <DeviceListFilterTableEntity, DeviceListFilter> >())); ret = await deviceListFilterRepository.SaveFilterAsync(newFilter, true); resp = new TableStorageResponse <DeviceListFilter> { Entity = newFilter, Status = TableStorageResponseStatus.NotFound }; _filterTableStorageClientMock.Setup( x => x.DoTableInsertOrReplaceAsync(It.IsNotNull <DeviceListFilterTableEntity>(), It.IsNotNull <Func <DeviceListFilterTableEntity, DeviceListFilter> >())) .ReturnsAsync(resp); _filterTableStorageClientMock.SetupSequence(x => x.ExecuteQueryAsync(It.IsNotNull <TableQuery <DeviceListFilterTableEntity> >())) .ReturnsAsync(tableEntities) .ReturnsAsync(new List <DeviceListFilterTableEntity>()); await Assert.ThrowsAnyAsync <FilterSaveException>(async() => await deviceListFilterRepository.SaveFilterAsync(newFilter, true)); }