public void TableExecuteQuerySegmentedQueryResolverTokenRequestOptionsOperationContextCancellationTokenTask()
        {
            TableQuery<BaseEntity> query = new TableQuery<BaseEntity>();
            EntityResolver<BaseEntity> resolver = (partitionKey, rowKey, timestamp, properties, etag) =>
            {
                BaseEntity entity = new BaseEntity(partitionKey, rowKey);
                entity.ETag = etag;
                entity.foo = properties["foo"].StringValue;
                entity.A = properties["A"].StringValue;
                entity.B = properties["B"].StringValue;
                entity.C = properties["C"].StringValue;
                entity.D = properties["D"].StringValue;
                entity.E = properties["E"].Int32Value.Value;
                return entity;
            };
            TableContinuationToken token = null;
            TableRequestOptions requestOptions = new TableRequestOptions();
            OperationContext operationContext = new OperationContext();
            CancellationToken cancellationToken = CancellationToken.None;

            int count = 0;
            do
            {
                TableQuerySegment<BaseEntity> querySegment = currentTable.ExecuteQuerySegmentedAsync(query, resolver, token, requestOptions, operationContext, cancellationToken).Result;
                token = querySegment.ContinuationToken;

                foreach (BaseEntity entity in querySegment)
                {
                    Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch"));
                    entity.Validate();
                    ++count;
                }
            }
            while (token != null);

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

            // Insert Entity
            BaseEntity ent = new BaseEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() };
            ent.Populate();

            // Create the Key to be used for wrapping.
            SymmetricKey aesKey = new SymmetricKey("symencryptionkey");

            // Create the resolver to be used for unwrapping.
            DictionaryKeyResolver resolver = new DictionaryKeyResolver();
            resolver.Add(aesKey);

            TableRequestOptions insertOptions = new TableRequestOptions()
            {
                EncryptionPolicy = new TableEncryptionPolicy(aesKey, null),
                EncryptionResolver = (pk, rk, propName) =>
                    {
                        if (propName == "A" || propName == "foo")
                        {
                            return true;
                        }

                        return false;
                    }
            };

            currentTable.Execute(TableOperation.Insert(ent), insertOptions, null);

            // Retrieve Entity
            // No need for an encryption resolver while retrieving the entity.
            TableRequestOptions retrieveOptions = new TableRequestOptions() { EncryptionPolicy = new TableEncryptionPolicy(null, resolver) };

            TableOperation operation = TableOperation.Retrieve<BaseEntity>(ent.PartitionKey, ent.RowKey);
            Assert.IsFalse(operation.IsTableEntity);
            TableResult result = currentTable.Execute(operation, retrieveOptions, null);

            BaseEntity retrievedEntity = result.Result as BaseEntity;
            Assert.IsNotNull(retrievedEntity);
            Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey);
            Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey);
            retrievedEntity.Validate();
        }
 private static BaseEntity GenerateRandomEntity(string pk)
 {
     BaseEntity ent = new BaseEntity();
     ent.Populate();
     ent.PartitionKey = pk;
     ent.RowKey = Guid.NewGuid().ToString();
     return ent;
 }
        public async Task TableSasUriTestAsync()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N"));

            try
            {
                await table.CreateAsync();

                BaseEntity entity = new BaseEntity("PK", "RK");
                BaseEntity entity1 = new BaseEntity("PK", "RK1");
                await table.ExecuteAsync(TableOperation.Insert(entity));
                await table.ExecuteAsync(TableOperation.Insert(entity1));

                SharedAccessTablePolicy policy = new SharedAccessTablePolicy()
                {
                    SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5),
                    SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30),
                    Permissions = SharedAccessTablePermissions.Delete,
                };

                string sasToken = table.GetSharedAccessSignature(policy, null, null, null, null, null);
                StorageCredentials creds = new StorageCredentials(sasToken);
                CloudStorageAccount sasAcc = new CloudStorageAccount(creds, null /* blobEndpoint */, null /* queueEndpoint */, new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint), null /* fileEndpoint */);
                CloudTableClient client = sasAcc.CreateCloudTableClient();

                CloudTable sasTable = new CloudTable(client.Credentials.TransformUri(table.Uri));
                await sasTable.ExecuteAsync(TableOperation.Delete(entity));

                CloudTable sasTable2 = new CloudTable(new Uri(table.Uri.ToString() + sasToken));
                await sasTable2.ExecuteAsync(TableOperation.Delete(entity1));
            }
            finally
            {
                table.DeleteIfExistsAsync().AsTask().Wait();
            }
        }
        /// <summary>
        /// Test a table operation on entities inside and outside the given range.
        /// </summary>
        /// <param name="tableName">The name of the table to test.</param>
        /// <param name="startPk">The start partition key range.</param>
        /// <param name="startRk">The start row key range.</param>
        /// <param name="endPk">The end partition key range.</param>
        /// <param name="endRk">The end row key range.</param>
        /// <param name="runOperationDelegate">A delegate with the table operation to test.</param>
        /// <param name="opName">The name of the operation being tested.</param>
        /// <param name="expectSuccess">Whether the operation should succeed on entities within the range.</param>
        /// <param name="expectedStatusCode">The status code expected for the response.</param>
        /// <param name="isRangeQuery">Specifies if the operation is a range query.</param>
        /// <param name="isPointQuery">Specifies if the operation is a point query.</param>
        private async Task TestOperationWithRange(
            string tableName,
            string startPk,
            string startRk,
            string endPk,
            string endRk,
            Action<BaseEntity, OperationContext> runOperationDelegate,
            string opName,
            bool expectSuccess,
            HttpStatusCode expectedStatusCode,
            bool isRangeQuery,
            bool isPointQuery)
        {
            CloudTableClient referenceClient = GenerateCloudTableClient();

            string partitionKey = startPk ?? endPk ?? "M";
            string rowKey = startRk ?? endRk ?? "S";

            // if we expect a success for creation - avoid inserting duplicate entities
            BaseEntity tableEntity = new BaseEntity(partitionKey, rowKey);
            if (expectedStatusCode == HttpStatusCode.Created)
            {
                try
                {
                    tableEntity.ETag = "*";
                    await referenceClient.GetTableReference(tableName).ExecuteAsync(TableOperation.Delete(tableEntity));
                }
                catch (Exception)
                {
                }
            }
            else
            {
                // only for add we should not be adding the entity
                await referenceClient.GetTableReference(tableName).ExecuteAsync(TableOperation.InsertOrReplace(tableEntity));
            }

            if (expectSuccess)
            {
                runOperationDelegate(tableEntity, null);
            }
            else
            {
                TestHelper.ExpectedException(
                    (ctx) => runOperationDelegate(tableEntity, ctx),
                    string.Format("{0} without appropriate permission.", opName),
                    (int)HttpStatusCode.Forbidden);
            }

            if (startPk != null)
            {
                tableEntity.PartitionKey = "A";
                if (startPk.CompareTo(tableEntity.PartitionKey) <= 0)
                {
                    Assert.Inconclusive("Test error: partition key for this test must not be less than or equal to \"A\"");
                }

                TestHelper.ExpectedException(
                    (ctx) => runOperationDelegate(tableEntity, ctx),
                    string.Format("{0} before allowed partition key range", opName),
                    (int)(isPointQuery ? HttpStatusCode.NotFound : HttpStatusCode.Forbidden));
                tableEntity.PartitionKey = partitionKey;
            }

            if (endPk != null)
            {
                tableEntity.PartitionKey = "Z";
                if (endPk.CompareTo(tableEntity.PartitionKey) >= 0)
                {
                    Assert.Inconclusive("Test error: partition key for this test must not be greater than or equal to \"Z\"");
                }

                TestHelper.ExpectedException(
                    (ctx) => runOperationDelegate(tableEntity, ctx),
                    string.Format("{0} after allowed partition key range", opName),
                    (int)(isPointQuery ? HttpStatusCode.NotFound : HttpStatusCode.Forbidden));

                tableEntity.PartitionKey = partitionKey;
            }

            if (startRk != null)
            {
                if (isRangeQuery || startPk != null)
                {
                    tableEntity.PartitionKey = startPk;
                    tableEntity.RowKey = "A";
                    if (startRk.CompareTo(tableEntity.RowKey) <= 0)
                    {
                        Assert.Inconclusive("Test error: row key for this test must not be less than or equal to \"A\"");
                    }

                    TestHelper.ExpectedException(
                        (ctx) => runOperationDelegate(tableEntity, ctx),
                        string.Format("{0} before allowed row key range", opName),
                        (int)(isPointQuery ? HttpStatusCode.NotFound : HttpStatusCode.Forbidden));

                    tableEntity.RowKey = rowKey;
                }
            }

            if (endRk != null)
            {
                if (isRangeQuery || endPk != null)
                {
                    tableEntity.PartitionKey = endPk;
                    tableEntity.RowKey = "Z";
                    if (endRk.CompareTo(tableEntity.RowKey) >= 0)
                    {
                        Assert.Inconclusive("Test error: row key for this test must not be greater than or equal to \"Z\"");
                    }

                    TestHelper.ExpectedException(
                        (ctx) => runOperationDelegate(tableEntity, ctx),
                        string.Format("{0} after allowed row key range", opName),
                        (int)(isPointQuery ? HttpStatusCode.NotFound : HttpStatusCode.Forbidden));

                    tableEntity.RowKey = rowKey;
                }
            }
        }
        public async Task TableUpdateSasTestAsync()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N"));

            try
            {
                await table.CreateAsync();

                BaseEntity entity = new BaseEntity("PK", "RK");
                await table.ExecuteAsync(TableOperation.Insert(entity));

                SharedAccessTablePolicy policy = new SharedAccessTablePolicy()
                {
                    SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5),
                    SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30),
                    Permissions = SharedAccessTablePermissions.Delete,
                };

                string sasToken = table.GetSharedAccessSignature(policy, null, null, null, null, null);
                StorageCredentials creds = new StorageCredentials(sasToken);
                CloudTable sasTable = new CloudTable(table.Uri, creds);
                OperationContext context = new OperationContext();
                await TestHelper.ExpectedExceptionAsync(
                    async () => await sasTable.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK2")), null, context),
                    context,
                    "Try to insert an entity when SAS doesn't allow inserts",
                    HttpStatusCode.Forbidden);

                await sasTable.ExecuteAsync(TableOperation.Delete(entity));

                SharedAccessTablePolicy policy2 = new SharedAccessTablePolicy()
                {
                    SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5),
                    SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30),
                    Permissions = SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Add,
                };

                string sasToken2 = table.GetSharedAccessSignature(policy2, null, null, null, null, null);
                creds.UpdateSASToken(sasToken2);

                sasTable = new CloudTable(table.Uri, creds);

                await sasTable.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK2")));

            }
            finally
            {
                table.DeleteIfExistsAsync().AsTask().Wait();
            }
        }
        public void TableSasUriPkRkTestSync()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N"));

            try
            {
                table.Create();

                SharedAccessTablePolicy policy = new SharedAccessTablePolicy()
                {
                    SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5),
                    SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30),
                    Permissions = SharedAccessTablePermissions.Add,
                };

                string sasTokenPkRk = table.GetSharedAccessSignature(policy, null, "tables_batch_0", "00",
                    "tables_batch_1", "04");
                StorageCredentials credsPkRk = new StorageCredentials(sasTokenPkRk);

                // transform uri from credentials
                CloudTable sasTableTransformed = new CloudTable(credsPkRk.TransformUri(table.Uri));

                // create uri by appending sas
                CloudTable sasTableDirect = new CloudTable(new Uri(table.Uri.ToString() + sasTokenPkRk));

                BaseEntity pkrkEnt = new BaseEntity("tables_batch_0", "00");
                sasTableTransformed.Execute(TableOperation.Insert(pkrkEnt));

                pkrkEnt = new BaseEntity("tables_batch_0", "01");
                sasTableDirect.Execute(TableOperation.Insert(pkrkEnt));

                Action<BaseEntity, CloudTable, OperationContext> insertDelegate = (tableEntity, sasTable1, ctx) =>
                {
                    sasTable1.Execute(TableOperation.Insert(tableEntity), null, ctx);
                };

                pkrkEnt = new BaseEntity("tables_batch_2", "00");
                TestHelper.ExpectedException(
                    (ctx) => insertDelegate(pkrkEnt, sasTableTransformed, ctx),
                    string.Format("Inserted entity without appropriate SAS permissions."),
                    (int)HttpStatusCode.Forbidden);
                TestHelper.ExpectedException(
                     (ctx) => insertDelegate(pkrkEnt, sasTableDirect, ctx),
                    string.Format("Inserted entity without appropriate SAS permissions."),
                     (int)HttpStatusCode.Forbidden);

                pkrkEnt = new BaseEntity("tables_batch_1", "05");
                TestHelper.ExpectedException(
                    (ctx) => insertDelegate(pkrkEnt, sasTableTransformed, ctx),
                    string.Format("Inserted entity without appropriate SAS permissions."),
                    (int)HttpStatusCode.Forbidden);
                TestHelper.ExpectedException(
                     (ctx) => insertDelegate(pkrkEnt, sasTableDirect, ctx),
                    string.Format("Inserted entity without appropriate SAS permissions."),
                     (int)HttpStatusCode.Forbidden);
            }
            finally
            {
                table.DeleteIfExists();
            }
        }
        public void CloudTableSASWithAbsoluteUri()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();

            CloudTable table = tableClient.GetTableReference(tableClient.BaseUri + GenerateRandomTableName());
            try
            {
                table.CreateIfNotExists();

                BaseEntity entity = new BaseEntity("PK", "RK");
                table.Execute(TableOperation.Insert(entity));

                SharedAccessTablePolicy policy = new SharedAccessTablePolicy()
                {
                    Permissions = SharedAccessTablePermissions.Delete,
                    SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5),
                    SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(10)
                };

                string sasToken = table.GetSharedAccessSignature(policy);
                StorageCredentials creds = new StorageCredentials(sasToken);

                CloudTable sasTable = new CloudTable(table.Uri, creds);
                sasTable.Execute(TableOperation.Delete(entity));
            }
            finally
            {
                table.DeleteIfExists();
            }
        }
        public void TableUpdateSasTestSync()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N"));

            try
            {
                table.Create();

                BaseEntity entity = new BaseEntity("PK", "RK");
                table.Execute(TableOperation.Insert(entity));

                SharedAccessTablePolicy policy = new SharedAccessTablePolicy()
                {
                    SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5),
                    SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30),
                    Permissions = SharedAccessTablePermissions.Delete,
                };

                string sasToken = table.GetSharedAccessSignature(policy);
                StorageCredentials creds = new StorageCredentials(sasToken);
                CloudTable sasTable = new CloudTable(table.Uri, creds);
                TestHelper.ExpectedException(
                    () => sasTable.Execute(TableOperation.Insert(new BaseEntity("PK", "RK2"))),
                    "Try to insert an entity when SAS doesn't allow inserts",
                    HttpStatusCode.NotFound);

                sasTable.Execute(TableOperation.Delete(entity));

                SharedAccessTablePolicy policy2 = new SharedAccessTablePolicy()
                {
                    SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5),
                    SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30),
                    Permissions = SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Add,
                };

                string sasToken2 = table.GetSharedAccessSignature(policy2);
                creds.UpdateSASToken(sasToken2);

                sasTable = new CloudTable(table.Uri, creds);

                sasTable.Execute(TableOperation.Insert(new BaseEntity("PK", "RK2")));

            }
            finally
            {
                table.DeleteIfExists();
            }
        }
        public void TableExecuteQuerySegmentedQueryResolverTokenTask()
        {
            TableQuery<BaseEntity> query = new TableQuery<BaseEntity>();
            EntityResolver<BaseEntity> resolver = (partitionKey, rowKey, timestamp, properties, etag) =>
            {
                BaseEntity entity = new BaseEntity(partitionKey, rowKey);
                entity.ETag = etag;
                entity.foo = properties["foo"].StringValue;
                entity.A = properties["A"].StringValue;
                entity.B = properties["B"].StringValue;
                entity.C = properties["C"].StringValue;
                entity.D = properties["D"].StringValue;
                return entity;
            };
            TableContinuationToken token = null;

            int count = 0;
            do
            {
                TableQuerySegment<BaseEntity> querySegment = currentTable.ExecuteQuerySegmentedAsync(query, resolver, token).Result;
                token = querySegment.ContinuationToken;

                foreach (BaseEntity entity in querySegment)
                {
                    Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch"));
                    entity.Validate();
                    ++count;
                }
            }
            while (token != null);

            Assert.AreEqual(1500, count);
        }