public async Task <bool> ConfirmAppendDataAsync(string subscriptionId, PwnedPasswordsTransaction transaction, CancellationToken cancellationToken = default) { try { Response <AppendTransactionEntity> transactionEntityResponse = await _transactionTable.GetEntityAsync <AppendTransactionEntity>(subscriptionId, transaction.TransactionId, cancellationToken : cancellationToken).ConfigureAwait(false); if (!transactionEntityResponse.Value.Confirmed) { transactionEntityResponse.Value.Confirmed = true; Response?updateResponse = await _transactionTable.UpdateEntityAsync(transactionEntityResponse.Value, transactionEntityResponse.Value.ETag, cancellationToken : cancellationToken).ConfigureAwait(false); _log.LogInformation("Subscription {SubscriptionId} successfully confirmed transaction {TransactionId}. Queueing data for blob updates.", subscriptionId, transaction.TransactionId); return(true); } // We've already confirmed this transaction. return(false); } catch (RequestFailedException e) when(e.Status == 404) { throw new ArgumentOutOfRangeException("Transaction id not found.", e); } catch (RequestFailedException e) when(e.Status == StatusCodes.Status409Conflict) { throw new ArgumentException("Transaciton has already been updated.", e); } catch (RequestFailedException e) { _log.LogError(e, "Error looking up/updating transaction with id = {TransactionId} for subscription {SubscriptionId}.", transaction.TransactionId, subscriptionId); throw new InvalidOperationException("Error confirming transaction.", e); } }
public async Task TableEntity_IfBoundToPocoTableEntity_CanCall() { // Arrange await TableClient.AddEntityAsync(new TableEntity(PartitionKey, RowKey) { { "Fruit", ("Banana") }, { "Duration", ("\"00:00:01\"") }, { "Value", ("Foo") } }); // Act await CallAsync <BindTableEntityToPocoTableEntityProgram>(); // Assert TableEntity entity = await TableClient.GetEntityAsync <TableEntity>(PartitionKey, RowKey); Assert.NotNull(entity); Assert.AreEqual(PartitionKey, entity.PartitionKey); // Guard Assert.AreEqual(RowKey, entity.RowKey); // Guard // TODO: behavior change. Was 3 before Assert.AreEqual(7, entity.Count); Assert.AreEqual("Pear", entity["Fruit"]); Assert.AreEqual("\"00:02:00\"", entity["Duration"]); Assert.AreEqual("Bar", entity["Value"]); }
public static async Task <IActionResult> UpdateTodo( [HttpTrigger(AuthorizationLevel.Anonymous, "put", Route = Route + "/{id}")] HttpRequest req, [Table(TableName, Connection = "AzureWebJobsStorage")] TableClient todoTable, ILogger log, string id) { string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); var updated = JsonConvert.DeserializeObject <TodoUpdateModel>(requestBody); TodoTableEntity existingRow; try { var findResult = await todoTable.GetEntityAsync <TodoTableEntity>(PartitionKey, id); existingRow = findResult.Value; } catch (RequestFailedException e) when(e.Status == 404) { return(new NotFoundResult()); } existingRow.IsCompleted = updated.IsCompleted; if (!string.IsNullOrEmpty(updated.TaskDescription)) { existingRow.TaskDescription = updated.TaskDescription; } await todoTable.UpdateEntityAsync(existingRow, existingRow.ETag, TableUpdateMode.Replace); return(new OkObjectResult(existingRow.ToTodo())); }
public async Task <DishEntity> InsertAsync(DishEntity dish) { if (dish.PartitionKey == null) { dish.PartitionKey = "lye"; } if (dish.RowKey == null) { dish.RowKey = Guid.NewGuid().ToString(); } var response = await _dishTable.AddEntityAsync(dish); _logger.LogInformation("Inserted new dish with RowKey {RowKey} - Status: {HttpStatus}", dish.RowKey, response.Status); var entity = await _dishTable.GetEntityAsync <DishEntity>(dish.PartitionKey, dish.RowKey); return(entity); }
public async Task Table_IfBoundToOutParameterAndTableIsMissingAndAdds_CreatesTable <T>() { // Act await CallAsync <BindOut <T> >(); // Assert var entity = TableClient.GetEntityAsync <TableEntity>(PartitionKey, RowKey); Assert.AreEqual("test value", entity.Result.Value["Value"]); }
private async Task TestTableBoundToCollectorCanCallAsync <T>() where T : new() { // Arrange await CallAsync <T>(); // Assert TableEntity entity = await TableClient.GetEntityAsync <TableEntity>(PartitionKey, RowKey); Assert.NotNull(entity); }
public async Task Table_IfBoundToICollectorJObject_AddInsertsEntity() { // Act await CallAsync <BindToICollectorJObjectProgram>(); // Assert TableEntity entity = await TableClient.GetEntityAsync <TableEntity>(PartitionKey, RowKey); Assert.NotNull(entity); Assert.AreEqual("abcdef", entity["ValueStr"]); Assert.AreEqual(123, entity["ValueNum"]); }
public async Task TableEntity_IfBoundToSdkTableEntity_CanCall() { // Arrange await TableClient.AddEntityAsync(CreateTableEntity(PartitionKey, RowKey, "Value", "Foo")); // Act await CallAsync <BindTableEntityToSdkTableEntityProgram>(); // Assert SdkTableEntity entity = await TableClient.GetEntityAsync <SdkTableEntity>(PartitionKey, RowKey); Assert.NotNull(entity); Assert.AreEqual("Bar", entity.Value); }
public async Task CustomizeSerialization() { string storageUri = StorageUri; string tableName = "OfficeSupplies" + _random.Next(); #region Snippet:CustomSerialization // Construct a new TableClient using a TokenCredential. var client = new TableClient( new Uri(storageUri), tableName, #if SNIPPET new DefaultAzureCredential()); #else new ClientSecretCredential( GetVariable("TENANT_ID"), GetVariable("CLIENT_ID"), GetVariable("CLIENT_SECRET"))); #endif // Create the table if it doesn't already exist. client.CreateIfNotExists(); // Create a new entity with our customization attributes. var entity = new CustomSerializationEntity { PartitionKey = "CustomInventory", RowKey = "special stock", Product = "Fancy Marker", Price = 1.00, Quantity = 42, IgnoreMe = "nothing to see here", RenameMe = "This property will be saved to the table as 'rename_me'" }; // Add the entity to the table. It will be serialized according to our customizations. await client.AddEntityAsync(entity); // Fetch the entity as a TableEntity so that we can verify that things were serialized as expected. var fetchedEntity = await client.GetEntityAsync <TableEntity>(entity.PartitionKey, entity.RowKey); // Print each property name to the console. foreach (string propertyName in fetchedEntity.Value.Keys) { Console.WriteLine(propertyName); } #endregion }
public async Task <SyncState> ReadAsync(CancellationToken cancellationToken = default) { TableClient tableClient = _tableServiceClient.GetTableClient(Constants.SyncStateTableName); try { var entity = await tableClient.GetEntityAsync <SyncStateEntity>(Constants.SyncStatePartitionKey, Constants.SyncStateRowKey, cancellationToken : cancellationToken); return(new SyncState(entity.Value.SyncedSequence, entity.Value.Timestamp.Value)); } catch (RequestFailedException) { return(SyncState.CreateInitialSyncState()); } }
// Assert the given table has the given entity with PropertyName=ExpectedValue private async Task AssertStringPropertyAsync( string propertyName, string expectedValue, string tableName = null, string partitionKey = PartitionKey, string rowKey = RowKey) { // Assert tableName ??= TableName; TableClient table = ServiceClient.GetTableClient(tableName); Assert.True(await TableExistsAsync(table).ConfigureAwait(false)); TableEntity entity = await table.GetEntityAsync <TableEntity>(partitionKey, rowKey); Assert.AreEqual(expectedValue, entity[propertyName]); }
private async Task TestBindToConcurrentlyUpdatedTableEntity <T>(string parameterName) { // Arrange await TableClient.CreateIfNotExistsAsync(); await TableClient.AddEntityAsync(CreateTableEntity(PartitionKey, RowKey, "Value", "Foo")); // Act & Assert var exception = Assert.CatchAsync <FunctionInvocationException>(async() => await CallAsync <T>("Call")); AssertInvocationETagFailure(parameterName, exception); SdkTableEntity entity = await TableClient.GetEntityAsync <SdkTableEntity>(PartitionKey, RowKey); Assert.NotNull(entity); Assert.AreEqual("FooBackground", entity.Value); }
public async Task TableEntity_IfBoundToJObject_CanCall() { // Arrange await TableClient.AddEntityAsync(CreateTableEntity(PartitionKey, RowKey, "Value", "Foo")); await CallAsync <BindTableEntityToJObjectProgram>(arguments : new { table = TableName, // Test resolution pk1 = PartitionKey, rk1 = RowKey }); // Assert SdkTableEntity entity = await TableClient.GetEntityAsync <SdkTableEntity>(PartitionKey, RowKey); Assert.NotNull(entity); }
public async Task <string?> GetTokenAsync(string tenantId, string userId) { await _tableClient.CreateIfNotExistsAsync(); try { var response = await _tableClient.GetEntityAsync <UserTokenEntity>(partitionKey : tenantId, rowKey : userId); _logger.LogInformation("Found token for user ([{tenantId}], [{userId}])", tenantId, userId); return(response?.Value?.Token); } catch (RequestFailedException ex) when(ex.Status == 404) { _logger.LogInformation("No token stored for user ([{tenantId}], [{userId}])", tenantId, userId); return(null); } }
public async Task <T> GetTableRow <T>(string tableName, string rowKey, string partitionKey = "default") where T : ValueWithEtag { TableClient tableClient = await this.GetTableClient(tableName); try { var res = await tableClient.GetEntityAsync <ContentDataEntity>(partitionKey, rowKey); T value = JsonConvert.DeserializeObject <T>(res.Value.Content); value.etag = res.Value.ETag; return(value); } catch (RequestFailedException e) { return(null); } }
public async Task <IActionResult> GetFileAsync(string fileId) { // TODO: Verify that user is allowed to get files for this chat/call // Prepare Table Storage clients TableServiceClient tableServiceClient = new TableServiceClient(_storageAccountConnectionString); TableClient tableClient = tableServiceClient.GetTableClient(_tableName); tableClient.CreateIfNotExists(); // Get file info from Table Storage Azure.Response <TableEntity> getTableEntityResponse; try { getTableEntityResponse = await tableClient.GetEntityAsync <TableEntity>(fileId, fileId); } catch (Azure.RequestFailedException e) { if (e.Status == 404) { return(NotFound()); } return(BadRequest("Couldn't get file from storage")); } var fileName = getTableEntityResponse.Value.GetString("FileName"); // Prepare Blob Storage clients and container BlobContainerClient containerClient = new BlobContainerClient(_storageAccountConnectionString, _blobContainerName); containerClient.CreateIfNotExists(); BlobClient blob = containerClient.GetBlobClient(fileId); // MemoryStream blobStream = new MemoryStream(); // var downloadResult = await blob.DownloadToAsync(blobStream); var blobStream = await blob.OpenReadAsync(); return(new FileStreamResult(blobStream, "application/octet-stream") { FileDownloadName = fileName }); }
public static async Task Call([Table(TableNameExpression)] ICollector <ITableEntity> collector, [Table(TableNameExpression)] TableClient table) { SdkTableEntity entity = await table.GetEntityAsync <SdkTableEntity>(PartitionKey, RowKey); Assert.NotNull(entity); Assert.AreEqual("Foo", entity.Value); // Update the entity to invalidate the version read by this method. await table.UpdateEntityAsync(new SdkTableEntity { PartitionKey = PartitionKey, RowKey = RowKey, Value = "FooBackground" }, ETag.All); // The attempted update by this method should now fail. collector.Add(new TableEntity(PartitionKey, RowKey) { ETag = entity.ETag, ["Value"] = "Bar" }); }
public async Task TableEntity_IfUpdatesPoco_Persists() { // Arrange const string originalValue = "abc"; const string expectedValue = "def"; await TableClient.AddEntityAsync(new TableEntity(PartitionKey, RowKey) { { "Value", (originalValue) } }); // Act await CallAsync <UpdatePocoProgram>(arguments : new { newValue = expectedValue }); // Assert TableEntity entity = await TableClient.GetEntityAsync <TableEntity>(PartitionKey, RowKey); Assert.NotNull(entity); Assert.AreEqual(expectedValue, entity["Value"]); }
public async Task TableEntity_IfBoundUsingRouteParameters_Binds() { // Arrange await TableClient.AddEntityAsync(new TableEntity(PartitionKey, RowKey) { { "Value", (123) } }); // Act await CallAsync <BindUsingRouteParametersProgram>(arguments : new { TableName = TableName, PartitionKey = PartitionKey, RowKey = RowKey }); // Assert TableEntity entity = await TableClient.GetEntityAsync <TableEntity>(PartitionKey, RowKey); Assert.NotNull(entity); Assert.AreEqual(456, entity["Value"]); }
public async Task TableEntity_IfUpdatesPoco_PersistsUsingNativeTableTypes() { // Arrange byte[] originalValue = new byte[] { 0x12, 0x34 }; byte[] expectedValue = new byte[] { 0x56, 0x78 }; await TableClient.AddEntityAsync(new TableEntity(PartitionKey, RowKey) { { "Value", (originalValue) } }); // Act await CallAsync <UpdatePocoWithByteArrayValueProgram>(arguments : new { expectedValue }); // Assert TableEntity entity = await TableClient.GetEntityAsync <TableEntity>(PartitionKey, RowKey); Assert.NotNull(entity); Assert.AreEqual(expectedValue, entity["Value"]); }
public Task <Response <T> > GetByRowKeyAsync(string rowKey) => _tableClient.GetEntityAsync <T>(_partitionKey, rowKey);
public async Task <long> StoreStateData <TData, TState>(StateDto metaData, long currentSequenceNumber, TData data, bool saveHistory, string parentIdentifier) where TData : BaseStateDataModel <TState> where TState : struct, IConvertible { var tableName = NormalizeTableName(metaData.MachineName); _logger.LogTrace($"Using table name {tableName}"); TableClient table = await GetTable(tableName); string partitionKey = string.IsNullOrWhiteSpace(parentIdentifier) ? metaData.Identifier : parentIdentifier; string rowKeyPrefix = string.IsNullOrWhiteSpace(parentIdentifier) ? "" : $"{metaData.Identifier}-"; var currentResponse = await table.GetEntityAsync <StateDataTable>(partitionKey, rowKeyPrefix + "current"); StateDataTable currentMarker = currentResponse?.Value; long sequenceNumber = currentMarker?.SequenceNumber ?? 0; if (sequenceNumber != currentSequenceNumber) { throw new Exception($"Out of sequence state update attempted. For {metaData.Identifier} attempted to replace {currentSequenceNumber}. Current version is actually {sequenceNumber}"); } long nextSequenceNumber = sequenceNumber + 1; if (currentMarker == null) { currentMarker = new StateDataTable(); } var serializedState = await _objectSerializer.Serialize(data); if (serializedState.Length > 28_000) { throw new Exception("Serialized data is > 28,000 chars"); } currentMarker.PartitionKey = partitionKey; currentMarker.RowKey = rowKeyPrefix + "current"; currentMarker.SequenceNumber = nextSequenceNumber; currentMarker.MachineName = metaData.MachineName; currentMarker.ContentLength = serializedState.Length; currentMarker.SerializedState = serializedState; currentMarker.Source = metaData.Source; currentMarker.Destination = metaData.Destination; currentMarker.IsReentry = metaData.IsReentry; currentMarker.Trigger = metaData.Trigger; currentMarker.CorrelationId = metaData.CorrelationId.ToString(); currentMarker.UserIdentifier = metaData.UserIdentifier; currentMarker.Username = metaData.Username; currentMarker.UpdateAuditable(metaData); var record = new StateDataTable { PartitionKey = partitionKey, RowKey = rowKeyPrefix + nextSequenceNumber, MachineName = metaData.MachineName, Source = metaData.Source, ContentLength = serializedState.Length, Destination = metaData.Destination, IsReentry = metaData.IsReentry, SequenceNumber = nextSequenceNumber, SerializedState = serializedState, Trigger = metaData.Trigger, UserIdentifier = metaData.UserIdentifier, Username = metaData.Username, CorrelationId = metaData.CorrelationId.ToString() }.UpdateAuditable(metaData); try { List <TableTransactionAction> batch = new List <TableTransactionAction>(); batch.Add(new TableTransactionAction(TableTransactionActionType.UpsertReplace, currentMarker)); if (saveHistory) { batch.Add(new TableTransactionAction(TableTransactionActionType.Add, record)); } await table.SubmitTransactionAsync(batch); } catch (Azure.Data.Tables.TableTransactionFailedException ex) { _logger.LogError($"StatusCode={ex.Status}, HttpMessage={ex.ErrorCode}"); throw; } catch (Exception ex) { var t = ex.GetType(); _logger.LogError(ex, "Error calling storage"); throw; } return(nextSequenceNumber); }
public static async Task <T> GetEntity <T>(this TableClient table, string partitionId, string rowId) where T : class, ITableEntity, new() { var result = await table.GetEntityAsync <T>(partitionId, rowId); return(result?.Value); }
public async Task Table_IfBoundToICollectorPoco_AddInsertsUsingNativeTableTypes() { // Arrange PocoWithAllTypes expected = new PocoWithAllTypes { PartitionKey = PartitionKey, RowKey = RowKey, BooleanProperty = true, NullableBooleanProperty = null, ByteArrayProperty = new byte[] { 0x12, 0x34 }, DateTimeProperty = DateTime.UtcNow, NullableDateTimeProperty = null, DateTimeOffsetProperty = DateTimeOffset.MaxValue, NullableDateTimeOffsetProperty = null, DoubleProperty = 3.14, NullableDoubleProperty = null, GuidProperty = Guid.NewGuid(), NullableGuidProperty = null, Int32Property = 123, NullableInt32Property = null, Int64Property = 456, NullableInt64Property = null, StringProperty = "abc", PocoProperty = new Poco { PartitionKey = "def", RowKey = "ghi", Property = "jkl" } }; // Act await CallAsync <BindToICollectorPocoWithAllTypesProgram>(arguments : new { entity = expected }); // Assert TableEntity entity = await TableClient.GetEntityAsync <TableEntity>(PartitionKey, RowKey); Assert.AreEqual(expected.PartitionKey, entity.PartitionKey); Assert.AreEqual(expected.RowKey, entity.RowKey); AssertNullablePropertyEqual(expected.BooleanProperty, entity, "BooleanProperty"); AssertPropertyNull(entity, "NullableBooleanProperty"); AssertPropertyEqual(expected.ByteArrayProperty, entity, "ByteArrayProperty"); // TODO: behavior change. DateTime was the default type before AssertNullablePropertyEqual(new DateTimeOffset(expected.DateTimeProperty), entity, "DateTimeProperty"); AssertPropertyNull(entity, "NullableDateTimeProperty"); AssertNullablePropertyEqual(expected.DateTimeOffsetProperty, entity, "DateTimeOffsetProperty"); AssertPropertyNull(entity, "NullableDateTimeOffsetProperty"); AssertNullablePropertyEqual(expected.DoubleProperty, entity, "DoubleProperty"); AssertPropertyNull(entity, "NullableDoubleProperty"); AssertNullablePropertyEqual(expected.GuidProperty, entity, "GuidProperty"); AssertPropertyNull(entity, "NullableGuidProperty"); AssertNullablePropertyEqual(expected.Int32Property, entity, "Int32Property"); AssertPropertyNull(entity, "NullableInt32Property"); AssertNullablePropertyEqual(expected.Int64Property, entity, "Int64Property"); AssertPropertyNull(entity, "NullableInt64Property"); AssertPropertyEqual(expected.StringProperty, entity, "StringProperty"); AssertPropertyEqual(JsonConvert.SerializeObject(expected.PocoProperty, Formatting.Indented), entity, "PocoProperty"); }