Esempio n. 1
0
        //Task.Status (Draft -> Requested -> Received -> Accepted -> Rejected ->
        //             Ready -> Cancelled -> In Progress -> On Hold ->
        //             Failed -> Completed -> Entered in Error)

        public Task.TaskStatus Run(Task Task)
        {
            try
            {
                //Task.TaskStatus? LocalTaskStatus = null;
                Task.ExecutionPeriod = new Period();
                Task.ExecutionPeriod.StartElement = new FhirDateTime(DateTimeOffset.Now);
                //Update the status of the task so that no other processes (instances of the server) also try and process this task can start it.
                //If this fails do nothing as we are to asume some other process is workng on this task, just return InProgress.
                if (!IFhirTaskTool.UpdateTaskAsStatus(Task.TaskStatus.InProgress, Task))
                {
                    return(Task.TaskStatus.InProgress);
                }

                Task.Output = new List <Task.OutputComponent>();

                if (!ProcessCompartmentDefinitionList(Task))
                {
                    using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction())
                    {
                        Task.ExecutionPeriod.EndElement = new FhirDateTime(DateTimeOffset.Now);
                        IFhirTaskTool.UpdateTaskAsStatus(Task.TaskStatus.Failed, Task);
                        Transaction.Commit();
                    }
                }
                return(Task.Status.Value);
            }
            catch (Exception Exec)
            {
                ILog.Error(Exec, $"Internal Server Error: Transaction was rolled back. " +
                           $"Task reference was: {Task.ResourceType.GetLiteral()}/{Task.Id}/_history/{Task.VersionId} The Task was not processed.");
                return(Task.TaskStatus.Failed);
            }
        }
        public Task.TaskStatus Run(Task Task)
        {
            _Task = Task;
            IGlobalProperties.ServerReadOnlyMode        = true;
            IGlobalProperties.ServerReadOnlyModeMessage =
                "The server is currently running a first time start-up task which loads all the base FHIR " +
                "specification search parameter resources as active search indexes within the Pyro FHIR server. " +
                $"This Task can be monitored by performing a GET on the servers Task endpoint for the Id of '{_Task.Id}'. " +
                $"For example: 'GET [base]/Task/{_Task.Id}'. While this Task is in progress the server can not allow resource writes " +
                $"to the server as these resources would not have their search parameter values indexed. Only once the Task is finished " +
                $"and all base search parameters are loaded will the server automatically switch out of read only mode. ";



            _SearchParameterResourceProcessedIdList = new List <string>();
            try
            {
                _Task.ExecutionPeriod = new Period();
                _Task.ExecutionPeriod.StartElement = new FhirDateTime(DateTimeOffset.Now);
                //Update the status of the task so that no other processes (instances of the server) also try and process this task can start it.
                //If this fails do nothing as we are to assume some other process is working on this task, just return InProgress.
                if (!IFhirTaskTool.UpdateTaskAsStatus(Task.TaskStatus.InProgress, _Task))
                {
                    IGlobalProperties.ServerReadOnlyMode = false;
                    ICacheClear.ClearCache();
                    return(Task.TaskStatus.InProgress);
                }

                SetParametersBeforeRunningTaskLoad(_Task);

                _Task.Output = new List <Task.OutputComponent>();
                //We process each file in the zip one at a time and commit and update the Task each time.
                //Once the IFhirSpecificationDefinitionLoaderParameters.TaskStatus == Completed we then return, or return is the Load retunes false.
                while (_CurrentTaskStatus == Task.TaskStatus.InProgress)
                {
                    _SearchParameterBundle = LoadFromZip();
                    if (_SearchParameterBundle != null)
                    {
                        TotalCounter = 0;
                        int CommitBlockCounter = 0;
                        IGlobalProperties.ServerReadOnlyModeMessage = SetServerReadOnlyMessage(0, _SearchParameterBundle.Entry.Count, _Task.Id);
                        foreach (var Entry in _SearchParameterBundle.Entry)
                        {
                            TotalCounter++;
                            IGlobalProperties.ServerReadOnlyModeMessage = SetServerReadOnlyMessage(TotalCounter, _SearchParameterBundle.Entry.Count, _Task.Id);
                            if (Entry.Resource != null)
                            {
                                if (Entry.Resource is SearchParameter SearchParam)
                                {
                                    if (!_SearchParameterResourceProcessedIdList.Contains(SearchParam.Id))
                                    {
                                        //Increment Counter end of loop
                                        CommitBlockCounter++;
                                        using (DbContextTransaction TransactionSet = IUnitOfWork.BeginTransaction())
                                        {
                                            try
                                            {
                                                _ResourceIdInProgress = SearchParam.Id;
                                                AddSearchParameterResourceToServer(SearchParam);
                                                if (FilterSearchParametersToSet(SearchParam))
                                                {
                                                    if (!SetSearchParameterServerIndex(SearchParam.Id))
                                                    {
                                                        IGlobalProperties.ServerReadOnlyMode = false;
                                                        ICacheClear.ClearCache();
                                                        throw new Exception("Failed to Set index!");
                                                    }
                                                }
                                                _SearchParameterResourceProcessedIdList.Add(_ResourceIdInProgress);
                                                TransactionSet.Commit();
                                            }
                                            catch (Exception Exec)
                                            {
                                                TransactionSet.Rollback();
                                                using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction())
                                                {
                                                    _InErrorMessage    = Exec.Message;
                                                    _ResourceIdInError = _ResourceIdInProgress;
                                                    _CurrentTaskStatus = Task.TaskStatus.Failed;
                                                    SetParametersOnFailedTaskLoad(_Task);
                                                    IFhirTaskTool.UpdateTaskAsStatus(_Task.Status.Value, _Task);
                                                    Transaction.Commit();
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    string Message = "Internal Server Error: The search-parameter.xml file contained a non SearchParameter Resource Type as an entry, found type {Entry.Resource.TypeName}.";
                                    using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction())
                                    {
                                        _InErrorMessage = Message;
                                        SetParametersOnFailedTaskLoad(_Task);
                                        IFhirTaskTool.UpdateTaskAsStatus(_Task.Status.Value, _Task);
                                        Transaction.Commit();
                                    }
                                    IGlobalProperties.ServerReadOnlyMode = false;
                                    ICacheClear.ClearCache();
                                    throw new Exception(Message);
                                }
                            }
                            else
                            {
                                string Message = $"Internal Server Error: The search-parameter.xml file contained a null resource entry.";
                                using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction())
                                {
                                    _InErrorMessage = Message;
                                    SetParametersOnFailedTaskLoad(_Task);
                                    IFhirTaskTool.UpdateTaskAsStatus(_Task.Status.Value, _Task);
                                    Transaction.Commit();
                                }
                                IGlobalProperties.ServerReadOnlyMode = false;
                                ICacheClear.ClearCache();
                                throw new Exception(Message);
                            }

                            //After each blockSize Commit the current progress to the Task
                            //It is ok if we process SearchParameters that have already been processed as all that will happen is the
                            //SearchParameter Resource will be Updated and the SearchIndex will not be set again.
                            if (CommitBlockCounter == _TaskCommitBlockSize)
                            {
                                using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction())
                                {
                                    SetParametersInProgressTaskLoad(_Task);
                                    IFhirTaskTool.UpdateTaskAsStatus(_Task.Status.Value, _Task);
                                    Transaction.Commit();
                                }
                                CommitBlockCounter = 0;
                            }
                        }

                        //Finished all so mark as Completed
                        if (_CurrentTaskStatus == Task.TaskStatus.InProgress)
                        {
                            ProcessCompositeSearchParameters();
                            using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction())
                            {
                                SetParametersOnCompletedTaskLoad(_Task);
                                IFhirTaskTool.UpdateTaskAsStatus(_Task.Status.Value, _Task);
                                Transaction.Commit();
                                _CurrentTaskStatus = Task.TaskStatus.Completed;
                                IGlobalProperties.ServerReadOnlyMode = false;
                                ICacheClear.ClearCache();
                            }
                        }
                    }
                }
                return(_CurrentTaskStatus);
            }
            catch (Exception Exec)
            {
                ILog.Error(Exec, $"Internal Server Error: Transaction was rolled back. " +
                           $"Task reference was: {_Task.ResourceType.GetLiteral()}/{_Task.Id}/_history/{_Task.VersionId} The Task was not processed.");
                IGlobalProperties.ServerReadOnlyMode = false;
                ICacheClear.ClearCache();
                return(Task.TaskStatus.Failed);
            }
        }
        //Task.Status (Draft -> Requested -> Received -> Accepted -> Rejected ->
        //             Ready -> Cancelled -> In Progress -> On Hold ->
        //             Failed -> Completed -> Entered in Error)

        public Task.TaskStatus Run(Task Task)
        {
            try
            {
                //Task.TaskStatus? LocalTaskStatus = null;
                Task.ExecutionPeriod = new Period();
                Task.ExecutionPeriod.StartElement = new FhirDateTime(DateTimeOffset.Now);
                //Update the status of the task so that no other processes (instances of the server) also try and process this task can start it.
                //If this fails do nothing as we are to assume some other process is working on this task, just return InProgress.
                if (!IFhirTaskTool.UpdateTaskAsStatus(Task.TaskStatus.InProgress, Task))
                {
                    return(Task.TaskStatus.InProgress);
                }

                SetParametersBeforeRunningTaskLoad(Task);

                Task.Output = new List <Task.OutputComponent>();
                //We process each file in the zip one at a time and commit and update the Task each time.
                //Once the IFhirSpecificationDefinitionLoaderParameters.TaskStatus == Completed we then return, or return is the Load retunes false.
                while (IFhirSpecificationDefinitionLoaderParameters.TaskStatus == Task.TaskStatus.InProgress)
                {
                    bool AllOk = false;
                    using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction())
                    {
                        AllOk = LoadFromZip(IFhirSpecificationDefinitionLoaderParameters);
                        if (AllOk)
                        {
                            if (IFhirSpecificationDefinitionLoaderParameters.TaskStatus != Task.TaskStatus.Completed)
                            {
                                //Still InProgress so update this file status and commit this Bundle Transaction and update the Task
                                //Then loop again for the next file
                                SetParametersInProgressTaskLoad(Task);
                                IFhirTaskTool.UpdateTaskAsStatus(IFhirSpecificationDefinitionLoaderParameters.TaskStatus.Value, Task);
                                Transaction.Commit();
                            }
                            else if (IFhirSpecificationDefinitionLoaderParameters.TaskStatus == Task.TaskStatus.Completed)
                            {
                                //AllOk was True so IFhirSpecificationDefinitionLoaderParameters.TaskStatus == Completed
                                //All finished set the Whole Task to Completed and set the Completed end timestamps to the Task and Commit
                                //The Break out of loop
                                SetParametersOnCompletedTaskLoad(Task);
                                IFhirTaskTool.UpdateTaskAsStatus(IFhirSpecificationDefinitionLoaderParameters.TaskStatus.Value, Task);
                                Transaction.Commit();
                                break;
                            }
                            else
                            {
                                //What went wrong, when SetParametersInProgressTaskLoad(Task) retunes True the TaskStatus must always be Completed
                                throw new Exception("Internal Server Error: SetParametersInProgressTaskLoad(Task) returned True yet TaskStatus was not Completed.");
                            }
                        }
                        else
                        {
                            //Roll-back the failed transaction, we will update the Task as failed
                            //in a separate transaction below
                            Transaction.Rollback();
                        }
                    }

                    //Update the Task as Failed in new Transaction
                    if (!AllOk)
                    {
                        SetParametersOnFailedTaskLoad(Task);
                        using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction())
                        {
                            IFhirTaskTool.UpdateTaskAsStatus(IFhirSpecificationDefinitionLoaderParameters.TaskStatus.Value, Task);
                            Transaction.Commit();
                            return(IFhirSpecificationDefinitionLoaderParameters.TaskStatus.Value);
                        }
                    }
                }
                //AllOk was True so IFhirSpecificationDefinitionLoaderParameters.TaskStatus == Completed
                return(IFhirSpecificationDefinitionLoaderParameters.TaskStatus.Value);
            }
            catch (Exception Exec)
            {
                ILog.Error(Exec, $"Internal Server Error: Transaction was rolled back. " +
                           $"Task reference was: {Task.ResourceType.GetLiteral()}/{Task.Id}/_history/{Task.VersionId} The Task was not processed.");
                return(Task.TaskStatus.Failed);
            }
        }