public async Task <TaskInfo> ResetAsync(string taskId, TaskResultData taskResultData, string runId, CancellationToken cancellationToken)
        {
            using (SqlConnectionWrapper sqlConnectionWrapper = await _sqlConnectionWrapperFactory.ObtainSqlConnectionWrapperAsync(cancellationToken, true))
                using (SqlCommandWrapper sqlCommandWrapper = sqlConnectionWrapper.CreateSqlCommand())
                {
                    try
                    {
                        VLatest.ResetTask.PopulateCommand(sqlCommandWrapper, taskId, runId, JsonConvert.SerializeObject(taskResultData));
                        SqlDataReader sqlDataReader = await sqlCommandWrapper.ExecuteReaderAsync(cancellationToken);

                        if (!sqlDataReader.Read())
                        {
                            return(null);
                        }

                        var taskInfoTable = VLatest.TaskInfo;
                        _ = sqlDataReader.Read(taskInfoTable.TaskId, 0);
                        string   queueId           = sqlDataReader.Read(taskInfoTable.QueueId, 1);
                        short    status            = sqlDataReader.Read(taskInfoTable.Status, 2);
                        short    taskTypeId        = sqlDataReader.Read(taskInfoTable.TaskTypeId, 3);
                        string   taskRunId         = sqlDataReader.Read(taskInfoTable.RunId, 4);
                        bool     isCanceled        = sqlDataReader.Read(taskInfoTable.IsCanceled, 5);
                        short    retryCount        = sqlDataReader.Read(taskInfoTable.RetryCount, 6);
                        short    maxRetryCount     = sqlDataReader.Read(taskInfoTable.MaxRetryCount, 7);
                        DateTime?heartbeatDateTime = sqlDataReader.Read(taskInfoTable.HeartbeatDateTime, 8);
                        string   inputData         = sqlDataReader.Read(taskInfoTable.InputData, 9);
                        string   taskContext       = sqlDataReader.Read(taskInfoTable.TaskContext, 10);
                        string   result            = sqlDataReader.Read(taskInfoTable.Result, 11);

                        TaskStatus taskStatus = (TaskStatus)status;
                        return(taskStatus == TaskStatus.Completed
                        ? throw new TaskAlreadyCompletedException("Task already completed or reach max retry count.")
                        : new TaskInfo()
                        {
                            TaskId = taskId,
                            QueueId = queueId,
                            Status = taskStatus,
                            TaskTypeId = taskTypeId,
                            RunId = taskRunId,
                            IsCanceled = isCanceled,
                            RetryCount = retryCount,
                            MaxRetryCount = maxRetryCount,
                            HeartbeatDateTime = heartbeatDateTime,
                            InputData = inputData,
                            Context = taskContext,
                            Result = result,
                        });
                    }
                    catch (SqlException sqlEx)
                    {
                        if (sqlEx.Number == SqlErrorCodes.NotFound)
                        {
                            throw new TaskNotExistException(sqlEx.Message);
                        }

                        throw;
                    }
                }
        }
        private async Task <TaskInfo> SetupAndExecuteCancelImportAsync(TaskStatus taskStatus, HttpStatusCode expectedStatusCode, bool isCanceled = false)
        {
            TaskInfo taskInfo = SetupBulkImportTask(taskStatus, isCanceled);

            CancelImportResponse response = await _mediator.CancelImportAsync(TaskId, _cancellationToken);

            Assert.NotNull(response);
            Assert.Equal(expectedStatusCode, response.StatusCode);

            return(taskInfo);
        }
        private TaskInfo SetupBulkImportTask(TaskStatus taskStatus, bool isCanceled)
        {
            var taskInfo = new TaskInfo
            {
                TaskId     = TaskId,
                QueueId    = "0",
                Status     = taskStatus,
                TaskTypeId = ImportProcessingTask.ImportProcessingTaskId,
                InputData  = string.Empty,
                IsCanceled = isCanceled,
            };

            _taskManager.GetTaskAsync(TaskId, _cancellationToken).Returns(taskInfo);
            _taskManager.CancelTaskAsync(TaskId, _cancellationToken).Returns(taskInfo);

            return(taskInfo);
        }
        public async Task GivenAFhirMediator_WhenCancelingExistingBulkImportTaskThatHasNotCompleted_ThenAcceptedStatusCodeShouldBeReturned(TaskStatus taskStatus)
        {
            TaskInfo taskInfo = await SetupAndExecuteCancelImportAsync(taskStatus, HttpStatusCode.Accepted);

            await _taskManager.Received(1).CancelTaskAsync(taskInfo.TaskId, _cancellationToken);
        }
        public async Task GivenAFhirMediator_WhenCancelingExistingBulkImportTaskThatHasAlreadyCompleted_ThenConflictStatusCodeShouldBeReturned(TaskStatus taskStatus)
        {
            OperationFailedException operationFailedException = await Assert.ThrowsAsync <OperationFailedException>(async() => await SetupAndExecuteCancelImportAsync(taskStatus, HttpStatusCode.Conflict));

            Assert.Equal(HttpStatusCode.Conflict, operationFailedException.ResponseStatusCode);
        }
        public async Task GivenAFhirMediator_WhenGettingAnExistingBulkImportTaskWithNotCompletedStatus_ThenHttpResponseCodeShouldBeAccepted(TaskStatus taskStatus)
        {
            GetImportResponse result = await SetupAndExecuteGetBulkImportTaskByIdAsync(taskStatus);

            Assert.Equal(HttpStatusCode.Accepted, result.StatusCode);
            Assert.Null(result.TaskResult);
        }
        private async Task <GetImportResponse> SetupAndExecuteGetBulkImportTaskByIdAsync(TaskStatus taskStatus, bool isCanceled = false, TaskResultData resultData = null)
        {
            // Result may be changed to real style result later
            var taskInfo = new TaskInfo
            {
                TaskId     = TaskId,
                QueueId    = "0",
                Status     = taskStatus,
                TaskTypeId = ImportProcessingTask.ImportProcessingTaskId,
                InputData  = string.Empty,
                IsCanceled = isCanceled,
                Result     = resultData != null?JsonConvert.SerializeObject(resultData) : string.Empty,
            };

            _taskManager.GetTaskAsync(taskInfo.TaskId, Arg.Any <CancellationToken>()).Returns(taskInfo);

            return(await _mediator.GetImportStatusAsync(taskInfo.TaskId, CancellationToken.None));
        }