Exemplo n.º 1
0
 public Task DeleteAccounts(DeleteAccountsCommand command, CancellationToken token)
 => HandlerDispatcher.Invoke <DeleteAccountsHandler, DeleteAccountsCommand>(command, token);
        private async Task Handle(DeleteAccountsCommand command, IEventPublisher publisher)
        {
            if (string.IsNullOrWhiteSpace(command.OperationId))
            {
                command.OperationId = Guid.NewGuid().ToString("N");
            }

            if (command.AccountIds == null || !command.AccountIds.Any())
            {
                publisher.PublishEvent(new AccountsDeletionFinishedEvent(
                                           command.OperationId,
                                           _systemClock.UtcNow.UtcDateTime,
                                           new List <string>(),
                                           new Dictionary <string, string>(),
                                           command.Comment
                                           ));
                return;
            }

            command.AccountIds = command.AccountIds.Distinct().ToList();

            var executionInfo = await _executionInfoRepository.GetOrAddAsync(
                OperationName,
                command.OperationId,
                () => new OperationExecutionInfo <DeleteAccountsData>(
                    OperationName,
                    command.OperationId,
                    new DeleteAccountsData
            {
                State = DeleteAccountsState.Initiated,
                OperationId = command.OperationId,
                AccountIds = command.AccountIds,
                Comment = command.Comment,
            },
                    _systemClock.UtcNow.UtcDateTime));

            if (executionInfo.Data.State != DeleteAccountsState.Initiated)
            {
                return;
            }

            var failedAccounts = await ValidateAccountsAsync(executionInfo.Data.AccountIds);

            foreach (var accountToBlock in command.AccountIds.Except(failedAccounts.Keys))
            {
                try
                {
                    var account = (await _accountsRepository.GetAsync(accountToBlock))
                                  .RequiredNotNull(nameof(accountToBlock), $"Account {accountToBlock} does not exist.");

                    var result = await _accountsRepository.UpdateAccountAsync(
                        accountToBlock,
                        true,
                        true);

                    _eventSender.SendAccountChangedEvent(
                        nameof(DeleteAccountsCommand),
                        result,
                        AccountChangedEventTypeContract.Updated,
                        $"{command.OperationId}_{accountToBlock}",
                        previousSnapshot: account);
                }
                catch (Exception exception)
                {
                    await _log.WriteErrorAsync(nameof(DeleteAccountsCommandsHandler),
                                               nameof(DeleteAccountsCommand), exception);

                    failedAccounts.Add(accountToBlock, exception.Message);
                }
            }

            if (!command.AccountIds.Except(failedAccounts.Keys).Any())
            {
                publisher.PublishEvent(new AccountsDeletionFinishedEvent(
                                           command.OperationId,
                                           _systemClock.UtcNow.UtcDateTime,
                                           new List <string>(),
                                           failedAccounts,
                                           executionInfo.Data.Comment
                                           ));
                return;
            }

            _chaosKitty.Meow($"{nameof(DeleteAccountsCommand)}: " +
                             "DeleteAccountsStartedInternalEvent: " +
                             $"{command.OperationId}");

            publisher.PublishEvent(new DeleteAccountsStartedInternalEvent(
                                       command.OperationId,
                                       _systemClock.UtcNow.UtcDateTime,
                                       failedAccounts
                                       ));
        }