public static OperationOutcome.IssueComponent ToPoco(this OperationOutcomeIssue issue)
        {
            EnsureArg.IsNotNull(issue, nameof(issue));

            CodeableConcept details = null;
            var             coding  = new List <Coding>();

            if (issue.DetailsCodes != null)
            {
                coding = issue.DetailsCodes.Coding.Select(x => new Coding(x.System, x.Code, x.Display)).ToList();
            }

            if (coding.Count != 0 || issue.DetailsText != null)
            {
                details = new CodeableConcept()
                {
                    Coding = coding,
                    Text   = issue.DetailsText,
                };
            }

            return(new OperationOutcome.IssueComponent
            {
                Severity = Enum.Parse <OperationOutcome.IssueSeverity>(issue.Severity),
                Code = Enum.Parse <OperationOutcome.IssueType>(issue.Code),
                Details = details,
                Diagnostics = issue.Diagnostics,
                Location = issue.Location,
            });
        }
Пример #2
0
        internal static BundleWrapper ReadEmbeddedSearchParameters(
            string embeddedResourceName,
            IModelInfoProvider modelInfoProvider,
            string embeddedResourceNamespace = null,
            Assembly assembly = null)
        {
            using Stream stream         = modelInfoProvider.OpenVersionedFileStream(embeddedResourceName, embeddedResourceNamespace, assembly);
            using TextReader reader     = new StreamReader(stream);
            using JsonReader jsonReader = new JsonTextReader(reader);
            try
            {
                ISourceNode sourceNode = FhirJsonNode.Read(jsonReader);
                return(new BundleWrapper(modelInfoProvider.ToTypedElement(sourceNode)));
            }
            catch (FormatException ex)
            {
                var issue = new OperationOutcomeIssue(
                    OperationOutcomeConstants.IssueSeverity.Fatal,
                    OperationOutcomeConstants.IssueType.Invalid,
                    ex.Message);

                throw new InvalidDefinitionException(
                          Core.Resources.SearchParameterDefinitionContainsInvalidEntry,
                          new OperationOutcomeIssue[] { issue });
            }
        }
        public FhirValidationFailure(string propertyName, string errorMessage, OperationOutcomeIssue issueComponent)
            : base(propertyName, errorMessage)
        {
            EnsureArg.IsNotNullOrEmpty(propertyName, nameof(propertyName));
            EnsureArg.IsNotNullOrEmpty(errorMessage, nameof(errorMessage));
            EnsureArg.IsNotNull(issueComponent, nameof(issueComponent));

            IssueComponent = issueComponent;
        }
Пример #4
0
        public static OperationOutcome.IssueComponent ToPoco(this OperationOutcomeIssue issue)
        {
            EnsureArg.IsNotNull(issue, nameof(issue));

            return(new OperationOutcome.IssueComponent
            {
                Severity = Enum.Parse <OperationOutcome.IssueSeverity>(issue.Severity),
                Code = Enum.Parse <OperationOutcome.IssueType>(issue.Code),
                Diagnostics = issue.Diagnostics,
                Location = issue.Location,
            });
        }
Пример #5
0
        private async Task CheckJobCompletionStatus(CancellationToken cancellationToken)
        {
            // If any query still in progress then we are not done
            if (_reindexJobRecord.QueryList.Where(q =>
                                                  q.Status == OperationStatus.Queued ||
                                                  q.Status == OperationStatus.Running).Any())
            {
                return;
            }
            else
            {
                // all queries marked as complete, reindex job is done, check success or failure
                if (_reindexJobRecord.QueryList.All(q => q.Status == OperationStatus.Completed))
                {
                    (bool success, string error) = await _reindexUtilities.UpdateSearchParameters(_reindexJobRecord.SearchParams, cancellationToken);

                    if (success)
                    {
                        await CompleteJobAsync(OperationStatus.Completed, cancellationToken);

                        _logger.LogInformation($"Reindex job successfully completed, id {_reindexJobRecord.Id}.");
                    }
                    else
                    {
                        var issue = new OperationOutcomeIssue(
                            OperationOutcomeConstants.IssueSeverity.Error,
                            OperationOutcomeConstants.IssueType.Exception,
                            error);
                        _reindexJobRecord.Error.Add(issue);
                        _logger.LogError(error);

                        await CompleteJobAsync(OperationStatus.Failed, cancellationToken);
                    }
                }
                else
                {
                    await CompleteJobAsync(OperationStatus.Failed, cancellationToken);

                    _logger.LogInformation($"Reindex job did not complete successfully, id: {_reindexJobRecord.Id}.");
                }
            }
        }
        public async Task GivenARequest_WhenReturningFhirValidationFailure_ThenOperationOutcomeIsUsedCorrectly()
        {
            var mockValidator = Substitute.For <AbstractValidator <UpsertResourceRequest> >();

            var validators = new[] { mockValidator };
            var upsertValidationHandler = new ValidateRequestPreProcessor <UpsertResourceRequest>(validators);
            var upsertResourceRequest   = new UpsertResourceRequest(Samples.GetDefaultObservation());

            var operationOutcomeIssue = new OperationOutcomeIssue(OperationOutcomeConstants.IssueSeverity.Error, OperationOutcomeConstants.IssueType.Invalid, "Id was Invalid");

            var validationError = Task.FromResult(new ValidationResult(new[] { new FhirValidationFailure("Id", operationOutcomeIssue.Diagnostics, operationOutcomeIssue) }));

            mockValidator
            .ValidateAsync(Arg.Any <ValidationContext <UpsertResourceRequest> >(), Arg.Any <CancellationToken>())
            .Returns(validationError);

            var exception = await Assert.ThrowsAsync <ResourceNotValidException>(async() => await upsertValidationHandler.Process(upsertResourceRequest, CancellationToken.None));

            Assert.Contains(operationOutcomeIssue, exception.Issues);
        }
Пример #7
0
        private async Task UpdateParametersAndCompleteJob(CancellationToken cancellationToken)
        {
            (bool success, string error) = await _reindexUtilities.UpdateSearchParameterStatus(_reindexJobRecord.SearchParams, cancellationToken);

            if (success)
            {
                await CompleteJobAsync(OperationStatus.Completed, cancellationToken);

                _logger.LogInformation($"Reindex job successfully completed, id {_reindexJobRecord.Id}.");
            }
            else
            {
                var issue = new OperationOutcomeIssue(
                    OperationOutcomeConstants.IssueSeverity.Error,
                    OperationOutcomeConstants.IssueType.Exception,
                    error);
                _reindexJobRecord.Error.Add(issue);
                _logger.LogError(error);

                await CompleteJobAsync(OperationStatus.Failed, cancellationToken);
            }
        }
Пример #8
0
        private async Task UpdateParametersAndCompleteJob()
        {
            // here we check if all the resource types which are base types of the search parameter
            // were reindexed by this job.  If so, then we should mark the search parameters
            // as fully reindexed
            var fullyIndexedParamUris = new List <string>();
            var reindexedResourcesSet = new HashSet <string>(_reindexJobRecord.Resources);

            foreach (var searchParam in _reindexJobRecord.SearchParams)
            {
                var searchParamInfo = _supportedSearchParameterDefinitionManager.GetSearchParameter(searchParam);
                if (reindexedResourcesSet.IsSupersetOf(searchParamInfo.BaseResourceTypes))
                {
                    fullyIndexedParamUris.Add(searchParam);
                }
            }

            _logger.LogTrace("Completing reindex job. Updating the status of the fully indexed search parameters: '{paramUris}'", string.Join("', '", fullyIndexedParamUris));
            (bool success, string error) = await _reindexUtilities.UpdateSearchParameterStatus(fullyIndexedParamUris, _cancellationToken);

            if (success)
            {
                await MoveToFinalStatusAsync(OperationStatus.Completed);

                _logger.LogInformation($"Reindex job successfully completed, id {_reindexJobRecord.Id}.");
            }
            else
            {
                var issue = new OperationOutcomeIssue(
                    OperationOutcomeConstants.IssueSeverity.Error,
                    OperationOutcomeConstants.IssueType.Exception,
                    error);
                _reindexJobRecord.Error.Add(issue);
                _logger.LogError(error);

                await MoveToFinalStatusAsync(OperationStatus.Failed);
            }
        }
Пример #9
0
        private async Task <ReindexJobQueryStatus> HandleQueryException(ReindexJobQueryStatus query, Exception ex, bool isFhirException, CancellationToken cancellationToken)
        {
            await _jobSemaphore.WaitAsync(cancellationToken);

            try
            {
                query.Error = ex.Message;
                query.FailureCount++;
                _logger.LogError(ex, "Encountered an unhandled exception. The query failure count increased to {failureCount}.", _reindexJobRecord.FailureCount);

                if (query.FailureCount >= _reindexJobConfiguration.ConsecutiveFailuresThreshold)
                {
                    if (isFhirException)
                    {
                        var issue = new OperationOutcomeIssue(
                            OperationOutcomeConstants.IssueSeverity.Error,
                            OperationOutcomeConstants.IssueType.Exception,
                            ex.Message);
                        _reindexJobRecord.Error.Add(issue);
                    }

                    query.Status = OperationStatus.Failed;
                }
                else
                {
                    query.Status = OperationStatus.Queued;
                }

                await UpdateJobAsync();
            }
            finally
            {
                _jobSemaphore.Release();
            }

            return(query);
        }
        public ITypedElement ToTypedElement(RawResource rawResource)
        {
            EnsureArg.IsNotNull(rawResource, nameof(rawResource));

            using TextReader reader     = new StringReader(rawResource.Data);
            using JsonReader jsonReader = new JsonTextReader(reader);
            try
            {
                ISourceNode sourceNode = FhirJsonNode.Read(jsonReader);
                return(sourceNode.ToTypedElement(StructureDefinitionSummaryProvider));
            }
            catch (FormatException ex)
            {
                var issue = new OperationOutcomeIssue(
                    OperationOutcomeConstants.IssueSeverity.Fatal,
                    OperationOutcomeConstants.IssueType.Invalid,
                    ex.Message);

                throw new ResourceNotValidException(new List <OperationOutcomeIssue>()
                {
                    issue
                });
            }
        }
        /// <summary>
        /// Converts the RawResource to an ITypedElement
        /// </summary>
        /// <param name="rawResource">The RawResource to convert</param>
        /// <param name="modelInfoProvider">The IModelInfoProvider to use when converting the RawResource</param>
        /// <returns>An ITypedElement of the RawResource</returns>
        public static ITypedElement ToITypedElement(this RawResource rawResource, IModelInfoProvider modelInfoProvider)
        {
            EnsureArg.IsNotNull(rawResource, nameof(rawResource));
            EnsureArg.IsNotNull(modelInfoProvider, nameof(modelInfoProvider));

            using TextReader reader     = new StringReader(rawResource.Data);
            using JsonReader jsonReader = new JsonTextReader(reader);
            try
            {
                ISourceNode sourceNode = FhirJsonNode.Read(jsonReader);
                return(modelInfoProvider.ToTypedElement(sourceNode));
            }
            catch (FormatException ex)
            {
                var issue = new OperationOutcomeIssue(
                    OperationOutcomeConstants.IssueSeverity.Fatal,
                    OperationOutcomeConstants.IssueType.Invalid,
                    ex.Message);

                throw new InvalidDefinitionException(
                          Core.Resources.SearchParameterDefinitionContainsInvalidEntry,
                          new OperationOutcomeIssue[] { issue });
            }
        }
Пример #12
0
 private static void AssertOperationOutcomeIssue(string message, string expectedStatusCode, OperationOutcomeIssue issue)
 {
     Assert.Equal(OperationOutcomeConstants.IssueSeverity.Error, issue.Severity);
     Assert.Equal(expectedStatusCode, issue.Code);
     Assert.Equal(message, issue.Diagnostics);
 }