Example #1
0
        // Helper functions for single-op API
        private static TableOperation TranslateWriteOp(TableOperationType opType, ITableEntity row)
        {
            TableOperation top = null;

            if (opType == TableOperationType.Delete)
            {
                top = TableOperation.Delete(row);
            }
            else if (opType == TableOperationType.Merge)
            {
                top = TableOperation.Merge(row);
            }
            else if (opType == TableOperationType.Replace)
            {
                top = TableOperation.Replace(row);
            }
            else if (opType == TableOperationType.Insert)
            {
                top = TableOperation.Insert(row, true);
            }
            else
            {
                throw new Exception("Unknown write operation.");
            }

            return(top);
        }
Example #2
0
        private void AssertOperationType(TableOperation operation, TableOperationType operationType)
        {
            var propInfo = typeof(TableOperation).GetProperty("OperationType", BindingFlags.NonPublic | BindingFlags.Instance);
            var type     = (TableOperationType)propInfo.GetValue(operation);

            Assert.Equal(operationType, type);
        }
Example #3
0
        private static void AddTableOperationToBatch(TableOperationType tableOperationType, TableBatchOperation batch, T item)
        {
            // TODO: check if a function like this is already available in the azure storage package.
            switch (tableOperationType)
            {
            case TableOperationType.InsertOrMerge:
                batch.Add(TableOperation.InsertOrMerge(item));
                break;

            case TableOperationType.Delete:
                batch.Add(TableOperation.Delete(item));
                break;

            case TableOperationType.Insert:
                batch.Add(TableOperation.Insert(item));
                break;

            case TableOperationType.Replace:
                batch.Add(TableOperation.Replace(item));
                break;

            case TableOperationType.Merge:
                batch.Add(TableOperation.Merge(item));
                break;

            case TableOperationType.InsertOrReplace:
                batch.Add(TableOperation.InsertOrReplace(item));
                break;

            case TableOperationType.Retrieve:
            case TableOperationType.Invalid:
                throw new ArgumentOutOfRangeException(nameof(tableOperationType),
                                                      $"TableOperationType {tableOperationType} not supported for {nameof(AddTableOperationToBatch)}.");
            }
        }
Example #4
0
        private async Task <TableResult> ExecuteAsync(TableOperationType operationType, T entity)
        {
            var operation = operationType == TableOperationType.Insert
                ? TableOperation.Insert(entity)
                : TableOperation.Replace(entity);
            var rollbackOperation = CreateRollbackAction(operationType, entity);

            var result = await _cloudTable.ExecuteAsync(operation);

            _scope.RollbackActions.Enqueue(rollbackOperation);

            if (entity is IAuditTracker)
            {
                // record audit and rollback
                var auditEntity = entity.CopyObject <T>();
                // need new partition and row keys for each audit entry
                auditEntity.PartitionKey = $"{entity.PartitionKey}-{entity.RowKey}";
                auditEntity.RowKey       = $"{DateTime.UtcNow:yyyy-mm-ddThh:mm:ss:fff}";

                var auditRollbackOperation = CreateRollbackAction(TableOperationType.Insert, auditEntity, true);
                _scope.RollbackActions.Enqueue(auditRollbackOperation);

                var auditTable = _cloudTableClient.GetTableReference($"{typeof(T).Name}Audit");
                await auditTable.ExecuteAsync(TableOperation.Insert(auditEntity));
            }
            return(result);
        }
Example #5
0
        private async Task <TableResult> ExecuteAsync(TableOperationType operationType, T entity)
        {
            var rollbackAction = CreateRollbackAction(operationType, entity);
            var operation      = operationType == TableOperationType.Insert
                ? TableOperation.Insert(entity)
                : TableOperation.Replace(entity);
            var result = await _storageTable.ExecuteAsync(operation);

            Scope.RollbackActions.Enqueue(rollbackAction);

            if (entity is IAuditTracker)
            {
                // new audit entry
                var auditEntity = entity.CopyObject <T>();
                auditEntity.PartitionKey = $"{auditEntity.PartitionKey}-{auditEntity.RowKey}";
                auditEntity.RowKey       = $"{DateTime.UtcNow:yyyy-MM-ddTHH:mm:ss.fff}";

                var auditOperation      = TableOperation.Insert(auditEntity);
                var auditRollbackAction = CreateRollbackAction(TableOperationType.Insert, auditEntity, true);
                var auditTable          = _tableClient.GetTableReference($"{typeof(T).Name}Audit");
                await auditTable.ExecuteAsync(auditOperation);

                Scope.RollbackActions.Enqueue(auditRollbackAction);
            }
            return(result);
        }
        /// <summary>
        /// Queue a new operation
        /// </summary>
        /// <typeparam name="T">Type of businessObject</typeparam>
        /// <param name="businessObject">Business object instance - cannot be NULL.</param>
        /// <param name="type">Type of TableOperation to generate</param>
        public void Add <T>(T businessObject, TableOperationType type) where T : class
        {
            if (_isDraining)
            {
                // no items can be added during a drain
                throw new Exception("Cannot queue items during a drain.");
            }

            if (businessObject == null)
            {
                throw new ArgumentNullException("businessObject");
            }

            TableOperation operation = type switch
            {
                TableOperationType.Delete => TableOperation.Delete(AzureTableEntity.From(businessObject, forDelete: true)),
                TableOperationType.Insert => TableOperation.Insert(AzureTableEntity.From(businessObject)),
                TableOperationType.InsertOrMerge => TableOperation.InsertOrMerge(AzureTableEntity.From(businessObject)),
                TableOperationType.InsertOrReplace => TableOperation.InsertOrReplace(AzureTableEntity.From(businessObject)),
                TableOperationType.Merge => TableOperation.Merge(AzureTableEntity.From(businessObject)),
                TableOperationType.Replace => TableOperation.Replace(AzureTableEntity.From(businessObject)),
                _ => throw new ArgumentOutOfRangeException("Unsupported operation for queue!")
            };

            _queueOrder.Enqueue(_queueIndex);

            _queue.TryAdd(_queueIndex++, new TableOperationWrapper(operation, AzureTablesDataSource.GetTableName <T>()));
        }
Example #7
0
 public static async Task ExecuteBatchUnordered <T>(CloudTable table, TableOperationType type, IEnumerable <T> entityList)
     where T : ITableEntity
 {
     foreach (var group in entityList.GroupBy(x => x.PartitionKey))
     {
         await ExecuteBatch(table, type, group);
     }
 }
Example #8
0
 public ExecutableTableOperation(string table, TableOperation operation, TableOperationType operationType, string partitionKey, string rowKey)
 {
     Table         = table;
     Operation     = operation;
     OperationType = operationType;
     PartitionKey  = partitionKey;
     RowKey        = rowKey;
 }
Example #9
0
 public ExecutableTableOperation( string table, TableOperation operation, TableOperationType operationType, string partitionKey, string rowKey )
 {
     Table = table;
      Operation = operation;
      OperationType = operationType;
      PartitionKey = partitionKey;
      RowKey = rowKey;
 }
Example #10
0
 private FakeStorageTableOperation(string retrievePartitionKey, string retrieveRowKey,
                                   IEntityResolver retrieveEntityResolver)
 {
     _operationType          = TableOperationType.Retrieve;
     _retrievePartitionKey   = retrievePartitionKey;
     _retrieveRowKey         = retrieveRowKey;
     _retrieveEntityResolver = retrieveEntityResolver;
 }
        public SendITableEntityToTableStorage(string storageConnectionString, string tableName, TableOperationType operation)
        {
            var acct = CloudStorageAccount.Parse(storageConnectionString);
            CloudTableClient tableClient = acct.CreateCloudTableClient();

            table = tableClient.GetTableReference(tableName);
            table.CreateIfNotExists();
            this.operation = operation;
        }
Example #12
0
 public void SetupOperationToFail(TableOperationType operation)
 {
     Setup(t => t.ExecuteAsync(It.Is <TableOperation>(op => op.OperationType == operation)))
     .ReturnsAsync(new TableResult
     {
         HttpStatusCode = 404,
         Result         = null
     });
 }
Example #13
0
 private static void SetupExecuteAsync(Mock <CloudTable> cloudTableMock,
                                       DynamicTableEntity entityToReturn,
                                       TableOperationType expectedTableOperation)
 {
     cloudTableMock.Setup(t =>
                          t.ExecuteAsync(It.Is <TableOperation>(o => o.OperationType == expectedTableOperation)))
     .Returns(Task.FromResult(new TableResult {
         Result = entityToReturn
     }));
 }
Example #14
0
 public void SetupOperation <T>(TableOperationType operation, Func <T> creator = null) where T : ITableEntity, new()
 {
     Setup(t => t.ExecuteAsync(It.Is <TableOperation>(op => op.OperationType == operation)))
     .ReturnsAsync(new TableResult
     {
         Etag           = "new!",
         HttpStatusCode = 200,
         Result         = creator == null ? new T() : creator.Invoke()
     });
 }
        /// <summary>
        /// Creates a new instance of the <see cref="TableOperation"/> class given the
        /// entity to operate on and the type of operation that is being
        /// performed.
        /// </summary>
        /// <param name="entity">The entity on which the operation is being performed.</param>
        /// <param name="operationType">The type of operation.</param>
        internal TableOperation(ITableEntity entity, TableOperationType operationType)
        {
            if (entity == null && operationType != TableOperationType.Retrieve)
            {
                throw new ArgumentNullException("entity");
            }

            this.Entity        = entity;
            this.OperationType = operationType;
        }
Example #16
0
 public void SetupOperation(ITableEntity entity, TableOperationType operation)
 {
     Setup(t => t.ExecuteAsync(It.Is <TableOperation>(op => op.OperationType == operation && op.Entity.RowKey == entity.RowKey)))
     .ReturnsAsync(new TableResult
     {
         Etag           = "new!",
         HttpStatusCode = 200,
         Result         = entity
     });
 }
        /// <summary>
        /// Creates a new instance of the TableOperation class given the
        /// entity to operate on and the type of operation that is being
        /// performed.
        /// </summary>
        /// <param name="entity">The entity that is being operated upon.</param>
        /// <param name="operationType">The type of operation.</param>
        internal TableOperation(ITableEntity entity, TableOperationType operationType)
        {
            if (entity == null && operationType != TableOperationType.Retrieve)
            {
                throw new ArgumentNullException("entity");
            }

            this.Entity = entity;
            this.OperationType = operationType;
        }
Example #18
0
        private TableOperationType GetOpType(TableOperation operation)
        {
            // WARNING: We use reflection to read an internal field in OperationType.
            //          We have a dependency on TableOperation fields in WindowsAzureStorage dll
            PropertyInfo opType = operation.GetType().GetProperty("OperationType", System.Reflection.BindingFlags.GetProperty |
                                                                  System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
            TableOperationType opTypeValue = (TableOperationType)(opType.GetValue(operation, null));

            return(opTypeValue);
        }
 internal TableOperation(ITableEntity entity, TableOperationType operationType, bool echoContent)
 {
     if (entity == null && operationType != TableOperationType.Retrieve)
     {
         throw new ArgumentNullException("entity");
     }
     Entity        = entity;
     OperationType = operationType;
     EchoContent   = echoContent;
 }
        internal TableOperation(ITableEntity entity, TableOperationType operationType, bool echoContent)
        {
            if (entity == null && operationType != TableOperationType.Retrieve && operationType != TableOperationType.RotateEncryptionKey)
            {
                throw new ArgumentNullException("entity");
            }

            this.Entity        = entity;
            this.OperationType = operationType;
            this.EchoContent   = echoContent;
        }
Example #21
0
        /*
         * ReadModifyWriteRow
         *   Execute a conditional write operation on a row.
         *
         *   Insert         - Success if currently no row exists on the key.
         *   Update & Merge - success only if current row exists and etag matches.
         *   Delete         - Success only if current row exist, and etag matches.
         *
         * param:
         *   table  - target table.
         *   opType - operation to execute, Insert / Replace / Merge / Delete.
         *   row    - target row to insert / delete, also serves as the parameter used for insert / replace / merge.
         *   etag   - for replace / merge / delete, provide the etag of target row.
         *
         * return:
         *   The result of query. Return null if the Azure request throws an unknown exception.
         */
        internal static TableResult ModifyRow(IChainTable table, TableOperationType opType, ITableEntity row, string eTag,
                                              TableRequestOptions requestOptions = null, OperationContext operationContext = null)
        {
            Assert.IsTrue(opType == TableOperationType.Insert || eTag != null);

            if (eTag != null)
            {
                row.ETag = eTag;
            }

            return(WriteConditionalRow(table, opType, row, requestOptions, operationContext));
        }
        internal TableOperation(ITableEntity entity, TableOperationType operationType, TablePaginationToken token, TableQueryOptions options)
        {
            _entity = entity;

            _operationType = operationType;

            _tableUri = new TableUri(entity, operationType, TableUriQueryBuilder.Build(token, options));

            if (operationType == TableOperationType.InsertEdmType)
            {
                _edmTypeEntity = EntityPropertyBuilder.Build(entity);
            }
        }
Example #23
0
        internal TableUri(ITableEntity entity, TableOperationType operationType, string filter)
        {
            if (operationType != TableOperationType.Insert && operationType != TableOperationType.InsertEdmType && !string.IsNullOrEmpty(entity.PartitionKey) && !string.IsNullOrEmpty(entity.RowKey))
            {
                Url = $"{entity.TableName}(PartitionKey='{entity.PartitionKey}',RowKey='{entity.RowKey}')";
            }
            else
            {
                Url = entity.TableName;
            }

            Filter = filter;
        }
Example #24
0
        private static (Mock <CloudTable> cloudTableMock, CloudTablePool pool) CreateTablePoolWithMockForExecute(
            DynamicTableEntity entityToReturnInTableResult,
            TableOperationType expectedTableOperation,
            Action <Mock <CloudTable>, DynamicTableEntity, TableOperationType> setupMethod)
        {
            const string tableName      = "UnitTestTable";
            var          cloudTableMock = new Mock <CloudTable>(new Uri($"https://nothing.net/{tableName}"), new TableClientConfiguration());


            setupMethod(cloudTableMock, entityToReturnInTableResult, expectedTableOperation);

            var pool = new CloudTablePool(tableName, cloudTableMock.Object);

            return(cloudTableMock, pool);
        }
Example #25
0
        private static void WriteOdataEntity(ITableEntity entity, TableOperationType operationType, OperationContext ctx, ODataWriter writer, TableRequestOptions options)
        {
            ODataEntry entry = new ODataEntry()
            {
                Properties = GetPropertiesWithKeys(entity, ctx, operationType, options),
                TypeName   = "account.sometype"
            };

            entry.SetAnnotation(new SerializationTypeNameAnnotation {
                TypeName = null
            });
            writer.WriteStart(entry);
            writer.WriteEnd();
            writer.Flush();
        }
Example #26
0
        private static void WriteOdataEntity(ITableEntity entity, TableOperationType operationType, OperationContext ctx, ODataWriter writer)
        {
            ODataEntry entry = new ODataEntry()
            {
                Properties = GetPropertiesWithKeys(entity, ctx)
            };

            if (operationType != TableOperationType.Insert && operationType != TableOperationType.Retrieve)
            {
                entry.ETag = entity.ETag;
            }

            writer.WriteStart(entry);
            writer.WriteEnd();
            writer.Flush();
        }
        private async Task <TableEntity> GetResponseByTableOperationAsync(TableOperationType operationType, TableEntity entity)
        {
            switch (operationType)
            {
            case TableOperationType.Insert:
                return(await this.client.InsertAsync(MockTableName, entity));

            case TableOperationType.InsertOrMerge:
                return(await this.client.InsertOrMergeAsync(MockTableName, entity));

            case TableOperationType.InsertOrReplace:
                return(await this.client.InsertOrReplaceAsync(MockTableName, entity));

            case TableOperationType.Delete:
                return(await this.client.DeleteAsync(MockTableName, entity));

            default:
                throw new NotImplementedException($"TableStorageClient does not have a test implementation for operation type {operationType}.");
            }
        }
        private static void WriteOdataEntity(ITableEntity entity, TableOperationType operationType, OperationContext ctx, ODataWriter writer)
        {
            ODataEntry entry = new ODataEntry()
            {
                Properties = GetPropertiesWithKeys(entity, ctx, operationType),
                TypeName   = "account.sometype"
            };

            if (operationType != TableOperationType.Insert && operationType != TableOperationType.Retrieve)
            {
                entry.ETag = entity.ETag;
            }

            entry.SetAnnotation(new SerializationTypeNameAnnotation {
                TypeName = null
            });
            writer.WriteStart(entry);
            writer.WriteEnd();
            writer.Flush();
        }
        private static int GetSuccessStatusCodeFromOperationType(TableOperationType operationType)
        {
            switch (operationType)
            {
            case TableOperationType.Insert:
                return(201);

            case TableOperationType.Delete:
            case TableOperationType.Replace:
            case TableOperationType.Merge:
            case TableOperationType.InsertOrReplace:
            case TableOperationType.InsertOrMerge:
                return(204);

            case TableOperationType.Retrieve:
                return(200);

            default:
                return(200);
            }
        }
Example #30
0
 private static TableResult WriteConditionalRow(IChainTable table, TableOperationType opType, ITableEntity row,
                                                TableRequestOptions options = null, OperationContext oc = null)
 {
     try
     {
         TableOperation top = TranslateWriteOp(opType, row);
         return(table.Execute(top, options, oc));
     }
     catch (StorageException e)
     {
         return(new TableResult()
         {
             Result = null, Etag = e.RequestInformation.Etag, HttpStatusCode = e.RequestInformation.HttpStatusCode
         });
     }
     catch (Exception e)
     {
         Console.WriteLine("TryWriteConditionalRow:Error: exception {0}", e);
         return(null);
     }
 }
Example #31
0
        public static async Task ExecuteBatch <T>(CloudTable table, TableOperationType type, IEnumerable <T> entityList)
            where T : ITableEntity
        {
            var operation = new TableBatchOperation();

            foreach (var entity in entityList)
            {
                operation.Execute(type, entity);

                if (operation.Count == MaxBatchCount)
                {
                    await table.ExecuteBatchAsync(operation);

                    operation.Clear();
                }
            }

            if (operation.Count > 0)
            {
                await table.ExecuteBatchAsync(operation);
            }
        }
        public async Task EntityOperationThrowsWhenUnableToCastResultTest(TableOperationType operationType)
        {
            this.mockTable
            .Setup(x => x.ExecuteAsync(
                       It.IsAny <TableOperation>()))
            .ReturnsAsync(
                new TableResult
            {
                Result = new
                {
                    UnusualResultKey = "value",
                },
            });

            await Assert.ThrowsAsync <Exception>(async() => await this.GetResponseByTableOperationAsync(operationType, CreateEntity()));

            this.mockTable
            .Verify(
                x => x.ExecuteAsync(
                    It.Is <TableOperation>(o => o.OperationType == operationType)),
                Times.Once);
        }
        internal static IEnumerable<ODataProperty> GetPropertiesWithKeys(ITableEntity entity, OperationContext operationContext, TableOperationType operationType, TableRequestOptions options)
        {
            if (operationType == TableOperationType.Insert)
            {
                if (entity.PartitionKey != null)
                {
                    yield return new ODataProperty() { Name = TableConstants.PartitionKey, Value = entity.PartitionKey };
                }

                if (entity.RowKey != null)
                {
                    yield return new ODataProperty() { Name = TableConstants.RowKey, Value = entity.RowKey };
                }
            }

            foreach (ODataProperty property in GetPropertiesFromDictionary(entity.WriteEntity(operationContext), options, entity.PartitionKey, entity.RowKey))
            {
                yield return property;
            }
        }
        private static void WriteOdataEntity(ITableEntity entity, TableOperationType operationType, OperationContext ctx, ODataWriter writer, TableRequestOptions options)
        {
            ODataEntry entry = new ODataEntry()
            {
                Properties = GetPropertiesWithKeys(entity, ctx, operationType, options),
                TypeName = "account.sometype"
            };

            entry.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = null });
            writer.WriteStart(entry);
            writer.WriteEnd();
            writer.Flush();
        }
        private static void WriteOdataEntity(ITableEntity entity, TableOperationType operationType, OperationContext ctx, ODataWriter writer)
        {
            ODataEntry entry = new ODataEntry()
            {
                Properties = GetPropertiesWithKeys(entity, ctx)
            };

            if (operationType != TableOperationType.Insert && operationType != TableOperationType.Retrieve)
            {
                entry.ETag = entity.ETag;
            }

            writer.WriteStart(entry);
            writer.WriteEnd();
            writer.Flush();
        }
Example #36
0
 // Methods
 public TableOperation(TableOperationType type, DataEntityModel entity)
 {
     m_Type = type;
       m_Table = entity;
       base.m_DataLayer = entity.Parent;
 }
 /// <summary>
 /// Creates a new instance of the <see cref="TableOperation"/> class given the
 /// entity to operate on and the type of operation that is being
 /// performed.
 /// </summary>
 /// <param name="entity">The entity on which the operation is being performed.</param>
 /// <param name="operationType">The type of operation.</param>
 internal TableOperation(ITableEntity entity, TableOperationType operationType)
     : this(entity, operationType, true)
 {
 }
Example #38
0
        /// <summary>
        /// Helper function to perform Delete, InsertOrReplace, Merge, or Replace operation for the specified set of jobType and jobId.
        /// And validate the results.
        /// </summary>
        /// <param name="opType"></param>
        /// <param name="jobType"></param>
        /// <param name="jobId"></param>
        /// <param name="updatedEntityMessage"></param>
        protected void PerformOperationAndValidate(
            TableOperationType opType,
            string jobType,
            string jobId,
            string updatedEntityMessage = "")
        {
            Console.WriteLine("\nValidating {0} operation: updatedEntityMessage={1}...", opType, updatedEntityMessage);
            for (int i = 0; i < this.numberOfPartitions; i++)
            {
                List<string> rowKeys = new List<string>(); // list of rowKey for the given paritionKey
                string partitionKey;
                string rowKey;
                SampleRTableEntity.GenerateKeys(this.GenerateJobType(jobType, i), "don't care", out partitionKey, out rowKey);
                //
                // GetAllRows()
                //
                Console.WriteLine("Calling GetAllRows() and then ReplaceRow() for partition {0}", i);
                IEnumerable<SampleRTableEntity> allRows = this.rtableWrapper.GetAllRows(partitionKey);
                int j = 0; // counting the number of rows per partition
                List<SampleRTableEntity> allRetrievedEntities = new List<SampleRTableEntity>();
                foreach (var retrievedEntity in allRows)
                {
                    allRetrievedEntities.Add(retrievedEntity);
                    j++;
                }
                Assert.AreEqual(this.numberOfRowsPerPartition, j, "Partition {0} only has {1} rows. Expected {2} rows", i, j, this.numberOfRowsPerPartition);

                j = 0;
                foreach (var oneEntry in allRetrievedEntities)
                {
                    int attempts = 1;
                    bool passed = true;
                    while (attempts < 3)
                    {
                        try
                        {
                            SampleRTableEntity retrievedEntity = this.rtableWrapper.FindRow(partitionKey, oneEntry.RowKey);
                            Console.WriteLine("attempts={0}. partitionKey={1} rowKey={2}. Calling {3} API...",
                                attempts, partitionKey, oneEntry.RowKey, opType);
                            switch (opType)
                            {
                                case TableOperationType.Delete:
                                    {
                                        retrievedEntity.ETag = retrievedEntity._rtable_Version.ToString(); // set ETag
                                        this.rtableWrapper.DeleteRow(retrievedEntity);
                                    }
                                    break;
                                case TableOperationType.InsertOrReplace:
                                    {
                                        retrievedEntity.Message = this.GenerateMessage(updatedEntityMessage, i, j);
                                        this.rtableWrapper.InsertOrReplaceRow(retrievedEntity);
                                        rowKeys.Add(retrievedEntity.RowKey);
                                    }
                                    break;
                                case TableOperationType.Merge:
                                    {
                                        retrievedEntity.Message = this.GenerateMessage(updatedEntityMessage, i, j);
                                        retrievedEntity.ETag = retrievedEntity._rtable_Version.ToString(); // set ETag
                                        this.rtableWrapper.MergeRow(retrievedEntity);
                                        rowKeys.Add(retrievedEntity.RowKey);
                                    }
                                    break;
                                case TableOperationType.Replace:
                                    {
                                        retrievedEntity.Message = this.GenerateMessage(updatedEntityMessage, i, j);
                                        retrievedEntity.ETag = retrievedEntity._rtable_Version.ToString(); // set ETag
                                        this.rtableWrapper.ReplaceRow(retrievedEntity);
                                        rowKeys.Add(retrievedEntity.RowKey);
                                    }
                                    break;
                                default:
                                    {
                                        throw new InvalidOperationException(string.Format("opType={0} is NOT supported", opType));
                                    }
                            }
                            passed = true;
                            break; // get out of while(attempts) if no RTableConflictException
                        }
                        catch (RTableConflictException)
                        {
                            passed = false;
                            Console.WriteLine("Got RTableConflictException. attempts={0}", attempts);
                            attempts++;
                            System.Threading.Thread.Sleep(1000);
                        }
                    }
                    Assert.IsTrue(passed, "Keep getting RTableConflictException when calling {0} API", opType);
                    j++;
                }
                Assert.AreEqual(this.numberOfRowsPerPartition, j, "Partition {0} only has {1} rows. Expected {2} rows", i, j, this.numberOfRowsPerPartition);

                //
                // FindRow()
                //
                Console.WriteLine("Calling FindRow() for partitionKey={0}", partitionKey);
                for (j = 0; j < rowKeys.Count; j++)
                {
                    if (opType == TableOperationType.Delete)
                    {
                        try
                        {
                            SampleRTableEntity retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKeys[j]);
                            Assert.Fail("After DeleteRow() was called, FindRow() did not throw RTableResourceNotFoundException");
                        }
                        catch (RTableResourceNotFoundException)
                        {
                        }
                    }
                    else
                    {
                        SampleRTableEntity retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKeys[j]);
                        this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, updatedEntityMessage, i, j);
                    }
                }
            }
            Console.WriteLine("Passed {0} validation.\n", opType);
        }
Example #39
0
 public static string GetOpName(TableOperationType type, DataEntityModel entity)
 {
     return (type + entity.MappingName);
 }
 private void AssertOperationType(TableOperation operation, TableOperationType operationType)
 {
     var propInfo = typeof(TableOperation).GetProperty("OperationType", BindingFlags.NonPublic | BindingFlags.Instance);
     var type = (TableOperationType)propInfo.GetValue(operation);
     Assert.Equal(operationType, type);
 }
Example #41
0
        /// <summary>
        /// Helper function to perform Delete, InsertOrReplace, Merge, or Replace operation for the specified set of jobType and jobId.
        /// And validate the results.
        /// </summary>
        /// <param name="opType"></param>
        /// <param name="jobType"></param>
        /// <param name="jobId"></param>
        /// <param name="partition"></param>
        /// <param name="row"></param>
        /// <param name="originalMessage"></param>
        /// <param name="updatedMessage"></param>
        protected void PerformIndividualOperationAndValidate(
            TableOperationType opType,
            string jobType,
            string jobId,
            int partition,
            int row,
            string originalMessage,
            string updatedMessage = "")
        {
            Console.WriteLine("\nValidating {0} operation: updatedEntityMessage={1}...", opType, message);

            string partitionKey;
            string rowKey;
            SampleRTableEntity.GenerateKeys(this.GenerateJobType(jobType, partition), this.GenerateJobId(jobId, partition, row), out partitionKey, out rowKey);

            Console.WriteLine("PartitionKey = {0}, RowKey = {1}", partitionKey, rowKey);

            int attempts = 1;
            bool passed = true;
            bool resetRow = false;

            SampleRTableEntity retrievedEntity = null;
            while (attempts < 3)
            {
                try
                {
                    if (opType != TableOperationType.Insert)
                    {
                        retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                    }

                    Console.WriteLine("attempts={0}. partitionKey={1} rowKey={2}. Calling {3} API...", attempts, partitionKey, rowKey, opType);
                    switch (opType)
                    {
                        case TableOperationType.Delete:
                            {
                                this.rtableWrapper.DeleteRow(retrievedEntity);

                                //Validate
                                try
                                {
                                    retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                                    Assert.Fail("After DeleteRow() was called, FindRow() did not throw RTableResourceNotFoundException");
                                }
                                catch (RTableResourceNotFoundException)
                                {
                                }
                            }
                            break;
                        case TableOperationType.Insert:
                            {
                                SampleRTableEntity sampleRtableEntity = new SampleRTableEntity(
                                    this.GenerateJobType(jobType, partition),
                                    this.GenerateJobId(jobId, partition, row),
                                    this.GenerateMessage(originalMessage, partition, row));
                                this.rtableWrapper.InsertRow(sampleRtableEntity);

                                //Validate
                                try
                                {
                                    retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                                }
                                catch (RTableResourceNotFoundException)
                                {
                                    Assert.Fail("After InsertRow() was called, FindRow() threw RTableResourceNotFoundException");
                                }
                            }
                            break;
                        case TableOperationType.InsertOrMerge:
                            {
                                retrievedEntity.Message = this.GenerateMessage(updatedMessage, partition, row);
                                this.rtableWrapper.InsertOrMergeRow(retrievedEntity);

                                retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                                this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, updatedMessage, partition, row);
                            }
                            break;
                        case TableOperationType.InsertOrReplace:
                            {
                                retrievedEntity.Message = this.GenerateMessage(updatedMessage, partition, row);
                                this.rtableWrapper.InsertOrReplaceRow(retrievedEntity);

                                retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                                this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, updatedMessage, partition, row);
                                resetRow = true;
                            }
                            break;
                        case TableOperationType.Merge:
                            {
                                retrievedEntity.Message = this.GenerateMessage(updatedMessage, partition, row);
                                this.rtableWrapper.MergeRow(retrievedEntity);

                                retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                                this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, updatedMessage, partition, row);
                            }
                            break;
                        case TableOperationType.Replace:
                            {
                                retrievedEntity.Message = this.GenerateMessage(updatedMessage, partition, row);
                                this.rtableWrapper.ReplaceRow(retrievedEntity);

                                retrievedEntity = this.rtableWrapper.FindRow(partitionKey, rowKey);
                                this.ValidateRetrievedRTableEntity(retrievedEntity, jobType, jobId, updatedMessage, partition, row);
                                resetRow = true;
                            }
                            break;
                        case TableOperationType.Retrieve:
                            {
                                this.rtableWrapper.FindRow(partitionKey, rowKey);
                            }
                            break;
                        default:
                            {
                                throw new InvalidOperationException(string.Format("opType={0} is NOT supported", opType));
                            }
                    }
                    passed = true;
                    break; // get out of while(attempts) if no RTableConflictException
                }
                catch (RTableConflictException)
                {
                    passed = false;
                    Console.WriteLine("Got RTableConflictException. attempts={0}", attempts);
                    attempts++;
                    System.Threading.Thread.Sleep(1000);
                }
            }
            Assert.IsTrue(passed, "Keep getting RTableConflictException when calling {0} API", opType);

            Console.WriteLine("Passed {0} validation.\n", opType);

            //Reset row to original values so subsequent updates on the same row get validated correctly
            if (resetRow == true)
            {
                Console.WriteLine("Resetting row to original values");
                retrievedEntity.Message = this.GenerateMessage(originalMessage, partition, row);
                this.rtableWrapper.ReplaceRow(retrievedEntity);
            }
        }
Example #42
0
 public static string GetSpName(DataAccessModel daLayer, DataEntityModel de, TableOperationType opType)
 {
     return string.Format("{0}{1}{2}", daLayer.Prefix, de.MappingName, opType);
 }