internal static HttpWebRequest BuildRequestForTableQuery(Uri uri, UriQueryBuilder builder, int? timeout, bool useVersionHeader, OperationContext ctx, TablePayloadFormat payloadFormat)
 {
     HttpWebRequest msg = BuildRequestCore(uri, builder, "GET", timeout, useVersionHeader, ctx);
     SetAcceptHeaderForHttpWebRequest(msg, payloadFormat);
     Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat);
     return msg;
 }
Пример #2
0
        private async Task DoTableQueryWithInvalidQueryAsync(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;
            TableQuery query = new TableQuery().Where(string.Format("(PartitionKey ) and (RowKey ge '{1}')", "tables_batch_1", "000050"));

            OperationContext opContext = new OperationContext();

            try
            {
#if !FACADE_NETCORE
                await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext);
#else
                await currentTable.ExecuteQuerySegmentedAsync <BaseEntity>(query, (pk, rk, tse, prop, etag) => new BaseEntity(pk, rk), null, null, opContext);
#endif
                Assert.Fail();
            }
            catch (Exception)
            {
                TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "A binary operator with incompatible types was detected. Found operand types 'Edm.String' and 'Edm.Boolean' for operator kind 'And'.");
            }
        }
        private void DoListTablesSegmentedMaxResultsSync(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();

            tableClient.DefaultRequestOptions.PayloadFormat = format;

            TableResultSegment segment      = null;
            List <CloudTable>  totalResults = new List <CloudTable>();

            int segCount = 0;

            do
            {
                segment = tableClient.ListTablesSegmented(string.Empty, 10, segment != null ? segment.ContinuationToken : null, null, null);
                totalResults.AddRange(segment);
                segCount++;
            }while (segment.ContinuationToken != null);

            Assert.AreEqual(totalResults.Count, tableClient.ListTables().Count());
            Assert.IsTrue(segCount >= totalResults.Count / 10);
        }
        private void DoCloudTableExistsSync(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();

            tableClient.DefaultRequestOptions.PayloadFormat = format;
            string     tableName = GenerateRandomTableName();
            CloudTable tableRef  = tableClient.GetTableReference(tableName);

            try
            {
                Assert.IsFalse(tableRef.Exists());
                tableRef.Create();
                Assert.IsTrue(tableRef.Exists());
                tableRef.Delete();
                Assert.IsFalse(tableRef.Exists());
            }
            finally
            {
                tableRef.DeleteIfExists();
            }
        }
Пример #5
0
        internal static StorageRequestMessage BuildStorageRequestMessageForTableOperation(Uri uri, TableOperation operation, ICanonicalizer canonicalizer, StorageCredentials cred, OperationContext ctx, TableRequestOptions options)
        {
            HttpMethod            httpMethod            = RESTCommandGeneratorUtils.ExtractHttpMethod(operation);
            StorageRequestMessage storageRequestMessage = new StorageRequestMessage(httpMethod, uri, canonicalizer, cred, cred.AccountName);

            storageRequestMessage.Headers.AcceptCharset.ParseAdd("UTF-8");
            storageRequestMessage.Headers.Add("MaxDataServiceVersion", "3.0;NetFx");
            TablePayloadFormat value = options.PayloadFormat.Value;

            Logger.LogInformational(ctx, "Setting payload format for the request to '{0}'.", value);
            SetAcceptHeaderValueForStorageRequestMessage(storageRequestMessage, value);
            storageRequestMessage.Headers.Add("DataServiceVersion", "3.0;");
            if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge)
            {
                storageRequestMessage.Headers.Add("X-HTTP-Method", "MERGE");
            }
            if ((operation.OperationType == TableOperationType.Delete || operation.OperationType == TableOperationType.Replace || operation.OperationType == TableOperationType.Merge) && operation.ETag != null)
            {
                storageRequestMessage.Headers.TryAddWithoutValidation("If-Match", operation.ETag);
            }
            if (operation.OperationType == TableOperationType.Insert)
            {
                storageRequestMessage.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)
            {
                MultiBufferMemoryStream multiBufferMemoryStream = new MultiBufferMemoryStream();
                using (JsonTextWriter jsonWriter = new JsonTextWriter(new StreamWriter(new NonCloseableStream(multiBufferMemoryStream))))
                {
                    WriteEntityContent(operation, ctx, options, jsonWriter);
                }
                multiBufferMemoryStream.Seek(0L, SeekOrigin.Begin);
                storageRequestMessage.Content = new StreamContent(multiBufferMemoryStream);
            }
            if (httpMethod != HttpMethod.Head && httpMethod != HttpMethod.Get && storageRequestMessage.Content != null)
            {
                storageRequestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
            return(storageRequestMessage);
        }
        private async Task DoTableGenericQueryWithContinuationAsync(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;

            OperationContext opContext = new OperationContext();

#if !FACADE_NETCORE
            TableQuery <BaseEntity>        query = new TableQuery <BaseEntity>();
            TableQuerySegment <BaseEntity> seg   = await currentTable.ExecuteQuerySegmentedAsync(query, fullResolver, null, null, opContext);
#else
            TableQuery query = new TableQuery();
            TableQuerySegment <BaseEntity> seg = await currentTable.ExecuteQuerySegmentedAsync <BaseEntity>(query, resolver, null, null, opContext);
#endif

            int count = 0;
            foreach (BaseEntity ent in seg)
            {
                Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch"));
                ent.Validate();
                count++;
            }

            // Second segment
            Assert.IsNotNull(seg.ContinuationToken);
#if !FACADE_NETCORE
            seg = await currentTable.ExecuteQuerySegmentedAsync(query, fullResolver, seg.ContinuationToken, null, opContext);
#else
            seg = await currentTable.ExecuteQuerySegmentedAsync <BaseEntity>(query, resolver, seg.ContinuationToken, null, opContext);
#endif

            foreach (BaseEntity ent in seg)
            {
                Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch"));
                ent.Validate();
                count++;
            }

            Assert.AreEqual(1500, count);
            TestHelper.AssertNAttempts(opContext, 2);
        }
Пример #7
0
        private void DoSingleEntityReplace(TablePayloadFormat format)
        {
            CloudTableClient    tableClient  = GenerateCloudTableClient();
            TableServiceContext ctx          = tableClient.GetTableServiceContext();
            TableServiceContext queryContext = tableClient.GetTableServiceContext();

            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);
            SetPayloadFormatOnDataServiceContext(queryContext, format, tableClient);

            // Insert Entity
            BaseEntity baseEntity = new BaseEntity("insert test", "foo" + format.ToString());

            baseEntity.Randomize();
            ctx.AddObject(currentTable.Name, baseEntity);
            ctx.SaveChangesWithRetries();
            string etag = ctx.Entities.First().ETag;

            ctx.Detach(baseEntity);

            MergeEntity replaceEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey);

            replaceEntity.Randomize();
            ctx.AttachTo(currentTable.Name, replaceEntity, etag);
            ctx.UpdateObject(replaceEntity);
            ctx.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);

            // Retrieve Entity
            UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery <UnionEnitity>(currentTable.Name)
                                            where ent.PartitionKey == baseEntity.PartitionKey &&
                                            ent.RowKey == baseEntity.RowKey
                                            select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault();

            Assert.IsNotNull(retrievedEntity);
            Assert.AreEqual(null, retrievedEntity.A);
            Assert.AreEqual(null, retrievedEntity.B);
            Assert.AreEqual(null, retrievedEntity.C);
            Assert.AreEqual(replaceEntity.D, retrievedEntity.D);
            Assert.AreEqual(replaceEntity.E, retrievedEntity.E);
            Assert.AreEqual(replaceEntity.F, retrievedEntity.F);
        }
Пример #8
0
        private void DoSingleEntityInsert(TablePayloadFormat format)
        {
            CloudTableClient    tableClient = GenerateCloudTableClient();
            TableServiceContext ctx         = tableClient.GetTableServiceContext();

            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

            // Insert Entity
            ComplexEntity insertEntity = new ComplexEntity("insert test", "foo" + format.ToString());

            ctx.AddObject(currentTable.Name, insertEntity);
            ctx.SaveChangesWithRetries();

            // Retrieve Entity
            ComplexEntity retrievedEntity = (from ent in ctx.CreateQuery <ComplexEntity>(currentTable.Name)
                                             where ent.PartitionKey == insertEntity.PartitionKey &&
                                             ent.RowKey == insertEntity.RowKey
                                             select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault();

            Assert.IsNotNull(retrievedEntity);
            ComplexEntity.AssertEquality(insertEntity, retrievedEntity);
        }
Пример #9
0
        private async Task DoTableQueryWithContinuationAsync(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;
            TableQuery query = new TableQuery();

            OperationContext opContext = new OperationContext();

#if !FACADE_NETCORE
            TableQuerySegment seg = await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext);
#else
            TableQuerySegment <DynamicTableEntity> seg = await currentTable.ExecuteQuerySegmentedAsync <DynamicTableEntity>(query, (pk, rk, tse, prop, etag) => new DynamicTableEntity(pk, rk, etag, prop), null, null, opContext);
#endif

            int count = 0;
            foreach (DynamicTableEntity ent in seg)
            {
                Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch"));
                Assert.AreEqual(ent.Properties.Count, 4);
                count++;
            }

            // Second segment
            Assert.IsNotNull(seg.ContinuationToken);
#if !FACADE_NETCORE
            seg = await currentTable.ExecuteQuerySegmentedAsync(query, seg.ContinuationToken, null, opContext);
#else
            seg = await currentTable.ExecuteQuerySegmentedAsync <DynamicTableEntity>(query, (pk, rk, tse, prop, etag) => new DynamicTableEntity(pk, rk, etag, prop), seg.ContinuationToken, null, opContext);
#endif

            foreach (DynamicTableEntity ent in seg)
            {
                Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch"));
                Assert.AreEqual(ent.Properties.Count, 4);
                count++;
            }

            Assert.AreEqual(1500, count);
            TestHelper.AssertNAttempts(opContext, 2);
        }
        private void DoTableGenericQueryProjection(TablePayloadFormat format)
        {
            tableClient.PayloadFormat = format;

            TableQuery <BaseEntity> query = new TableQuery <BaseEntity>().Select(new List <string>()
            {
                "A", "C"
            });

            foreach (BaseEntity ent in ExecuteQuery(currentTable, query))
            {
                Assert.IsNotNull(ent.PartitionKey);
                Assert.IsNotNull(ent.RowKey);
                Assert.IsNotNull(ent.Timestamp);

                Assert.AreEqual(ent.A, "a");
                Assert.IsNull(ent.B);
                Assert.AreEqual(ent.C, "c");
                Assert.IsNull(ent.D);
                Assert.AreEqual(ent.E, 0);
            }
        }
Пример #11
0
        private void DoSingleEntityDelete(TablePayloadFormat format)
        {
            CloudTableClient    tableClient = GenerateCloudTableClient();
            TableServiceContext ctx         = tableClient.GetTableServiceContext();

            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

            // Insert Entity
            ComplexEntity insertEntity = new ComplexEntity("insert test", "foo");

            ctx.AddObject(currentTable.Name, insertEntity);
            ctx.SaveChangesWithRetries();

            // Retrieve Entity

            ComplexEntity retrievedEntity = (from ent in ctx.CreateQuery <ComplexEntity>(currentTable.Name)
                                             where ent.PartitionKey == insertEntity.PartitionKey &&
                                             ent.RowKey == insertEntity.RowKey
                                             select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault();

            Assert.IsNotNull(retrievedEntity);
            ctx.DeleteObject(retrievedEntity);
            ctx.SaveChangesWithRetries();

            try
            {
                // Retrieve Entity
                retrievedEntity = (from ent in ctx.CreateQuery <ComplexEntity>(currentTable.Name)
                                   where ent.PartitionKey == insertEntity.PartitionKey &&
                                   ent.RowKey == insertEntity.RowKey
                                   select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault();
                Assert.Fail();
            }
            catch (StorageException ex)
            {
                Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.NotFound);
            }
        }
Пример #12
0
        private async Task DoTableQueryEmptyValueAsync(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;
            CloudTable table = tableClient.GetTableReference(GenerateRandomTableName());
            await table.CreateAsync();

            // Setup
            string pk = Guid.NewGuid().ToString();

            DynamicTableEntity dynEnt = new DynamicTableEntity(pk, "rowkey");

            dynEnt.Properties.Add("A", new EntityProperty(string.Empty));
            await table.ExecuteAsync(TableOperation.Insert(dynEnt));

            // 1. Filter on String
            List <DynamicTableEntity> results = (await table.ExecuteQuerySegmentedAsync(new TableQuery().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty)), null)).ToList();

            Assert.AreEqual(1, results.Count);

            List <BaseEntity> pocoresults = (await table.ExecuteQuerySegmentedAsync(new TableQuery <BaseEntity>().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty)), null)).ToList();

            Assert.AreEqual(1, pocoresults.Count);
        }
Пример #13
0
        private async Task DoCloudTableExistsAsync(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();

            tableClient.PayloadFormat = format;
            string     tableName = GenerateRandomTableName();
            CloudTable tableRef  = tableClient.GetTableReference(tableName);

            try
            {
                Assert.IsFalse(await tableRef.ExistsAsync());
                await tableRef.CreateAsync();

                Assert.IsTrue(await tableRef.ExistsAsync());
                await tableRef.DeleteAsync();

                Assert.IsFalse(await tableRef.ExistsAsync());
            }
            finally
            {
                tableRef.DeleteIfExistsAsync().Wait();
            }
        }
        private void DoTableGenericWithResolver(TablePayloadFormat format)
        {
            tableClient.PayloadFormat = format;

            TableQuery <TableEntity> query = new TableQuery <TableEntity>().Select(new List <string>()
            {
                "A", "C", "E"
            });

            TableRequestOptions options = new TableRequestOptions()
            {
                PropertyResolver = (pk, rk, propName, propValue) => BaseEntity.BaseEntityPropertyResolver(pk, rk, propName, propValue)
            };

            foreach (string ent in ExecuteQuery(currentTable, query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue + prop["E"].Int32Value, options))
            {
                Assert.AreEqual(ent, "ac" + 1234);
            }

            foreach (BaseEntity ent in ExecuteQuery(currentTable, query,
                                                    (pk, rk, ts, prop, etag) => new BaseEntity()
            {
                PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, E = prop["E"].Int32Value.Value, ETag = etag
            }, options))
            {
                Assert.IsNotNull(ent.PartitionKey);
                Assert.IsNotNull(ent.RowKey);
                Assert.IsNotNull(ent.Timestamp);
                Assert.IsNotNull(ent.ETag);

                Assert.AreEqual(ent.A, "a");
                Assert.IsNull(ent.B);
                Assert.AreEqual(ent.C, "c");
                Assert.IsNull(ent.D);
                Assert.AreEqual(ent.E, 1234);
            }
        }
Пример #15
0
        private void DoBatchInsert(TablePayloadFormat format)
        {
            CloudTableClient    tableClient = GenerateCloudTableClient();
            TableServiceContext ctx         = tableClient.GetTableServiceContext();

            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

            // Insert Entities
            SortedDictionary <string, ComplexEntity> entities = new SortedDictionary <string, ComplexEntity>();

            for (int i = 0; i < 100; i++)
            {
                ComplexEntity insertEntity = new ComplexEntity("insert test" + format.ToString(), "foo" + format.ToString() + i);
                entities.Add(insertEntity.RowKey, insertEntity);
                ctx.AddObject(currentTable.Name, insertEntity);
            }

            DataServiceResponse response = ctx.SaveChangesWithRetries(SaveChangesOptions.Batch);

            Assert.AreEqual((int)HttpStatusCode.Accepted, response.BatchStatusCode);

            // Retrieve Entities
            List <ComplexEntity> retrievedEntities = (from ent in ctx.CreateQuery <ComplexEntity>(currentTable.Name)
                                                      where ent.PartitionKey == entities.First().Value.PartitionKey
                                                      select ent).AsTableServiceQuery(ctx).Execute().ToList();

            Assert.AreEqual(entities.Count, retrievedEntities.Count);

            foreach (ComplexEntity retrievedEntity in retrievedEntities)
            {
                ComplexEntity.AssertEquality(entities[retrievedEntity.RowKey], retrievedEntity);
                entities.Remove(retrievedEntity.RowKey);
            }

            Assert.AreEqual(0, entities.Count);
        }
        private void DoListTablesSegmentedWithPrefixSync(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();

            tableClient.PayloadFormat = format;

            TableResultSegment segment      = null;
            List <CloudTable>  totalResults = new List <CloudTable>();

            int segCount = 0;

            do
            {
                segment = tableClient.ListTablesSegmented(prefixTablesPrefix, null, segment != null ? segment.ContinuationToken : null, null, null);
                totalResults.AddRange(segment);
                segCount++;
            }while (segment.ContinuationToken != null);

            Assert.AreEqual(totalResults.Count, 20);
            foreach (CloudTable tbl in totalResults)
            {
                Assert.IsTrue(tbl.Name.StartsWith(prefixTablesPrefix));
            }
        }
Пример #17
0
        private void DoSingleEntityInsertEntityOver1MB(TablePayloadFormat format)
        {
            CloudTableClient    tableClient = GenerateCloudTableClient();
            TableServiceContext ctx         = tableClient.GetTableServiceContext();

            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

            // Insert Entity
            ComplexEntity insertEntity = new ComplexEntity("insert test", "foo");

            insertEntity.Binary = new byte[1024 * 1024];
            ctx.AddObject(currentTable.Name, insertEntity);
            OperationContext opContext = new OperationContext();

            try
            {
                ctx.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext);
                Assert.Fail();
            }
            catch (StorageException)
            {
                TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "EntityTooLarge" }, "The entity is larger than the maximum allowed size (1MB).");
            }
        }
        private async Task DoTableQueryEmptyValueAsync(TablePayloadFormat format)
        {
            CloudTableClient client = GenerateCloudTableClient();
            client.DefaultRequestOptions.PayloadFormat = format;

            CloudTable table = client.GetTableReference(GenerateRandomTableName());
            await table.CreateAsync();

            // Setup
            string pk = Guid.NewGuid().ToString();

            DynamicTableEntity dynEnt = new DynamicTableEntity(pk, "rowkey");
            dynEnt.Properties.Add("A", new EntityProperty(string.Empty));
            await table.ExecuteAsync(TableOperation.Insert(dynEnt));

            // 1. Filter on String
            List<DynamicTableEntity> results = (await table.ExecuteQuerySegmentedAsync(new TableQuery().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty)), null)).ToList();
            Assert.AreEqual(1, results.Count);

            List<BaseEntity> pocoresults = (await table.ExecuteQuerySegmentedAsync(new TableQuery<BaseEntity>().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty)), null)).ToList();
            Assert.AreEqual(1, pocoresults.Count);
        }
        internal static StorageRequestMessage BuildRequestForTableBatchOperation <T>(RESTCommand <T> cmd, Uri uri, UriQueryBuilder builder, int?timeout, string tableName, TableBatchOperation batch, CloudTableClient client, HttpContent content, OperationContext ctx, TablePayloadFormat payloadFormat, ICanonicalizer canonicalizer, StorageCredentials credentials)
        {
            StorageRequestMessage msg = BuildRequestCore(NavigationHelper.AppendPathToSingleUri(uri, "$batch"), builder, HttpMethod.Post, timeout, content, ctx, canonicalizer, credentials);

            Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat);



            MultiBufferMemoryStream batchContentStream = new MultiBufferMemoryStream(client.BufferManager);

            string batchID     = Guid.NewGuid().ToString();
            string changesetID = Guid.NewGuid().ToString();

            using (StreamWriter contentWriter = new StreamWriter(new NonCloseableStream(batchContentStream)))
            {
                msg.Headers.Add(Constants.HeaderConstants.DataServiceVersion, Constants.HeaderConstants.DataServiceVersionValue);

                string batchSeparator     = Constants.BatchSeparator + batchID;
                string changesetSeparator = Constants.ChangesetSeparator + changesetID;
                string acceptHeader       = "Accept: ";

                switch (payloadFormat)
                {
                case TablePayloadFormat.Json:
                    acceptHeader = acceptHeader + Constants.JsonLightAcceptHeaderValue;
                    break;

                case TablePayloadFormat.JsonFullMetadata:
                    acceptHeader = acceptHeader + Constants.JsonFullMetadataAcceptHeaderValue;
                    break;

                case TablePayloadFormat.JsonNoMetadata:
                    acceptHeader = acceptHeader + Constants.JsonNoMetadataAcceptHeaderValue;
                    break;
                }

                contentWriter.WriteLine(batchSeparator);

                bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve;

                // Query operations should not be inside changeset in payload
                if (!isQuery)
                {
                    // Start Operation
                    contentWriter.WriteLine(Constants.ChangesetBoundaryMarker + changesetID);
                    contentWriter.WriteLine();
                }

                foreach (TableOperation operation in batch)
                {
                    string httpMethod = operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge ? "MERGE" : operation.HttpMethod.Method;

                    if (!isQuery)
                    {
                        contentWriter.WriteLine(changesetSeparator);
                    }

                    contentWriter.WriteLine(Constants.ContentTypeApplicationHttp);
                    contentWriter.WriteLine(Constants.ContentTransferEncodingBinary);
                    contentWriter.WriteLine();

                    string tableURI = Uri.EscapeUriString(operation.GenerateRequestURI(uri, tableName).ToString());

                    // "EscapeUriString" is almost exactly what we need, except that it contains special logic for
                    // the percent sign, which results in an off-by-one error in the number of times "%" is encoded.
                    // This corrects for that.
                    tableURI = tableURI.Replace(@"%25", @"%");

                    contentWriter.WriteLine(httpMethod + " " + tableURI + " " + Constants.HTTP1_1);
                    contentWriter.WriteLine(acceptHeader);
                    contentWriter.WriteLine(Constants.ContentTypeApplicationJson);

                    if (operation.OperationType == TableOperationType.Insert)
                    {
                        contentWriter.WriteLine(Constants.HeaderConstants.Prefer + @": " + (operation.EchoContent ? Constants.HeaderConstants.PreferReturnContent : Constants.HeaderConstants.PreferReturnNoContent));
                    }

                    contentWriter.WriteLine(Constants.HeaderConstants.DataServiceVersion + ": " + Constants.HeaderConstants.DataServiceVersionValue);

                    // etag
                    if (operation.OperationType == TableOperationType.Delete ||
                        operation.OperationType == TableOperationType.Replace ||
                        operation.OperationType == TableOperationType.Merge)
                    {
                        contentWriter.WriteLine(Constants.HeaderConstants.IfMatch + @": " + operation.ETag);
                    }

                    contentWriter.WriteLine();

                    if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve)
                    {
                        using (JsonTextWriter jsonWriter = new JsonTextWriter(contentWriter))
                        {
                            jsonWriter.CloseOutput = false;
                            WriteEntityContent(operation, ctx, jsonWriter);
                        }
                        contentWriter.WriteLine();
                    }
                }

                if (!isQuery)
                {
                    contentWriter.WriteLine(changesetSeparator + "--");
                }

                contentWriter.WriteLine(batchSeparator + "--");
            }

            batchContentStream.Seek(0, SeekOrigin.Begin);
            msg.Content = new StreamContent(batchContentStream);
            msg.Content.Headers.ContentLength = batchContentStream.Length;
            msg.Content.Headers.ContentType   = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(Constants.BatchBoundaryMarker + batchID);//new System.Net.Http.Headers.MediaTypeHeaderValue(Constants.BatchBoundaryMarker + batchID);

            return(msg);
        }
 private static void SetAcceptHeaderForHttpWebRequest(StorageRequestMessage msg, TablePayloadFormat payloadFormat)
 {
     if (payloadFormat == TablePayloadFormat.JsonFullMetadata)
     {
         msg.Headers.Add(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonFullMetadataAcceptHeaderValue);
     }
     else if (payloadFormat == TablePayloadFormat.Json)
     {
         msg.Headers.Add(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonLightAcceptHeaderValue);
     }
     else if (payloadFormat == TablePayloadFormat.JsonNoMetadata)
     {
         msg.Headers.Add(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonNoMetadataAcceptHeaderValue);
     }
 }
        private void DoListTablesWithPrefixExtended(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();

            tableClient.PayloadFormat = format;

            int    NumTables       = 50;
            int    TableNameLength = 8;
            int    NumQueries      = 100;
            string alpha           = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string numerics        = "0123456789";
            string legalChars      = alpha + numerics;

            string            queryString = string.Empty;
            List <CloudTable> tableList   = new List <CloudTable>();
            List <CloudTable> localTestCreatedTableList = new List <CloudTable>();

            Random rand = new Random();

            try
            {
                #region Generate Tables

                // Generate Tables in Storage
                // This will generate all caps Tables, i.e. AAAAAAAA, BBBBBBBB....
                for (int h = 26; h < alpha.Length; h++)
                {
                    string tString = string.Empty;
                    for (int i = 0; i < TableNameLength; i++)
                    {
                        tString += alpha[h];
                    }

                    CloudTable table = tableClient.GetTableReference(tString);

                    if (table.CreateIfNotExists())
                    {
                        tableList.Add(table);
                        localTestCreatedTableList.Add(table);
                    }
                }

                // Generate some random tables of TableNameLength, table must start with a letter
                for (int m = 0; m < NumTables; m++)
                {
                    string tableName = GenerateRandomStringFromCharset(1, alpha, rand).ToLower() +
                                       GenerateRandomStringFromCharset(TableNameLength - 1, legalChars, rand).ToLower();

                    CloudTable table = tableClient.GetTableReference(tableName);

                    if (table.CreateIfNotExists())
                    {
                        tableList.Add(table);
                        localTestCreatedTableList.Add(table);
                    }
                }

                #endregion

                #region Generate Query Strings to cover all boundary conditions
                List <string> queryStrings = new List <string>()
                {
                    String.Empty, "aa", "zz", "az", "Az", "Aa", "zZ", "AA", "ZZ", "AZ", "z9", "a9", "aaa"
                };
                for (int k = 0; k < legalChars.Length; k++)
                {
                    queryStrings.Add(legalChars[k].ToString());
                }

                for (int n = 0; n <= NumQueries; n++)
                {
                    queryStrings.Add(GenerateRandomStringFromCharset((n % TableNameLength) + 1, legalChars, rand));
                }
                #endregion

                #region Merge Created Tables With Pre-existing ones
                int totalTables = 0;
                foreach (CloudTable listedTable in tableClient.ListTables())
                {
                    totalTables++;
                    if (tableList.Where((tbl) => tbl.Uri == listedTable.Uri).FirstOrDefault() != null)
                    {
                        continue;
                    }

                    tableList.Add(listedTable);
                }

                Assert.AreEqual(tableList.Count, totalTables);
                #endregion

                List <CloudTable> serviceResult = null;
                List <CloudTable> LINQResult    = null;

                try
                {
                    foreach (string queryValue in queryStrings)
                    {
                        queryString = queryValue;

                        serviceResult = tableClient.ListTables(queryString).OrderBy((table) => table.Name).ToList();
                        LINQResult    = tableList.Where((table) => table.Name.ToLower().StartsWith(queryString.ToLower())).OrderBy((table) => table.Name).ToList();

                        Assert.AreEqual(serviceResult.Count(), LINQResult.Count());

                        for (int listDex = 0; listDex < serviceResult.Count(); listDex++)
                        {
                            Assert.AreEqual(serviceResult[listDex].Name, LINQResult[listDex].Name);
                        }
                    }
                }
                catch (Exception)
                {
                    // On exception log table names for repro
                    this.testContextInstance.WriteLine("Exception in ListTablesWithPrefix, Dumping Tables for repro. QueryString = {0}\r\n", queryString);

                    foreach (CloudTable table in tableList)
                    {
                        this.testContextInstance.WriteLine(table.Name);
                    }

                    this.testContextInstance.WriteLine("Linq results =======================");

                    foreach (CloudTable table in LINQResult)
                    {
                        this.testContextInstance.WriteLine(table.Name);
                    }

                    this.testContextInstance.WriteLine("Service results =======================");

                    foreach (CloudTable table in serviceResult)
                    {
                        this.testContextInstance.WriteLine(table.Name);
                    }
                    throw;
                }
            }
            finally
            {
                // Cleanup
                foreach (CloudTable table in localTestCreatedTableList)
                {
                    // Dont delete Class level tables
                    if (createdTables.Where((tbl) => tbl.Uri == table.Uri).FirstOrDefault() != null)
                    {
                        continue;
                    }

                    // Delete other tables
                    table.DeleteIfExists();
                }
            }
        }
 private static void SetAcceptAndContentTypeForODataBatchMessage(ODataBatchOperationRequestMessage mimePartMsg, TablePayloadFormat payloadFormat)
 {
     if (payloadFormat == TablePayloadFormat.AtomPub)
     {
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.AtomAcceptHeaderValue);
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.AtomContentTypeHeaderValue);
     }
     else if (payloadFormat == TablePayloadFormat.JsonFullMetadata)
     {
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonFullMetadataAcceptHeaderValue);
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue);
     }
     else if (payloadFormat == TablePayloadFormat.Json)
     {
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonLightAcceptHeaderValue);
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue);
     }
     else
     {
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonNoMetadataAcceptHeaderValue);
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue);
     }
 }
 private static void SetContentTypeForHttpWebRequest(HttpWebRequest msg, TablePayloadFormat payloadFormat)
 {
     if (payloadFormat == TablePayloadFormat.AtomPub)
     {
         msg.ContentType = Constants.AtomContentTypeHeaderValue;
     }
     else
     {
         msg.ContentType = Constants.JsonContentTypeHeaderValue;
     }
 }
        private void DoCloudTableDeleteIfExistsSync(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            tableClient.PayloadFormat = format;
            string tableName = GenerateRandomTableName();
            CloudTable tableRef = tableClient.GetTableReference(tableName);

            try
            {
                Assert.IsFalse(tableRef.Exists());
                Assert.IsFalse(tableRef.DeleteIfExists());
                tableRef.Create();
                Assert.IsTrue(tableRef.Exists());
                Assert.IsTrue(tableRef.DeleteIfExists());
                Assert.IsFalse(tableRef.DeleteIfExists());
            }
            finally
            {
                tableRef.DeleteIfExists();
            }
        }
Пример #25
0
 private static void SetAcceptAndContentTypeForODataBatchMessage(ODataBatchOperationRequestMessage mimePartMsg, TablePayloadFormat payloadFormat)
 {
     if (payloadFormat == TablePayloadFormat.AtomPub)
     {
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.AtomAcceptHeaderValue);
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.AtomContentTypeHeaderValue);
     }
     else if (payloadFormat == TablePayloadFormat.JsonFullMetadata)
     {
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonFullMetadataAcceptHeaderValue);
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue);
     }
     else if (payloadFormat == TablePayloadFormat.Json)
     {
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonLightAcceptHeaderValue);
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue);
     }
     else
     {
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonNoMetadataAcceptHeaderValue);
         mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue);
     }
 }
Пример #26
0
        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);

            // Start Batch
            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()));
        }
Пример #27
0
        public static void SetPayloadFormatOnDataServiceContext(TableServiceContext ctx, TablePayloadFormat format, CloudTableClient tableClient)
        {
#pragma warning disable 0618
            if (format == TablePayloadFormat.AtomPub)
#pragma warning restore 0618
            {
                ctx.Format.UseAtom();
            }
            else
            {
                ctx.Format.UseJson(new TableStorageModel(tableClient.Credentials.AccountName));
            }
        }
        private void DoBatchInsert(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            TableServiceContext ctx = tableClient.GetTableServiceContext();
            SetPayloadFormatOnDataServiceContext(ctx, format, tableClient);

            // Insert Entities
            SortedDictionary<string, ComplexEntity> entities = new SortedDictionary<string, ComplexEntity>();
            for (int i = 0; i < 100; i++)
            {
                ComplexEntity insertEntity = new ComplexEntity("insert test" + format.ToString(), "foo" + format.ToString() + i);
                entities.Add(insertEntity.RowKey, insertEntity);
                ctx.AddObject(currentTable.Name, insertEntity);
            }

            DataServiceResponse response = ctx.SaveChangesWithRetries(SaveChangesOptions.Batch);
            Assert.AreEqual((int)HttpStatusCode.Accepted, response.BatchStatusCode);

            // Retrieve Entities
            List<ComplexEntity> retrievedEntities = (from ent in ctx.CreateQuery<ComplexEntity>(currentTable.Name)
                                                     where ent.PartitionKey == entities.First().Value.PartitionKey
                                                     select ent).AsTableServiceQuery(ctx).Execute().ToList();

            Assert.AreEqual(entities.Count, retrievedEntities.Count);

            foreach (ComplexEntity retrievedEntity in retrievedEntities)
            {
                ComplexEntity.AssertEquality(entities[retrievedEntity.RowKey], retrievedEntity);
                entities.Remove(retrievedEntity.RowKey);
            }

            Assert.AreEqual(0, entities.Count);
        }
        internal static StorageRequestMessage BuildRequestForTableOperation <T>(RESTCommand <T> cmd, Uri uri, UriQueryBuilder builder, int?timeout, TableOperation operation, CloudTableClient client, HttpContent content, OperationContext ctx, TablePayloadFormat payloadFormat, ICanonicalizer canonicalizer, StorageCredentials credentials)
        {
            StorageRequestMessage msg = BuildRequestCore(uri, builder, operation.HttpMethod, timeout, content, ctx, canonicalizer, credentials);

            // Set Accept and Content-Type based on the payload format.
            SetAcceptHeaderForHttpWebRequest(msg, payloadFormat);
            Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat);

            if (!operation.HttpMethod.Equals("HEAD") && !operation.HttpMethod.Equals("GET"))
            {
                SetContentTypeForHttpWebRequest(msg);
            }

            if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge)
            {
                // post tunnelling
                msg.Headers.Add("X-HTTP-Method", "MERGE");
            }

            // etag
            if (operation.OperationType == TableOperationType.Delete ||
                operation.OperationType == TableOperationType.Replace ||
                operation.OperationType == TableOperationType.Merge)
            {
                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
                };

                HttpRequestAdapterMessage adapterMsg = new HttpRequestAdapterMessage(msg, client.BufferManager, (int)Constants.KB);
                if (!operation.HttpMethod.Equals("HEAD") && !operation.HttpMethod.Equals("GET"))
                {
                    adapterMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue);
                }

                cmd.StreamToDispose = adapterMsg.GetStream();

                ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings, new TableStorageModel(client.AccountName));
                ODataWriter        writer      = odataWriter.CreateODataEntryWriter();
                WriteOdataEntity(operation.Entity, operation.OperationType, ctx, writer);

                return(adapterMsg.GetPopulatedMessage());
            }

            return(msg);
        }
        internal static StorageRequestMessage BuildRequestForTableQuery(Uri uri, UriQueryBuilder builder, int?timeout, HttpContent content, OperationContext ctx, TablePayloadFormat payloadFormat, ICanonicalizer canonicalizer, StorageCredentials credentials)
        {
            StorageRequestMessage msg = BuildRequestCore(uri, builder, HttpMethod.Get, timeout, content, ctx, canonicalizer, credentials);

            // Set Accept and Content-Type based on the payload format.
            SetAcceptHeaderForHttpWebRequest(msg, payloadFormat);
            Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat);
            return(msg);
        }
        private void DoTableQueryWithInvalidTakeCount(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;
            try
            {
                TableQuery query = new TableQuery().Take(0);
                Assert.Fail();
            }
            catch (ArgumentException ex)
            {
                Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0.");
            }
            catch (Exception)
            {
                Assert.Fail();
            }

            try
            {
                TableQuery query = new TableQuery().Take(-1);
                Assert.Fail();
            }
            catch (ArgumentException ex)
            {
                Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0.");
            }
            catch (Exception)
            {
                Assert.Fail();
            }
        }
Пример #32
0
        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));
        }
        private void DoCloudTableDeleteWhenNotExistSync(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            tableClient.PayloadFormat = format;
            string tableName = GenerateRandomTableName();
            CloudTable tableRef = tableClient.GetTableReference(tableName);
            OperationContext ctx = new OperationContext();

            try
            {
                Assert.IsFalse(tableRef.Exists());

                // This should throw with no retries               
                tableRef.Delete(null, ctx);
                Assert.Fail();
            }
            catch (StorageException ex)
            {
                Assert.AreEqual(ex.RequestInformation.HttpStatusCode, 404);
                Assert.AreEqual(ex.RequestInformation.ExtendedErrorInformation.ErrorCode, "ResourceNotFound");
                TestHelper.AssertNAttempts(ctx, 1);
            }
            finally
            {
                tableRef.DeleteIfExists();
            }
        }
        private void DoTableGenericQueryWithSpecificOnSupportedTypes(TablePayloadFormat format)
        {
            CloudTableClient client = GenerateCloudTableClient();

            CloudTable table = client.GetTableReference(GenerateRandomTableName());
            table.Create();
            client.DefaultRequestOptions.PayloadFormat = format;

            try
            {
                // Setup
                TableBatchOperation batch = new TableBatchOperation();
                string pk = Guid.NewGuid().ToString();
                ComplexEntity middleRef = null;
                for (int m = 0; m < 100; m++)
                {
                    ComplexEntity complexEntity = new ComplexEntity(pk, string.Format("{0:0000}", m));
                    complexEntity.String = string.Format("{0:0000}", m);
                    complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m };
                    complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m };
                    complexEntity.Bool = m % 2 == 0 ? true : false;
                    complexEntity.BoolPrimitive = m % 2 == 0 ? true : false;
                    complexEntity.Double = m + ((double)m / 100);
                    complexEntity.DoublePrimitive = m + ((double)m / 100);
                    complexEntity.Int32 = m;
                    complexEntity.IntegerPrimitive = m;
                    complexEntity.Int64 = (long)int.MaxValue + m;
                    complexEntity.LongPrimitive = (long)int.MaxValue + m;
                    complexEntity.Guid = Guid.NewGuid();

                    batch.Insert(complexEntity);

                    if (m == 50)
                    {
                        middleRef = complexEntity;
                    }

                    // Add delay to make times unique
                    Thread.Sleep(100);
                }

                table.ExecuteBatch(batch);

                // 1. Filter on String
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50);

                // 2. Filter on Guid
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef.Guid), 1);

                // 3. Filter on Long
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual,
                                middleRef.LongPrimitive), 50);

                ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive",
                        QueryComparisons.GreaterThanOrEqual, middleRef.LongPrimitive), 50);

                // 4. Filter on Double
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual,
                                middleRef.Double), 50);

                ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive",
                        QueryComparisons.GreaterThanOrEqual, middleRef.DoublePrimitive), 50);

                // 5. Filter on Integer
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual,
                                middleRef.Int32), 50);

                ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive",
                        QueryComparisons.GreaterThanOrEqual, middleRef.IntegerPrimitive), 50);

                // 6. Filter on Date
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual,
                                middleRef.DateTimeOffset), 50);

                // 7. Filter on Boolean
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef.Bool), 50);

                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef.BoolPrimitive),
                        50);

                // 8. Filter on Binary 
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef.Binary), 1);

                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal,
                                middleRef.BinaryPrimitive), 1);

                // 9. Filter on Binary GTE
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual,
                                middleRef.Binary), 50);

                ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive",
                        QueryComparisons.GreaterThanOrEqual, middleRef.BinaryPrimitive), 50);

                // 10. Complex Filter on Binary GTE
                ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters(
                        TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal,
                                middleRef.PartitionKey),
                        TableOperators.And,
                        TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual,
                                middleRef.Binary)), 50);

                ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive",
                        QueryComparisons.GreaterThanOrEqual, middleRef.BinaryPrimitive), 50);
            }
            finally
            {
                table.DeleteIfExists();
            }
        }
 private static void SetAcceptHeaderForHttpWebRequest(HttpWebRequest msg, TablePayloadFormat payloadFormat)
 {
     if (payloadFormat == TablePayloadFormat.AtomPub)
     {
         msg.Accept = Constants.AtomAcceptHeaderValue;
     }
     else if (payloadFormat == TablePayloadFormat.JsonFullMetadata)
     {
         msg.Accept = Constants.JsonFullMetadataAcceptHeaderValue;
     }
     else if (payloadFormat == TablePayloadFormat.Json)
     {
         msg.Accept = Constants.JsonLightAcceptHeaderValue;
     }
     else if (payloadFormat == TablePayloadFormat.JsonNoMetadata)
     {
         msg.Accept = Constants.JsonNoMetadataAcceptHeaderValue;
     }
 }
        internal static StorageRequestMessage BuildRequestForTableOperation <T>(RESTCommand <T> cmd, Uri uri, UriQueryBuilder builder, int?timeout, TableOperation operation, CloudTableClient client, HttpContent content, OperationContext ctx, TablePayloadFormat payloadFormat, ICanonicalizer canonicalizer, StorageCredentials credentials)
        {
            StorageRequestMessage msg = BuildRequestCore(uri, builder, operation.HttpMethod, timeout, content, ctx, canonicalizer, credentials);

            // Set Accept and Content-Type based on the payload format.
            SetAcceptHeaderForHttpWebRequest(msg, payloadFormat);
            Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat);

            msg.Headers.Add(Constants.HeaderConstants.DataServiceVersion, Constants.HeaderConstants.DataServiceVersionValue);

            if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge)
            {
                // post tunnelling
                msg.Headers.Add(Constants.HeaderConstants.PostTunnelling, "MERGE");
            }

            // etag
            if (operation.OperationType == TableOperationType.Delete ||
                operation.OperationType == TableOperationType.Replace ||
                operation.OperationType == TableOperationType.Merge)
            {
                msg.Headers.Add(Constants.HeaderConstants.IfMatch, operation.ETag);
            }

            // Prefer header
            if (operation.OperationType == TableOperationType.Insert)
            {
                msg.Headers.Add(Constants.HeaderConstants.Prefer, operation.EchoContent ? Constants.HeaderConstants.PreferReturnContent : Constants.HeaderConstants.PreferReturnNoContent);
            }

            if (operation.OperationType == TableOperationType.Insert ||
                operation.OperationType == TableOperationType.Merge ||
                operation.OperationType == TableOperationType.InsertOrMerge ||
                operation.OperationType == TableOperationType.InsertOrReplace ||
                operation.OperationType == TableOperationType.Replace)
            {
                MultiBufferMemoryStream ms = new MultiBufferMemoryStream(client.BufferManager);
                using (JsonTextWriter jsonWriter = new JsonTextWriter(new StreamWriter(new NonCloseableStream(ms))))
                {
                    WriteEntityContent(operation, ctx, jsonWriter);
                }

                ms.Seek(0, SeekOrigin.Begin);
                msg.Content = new StreamContent(ms);
                msg.Content.Headers.ContentLength = ms.Length;
                if (!operation.HttpMethod.Equals("HEAD") && !operation.HttpMethod.Equals("GET"))
                {
                    SetContentTypeForHttpWebRequest(msg);
                }
                return(msg);
            }

            return(msg);
        }
 private static void SetContentTypeForAdapterMessage(HttpWebRequestAdapterMessage adapterMsg, TablePayloadFormat payloadFormat)
 {
     if (payloadFormat == TablePayloadFormat.AtomPub)
     {
         adapterMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.AtomContentTypeHeaderValue);
     }
     else
     {
         adapterMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue);
     }
 }
        private void DoTableGenericQueryEnumerateTwice(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;

            TableQuery<BaseEntity> query = new TableQuery<BaseEntity>();

            OperationContext opContext = new OperationContext();
            IEnumerable<BaseEntity> enumerable = currentTable.ExecuteQuery(query);

            List<BaseEntity> firstIteration = new List<BaseEntity>();
            List<BaseEntity> secondIteration = new List<BaseEntity>();

            foreach (BaseEntity ent in enumerable)
            {
                Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch"));
                ent.Validate();
                firstIteration.Add(ent);
            }

            foreach (BaseEntity ent in enumerable)
            {
                Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch"));
                ent.Validate();
                secondIteration.Add(ent);
            }

            Assert.AreEqual(firstIteration.Count, secondIteration.Count);

            for (int m = 0; m < firstIteration.Count; m++)
            {
                Assert.AreEqual(firstIteration[m].PartitionKey, secondIteration[m].PartitionKey);
                Assert.AreEqual(firstIteration[m].RowKey, secondIteration[m].RowKey);
                Assert.AreEqual(firstIteration[m].Timestamp, secondIteration[m].Timestamp);
                Assert.AreEqual(firstIteration[m].ETag, secondIteration[m].ETag);
                firstIteration[m].Validate();
            }
        }
        internal static Tuple <HttpWebRequest, Stream> BuildRequestForTableOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int?timeout, TableOperation operation, bool useVersionHeader, OperationContext ctx, TableRequestOptions options)
        {
            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);

            msg.Headers.Add(Constants.HeaderConstants.DataServiceVersion, Constants.HeaderConstants.DataServiceVersionValue);
            if (operation.HttpMethod != "HEAD" && operation.HttpMethod != "GET")
            {
                msg.ContentType = Constants.JsonContentTypeHeaderValue;
            }

            if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge)
            {
                // Client-side encryption is not supported on merge requests.
                // This is because we maintain the list of encrypted properties as a property on the entity, and we can't update this
                // properly for merge operations.
                options.AssertNoEncryptionPolicyOrStrictMode();

                // post tunnelling
                msg.Headers.Add(Constants.HeaderConstants.PostTunnelling, "MERGE");
            }

            if (operation.OperationType == TableOperationType.RotateEncryptionKey)
            {
                // post tunnelling
                msg.Headers.Add(Constants.HeaderConstants.PostTunnelling, "MERGE");
            }

            // etag
            if (operation.OperationType == TableOperationType.Delete ||
                operation.OperationType == TableOperationType.Replace ||
                operation.OperationType == TableOperationType.Merge ||
                operation.OperationType == TableOperationType.RotateEncryptionKey)
            {
                if (operation.ETag != null)
                {
                    msg.Headers.Add(Constants.HeaderConstants.IfMatch, operation.ETag);
                }
            }

            // Prefer header
            if (operation.OperationType == TableOperationType.Insert)
            {
                msg.Headers.Add(Constants.HeaderConstants.Prefer, operation.EchoContent ? Constants.HeaderConstants.PreferReturnContent : Constants.HeaderConstants.PreferReturnNoContent);
            }

            if (operation.OperationType == TableOperationType.Insert ||
                operation.OperationType == TableOperationType.Merge ||
                operation.OperationType == TableOperationType.InsertOrMerge ||
                operation.OperationType == TableOperationType.InsertOrReplace ||
                operation.OperationType == TableOperationType.Replace ||
                operation.OperationType == TableOperationType.RotateEncryptionKey)
            {
                MultiBufferMemoryStream ms = new MultiBufferMemoryStream(bufferManager);
                using (JsonTextWriter jsonWriter = new JsonTextWriter(new StreamWriter(new NonCloseableStream(ms))))
                {
                    WriteEntityContent(operation, ctx, options, jsonWriter);
                }

                ms.Seek(0, SeekOrigin.Begin);
                msg.ContentLength = ms.Length;
                return(new Tuple <HttpWebRequest, Stream>(msg, ms));
            }

            return(new Tuple <HttpWebRequest, Stream>(msg, null));
        }
        public void DoTableGenericQueryProjectionWithSpecialCases(CloudTable table, TablePayloadFormat format, bool disableCompiledSerializers)
        {
            table.ServiceClient.DefaultRequestOptions.PayloadFormat = format;
            BaseEntity.DisableCompiledSerializers = disableCompiledSerializers;

            // Query on A, B, and E
            TableQuery<BaseEntity> query = new TableQuery<BaseEntity>().Select(new List<string>() { "A", "B", "E" });
            IEnumerable<BaseEntity> entities = table.ExecuteQuery(query, null);

            // Verify A has a set value and B and E have type defaults
            Assert.AreEqual(1, entities.Count());
            BaseEntity entity = entities.First();
            Assert.AreEqual("a", entity.A);
            Assert.IsNull(entity.B);
            Assert.AreEqual(0, entity.E);      
        }
        private async Task DoListTablesSegmentedBasicAsync(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            tableClient.PayloadFormat = format;
            TableResultSegment segment = null;
            List<CloudTable> totalResults = new List<CloudTable>();

            do
            {
                segment = await tableClient.ListTablesSegmentedAsync(segment != null ? segment.ContinuationToken : null, CancellationToken.None);
                totalResults.AddRange(segment);
            }
            while (segment.ContinuationToken != null);

            // Assert.AreEqual(totalResults.Count, tableClient.ListTables().Count());
        }
        internal static StorageRequestMessage BuildRequestForTableBatchOperation <T>(RESTCommand <T> cmd, Uri uri, UriQueryBuilder builder, int?timeout, string tableName, TableBatchOperation batch, CloudTableClient client, HttpContent content, OperationContext ctx, TablePayloadFormat payloadFormat, ICanonicalizer canonicalizer, StorageCredentials credentials)
        {
            StorageRequestMessage msg = BuildRequestCore(NavigationHelper.AppendPathToSingleUri(uri, "$batch"), builder, HttpMethod.Post, timeout, content, ctx, canonicalizer, credentials);

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

            HttpRequestAdapterMessage adapterMsg = new HttpRequestAdapterMessage(msg, client.BufferManager, 64 * (int)Constants.KB);

            cmd.StreamToDispose = adapterMsg.GetStream();

            // Start Batch
            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.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge ? "MERGE" : operation.HttpMethod.Method;

                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(client.AccountName)))
                    {
                        // Write entity
                        ODataWriter entryWriter = batchEntryWriter.CreateODataEntryWriter();
                        WriteOdataEntity(operation.Entity, operation.OperationType, ctx, entryWriter);
                    }
                }
            }

            if (!isQuery)
            {
                // End Operation
                batchWriter.WriteEndChangeset();
            }

            // End Batch
            batchWriter.WriteEndBatch();
            batchWriter.Flush();

            return(adapterMsg.GetPopulatedMessage());
        }
Пример #43
0
 private static void SetContentTypeForAdapterMessage(HttpWebRequestAdapterMessage adapterMsg, TablePayloadFormat payloadFormat)
 {
     if (payloadFormat == TablePayloadFormat.AtomPub)
     {
         adapterMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.AtomContentTypeHeaderValue);
     }
     else
     {
         adapterMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue);
     }
 }
        private async Task DoListTablesSegmentedWithPrefixAsync(TablePayloadFormat format)
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            tableClient.PayloadFormat = format;

            TableResultSegment segment = null;
            List<CloudTable> totalResults = new List<CloudTable>();

            int segCount = 0;
            do
            {
                segment = await tableClient.ListTablesSegmentedAsync(prefixTablesPrefix, null, segment != null ? segment.ContinuationToken : null, null, null);
                totalResults.AddRange(segment);
                segCount++;
            }
            while (segment.ContinuationToken != null);

            Assert.AreEqual(totalResults.Count, 20);
            foreach (CloudTable tbl in totalResults)
            {
                Assert.IsTrue(tbl.Name.StartsWith(prefixTablesPrefix));
            }
        }
Пример #45
0
        internal static HttpWebRequest BuildRequestForTableQuery(Uri uri, UriQueryBuilder builder, int?timeout, bool useVersionHeader, OperationContext ctx, TablePayloadFormat payloadFormat)
        {
            HttpWebRequest msg = BuildRequestCore(uri, builder, "GET", timeout, useVersionHeader, ctx);

            // Set Accept and Content-Type based on the payload format.
            SetAcceptHeaderForHttpWebRequest(msg, payloadFormat);
            Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat);
            return(msg);
        }
        private void DoTableQueryGenericWithTakeCount(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;

            // No continuation
            TableQuery<BaseEntity> query = new TableQuery<BaseEntity>().Take(100);

            OperationContext opContext = new OperationContext();
            IEnumerable<BaseEntity> enumerable = currentTable.ExecuteQuery(query, null, opContext);

            Assert.AreEqual(query.TakeCount, enumerable.Count());
            TestHelper.AssertNAttempts(opContext, 1);


            // With continuations
            query.TakeCount = 1200;
            opContext = new OperationContext();
            enumerable = currentTable.ExecuteQuery(query, null, opContext);

            Assert.AreEqual(query.TakeCount, enumerable.Count());
            TestHelper.AssertNAttempts(opContext, 2);

            foreach (BaseEntity entity in enumerable)
            {
                entity.Validate();
            }
        }
        private void DoTableQuerySegmentedResolverWithDynamic(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;

            TableRequestOptions options = new TableRequestOptions()
            {
                PropertyResolver = (pk, rk, propName, propValue) => BaseEntity.BaseEntityPropertyResolver(pk, rk, propName, propValue)
            };

            TableQuery query = new TableQuery().Select(new List<string>() { "A", "C", "E" });
            TableContinuationToken token = null;
            List<string> list = new List<string>();
            do
            {
                TableQuerySegment<string> segment = currentTable.ExecuteQuerySegmented<string>(query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue + prop["E"].Int32Value, token, options, null);
                list.AddRange(segment.Results);
                token = segment.ContinuationToken;
            } while (token != null);

            foreach (string ent in list)
            {
                Assert.AreEqual(ent, "ac" + 1234);
            }

            List<BaseEntity> list1 = new List<BaseEntity>();
            do
            {
                TableQuerySegment<BaseEntity> segment = currentTable.ExecuteQuerySegmented<BaseEntity>(query, (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, E = prop["E"].Int32Value.Value, ETag = etag }, token, options, null);
                list1.AddRange(segment.Results);
                token = segment.ContinuationToken;
            } while (token != null);

            foreach (BaseEntity ent in list1)
            {
                Assert.IsNotNull(ent.PartitionKey);
                Assert.IsNotNull(ent.RowKey);
                Assert.IsNotNull(ent.Timestamp);
                Assert.IsNotNull(ent.ETag);

                Assert.AreEqual(ent.A, "a");
                Assert.IsNull(ent.B);
                Assert.AreEqual(ent.C, "c");
                Assert.IsNull(ent.D);
                Assert.AreEqual(ent.E, 1234);
            }
        }
        private void DoTableGenericQueryWithInternalType(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;

            TableQuery<InternalEntity> query = new TableQuery<InternalEntity>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1"));

            TableQuerySegment<InternalEntity> seg = currentTable.ExecuteQuerySegmented(query, null);

            foreach (InternalEntity ent in seg)
            {
                Assert.AreEqual(ent.PartitionKey, "tables_batch_1");
                ent.Validate();
            }
        }
        private void DoTableGenericQueryComplexWithoutPropertyResolverSync(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;
            CloudTable currentTestTable = tableClient.GetTableReference("tbl" + Guid.NewGuid().ToString("N"));
            try
            {
                currentTestTable.CreateIfNotExists();

                ComplexEntity ent = new ComplexEntity("tables_batch_1", Guid.NewGuid().ToString());
                currentTestTable.Execute(TableOperation.Insert(ent));

                TableQuery<ComplexEntity> query = new TableQuery<ComplexEntity>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1"));

                TableQuerySegment<ComplexEntity> seg = currentTestTable.ExecuteQuerySegmented(query, null);

                foreach (ComplexEntity retrievedEnt in seg)
                {
                    Assert.AreEqual(retrievedEnt.PartitionKey, "tables_batch_1");
                    ComplexEntity.AssertEquality(ent, retrievedEnt);
                }
            }
            finally
            {
                currentTestTable.DeleteIfExists();
            }
        }
        private void DoTableGenericQueryWithContinuationSync(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;

            TableQuery<BaseEntity> query = new TableQuery<BaseEntity>();

            OperationContext opContext = new OperationContext();
            TableQuerySegment<BaseEntity> seg = currentTable.ExecuteQuerySegmented(query, null, null, opContext);

            int count = 0;
            foreach (BaseEntity ent in seg)
            {
                Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch"));
                ent.Validate();
                count++;
            }

            // Second segment
            Assert.IsNotNull(seg.ContinuationToken);
            seg = currentTable.ExecuteQuerySegmented(query, seg.ContinuationToken, null, opContext);

            foreach (BaseEntity ent in seg)
            {
                Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch"));
                ent.Validate();
                count++;
            }

            Assert.AreEqual(1500, count);
            TestHelper.AssertNAttempts(opContext, 2);
        }
        private void DoTableQueryGenericWithTakeCountAndResolver(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;

            // No continuation
            TableQuery<BaseEntity> query = new TableQuery<BaseEntity>().Take(100);

            OperationContext opContext = new OperationContext();
            IEnumerable<string> enumerable = currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => pk + rk, null, opContext);

            Assert.AreEqual(query.TakeCount, enumerable.Count());
            TestHelper.AssertNAttempts(opContext, 1);

            // With continuations
            query.TakeCount = 1200;
            opContext = new OperationContext();
            enumerable = currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => pk + rk, null, opContext);

            Assert.AreEqual(query.TakeCount, enumerable.Count());
            TestHelper.AssertNAttempts(opContext, 2);
        }
        private async Task DoTableQueryBasicAsync(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;
            TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1"));

            TableQuerySegment<DynamicTableEntity> seg = await currentTable.ExecuteQuerySegmentedAsync(query, null);

            foreach (DynamicTableEntity ent in seg)
            {
                Assert.AreEqual(ent.PartitionKey, "tables_batch_1");
                Assert.AreEqual(ent.Properties.Count, 4);
            }
        }
        private void DoTableGenericQueryWithInvalidQuery(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;

            TableQuery<ComplexEntity> query = new TableQuery<ComplexEntity>().Where(string.Format("(PartitionKey ) and (RowKey ge '{1}')", "tables_batch_1", "000050"));

            OperationContext opContext = new OperationContext();
            try
            {
                currentTable.ExecuteQuerySegmented(query, null, null, opContext);
                Assert.Fail();
            }
            catch (StorageException)
            {
                TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "One of the request inputs is not valid.");
            }
        }
        private async Task DoTableQueryWithContinuationAsync(TablePayloadFormat format)
        {
            TableQuery query = new TableQuery();
            tableClient.DefaultRequestOptions.PayloadFormat = format;

            OperationContext opContext = new OperationContext();
            TableQuerySegment<DynamicTableEntity> seg = await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext);

            int count = 0;
            foreach (DynamicTableEntity ent in seg)
            {
                Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch"));
                Assert.AreEqual(ent.Properties.Count, 4);
                count++;
            }

            // Second segment
            Assert.IsNotNull(seg.ContinuationToken);
            seg = await currentTable.ExecuteQuerySegmentedAsync(query, seg.ContinuationToken, null, opContext);

            foreach (DynamicTableEntity ent in seg)
            {
                Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch"));
                Assert.AreEqual(ent.Properties.Count, 4);
                count++;
            }

            Assert.AreEqual(1500, count);
            TestHelper.AssertNAttempts(opContext, 2);
        }
        private void DoTableGenericQueryWithFilter(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;
            TableQuery<BaseEntity> query = new TableQuery<BaseEntity>().Where(string.Format("(PartitionKey eq '{0}') and (RowKey ge '{1}')", "tables_batch_1", "0050"));

            OperationContext opContext = new OperationContext();
            int count = 0;

            foreach (BaseEntity ent in currentTable.ExecuteQuery(query))
            {
                Assert.AreEqual(ent.PartitionKey, "tables_batch_1");
                Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50));
                ent.Validate();
                count++;
            }

            Assert.AreEqual(count, 50);
        }
        private void DoTableQueryWithFilterAsync(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;

            TableQuery query = new TableQuery().Where(string.Format("(PartitionKey eq '{0}') and (RowKey ge '{1}')", "tables_batch_1", "0050"));
            OperationContext opContext = new OperationContext();
            int count = 0;

            foreach (DynamicTableEntity ent in ExecuteQuery(currentTable, query))
            {
                Assert.AreEqual(ent.Properties["foo"].StringValue, "bar");

                Assert.AreEqual(ent.PartitionKey, "tables_batch_1");
                Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50));
                count++;
            }

            Assert.AreEqual(count, 50);
        }
        private void DoTableGenericQueryProjectionSpecifyingSystemProperties(TablePayloadFormat format, bool projectSystemProperties)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;
            tableClient.DefaultRequestOptions.ProjectSystemProperties = projectSystemProperties;

            TableQuery<BaseEntity> query = new TableQuery<BaseEntity>().Select(new List<string>() { "A", "C", TableConstants.PartitionKey, TableConstants.Timestamp });

            foreach (BaseEntity ent in currentTable.ExecuteQuery(query))
            {
                Assert.AreEqual(ent.A, "a");
                Assert.IsNull(ent.B);
                Assert.AreEqual(ent.C, "c");
                Assert.IsNull(ent.D);
                Assert.AreEqual(ent.E, 0);
                Assert.AreNotEqual(default(string), ent.PartitionKey);
                Assert.AreNotEqual(default(DateTimeOffset), ent.Timestamp);

                if (tableClient.DefaultRequestOptions.ProjectSystemProperties.HasValue)
                {
                    Assert.AreNotEqual(tableClient.DefaultRequestOptions.ProjectSystemProperties.Value, ent.RowKey == default(string), "Missing expected " + TableConstants.RowKey);
                }
            }
        }
        private void DoTableQueryProjectionAsync(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;
            TableQuery query = new TableQuery().Select(new List<string>() { "a", "c" });

            foreach (DynamicTableEntity ent in ExecuteQuery(currentTable, query))
            {
                Assert.IsNotNull(ent.PartitionKey);
                Assert.IsNotNull(ent.RowKey);
                Assert.IsNotNull(ent.Timestamp);

                Assert.AreEqual(ent.Properties["a"].StringValue, "a");
                Assert.IsFalse(ent.Properties.ContainsKey("b"));
                Assert.AreEqual(ent.Properties["c"].StringValue, "c");
                Assert.IsFalse(ent.Properties.ContainsKey("d"));
            }
        }
        private void DoTableGenericWithResolver(TablePayloadFormat format)
        {
            tableClient.DefaultRequestOptions.PayloadFormat = format;

            TableQuery<TableEntity> query = new TableQuery<TableEntity>().Select(new List<string>() { "A", "C", "E" });
            query.TakeCount = 1000;

            TableRequestOptions options = new TableRequestOptions()
            {
                PropertyResolver = (pk, rk, propName, propValue) => BaseEntity.BaseEntityPropertyResolver(pk, rk, propName, propValue)
            };

            foreach (string ent in currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue + prop["E"].Int32Value, options, null))
            {
                Assert.AreEqual(ent, "ac" + 1234);
            }

            foreach (BaseEntity ent in currentTable.ExecuteQuery(query,
                (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, E = prop["E"].Int32Value.Value, ETag = etag }, options, null))
            {
                Assert.IsNotNull(ent.PartitionKey);
                Assert.IsNotNull(ent.RowKey);
                Assert.IsNotNull(ent.Timestamp);
                Assert.IsNotNull(ent.ETag);

                Assert.AreEqual(ent.A, "a");
                Assert.IsNull(ent.B);
                Assert.AreEqual(ent.C, "c");
                Assert.IsNull(ent.D);
                Assert.AreEqual(ent.E, 1234);
            }

            Assert.AreEqual(1000, query.TakeCount);
        }
        private async Task DoTableRegionalQueryOnSupportedTypesAsync(TablePayloadFormat format)
        {
            CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
            Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");

            CloudTableClient client = GenerateCloudTableClient();
            client.DefaultRequestOptions.PayloadFormat = format;

            CloudTable table = client.GetTableReference(GenerateRandomTableName());
            await table.CreateAsync();

            try
            {
                // Setup
                TableBatchOperation batch = new TableBatchOperation();
                string pk = Guid.NewGuid().ToString();
                DynamicTableEntity middleRef = null;
                for (int m = 0; m < 100; m++)
                {
                    ComplexEntity complexEntity = new ComplexEntity();
                    complexEntity.String = string.Format("{0:0000}", m);
                    complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m };
                    complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m };
                    complexEntity.Bool = m % 2 == 0 ? true : false;
                    complexEntity.BoolPrimitive = m % 2 == 0 ? true : false;
                    complexEntity.Double = m + ((double)m / 100);
                    complexEntity.DoublePrimitive = m + ((double)m / 100);
                    complexEntity.Int32 = m;
                    complexEntity.IntegerPrimitive = m;
                    complexEntity.Int64 = (long)int.MaxValue + m;
                    complexEntity.LongPrimitive = (long)int.MaxValue + m;
                    complexEntity.Guid = Guid.NewGuid();

                    DynamicTableEntity dynEnt = new DynamicTableEntity(pk, string.Format("{0:0000}", m));
                    dynEnt.Properties = complexEntity.WriteEntity(null);
                    batch.Insert(dynEnt);

                    if (m == 50)
                    {
                        middleRef = dynEnt;
                    }

                    // Add delay to make times unique
                    await Task.Delay(100);
                }

                await table.ExecuteBatchAsync(batch);

                // 1. Filter on String
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50);

                // 2. Filter on Guid
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef.Properties["Guid"].GuidValue.Value), 1);

                // 3. Filter on Long
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual,
                                middleRef.Properties["LongPrimitive"].Int64Value.Value), 50);

                ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive",
                        QueryComparisons.GreaterThanOrEqual, middleRef.Properties["LongPrimitive"].Int64Value.Value), 50);

                // 4. Filter on Double
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual,
                                middleRef.Properties["Double"].DoubleValue.Value), 50);

                ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive",
                        QueryComparisons.GreaterThanOrEqual, middleRef.Properties["DoublePrimitive"].DoubleValue.Value), 50);

                // 5. Filter on Integer
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual,
                                middleRef.Properties["Int32"].Int32Value.Value), 50);

                ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive",
                        QueryComparisons.GreaterThanOrEqual, middleRef.Properties["IntegerPrimitive"].Int32Value.Value), 50);

                // 6. Filter on Date
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual,
                                middleRef.Properties["DateTimeOffset"].DateTimeOffsetValue.Value), 50);

                // 7. Filter on Boolean
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef.Properties["Bool"].BooleanValue.Value), 50);

                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef.Properties["BoolPrimitive"].BooleanValue.Value),
                        50);

                // 8. Filter on Binary 
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef.Properties["Binary"].BinaryValue), 1);

                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal,
                                middleRef.Properties["BinaryPrimitive"].BinaryValue), 1);

                // 9. Filter on Binary GTE
                ExecuteQueryAndAssertResults(table,
                        TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual,
                                middleRef.Properties["Binary"].BinaryValue), 50);

                ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive",
                        QueryComparisons.GreaterThanOrEqual, middleRef.Properties["BinaryPrimitive"].BinaryValue), 50);

                // 10. Complex Filter on Binary GTE
                ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters(
                        TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal,
                                middleRef.PartitionKey),
                        TableOperators.And,
                        TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual,
                                middleRef.Properties["Binary"].BinaryValue)), 50);

                ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive",
                        QueryComparisons.GreaterThanOrEqual, middleRef.Properties["BinaryPrimitive"].BinaryValue), 50);
            }
            finally
            {
                Thread.CurrentThread.CurrentCulture = currentCulture;
                table.DeleteIfExistsAsync().Wait();
            }
        }