public Task <TResult> ExecuteInsertOrReplaceAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                             string rowKeyRef, string partitionKeyRef,
                                                                             TEntity value, IDictionary <string, EntityProperty> dictionary,
                                                                             AzureTableDriverDynamic repository,
                                                                             Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                             Func <TResult> onFailure)
        {
            var existingRowKey       = GetRowKey(memberInfo, value);
            var existingPartitionKey = GetPartitionKey(memberInfo, value);
            var tableName            = GetLookupTableName(memberInfo);

            return(repository.FindByIdAsync <DateTimeLookupTable, TResult>(existingRowKey, existingPartitionKey,
                                                                           (lookup) =>
            {
                var rowAndParitionKeys = lookup.rows
                                         .NullToEmpty()
                                         .Zip(lookup.partitions.NullToEmpty(), (k, v) => k.PairWithValue(v))
                                         .ToArray();
                var rowKeyFound = rowAndParitionKeys
                                  .NullToEmpty()
                                  .Where(kvp => kvp.Key == rowKeyRef)
                                  .Any();
                var partitionKeyFound = rowAndParitionKeys
                                        .NullToEmpty()
                                        .Where(kvp => kvp.Value == partitionKeyRef)
                                        .Any();
                if (rowKeyFound && partitionKeyFound)
                {
                    return onSuccessWithRollback(() => true.AsTask());
                }
                return onFailure();
            },
                                                                           onNotFound: () => onFailure(),
                                                                           tableName: tableName));
        }
        public async Task <TResult> ExecuteUpdateAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                          IAzureStorageTableEntity <TEntity> updatedEntity, IAzureStorageTableEntity <TEntity> existingEntity,
                                                                          AzureTableDriverDynamic repository,
                                                                          Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                          Func <TResult> onFailure)
        {
            var newValue      = memberInfo.GetValue(updatedEntity.Entity);
            var existingValue = memberInfo.GetValue(updatedEntity.Entity);

            if (newValue.GetType().IsAssignableTo(typeof(System.Delegate)))
            {
                var dele     = (Delegate)newValue;
                var deleType = dele.Target.GetType();
                if (deleType.DeclaringType.GUID == typeof(StorageSubtableAttribute).GUID)
                {
                    return(onSuccessWithRollback(() => true.AsTask()));
                }
            }

            var rowKeyRef       = updatedEntity.RowKey;
            var partitionKeyRef = updatedEntity.PartitionKey;

            var memberType  = typeof(TEntity);
            var taskValue   = newValue.ExecuteFunction(out Type taskType);
            var resultValue = await taskValue.CastAsTaskObjectAsync(out Type typeToSave);

            var rawValues = Serialize(resultValue, typeToSave);

            ITableEntity subtableEntity = new SubtableEntity(rowKeyRef, partitionKeyRef, rawValues);
            var          tableName      = StorageLookupAttribute.GetMemberTableName(memberInfo);
            var          tableRef       = repository.TableClient.GetTableReference(tableName);

            return(await repository.InsertOrReplaceAsync(subtableEntity, new E5CloudTable(tableRef),
                                                         (created, tr) => onSuccessWithRollback(() => 1.AsTask())));
        }
Ejemplo n.º 3
0
        public static Uri GenerateBlobFileSasLink(this string containerName, string blobName,
                                                  TimeSpan?lifespan = default(TimeSpan?))
        {
            var expiresOn = lifespan.HasValue ?
                            DateTime.UtcNow + lifespan.Value
                :
                            DateTime.UtcNow.AddMinutes(15);//default SAS token expire after 15 minutes.

            var blobSasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = containerName,
                BlobName          = blobName,
                ExpiresOn         = expiresOn,
            };

            blobSasBuilder.SetPermissions(BlobSasPermissions.Write);

            var azureDriver         = AzureTableDriverDynamic.FromSettings();
            var blobClient          = azureDriver.BlobClient;
            var sharedKeyCredential = azureDriver.StorageSharedKeyCredential;
            var sasToken            = blobSasBuilder.ToSasQueryParameters(sharedKeyCredential).ToString();
            var sasUrl = blobClient.Uri
                         .AppendToPath(containerName)
                         .AppendToPath(blobName)
                         .SetQuery(sasToken);

            return(sasUrl);
        }
        public async Task <TResult> ExecuteDeleteAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                          string rowKeyRef, string partitionKeyRef,
                                                                          TEntity value, IDictionary <string, EntityProperty> dictionary,
                                                                          AzureTableDriverDynamic repository,
                                                                          Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                          Func <TResult> onFailure)
        {
            var type     = memberInfo.GetMemberType().GenericTypeArguments.First();
            var rollback = await type
                           .GetMembers(BindingFlags.Public | BindingFlags.Instance)
                           .Where(member => member.ContainsAttributeInterface <IDeleteCascaded>())
                           .First <MemberInfo, Task <Func <Task> > >(
                (member, next) =>
            {
                var cascadeAttr = member.GetAttributeInterface <IDeleteCascaded>();
                if (cascadeAttr.Cascade != this.Name)
                {
                    return(next());
                }
                return(cascadeAttr.CascadeDeleteAsync(member,
                                                      rowKeyRef, partitionKeyRef,
                                                      value, dictionary,
                                                      repository));
            },
                () => throw new Exception($"Cascade references property named {this.Name} on {type.FullName} which does not exists or does not contain attribute of type {typeof(IDeleteCascaded).FullName}."));

            return(onSuccessWithRollback(rollback));
        }
Ejemplo n.º 5
0
        public Task <TResult> ExecuteUpdateAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                    string rowKey, string partitionKey,
                                                                    TEntity valueExisting, IDictionary <string, EntityProperty> dictionaryExisting,
                                                                    TEntity valueUpdated, IDictionary <string, EntityProperty> dictionaryUpdated,
                                                                    AzureTableDriverDynamic repository,
                                                                    Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                    Func <TResult> onFailure)
        {
            var to             = (IModifyAzureStorageTablePartitionKey)Activator.CreateInstance(this.To);
            var toPartitionKey = to.GeneratePartitionKey(rowKey, valueUpdated, memberInfo);
            var typeWrapper    = new TypeWrapper(rowKey, toPartitionKey, dictionaryUpdated);

            return(repository.InsertOrReplaceAsync <TEntity, TResult>(typeWrapper,
                                                                      (created, newEntity) => onSuccessWithRollback(
                                                                          () =>
            {
                if (created)
                {
                    return repository.DeleteAsync <TEntity, bool>(newEntity,
                                                                  () => true,
                                                                  () => true);
                }
                var typeWrapperExisting = new TypeWrapper(rowKey, toPartitionKey, dictionaryExisting);
                return repository.ReplaceAsync <TEntity, bool>(typeWrapperExisting,
                                                               () => true);
            })));
        }
 public Task <TResult> ExecuteDeleteModifiersAsync <TResult>(AzureTableDriverDynamic repository,
                                                             Func <Func <Task>, TResult> onSuccessWithRollback,
                                                             Func <MemberInfo[], TResult> onFailure)
 {
     return(GetExecutionResults(repository,
                                (memberInfo, storageModifier) =>
     {
         return storageModifier.ExecuteDeleteAsync(memberInfo,
                                                   this.RowKey, this.PartitionKey,
                                                   this.Entity, this.WriteEntity(null),
                                                   repository,
                                                   rollback =>
         {
             return new ExecResult
             {
                 success = true,
                 rollback = rollback,
                 member = memberInfo,
             };
         },
                                                   () =>
         {
             return new ExecResult
             {
                 success = false,
                 rollback = default(Func <Task>),
                 member = memberInfo,
             };
         });
     },
                                onSuccessWithRollback: onSuccessWithRollback,
                                onFailure: onFailure));
 }
        public virtual async Task <TResult> ExecuteAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                            string rowKeyRef, string partitionKeyRef,
                                                                            TEntity value, IDictionary <string, EntityProperty> dictionary,
                                                                            AzureTableDriverDynamic repository,
                                                                            Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                            Func <TResult> onFailure)
        {
            var propertyValueType    = memberInfo.GetMemberType();
            var rowKeyValue          = memberInfo.GetValue(value);
            var referencedEntityType = ReferenceType.IsDefaultOrNull() ?
                                       propertyValueType.GetGenericArguments().First()
                :
                                       ReferenceType;

            if (!propertyValueType.IsSubClassOfGeneric(typeof(IRef <>)))
            {
                throw new Exception($"`{propertyValueType.FullName}` is instance of IRef<>");
            }

            Task <TResult> result = (Task <TResult>) this.GetType()
                                    .GetMethod("ExecuteTypedAsync", BindingFlags.Public | BindingFlags.Instance)
                                    .MakeGenericMethod(typeof(TEntity), referencedEntityType, typeof(TResult))
                                    .Invoke(this, new object[] { rowKeyValue,
                                                                 memberInfo, rowKeyRef, partitionKeyRef, value, dictionary, repository, onSuccessWithRollback, onFailure });

            return(await result);
        }
Ejemplo n.º 8
0
        public Task <TResult> ExecuteUpdateAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                    IAzureStorageTableEntity <TEntity> updatedEntity,
                                                                    IAzureStorageTableEntity <TEntity> existingEntity,
                                                                    AzureTableDriverDynamic repository,
                                                                    Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                    Func <TResult> onFailure)
        {
            var rowKey            = updatedEntity.RowKey;
            var valueUpdated      = updatedEntity.Entity;
            var dictionaryUpdated = updatedEntity.WriteEntity(null);
            var to                 = (IModifyAzureStorageTablePartitionKey)Activator.CreateInstance(this.To);
            var toPartitionKey     = to.GeneratePartitionKey(rowKey, valueUpdated, memberInfo);
            var typeWrapper        = new TypeWrapper(rowKey, toPartitionKey, dictionaryUpdated);
            var dictionaryExisting = existingEntity.WriteEntity(null);

            return(repository.InsertOrReplaceAsync <TEntity, TResult>(typeWrapper,
                                                                      (created, newEntity) => onSuccessWithRollback(
                                                                          () =>
            {
                if (created)
                {
                    return repository.DeleteAsync <TEntity, bool>(newEntity,
                                                                  () => true,
                                                                  () => true,
                                                                  () => false,
                                                                  (codes, why) => false);
                }
                var typeWrapperExisting = new TypeWrapper(rowKey, toPartitionKey, dictionaryExisting);
                return repository.ReplaceAsync <TEntity, bool>(typeWrapperExisting,
                                                               () => true);
            })));
        }
 public Task <TResult> ExecuteUpdateModifiersAsync <TResult>(IAzureStorageTableEntity <EntityType> current,
                                                             AzureTableDriverDynamic repository,
                                                             Func <Func <Task>, TResult> onSuccessWithRollback,
                                                             Func <MemberInfo[], TResult> onFailure)
 {
     return(GetExecutionResults(repository,
                                (memberInfo, storageModifier) =>
     {
         return storageModifier.ExecuteUpdateAsync(memberInfo,
                                                   this, current,
                                                   repository,
                                                   rollback =>
         {
             return new ExecResult
             {
                 success = true,
                 rollback = rollback,
                 member = memberInfo,
             };
         },
                                                   () =>
         {
             return new ExecResult
             {
                 success = false,
                 rollback = default(Func <Task>),
                 member = memberInfo,
             };
         });
     },
                                onSuccessWithRollback: onSuccessWithRollback,
                                onFailure: onFailure));
 }
        public async Task <TResult> ExecuteDeleteAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                          string rowKeyRef, string partitionKeyRef,
                                                                          TEntity value, IDictionary <string, EntityProperty> dictionary,
                                                                          AzureTableDriverDynamic repository,
                                                                          Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                          Func <TResult> onFailure)
        {
            if (IsIgnored(memberInfo, value))
            {
                return(onSuccessWithRollback(() => true.AsTask()));
            }

            var hashRowKey       = GetHashRowKey(memberInfo, value, out string discard);
            var hashPartitionKey = memberInfo.DeclaringType.Name;
            var tableName        = GetLookupTableName(memberInfo);

            return(await repository.DeleteAsync <StorageLookupTable, TResult>(
                       hashRowKey, hashPartitionKey,
                       async (entity, deleteAsync) =>
            {
                await deleteAsync();
                return onSuccessWithRollback(
                    () => repository.CreateAsync(entity,
                                                 (discardAgain, discard2x) => true, () => false));
            },
                       () => onSuccessWithRollback(() => 1.AsTask()),
                       (codes, why) => onSuccessWithRollback(() => 1.AsTask()),
                       tableName : tableName));
        }
Ejemplo n.º 11
0
        // NOTE: This table will contain duplication indexes.
        // This is important so rollback can undo exactly what it did.
        // Removal of duplicate entries inside of Execution Chain can
        // result in data loss during concurrent operations.

        public virtual async Task <TResult> ExecuteAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                            string rowKeyRef, string partitionKeyRef,
                                                                            TEntity value, IDictionary <string, EntityProperty> dictionary,
                                                                            AzureTableDriverDynamic repository,
                                                                            Func <IEnumerable <KeyValuePair <string, string> >, IEnumerable <KeyValuePair <string, string> > > mutateCollection,
                                                                            Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                            Func <TResult> onFailure)
        {
            var rollbacks = await GetKeys(memberInfo, value)
                            .Select(
                lookupKey =>
            {
                return(MutateLookupTable(lookupKey.RowKey, lookupKey.PartitionKey,
                                         memberInfo, repository, mutateCollection));
            })
                            .WhenAllAsync();

            Func <Task> allRollbacks =
                () =>
            {
                var tasks = rollbacks.Select(rb => rb());
                return(Task.WhenAll(tasks));
            };

            return(onSuccessWithRollback(allRollbacks));
        }
        public async Task <TResult> ExecuteInsertOrReplaceAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                                   string rowKeyRef, string partitionKeyRef,
                                                                                   TEntity value, IDictionary <string, EntityProperty> dictionary,
                                                                                   AzureTableDriverDynamic repository,
                                                                                   Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                                   Func <TResult> onFailure)
        {
            if (IsIgnored(memberInfo, value))
            {
                return(onSuccessWithRollback(() => true.AsTask()));
            }
            var hashRowKey       = GetHashRowKey(memberInfo, value, out string[] hashKeys);
            var hashPartitionKey = memberInfo.DeclaringType.Name;
            var tableName        = GetLookupTableName(memberInfo);

            return(await repository.UpdateOrCreateAsync <StorageLookupTable, TResult>(
                       hashRowKey, hashPartitionKey,
                       async (created, lookup, saveAsync) =>
            {
                bool ClaimedByDifferentResource()
                {
                    if (created)
                    {
                        return false;
                    }

                    if (lookup.rowKeyRef != rowKeyRef)
                    {
                        return true;
                    }

                    if (lookup.partitionKeyRef != partitionKeyRef)
                    {
                        return true;
                    }

                    return false;
                }

                if (ClaimedByDifferentResource())
                {
                    return onFailure();
                }

                lookup.rowKeyRef = rowKeyRef;
                lookup.partitionKeyRef = partitionKeyRef;
                lookup.hashvalues = hashKeys;
                await saveAsync(lookup);
                Func <Task <bool> > rollback =
                    async() =>
                {
                    return await repository.DeleteAsync <StorageLookupTable, bool>(hashRowKey, hashPartitionKey,
                                                                                   () => true,
                                                                                   () => false,
                                                                                   tableName: tableName);
                };
                return onSuccessWithRollback(rollback);
            },
                       tableName : tableName));
        }
Ejemplo n.º 13
0
        public Task <Func <Task> > CascadeDeleteAsync <TEntity>(MemberInfo memberInfo,
                                                                string rowKeyRef, string partitionKeyRef,
                                                                TEntity memberValue, IDictionary <string, EntityProperty> dictionary,
                                                                AzureTableDriverDynamic repository)
        {
            var tableName = GetLookupTableName(memberInfo);

            return(repository
                   .DeleteAsync <StorageLookupTable, Func <Task> >(rowKeyRef, partitionKeyRef,
                                                                   async(lookupTable, deleteAsync) =>
            {
                var lookupEntity = await deleteAsync();
                var rollbacks = await lookupTable
                                .rowAndPartitionKeys
                                .NullToEmpty()
                                .Select(rowParitionKeyKvp =>
                                        repository.DeleteAsync <Func <Task> >(rowParitionKeyKvp.Key, rowParitionKeyKvp.Value, memberInfo.DeclaringType,
                                                                              (entity, data) =>
                                                                              () => (Task)repository.CreateAsync(entity, memberInfo.DeclaringType,
                                                                                                                 (x) => true, () => false),
                                                                              () =>
                                                                              () => 1.AsTask()))
                                .AsyncEnumerable()
                                .Append(
                    () => repository.CreateAsync(lookupEntity, tableName,
                                                 x => true,
                                                 () => false))
                                .ToArrayAsync();
                Func <Task> rollbacksAll = () => Task.WhenAll(rollbacks.Select(rollback => rollback()));
                return rollbacksAll;
            },
                                                                   () => () => 0.AsTask(),
                                                                   tableName: tableName));
        }
Ejemplo n.º 14
0
 public Task <TResult> ExecuteInsertOrReplaceAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                      string rowKeyRef, string partitionKeyRef,
                                                                      TEntity value, IDictionary <string, EntityProperty> dictionary,
                                                                      AzureTableDriverDynamic repository,
                                                                      Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                      Func <TResult> onFailure)
 {
     return(onFailure().AsTask());
 }
 public Task <TResult> ExecuteUpdateAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                             IAzureStorageTableEntity <TEntity> updatedEntity,
                                                             IAzureStorageTableEntity <TEntity> existingEntity,
                                                             AzureTableDriverDynamic repository,
                                                             Func <Func <Task>, TResult> onSuccessWithRollback,
                                                             Func <TResult> onFailure)
 {
     return(onSuccessWithRollback(() => true.AsTask()).AsTask());
 }
 public Task <TResult> ExecuteUpdateAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                             string rowKeyRef, string partitionKeyRef,
                                                             TEntity valueExisting, IDictionary <string, EntityProperty> dictionaryExisting,
                                                             TEntity valueUpdated, IDictionary <string, EntityProperty> dictionaryUpdated,
                                                             AzureTableDriverDynamic repository,
                                                             Func <Func <Task>, TResult> onSuccessWithRollback,
                                                             Func <TResult> onFailure)
 {
     return(onSuccessWithRollback(() => true.AsTask()).AsTask());
 }
 public Task <TResult> ExecuteUpdateAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                             IAzureStorageTableEntity <TEntity> updatedEntity,
                                                             IAzureStorageTableEntity <TEntity> existingEntity,
                                                             AzureTableDriverDynamic repository,
                                                             Func <Func <Task>, TResult> onSuccessWithRollback,
                                                             Func <TResult> onFailure)
 {
     // Since only updating the row/partition keys could force a change here, just ignroe
     return(onSuccessWithRollback(
                () => true.AsTask()).AsTask());
 }
Ejemplo n.º 18
0
 public StorageQueryProvideQuery(AzureTableDriverDynamic storageDriver)
     : base(
         (queryProvider, type) => (queryProvider is StorageQuery <TResource>)?
         (queryProvider as StorageQuery <TResource>).From()
             :
         new StorageQuery <TResource>(storageDriver),
         (queryProvider, expression, type) => (queryProvider is StorageQuery <TResource>) ?
         (queryProvider as StorageQuery <TResource>).FromExpression(expression)
             :
         new StorageQuery <TResource>(storageDriver, expression))
 {
 }
Ejemplo n.º 19
0
 internal static AzureTableDriverDynamic GetRepository(string connectionString)
 {
     if (!repositories.TryGetValue(connectionString, out AzureTableDriverDynamic repository))
     {
         repository = AzureTableDriverDynamic.FromStorageString(connectionString);
         if (!repositories.TryAdd(connectionString, repository))
         {
             repositories.TryGetValue(connectionString, out repository);
         }
     }
     return(repository);
 }
Ejemplo n.º 20
0
        public virtual Task <IHttpResponse> InstigatorDelegateGeneric(Type type,
                                                                      IApplication httpApp, IHttpRequest routeData, ParameterInfo parameterInfo,
                                                                      Func <object, Task <IHttpResponse> > onSuccess)
        {
            var constructor = typeof(StorageQuery <>)
                              .MakeGenericType(type.GenericTypeArguments)
                              .GetConstructors(BindingFlags.Public | BindingFlags.Instance)
                              .First();
            var parameter = AzureTableDriverDynamic.FromSettings();
            var sq        = constructor.Invoke(parameter.AsArray());

            return(onSuccess(sq));
        }
            public async Task <TResult> ExecuteCreateModifiersAsync <TResult>(AzureTableDriverDynamic repository,
                                                                              Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                              Func <MemberInfo[], TResult> onFailure)
            {
                var modifierResults = await typeof(EntityType)
                                      .GetPropertyOrFieldMembers()
                                      .Where(member => member.ContainsAttributeInterface <IModifyAzureStorageTableSave>())
                                      .SelectMany(memberInfo =>
                                                  memberInfo
                                                  .GetAttributesInterface <IModifyAzureStorageTableSave>()
                                                  .Select(
                                                      storageModifier =>
                {
                    return(storageModifier.ExecuteCreateAsync(memberInfo,
                                                              this.RowKey, this.PartitionKey,
                                                              this.Entity, this.WriteEntity(null),
                                                              repository,
                                                              rollback =>
                                                              new ExecResult
                    {
                        success = true,
                        rollback = rollback,
                        member = memberInfo,
                    },
                                                              () =>
                                                              new ExecResult
                    {
                        success = false,
                        member = memberInfo,
                    }));
                }))
                                      .AsyncEnumerable()
                                      .ToArrayAsync();
                var rollbacks = modifierResults
                                .Where(result => result.success)
                                .Select(result => result.rollback());
                var failures = modifierResults
                               .Where(result => !result.success)
                               .Select(result => result.member);
                var didFail = failures.Any();

                if (didFail)
                {
                    await Task.WhenAll(rollbacks);

                    return(onFailure(failures.ToArray()));
                }

                return(onSuccessWithRollback(
                           () => Task.WhenAll(rollbacks)));
            }
Ejemplo n.º 22
0
        public static async Task <HttpResponseMessage> QueueUpBackupPartitions(
            [Property(Name = IdPropertyName)] IRef <RepositoryBackup> repositoryBackupRef,
            [Property(Name = StorageSettingCopyFromPropertyName)] string storageSettingCopyFrom,
            [Property(Name = StorageSettingCopyToPropertyName)] string storageSettingCopyTo,
            [Resource] RepositoryBackup repositoryBackup,
            AzureApplication application,
            RequestMessage <TableBackup> requestQuery,
            HttpRequestMessage request,
            EastFive.Analytics.ILogger logger,
            MultipartResponseAsync <InvocationMessage> onQueued,
            AlreadyExistsResponse onAlreadyExists)
        {
            logger.Trace($"Cleaning backup results");
            var repo = AzureTableDriverDynamic.FromStorageString(storageSettingCopyTo);

            await DeleteAllAsync(GetRepository(storageSettingCopyTo));

            CloudStorageAccount account = CloudStorageAccount
                                          .Parse(storageSettingCopyFrom);
            CloudTableClient tableClient =
                new CloudTableClient(account.TableEndpoint, account.Credentials);

            return(await await repositoryBackup.StorageCreateAsync(
                       (discard) =>
            {
                var resourceInfoToProcess = tableClient
                                            .ListTables()
                                            .Distinct()
                                            .Select(
                    async cloudTable =>
                {
                    var tableBackup = new TableBackup()
                    {
                        tableBackupRef = Ref <TableBackup> .NewRef(),
                        backup = repositoryBackupRef,
                        tableName = cloudTable.Name,
                        when = DateTime.UtcNow,
                    };
                    var invocationMessage = await requestQuery
                                            .HttpPost(tableBackup)
                                            .CompileRequest(request)
                                            .FunctionAsync();

                    logger.Trace($"Invocation[{invocationMessage.id}] will backup table `{tableBackup.tableName}`.");
                    return invocationMessage;
                })
                                            .AsyncEnumerable();
                return onQueued(resourceInfoToProcess);
            },
                       () => onAlreadyExists().AsTask()));
        }
 public Task <TResult> ExecuteDeleteAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                             string rowKeyRef, string partitionKeyRef,
                                                             TEntity value, IDictionary <string, EntityProperty> dictionary,
                                                             AzureTableDriverDynamic repository,
                                                             Func <Func <Task>, TResult> onSuccessWithRollback,
                                                             Func <TResult> onFailure)
 {
     return(ExecuteAsync(memberInfo,
                         rowKeyRef, partitionKeyRef,
                         value, dictionary,
                         repository,
                         onSuccessWithRollback,
                         onFailure));
 }
Ejemplo n.º 24
0
 public virtual Task <TResult> ExecuteCreateAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                     string rowKeyRef, string partitionKeyRef,
                                                                     TEntity value, IDictionary <string, EntityProperty> dictionary,
                                                                     AzureTableDriverDynamic repository,
                                                                     Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                     Func <TResult> onFailure)
 {
     return(ExecuteAsync(memberInfo,
                         rowKeyRef, partitionKeyRef,
                         value, dictionary,
                         repository,
                         (rowAndParitionKeys) => rowAndParitionKeys.NullToEmpty().Append(rowKeyRef.PairWithValue(partitionKeyRef)),
                         onSuccessWithRollback,
                         onFailure));
 }
Ejemplo n.º 25
0
        public Task <TResult> ExecuteDeleteModifiersAsync <TResult>(AzureTableDriverDynamic repository,
                                                                    Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                    Func <MemberInfo[], TResult> onFailure)
        {
            var hasModifiers = typeof(EntityType)
                               .GetPropertyOrFieldMembers()
                               .Where(member => member.ContainsAttributeInterface <IModifyAzureStorageTableSave>())
                               .Any();

            if (hasModifiers)
            {
                throw new NotImplementedException("Please use the non-depricated StorageTableAttribute with modifier classes");
            }

            return(onSuccessWithRollback(
                       () => 1.AsTask()).AsTask());
        }
            public static Task CreateOrUpdateAsync(AzureTableDriverDynamic destRepo, string resource, string filter, int?count = default, double?seconds = default)
            {
                var backupRef = GetBackupRef(resource, filter);

                return(destRepo.UpdateOrCreateAsync <Backup, Backup>(
                           backupRef.StorageComputeRowKey(),
                           backupRef.StorageComputePartitionKey(),
                           async(created, storageToUpdate, saveAsync) =>
                {
                    storageToUpdate.resource = resource;
                    storageToUpdate.filter = filter;
                    storageToUpdate.count = count;
                    storageToUpdate.seconds = seconds;
                    await saveAsync(storageToUpdate);
                    return storageToUpdate;
                }));
            }
Ejemplo n.º 27
0
 public Task <TResult> ExecuteDeleteAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                             string rowKeyRef, string partitionKeyRef,
                                                             TEntity value, IDictionary <string, EntityProperty> dictionary,
                                                             AzureTableDriverDynamic repository,
                                                             Func <Func <Task>, TResult> onSuccessWithRollback,
                                                             Func <TResult> onFailure)
 {
     return(ExecuteAsync(memberInfo,
                         rowKeyRef, partitionKeyRef,
                         value, dictionary,
                         repository,
                         (rowAndParitionKeys) => rowAndParitionKeys
                         .NullToEmpty()
                         .Where(kvp => kvp.Key != rowKeyRef && kvp.Value != partitionKeyRef),
                         onSuccessWithRollback,
                         onFailure));
 }
Ejemplo n.º 28
0
        public async Task <TResult> ExecuteUpdateAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                          IAzureStorageTableEntity <TEntity> updatedEntity,
                                                                          IAzureStorageTableEntity <TEntity> existingEntity,
                                                                          AzureTableDriverDynamic repository,
                                                                          Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                          Func <TResult> onFailure)
        {
            var existingRowKeys   = GetKeys(memberInfo, existingEntity.Entity);
            var updatedRowKeys    = GetKeys(memberInfo, updatedEntity.Entity);
            var rowKeysDeleted    = existingRowKeys.Except(updatedRowKeys, rk => $"{rk.RowKey}|{rk.PartitionKey}");
            var rowKeysAdded      = updatedRowKeys.Except(existingRowKeys, rk => $"{rk.RowKey}|{rk.PartitionKey}");
            var deletionRollbacks = rowKeysDeleted
                                    .Select(
                rowKey =>
            {
                return(MutateLookupTable(rowKey.RowKey, rowKey.PartitionKey, memberInfo,
                                         repository,
                                         (rowAndParitionKeys) => rowAndParitionKeys
                                         .NullToEmpty()
                                         .Where(kvp =>
                                                kvp.Key != existingEntity.RowKey &&
                                                kvp.Value != existingEntity.PartitionKey)
                                         .ToArray()));
            });
            var additionRollbacks = rowKeysAdded
                                    .Select(
                rowKey =>
            {
                return(MutateLookupTable(rowKey.RowKey, rowKey.PartitionKey, memberInfo,
                                         repository,
                                         (rowAndParitionKeys) => rowAndParitionKeys
                                         .NullToEmpty()
                                         .Append(updatedEntity.RowKey.PairWithValue(updatedEntity.PartitionKey))
                                         .ToArray()));
            });
            var allRollbacks = await additionRollbacks.Concat(deletionRollbacks).WhenAllAsync();

            Func <Task> allRollback =
                () =>
            {
                var tasks = allRollbacks.Select(rb => rb());
                return(Task.WhenAll(tasks));
            };

            return(onSuccessWithRollback(allRollback));
        }
Ejemplo n.º 29
0
        public virtual Task <TResult> ExecuteCreateAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                            string rowKey, string partitionKey,
                                                                            TEntity value, IDictionary <string, EntityProperty> dictionary,
                                                                            AzureTableDriverDynamic repository,
                                                                            Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                            Func <TResult> onFailure)
        {
            var to             = (IModifyAzureStorageTablePartitionKey)Activator.CreateInstance(this.To);
            var toPartitionKey = to.GeneratePartitionKey(rowKey, value, memberInfo);
            var typeWrapper    = new TypeWrapper(rowKey, toPartitionKey, dictionary);

            return(repository.CreateAsync <TEntity, TResult>(typeWrapper,
                                                             (entity) => onSuccessWithRollback(
                                                                 () => repository.DeleteAsync <TEntity, bool>(entity,
                                                                                                              () => true,
                                                                                                              () => true)),
                                                             () => onSuccessWithRollback(() => false.AsTask())));
        }
Ejemplo n.º 30
0
        public async Task <TResult> ExecuteInsertOrReplaceAsync <TEntity, TResult>(MemberInfo memberInfo,
                                                                                   string rowKeyRef, string partitionKeyRef,
                                                                                   TEntity value, IDictionary <string, EntityProperty> dictionary,
                                                                                   AzureTableDriverDynamic repository,
                                                                                   Func <Func <Task>, TResult> onSuccessWithRollback,
                                                                                   Func <TResult> onFailure)
        {
            var existingRowKeys = GetKeys(memberInfo, value);
            var tableName       = GetLookupTableName(memberInfo);
            var missingRows     = existingRowKeys
                                  .Select(
                async astKey =>
            {
                var isGood = await repository.FindByIdAsync <StorageLookupTable, bool>(astKey.RowKey, astKey.PartitionKey,
                                                                                       (lookup, tableResult) =>
                {
                    var rowAndParitionKeys = lookup.rowAndPartitionKeys;
                    var rowKeyFound        = rowAndParitionKeys
                                             .NullToEmpty()
                                             .Where(kvp => kvp.Key == rowKeyRef)
                                             .Any();
                    var partitionKeyFound = rowAndParitionKeys
                                            .NullToEmpty()
                                            .Where(kvp => kvp.Value == partitionKeyRef)
                                            .Any();
                    if (rowKeyFound && partitionKeyFound)
                    {
                        return(true);
                    }
                    return(false);
                },
                                                                                       onNotFound: () => false,
                                                                                       tableName: tableName);
                return(isGood);
            })
                                  .AsyncEnumerable()
                                  .Where(item => !item);

            if (await missingRows.AnyAsync())
            {
                return(onFailure());
            }
            return(onSuccessWithRollback(() => 1.AsTask()));
        }