public async Task ExecuteJob(long jobId)
        {
            try
            {
                _jobHistoryService.ChangeJobStatus(JobStatus.Executing, jobId);
                var status = new StatusEnum();

                var jobTimeline     = _entity.JobTimeline.Find(jobId);
                var jobDefinitionId = jobTimeline.Schedule.JobDefinition.Id;
                var fromAdapter     = jobTimeline.Schedule.JobDefinition.Adapter;

                string fromBlock;
                string toBlock;
                string address;

                int ethLimit = Int32.Parse(_configuration["Limits:EthereumBlocks"]);
                int btcLimit = Int32.Parse(_configuration["Limits:BitcoinBlocks"]);
                int neoLimit = Int32.Parse(_configuration["Limits:NEOBlocks"]);
                int ltcLimit = Int32.Parse(_configuration["Limits:LitecoinBlocks"]);

                switch ((AdapterTypeItemEnum)fromAdapter.AdapterTypeItemId)
                {
                case AdapterTypeItemEnum.MSSQL:
                case AdapterTypeItemEnum.MySQL:
                case AdapterTypeItemEnum.Oracle:

                    var data = _dbAdapterService.GetAdapterData(jobDefinitionId);

                    if (data.Status == StatusEnum.Success && data.Value.Count > 0)
                    {
                        var transactionData = new TransactionDataModel
                        {
                            JobId = jobId,
                            Data  = data.Value
                        };

                        await _transactionService.AddToTransaction(transactionData);

                        var transactions = _transactionService.GetTransactionsWithoutHash(jobId);

                        if (transactions.Status == StatusEnum.Success)
                        {
                            var blockchainDataList = new List <BlockchainDataModel>()
                            {
                                new BlockchainDataModel
                                {
                                    JobId        = jobId,
                                    Transactions = transactions.Value
                                }
                            };

                            status = await SendData(jobId, blockchainDataList);

                            break;
                        }
                    }
                    status = StatusEnum.Error;
                    break;

                case AdapterTypeItemEnum.MongoDB:
                    break;

                case AdapterTypeItemEnum.Ethereum:

                    fromBlock = jobTimeline.Schedule.JobDefinition.JobDefinitionProperty.FirstOrDefault(jdp => jdp.PropertyId == (long)PropertyEnum.FromBlock).Value;
                    toBlock   = jobTimeline.Schedule.JobDefinition.JobDefinitionProperty.FirstOrDefault(jdp => jdp.PropertyId == (long)PropertyEnum.ToBlock).Value;
                    address   = jobTimeline.Schedule.JobDefinition.JobDefinitionProperty.FirstOrDefault(jdp => jdp.PropertyId == (long)PropertyEnum.EthereumAccount).Value;

                    int fromBlockConverted;
                    int toBlockConverted;

                    Int32.TryParse(fromBlock, out fromBlockConverted);
                    Int32.TryParse(toBlock, out toBlockConverted);

                    var ethereumCurrentBlock = await _blockchainService.GetCurrentBlockNumber(fromAdapter.Id, AdapterTypeItemEnum.Ethereum);

                    if (ethereumCurrentBlock.Status == StatusEnum.Success)
                    {
                        if (fromBlockConverted == 0)
                        {
                            fromBlockConverted = 1;
                        }

                        if (toBlockConverted == 0)
                        {
                            toBlockConverted = ethereumCurrentBlock.Value;
                        }

                        if (Math.Abs(toBlockConverted - fromBlockConverted) < ethLimit && fromBlockConverted < ethereumCurrentBlock.Value && toBlockConverted <= ethereumCurrentBlock.Value)
                        {
                            var blocks = await _blockchainService.GetBlocksWithTransactions <EthereumBlockModel>(fromAdapter.Id, fromBlockConverted, toBlockConverted, address);

                            if (blocks.Status == StatusEnum.Success)
                            {
                                status = await SendData(jobId, blocks.Value);

                                if (status != StatusEnum.Error)
                                {
                                    if (jobTimeline.Schedule.RecurrenceRule != null)
                                    {
                                        _blockTransactionService.AddBlocksWithTransactions(jobId, blocks.Value);
                                    }
                                    break;
                                }
                            }
                            status = StatusEnum.Error;
                            break;
                        }
                        _jobHistoryService.ChangeJobStatus(JobStatus.Failed, jobId, limitExceeded: true);
                        break;
                    }

                    status = StatusEnum.Error;
                    break;

                case AdapterTypeItemEnum.Cardano:
                case AdapterTypeItemEnum.EOS:
                    break;

                case AdapterTypeItemEnum.NEO:

                    fromBlock = jobTimeline.Schedule.JobDefinition.JobDefinitionProperty.FirstOrDefault(jdp => jdp.PropertyId == (long)PropertyEnum.FromBlock).Value;
                    toBlock   = jobTimeline.Schedule.JobDefinition.JobDefinitionProperty.FirstOrDefault(jdp => jdp.PropertyId == (long)PropertyEnum.ToBlock).Value;
                    address   = jobTimeline.Schedule.JobDefinition.JobDefinitionProperty.FirstOrDefault(jdp => jdp.PropertyId == (long)PropertyEnum.NeoAddress).Value;

                    Int32.TryParse(fromBlock, out fromBlockConverted);
                    Int32.TryParse(toBlock, out toBlockConverted);

                    var neoCurrentBlock = await _blockchainService.GetCurrentBlockNumber(fromAdapter.Id, AdapterTypeItemEnum.NEO);

                    if (neoCurrentBlock.Status == StatusEnum.Success)
                    {
                        if (fromBlockConverted == 0)
                        {
                            fromBlockConverted = 1;
                        }

                        if (toBlockConverted == 0)
                        {
                            toBlockConverted = neoCurrentBlock.Value;
                        }

                        if (Math.Abs(toBlockConverted - fromBlockConverted) < neoLimit && fromBlockConverted < neoCurrentBlock.Value && toBlockConverted <= neoCurrentBlock.Value)
                        {
                            var neoBlocks = await _blockchainService.GetBlocksWithTransactions <NeoBlockModel>(fromAdapter.Id, fromBlockConverted, toBlockConverted, address);

                            if (neoBlocks.Status == StatusEnum.Success)
                            {
                                status = await SendData(jobId, neoBlocks.Value);

                                if (status != StatusEnum.Error)
                                {
                                    if (jobTimeline.Schedule.RecurrenceRule != null)
                                    {
                                        _blockTransactionService.AddBlocksWithTransactions(jobId, neoBlocks.Value);
                                    }
                                    break;
                                }
                            }
                            status = StatusEnum.Error;
                            break;
                        }
                        _jobHistoryService.ChangeJobStatus(JobStatus.Failed, jobId, limitExceeded: true);
                        break;
                    }
                    status = StatusEnum.Error;
                    break;

                case AdapterTypeItemEnum.Bitcoin:

                    fromBlock = jobTimeline.Schedule.JobDefinition.JobDefinitionProperty.FirstOrDefault(jdp => jdp.PropertyId == (long)PropertyEnum.FromBlock).Value;
                    toBlock   = jobTimeline.Schedule.JobDefinition.JobDefinitionProperty.FirstOrDefault(jdp => jdp.PropertyId == (long)PropertyEnum.ToBlock).Value;
                    address   = jobTimeline.Schedule.JobDefinition.JobDefinitionProperty.FirstOrDefault(jdp => jdp.PropertyId == (long)PropertyEnum.BitcoinAddress).Value;

                    Int32.TryParse(fromBlock, out fromBlockConverted);
                    Int32.TryParse(toBlock, out toBlockConverted);

                    var bitcoinCurrentBlock = await _blockchainService.GetCurrentBlockNumber(fromAdapter.Id, AdapterTypeItemEnum.Bitcoin);

                    if (bitcoinCurrentBlock.Status == StatusEnum.Success)
                    {
                        if (fromBlockConverted == 0)
                        {
                            fromBlockConverted = 1;
                        }

                        if (toBlockConverted == 0)
                        {
                            toBlockConverted = bitcoinCurrentBlock.Value;
                        }

                        if (Math.Abs(toBlockConverted - fromBlockConverted) < btcLimit && fromBlockConverted < bitcoinCurrentBlock.Value && toBlockConverted <= bitcoinCurrentBlock.Value)
                        {
                            var bitcoinBlocks = await _blockchainService.GetBlocksWithTransactions <BitcoinBlockModel>(fromAdapter.Id, fromBlockConverted, toBlockConverted, address);

                            if (bitcoinBlocks.Status == StatusEnum.Success)
                            {
                                status = await SendData(jobId, bitcoinBlocks.Value);

                                if (status != StatusEnum.Error)
                                {
                                    if (jobTimeline.Schedule.RecurrenceRule != null)
                                    {
                                        _blockTransactionService.AddBlocksWithTransactions(jobId, bitcoinBlocks.Value);
                                    }
                                    break;
                                }
                            }
                            status = StatusEnum.Error;
                            break;
                        }
                        _jobHistoryService.ChangeJobStatus(JobStatus.Failed, jobId, limitExceeded: true);
                        break;
                    }
                    status = StatusEnum.Error;

                    break;

                case AdapterTypeItemEnum.Litecoin:

                    fromBlock = jobTimeline.Schedule.JobDefinition.JobDefinitionProperty.FirstOrDefault(jdp => jdp.PropertyId == (long)PropertyEnum.FromBlock).Value;
                    toBlock   = jobTimeline.Schedule.JobDefinition.JobDefinitionProperty.FirstOrDefault(jdp => jdp.PropertyId == (long)PropertyEnum.ToBlock).Value;
                    address   = jobTimeline.Schedule.JobDefinition.JobDefinitionProperty.FirstOrDefault(jdp => jdp.PropertyId == (long)PropertyEnum.LitecoinAddress).Value;

                    Int32.TryParse(fromBlock, out fromBlockConverted);
                    Int32.TryParse(toBlock, out toBlockConverted);

                    var litecoinCurrentBlock = await _blockchainService.GetCurrentBlockNumber(fromAdapter.Id, AdapterTypeItemEnum.Litecoin);

                    if (litecoinCurrentBlock.Status == StatusEnum.Success)
                    {
                        if (fromBlockConverted == 0)
                        {
                            fromBlockConverted = 1;
                        }

                        if (toBlockConverted == 0)
                        {
                            toBlockConverted = litecoinCurrentBlock.Value;
                        }

                        if (Math.Abs(toBlockConverted - fromBlockConverted) < ltcLimit && fromBlockConverted < litecoinCurrentBlock.Value && toBlockConverted <= litecoinCurrentBlock.Value)
                        {
                            var litecoinBlocks = await _blockchainService.GetBlocksWithTransactions <LitecoinBlockModel>(fromAdapter.Id, fromBlockConverted, toBlockConverted, address);

                            if (litecoinBlocks.Status == StatusEnum.Success)
                            {
                                status = await SendData(jobId, litecoinBlocks.Value);

                                if (status != StatusEnum.Error)
                                {
                                    if (jobTimeline.Schedule.RecurrenceRule != null)
                                    {
                                        _blockTransactionService.AddBlocksWithTransactions(jobId, litecoinBlocks.Value);
                                    }
                                    break;
                                }
                            }
                            status = StatusEnum.Error;
                            break;
                        }
                        _jobHistoryService.ChangeJobStatus(JobStatus.Failed, jobId, limitExceeded: true);
                        break;
                    }
                    status = StatusEnum.Error;

                    break;

                case AdapterTypeItemEnum.Excel:
                case AdapterTypeItemEnum.MATLAB:
                    break;

                default:
                    status = StatusEnum.Error;
                    break;
                }

                if (status == StatusEnum.Error)
                {
                    _jobHistoryService.ChangeJobStatus(JobStatus.Failed, jobId);
                }
            }
            catch (Exception ex)
            {
                _jobHistoryService.ChangeJobStatus(JobStatus.Failed, jobId);
                _logger.Information($"JobService.ExecuteJob(jobId: {jobId})");
                _logger.Error(ex.Message);
            }
        }