internal static Tuple<HttpWebRequest, Stream> BuildRequestForTableOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int? timeout, TableOperation operation, bool useVersionHeader, OperationContext ctx, TableRequestOptions options, string accountName) { HttpWebRequest msg = BuildRequestCore(uri, builder, operation.HttpMethod, timeout, useVersionHeader, ctx); TablePayloadFormat payloadFormat = options.PayloadFormat.Value; // Set Accept and Content-Type based on the payload format. SetAcceptHeaderForHttpWebRequest(msg, payloadFormat); Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat); if (operation.HttpMethod != "HEAD" && operation.HttpMethod != "GET") { SetContentTypeForHttpWebRequest(msg, payloadFormat); } if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge) { options.AssertNoEncryptionPolicyOrStrictMode(); // post tunnelling msg.Headers.Add("X-HTTP-Method", "MERGE"); } // etag if (operation.OperationType == TableOperationType.Delete || operation.OperationType == TableOperationType.Replace || operation.OperationType == TableOperationType.Merge) { if (operation.Entity.ETag != null) { msg.Headers.Add("If-Match", operation.Entity.ETag); } } // prefer header if (operation.OperationType == TableOperationType.Insert) { msg.Headers.Add("Prefer", operation.EchoContent ? "return-content" : "return-no-content"); } if (operation.OperationType == TableOperationType.Insert || operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.InsertOrReplace || operation.OperationType == TableOperationType.Replace) { // create the writer, indent for readability of the examples. ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() { CheckCharacters = false, // sets this flag on the XmlWriter for ATOM Version = TableConstants.ODataProtocolVersion // set the Odata version to use when writing the entry }; HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg, bufferManager); if (operation.HttpMethod != "HEAD" && operation.HttpMethod != "GET") { SetContentTypeForAdapterMessage(adapterMsg, payloadFormat); } ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings, new TableStorageModel(accountName)); ODataWriter writer = odataWriter.CreateODataEntryWriter(); WriteOdataEntity(operation.Entity, operation.OperationType, ctx, writer, options); return new Tuple<HttpWebRequest, Stream>(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream()); } return new Tuple<HttpWebRequest, Stream>(msg, null); }
internal static IEnumerable<ODataProperty> GetPropertiesFromDictionary(IDictionary<string, EntityProperty> properties, TableRequestOptions options, string partitionKey, string rowKey) { // Check if encryption policy is set and invoke EncryptEnity if it is set. if (options != null) { options.AssertPolicyIfRequired(); if (options.EncryptionPolicy != null) { properties = options.EncryptionPolicy.EncryptEntity(properties, partitionKey, rowKey, options.EncryptionResolver); } } return properties.Select(kvp => new ODataProperty() { Name = kvp.Key, Value = kvp.Value.PropertyAsObject }); }
internal static IEnumerable<ODataProperty> GetPropertiesWithKeys(ITableEntity entity, OperationContext operationContext, TableOperationType operationType, TableRequestOptions options) { if (operationType == TableOperationType.Insert) { if (entity.PartitionKey != null) { yield return new ODataProperty() { Name = TableConstants.PartitionKey, Value = entity.PartitionKey }; } if (entity.RowKey != null) { yield return new ODataProperty() { Name = TableConstants.RowKey, Value = entity.RowKey }; } } foreach (ODataProperty property in GetPropertiesFromDictionary(entity.WriteEntity(operationContext), options, entity.PartitionKey, entity.RowKey)) { yield return property; } }
internal static Tuple<HttpWebRequest, Stream> BuildRequestForTableBatchOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int? timeout, string tableName, TableBatchOperation batch, bool useVersionHeader, OperationContext ctx, TableRequestOptions options, string accountName) { HttpWebRequest msg = BuildRequestCore(NavigationHelper.AppendPathToSingleUri(uri, "$batch"), builder, "POST", timeout, useVersionHeader, ctx); TablePayloadFormat payloadFormat = options.PayloadFormat.Value; Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat); // create the writer, indent for readability of the examples. ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() { CheckCharacters = false, // sets this flag on the XmlWriter for ATOM Version = TableConstants.ODataProtocolVersion // set the Odata version to use when writing the entry }; HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg, bufferManager); ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings); ODataBatchWriter batchWriter = odataWriter.CreateODataBatchWriter(); batchWriter.WriteStartBatch(); bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve; // Query operations should not be inside changeset in payload if (!isQuery) { // Start Operation batchWriter.WriteStartChangeset(); batchWriter.Flush(); } foreach (TableOperation operation in batch) { string httpMethod = operation.HttpMethod; if (operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge) { options.AssertNoEncryptionPolicyOrStrictMode(); httpMethod = "MERGE"; } ODataBatchOperationRequestMessage mimePartMsg = batchWriter.CreateOperationRequestMessage(httpMethod, operation.GenerateRequestURI(uri, tableName)); SetAcceptAndContentTypeForODataBatchMessage(mimePartMsg, payloadFormat); // etag if (operation.OperationType == TableOperationType.Delete || operation.OperationType == TableOperationType.Replace || operation.OperationType == TableOperationType.Merge) { mimePartMsg.SetHeader("If-Match", operation.Entity.ETag); } // Prefer header if (operation.OperationType == TableOperationType.Insert) { mimePartMsg.SetHeader("Prefer", operation.EchoContent ? "return-content" : "return-no-content"); } if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve) { using (ODataMessageWriter batchEntryWriter = new ODataMessageWriter(mimePartMsg, writerSettings, new TableStorageModel(accountName))) { // Write entity ODataWriter entryWriter = batchEntryWriter.CreateODataEntryWriter(); WriteOdataEntity(operation.Entity, operation.OperationType, ctx, entryWriter, options); } } } if (!isQuery) { // End Operation batchWriter.WriteEndChangeset(); } // End Batch batchWriter.WriteEndBatch(); batchWriter.Flush(); return new Tuple<HttpWebRequest, Stream>(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream()); }
private static void WriteOdataEntity(ITableEntity entity, TableOperationType operationType, OperationContext ctx, ODataWriter writer, TableRequestOptions options) { ODataEntry entry = new ODataEntry() { Properties = GetPropertiesWithKeys(entity, ctx, operationType, options), TypeName = "account.sometype" }; entry.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = null }); writer.WriteStart(entry); writer.WriteEnd(); writer.Flush(); }
public void TableSetPermissionsPermissionsRequestOptionsOperationContextCancellationTokenTask() { CloudTableClient tableClient = GenerateCloudTableClient(); string tableName = GenerateRandomTableName(); CloudTable table = tableClient.GetTableReference(tableName); TablePermissions permissions = new TablePermissions(); TableRequestOptions requestOptions = new TableRequestOptions(); OperationContext operationContext = new OperationContext(); CancellationToken cancellationToken = CancellationToken.None; permissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy() { Permissions = SharedAccessTablePermissions.Query, SharedAccessStartTime = DateTimeOffset.Now.Add(new TimeSpan(-1, 0, 0)), SharedAccessExpiryTime = DateTimeOffset.Now.Add(new TimeSpan(1, 0, 0)) }); try { table.CreateAsync().Wait(); table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))).Wait(); table.SetPermissionsAsync(permissions, requestOptions, operationContext, cancellationToken); } finally { table.DeleteIfExistsAsync().Wait(); } }
public void TableServiceContextTimeoutDuringSaveChangesNonBatchAPM() { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); for (int m = 0; m < 100; m++) { BaseEntity ent = new BaseEntity("testpartition", m.ToString()); ent.Randomize(); ent.A = ent.RowKey; ctx.AddObject(currentTable.Name, ent); } OperationContext opContext = new OperationContext(); TableRequestOptions requestOptions = new TableRequestOptions() { MaximumExecutionTime = TimeSpan.FromSeconds(5) }; using (HttpMangler proxy = new HttpMangler(false, new[] { DelayBehaviors.DelayAllRequestsIf(2000, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).SkipNSessions(10)) })) { try { using (ManualResetEvent evt = new ManualResetEvent(false)) { IAsyncResult result = ctx.BeginSaveChangesWithRetries(SaveChangesOptions.None, requestOptions, opContext, (res) => { result = res; evt.Set(); }, null); evt.WaitOne(); ctx.EndSaveChangesWithRetries(result); } ctx.SaveChangesWithRetries(SaveChangesOptions.None, requestOptions, opContext); } catch (StorageException ex) { Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.RequestTimeout); Assert.AreEqual("The client could not finish the operation within specified timeout.", ex.Message); Assert.IsTrue(ex.InnerException is TimeoutException); } } }
internal TableCommand<DataServiceResponse, DataServiceResponse> GenerateSaveChangesCommand(SaveChangesOptions options, TableRequestOptions requestOptions) { TableCommand<DataServiceResponse, DataServiceResponse> cmd = new TableCommand<DataServiceResponse, DataServiceResponse>(); if (requestOptions.ServerTimeout.HasValue) { this.Timeout = (int)requestOptions.ServerTimeout.Value.TotalSeconds; } cmd.ExecuteFunc = () => this.SaveChanges(options); cmd.Begin = (callback, state) => this.BeginSaveChanges(options, callback, state); cmd.End = this.EndSaveChanges; cmd.ParseResponse = this.ParseDataServiceResponse; cmd.ParseDataServiceError = StorageExtendedErrorInformation.ReadDataServiceResponseFromStream; cmd.Context = this; requestOptions.ApplyToStorageCommand(cmd); return cmd; }
public void TableGetPermissionsRequestOptionsOperationContextCancellationTokenTask() { CloudTableClient tableClient = GenerateCloudTableClient(); string tableName = GenerateRandomTableName(); CloudTable table = tableClient.GetTableReference(tableName); TableRequestOptions requestOptions = new TableRequestOptions(); OperationContext operationContext = new OperationContext(); CancellationToken cancellationToken = CancellationToken.None; try { table.CreateAsync().Wait(); table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))).Wait(); TablePermissions expected = new TablePermissions(); TablePermissions actual = table.GetPermissionsAsync(requestOptions, operationContext, cancellationToken).Result; AssertPermissionsEqual(expected, actual); } finally { table.DeleteIfExistsAsync().Wait(); } }
public Task<DataServiceResponse> SaveChangesWithRetriesAsync(SaveChangesOptions options, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) { return AsyncExtensions.TaskFromApm(this.BeginSaveChangesWithRetries, this.EndSaveChangesWithRetries, options, requestOptions, operationContext, cancellationToken); }
public Task<DataServiceResponse> SaveChangesWithRetriesAsync(SaveChangesOptions options, TableRequestOptions requestOptions, OperationContext operationContext) { return this.SaveChangesWithRetriesAsync(options, requestOptions, operationContext, CancellationToken.None); }
public ICancellableAsyncResult BeginSaveChangesWithRetries(SaveChangesOptions options, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) { requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); operationContext = operationContext ?? new OperationContext(); TableCommand<DataServiceResponse, DataServiceResponse> cmd = this.GenerateSaveChangesCommand(options, requestOptions); return TableExecutor.BeginExecuteAsync(cmd, requestOptions.RetryPolicy, operationContext, callback, state); }
public DataServiceResponse SaveChangesWithRetries(SaveChangesOptions options, TableRequestOptions requestOptions = null, OperationContext operationContext = null) { requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); operationContext = operationContext ?? new OperationContext(); TableCommand<DataServiceResponse, DataServiceResponse> cmd = this.GenerateSaveChangesCommand(options, requestOptions); return TableExecutor.ExecuteSync(cmd, requestOptions.RetryPolicy, operationContext); }
internal TableCommand<DataServiceResponse, DataServiceResponse> GenerateSaveChangesCommand(SaveChangesOptions options, TableRequestOptions requestOptions) { TableCommand<DataServiceResponse, DataServiceResponse> cmd = new TableCommand<DataServiceResponse, DataServiceResponse>(); if (requestOptions.ServerTimeout.HasValue) { this.Timeout = (int)requestOptions.ServerTimeout.Value.TotalSeconds; } cmd.ExecuteFunc = () => this.SaveChanges(options); cmd.Begin = (callback, state) => this.BeginSaveChanges(options, callback, state); cmd.End = this.EndSaveChanges; cmd.ParseResponse = this.ParseDataServiceResponse; cmd.ApplyRequestOptions(requestOptions); cmd.Context = this; return cmd; }