public async void SendWaitForTransactionEndingCommand([FromBody] EnrollToMatchingEngineCommand command)
 {
     _cqrsEngine.SendCommand(command, $"{CqrsModule.Self}.saga", CqrsModule.Self);
 }
示例#2
0
        public async Task <CommandHandlingResult> Handle(EnrollToMatchingEngineCommand command, IEventPublisher publisher)
        {
            // First level deduplication just to reduce traffic to the ME
            if (await _deduplicationRepository.IsExistsAsync(command.CashinOperationId))
            {
                _log.Info("Deduplicated at first level", command);

                // Workflow should be continued

                publisher.PublishEvent(new CashinEnrolledToMatchingEngineEvent
                {
                    CashoutOperationId = command.CashoutOperationId
                });

                return(CommandHandlingResult.Ok());
            }

            var cashInResult = await _meClient.CashInOutAsync(
                command.CashinOperationId.ToString(),
                command.RecipientClientId.ToString(),
                command.AssetId,
                (double)command.Amount);

            _chaosKitty.Meow(command.CashoutOperationId);

            if (cashInResult == null)
            {
                throw new InvalidOperationException("ME response is null, don't know what to do");
            }

            switch (cashInResult.Status)
            {
            case MeStatusCodes.Ok:
            case MeStatusCodes.Duplicate:
                if (cashInResult.Status == MeStatusCodes.Duplicate)
                {
                    _log.Info("Deduplicated by the ME", command);
                }

                publisher.PublishEvent(new CashinEnrolledToMatchingEngineEvent
                {
                    CashoutOperationId = command.CashoutOperationId
                });

                _chaosKitty.Meow(command.CashinOperationId);

                await _deduplicationRepository.InsertOrReplaceAsync(command.CashinOperationId);

                _chaosKitty.Meow(command.CashinOperationId);

                return(CommandHandlingResult.Ok());

            case MeStatusCodes.Runtime:
                // Retry forever with the default delay + log the error outside.
                throw new Exception($"Cashin into the ME is failed. ME status: {cashInResult.Status}, ME message: {cashInResult.Message}");

            default:
                // Just abort cashout for further manual processing. ME call could not be retried anyway if responce was received.
                _log.Warning(
                    $"Unexpected response from ME. Status: {cashInResult.Status}, ME message: {cashInResult.Message}",
                    context: command);
                return(CommandHandlingResult.Ok());
            }
        }
示例#3
0
        public async Task <CommandHandlingResult> Handle(EnrollToMatchingEngineCommand command, IEventPublisher publisher)
        {
            var clientId = command.ClientId;

            var amountDecimal = (decimal)command.MatchingEngineOperationAmount;

            var scale  = amountDecimal.GetScale();
            var amount = command.MatchingEngineOperationAmount.TruncateDecimalPlaces(scale);

            if (clientId == null)
            {
                clientId = await _walletsClient.TryGetClientIdAsync(
                    command.BlockchainType,
                    command.DepositWalletAddress);
            }

            if (clientId == null)
            {
                throw new InvalidOperationException("Client ID for the blockchain deposit wallet address is not found");
            }

            // First level deduplication just to reduce traffic to the ME
            if (await _deduplicationRepository.IsExistsAsync(command.OperationId))
            {
                _log.Info(nameof(EnrollToMatchingEngineCommand), "Deduplicated at first level", command.OperationId);

                // Workflow should be continued

                publisher.PublishEvent(new CashinEnrolledToMatchingEngineEvent
                {
                    ClientId    = clientId.Value,
                    OperationId = command.OperationId
                });

                return(CommandHandlingResult.Ok());
            }

            var cashInResult = await _meClient.CashInOutAsync
                               (
                id : command.OperationId.ToString(),
                clientId : clientId.Value.ToString(),
                assetId : command.AssetId,
                amount : amount
                               );

            _chaosKitty.Meow(command.OperationId);

            if (cashInResult == null)
            {
                throw new InvalidOperationException("ME response is null, don't know what to do");
            }

            switch (cashInResult.Status)
            {
            case MeStatusCodes.Ok:
            case MeStatusCodes.Duplicate:
                if (cashInResult.Status == MeStatusCodes.Duplicate)
                {
                    _log.Info(nameof(EnrollToMatchingEngineCommand), "Deduplicated by the ME", command.OperationId);
                }

                publisher.PublishEvent(new CashinEnrolledToMatchingEngineEvent
                {
                    ClientId    = clientId.Value,
                    OperationId = command.OperationId
                });

                _chaosKitty.Meow(command.OperationId);

                await _deduplicationRepository.InsertOrReplaceAsync(command.OperationId);

                _chaosKitty.Meow(command.OperationId);

                return(CommandHandlingResult.Ok());

            case MeStatusCodes.Runtime:
                // Retry forever with the default delay + log the error outside.
                throw new Exception($"Cashin into the ME is failed. ME status: {cashInResult.Status}, ME message: {cashInResult.Message}");

            default:
                // Just abort cashin for futher manual processing. ME call could not be retried anyway if responce was received.
                _log.Error(nameof(EnrollToMatchingEngineCommand), null, $"Unexpected response from ME. Status: {cashInResult.Status}, ME message: {cashInResult.Message}", context: command.OperationId);
                return(CommandHandlingResult.Ok());
            }
        }