Exemple #1
0
        public void WhenSettingAnETagHeader_ThenFhirResultHasAnETagHeader()
        {
            var version    = _mockResource.VersionId;
            var fhirResult = FhirResult.Create(_mockResource).SetETagHeader();

            Assert.Equal(string.Format(ETagFormat, version), fhirResult.Headers[HeaderNames.ETag]);
        }
        public async Task <IActionResult> Validate([FromBody] Resource resource, [FromQuery(Name = KnownQueryParameterNames.Profile)] string profile, [FromQuery(Name = KnownQueryParameterNames.Mode)] string mode)
        {
            if (!_features.SupportsValidate)
            {
                throw new OperationNotImplementedException(Resources.ValidationNotSupported);
            }

            if (resource.ResourceType == ResourceType.Parameters)
            {
                throw new OperationNotImplementedException(Resources.ValidateWithParametersNotSupported);
            }

            if (!string.IsNullOrEmpty(profile))
            {
                throw new OperationNotImplementedException(Resources.ValidateWithProfileNotSupported);
            }

            if (!string.IsNullOrEmpty(mode))
            {
                throw new OperationNotImplementedException(Resources.ValidationModesNotSupported);
            }

            var response = await _mediator.Send <ValidateOperationResponse>(new ValidateOperationRequest(resource.ToResourceElement()));

            return(FhirResult.Create(new OperationOutcome
            {
                Issue = response.Issues.Select(x => x.ToPoco()).ToList(),
            }.ToResourceElement()));
        }
        public async Task <IActionResult> Create([FromBody] Resource resource)
        {
            StringValues conditionalCreateHeader = HttpContext.Request.Headers[KnownFhirHeaders.IfNoneExist];

            ResourceElement response;

            if (!string.IsNullOrEmpty(conditionalCreateHeader))
            {
                Tuple <string, string>[] conditionalParameters = QueryHelpers.ParseQuery(conditionalCreateHeader)
                                                                 .SelectMany(query => query.Value, (query, value) => Tuple.Create(query.Key, value)).ToArray();

                UpsertResourceResponse createResponse = await _mediator.Send <UpsertResourceResponse>(new ConditionalCreateResourceRequest(resource.ToResourceElement(), conditionalParameters), HttpContext.RequestAborted);

                if (createResponse == null)
                {
                    return(Ok());
                }

                response = createResponse.Outcome.Resource;
            }
            else
            {
                response = await _mediator.CreateResourceAsync(resource.ToResourceElement(), HttpContext.RequestAborted);
            }

            return(FhirResult.Create(response, HttpStatusCode.Created)
                   .SetETagHeader()
                   .SetLastModifiedHeader()
                   .SetLocationHeader(_urlResolver));
        }
Exemple #4
0
        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            catch (Exception exception)
            {
                if (context.Response.HasStarted)
                {
                    _logger.LogWarning("The response has already started, the base exception middleware will not be executed.");
                    throw;
                }

                var localCorrelationId = _fhirRequestContextAccessor.FhirRequestContext?.CorrelationId;

                Debug.Assert(!string.IsNullOrWhiteSpace(localCorrelationId), "The correlation id should have been generated.");

                context.Response.Clear();

                var diagnostics = Resources.GeneralInternalError;

                // If any of these exceptions are encountered, show a more specific diagnostic message
                if (exception.Message.StartsWith("IDX10803: Unable to obtain configuration from:", StringComparison.OrdinalIgnoreCase))
                {
                    diagnostics = Resources.UnableToObtainOpenIdConfiguration;
                }
                else if (exception.Message.StartsWith("The MetadataAddress or Authority must use HTTPS", StringComparison.OrdinalIgnoreCase))
                {
                    diagnostics = Resources.RequireHttpsMetadataError;
                }

                var operationOutcome = new OperationOutcome
                {
                    Id    = localCorrelationId,
                    Issue = new List <OperationOutcome.IssueComponent>
                    {
                        new OperationOutcome.IssueComponent
                        {
                            Severity    = OperationOutcome.IssueSeverity.Fatal,
                            Code        = OperationOutcome.IssueType.Exception,
                            Diagnostics = diagnostics,
                        },
                    },
                };

                try
                {
                    await _contentTypeService.CheckRequestedContentTypeAsync(context);
                }
                catch (UnsupportedMediaTypeException)
                {
                    context.Response.ContentType = ContentType.JSON_CONTENT_HEADER;
                }

                var result = FhirResult.Create(operationOutcome, HttpStatusCode.InternalServerError);

                await ExecuteResultAsync(context, result);
            }
        }
Exemple #5
0
        public async Task <IActionResult> Update([FromBody] Resource resource)
        {
            var suppliedWeakETag = HttpContext.Request.Headers[HeaderNames.IfMatch];

            WeakETag weakETag = null;

            if (!string.IsNullOrWhiteSpace(suppliedWeakETag))
            {
                weakETag = WeakETag.FromWeakETag(suppliedWeakETag);
            }

            SaveOutcome response = await _mediator.UpsertResourceAsync(resource.ToResourceElement(), weakETag, HttpContext.RequestAborted);

            switch (response.Outcome)
            {
            case SaveOutcomeType.Created:
                return(FhirResult.Create(response.Resource, HttpStatusCode.Created)
                       .SetETagHeader()
                       .SetLastModifiedHeader()
                       .SetLocationHeader(_urlResolver));

            case SaveOutcomeType.Updated:
                return(FhirResult.Create(response.Resource, HttpStatusCode.OK)
                       .SetETagHeader()
                       .SetLastModifiedHeader());
            }

            return(FhirResult.Create(response.Resource, HttpStatusCode.BadRequest));
        }
        public async Task <IActionResult> CreateReindexJob([FromBody] Parameters inputParams)
        {
            CheckIfReindexIsEnabledAndRespond();

            ValidateParams(inputParams);

            ushort?maximumConcurrency   = (ushort?)ReadNumericParameter(inputParams, JobRecordProperties.MaximumConcurrency);
            uint?  maxResourcesPerQuery = (uint?)ReadNumericParameter(inputParams, JobRecordProperties.MaximumNumberOfResourcesPerQuery);
            int?   queryDelay           = ReadNumericParameter(inputParams, JobRecordProperties.QueryDelayIntervalInMilliseconds);
            ushort?targetDataStoreResourcePercentage = (ushort?)ReadNumericParameter(inputParams, JobRecordProperties.TargetDataStoreUsagePercentage);

            ResourceElement response = await _mediator.CreateReindexJobAsync(
                maximumConcurrency,
                maxResourcesPerQuery,
                queryDelay,
                targetDataStoreResourcePercentage,
                HttpContext.RequestAborted);

            var result = FhirResult.Create(response, HttpStatusCode.Created)
                         .SetETagHeader()
                         .SetLastModifiedHeader();

            result.SetContentLocationHeader(_urlResolver, OperationsConstants.Reindex, response.Id);
            return(result);
        }
        public async Task <IActionResult> Read(string type, string id)
        {
            Resource response = await _mediator.GetResourceAsync(new ResourceKey(type, id), HttpContext.RequestAborted);

            return(FhirResult.Create(response)
                   .SetETagHeader()
                   .SetLastModifiedHeader());
        }
        private async Task <IActionResult> GetOperationDefinitionAsync(string operationName)
        {
            CheckIfOperationIsEnabledAndRespond(operationName);

            OperationDefinitionResponse response = await _mediator.GetOperationDefinitionAsync(operationName, HttpContext.RequestAborted);

            return(FhirResult.Create(response.OperationDefinition, HttpStatusCode.OK));
        }
        private async Task <IActionResult> RunValidationAsync(ResourceElement resource, Uri profile)
        {
            var response = await _mediator.Send <ValidateOperationResponse>(new ValidateOperationRequest(resource, profile));

            return(FhirResult.Create(new OperationOutcome {
                Issue = response.Issues.Select(x => x.ToPoco()).ToList()
            }.ToResourceElement()));
        }
Exemple #10
0
        public async Task <IActionResult> VRead(string typeParameter, string idParameter, string vidParameter)
        {
            ResourceElement response = await _mediator.GetResourceAsync(new ResourceKey(typeParameter, idParameter, vidParameter), HttpContext.RequestAborted);

            return(FhirResult.Create(response, HttpStatusCode.OK)
                   .SetETagHeader()
                   .SetLastModifiedHeader());
        }
Exemple #11
0
        public async Task <IActionResult> VRead(string type, string id, string vid)
        {
            var response = await _mediator.Send(new GetResourceRequest(type, id, vid), HttpContext.RequestAborted);

            return(FhirResult.Create(response.Resource, HttpStatusCode.OK)
                   .SetETagHeader()
                   .SetLastModifiedHeader());
        }
Exemple #12
0
        public async Task <IActionResult> Create([FromBody] Resource resource)
        {
            var response = await _mediator.Send <UpsertResourceResponse>(new CreateResourceRequest(resource), HttpContext.RequestAborted);

            return(FhirResult.Create(response.Outcome.Resource, HttpStatusCode.Created)
                   .SetETagHeader()
                   .SetLastModifiedHeader()
                   .SetLocationHeader(_urlResolver));
        }
Exemple #13
0
        public async Task <IActionResult> Create([FromBody] Resource resource)
        {
            ResourceElement response = await _mediator.CreateResourceAsync(resource.ToResourceElement(), HttpContext.RequestAborted);

            return(FhirResult.Create(response, HttpStatusCode.Created)
                   .SetETagHeader()
                   .SetLastModifiedHeader()
                   .SetLocationHeader(_urlResolver));
        }
Exemple #14
0
        public async Task <IActionResult> ListReindexJobs()
        {
            CheckIfReindexIsEnabledAndRespond();

            ResourceElement response = await _mediator.GetReindexJobAsync(null, HttpContext.RequestAborted);

            return(FhirResult.Create(response, HttpStatusCode.OK)
                   .SetETagHeader()
                   .SetLastModifiedHeader());
        }
Exemple #15
0
        public async Task <IActionResult> CancelReindex(string idParameter)
        {
            CheckIfReindexIsEnabledAndRespond();

            ResourceElement response = await _mediator.CancelReindexAsync(idParameter, HttpContext.RequestAborted);

            return(FhirResult.Create(response, HttpStatusCode.Accepted)
                   .SetETagHeader()
                   .SetLastModifiedHeader());
        }
Exemple #16
0
        public async Task <IActionResult> SystemHistory(
            [FromQuery(Name = KnownQueryParameterNames.At)] PartialDateTime at,
            [FromQuery(Name = KnownQueryParameterNames.Since)] PartialDateTime since,
            [FromQuery(Name = KnownQueryParameterNames.Count)] int?count,
            string ct)
        {
            var response = await _mediator.Send(new SearchResourceHistoryRequest(since, at, count, ct), HttpContext.RequestAborted);

            return(FhirResult.Create(response.Bundle));
        }
        public async Task <IActionResult> ReindexSingleResource(string typeParameter, string idParameter)
        {
            CheckIfReindexIsEnabledAndRespond();

            ReindexSingleResourceResponse response = await _mediator.SendReindexSingleResourceRequestAsync(Request.Method, typeParameter, idParameter, HttpContext.RequestAborted);

            var result = FhirResult.Create(response.ParameterResource, HttpStatusCode.OK);

            return(result);
        }
Exemple #18
0
        public async Task <IActionResult> SystemHistory(
            [FromQuery(Name = KnownQueryParameterNames.At)] PartialDateTime at,
            [FromQuery(Name = KnownQueryParameterNames.Since)] PartialDateTime since,
            [FromQuery(Name = KnownQueryParameterNames.Before)] PartialDateTime before,
            [FromQuery(Name = KnownQueryParameterNames.Count)] int?count,
            string ct)
        {
            ResourceElement response = await _mediator.SearchResourceHistoryAsync(since, before, at, count, ct, HttpContext.RequestAborted);

            return(FhirResult.Create(response));
        }
        public async Task <IActionResult> TypeHistory(
            string type,
            [FromQuery(Name = KnownQueryParameterNames.At)] PartialDateTime at,
            [FromQuery(Name = KnownQueryParameterNames.Since)] PartialDateTime since,
            [FromQuery(Name = KnownQueryParameterNames.Count)] int?count,
            string ct)
        {
            Bundle response = await _mediator.SearchResourceHistoryAsync(type, since, at, count, ct, HttpContext.RequestAborted);

            return(FhirResult.Create(response));
        }
Exemple #20
0
        public void WhenSettingALocationHeader_ThenFhirResultHasALocationHeader()
        {
            var locationUrl = new Uri($"http://localhost/{_mockResource.GetType().Name}/{_mockResource.Id}/_history/{_mockResource.Meta.VersionId}");
            var urlResolver = Substitute.For <IUrlResolver>();

            urlResolver.ResolveResourceUrl(Arg.Any <Resource>(), Arg.Any <bool>()).Returns(locationUrl);

            var fhirResult = FhirResult.Create(_mockResource).SetLocationHeader(urlResolver);

            Assert.Equal(locationUrl.AbsoluteUri, fhirResult.Headers[HeaderNames.Location]);
        }
Exemple #21
0
        public async Task <IActionResult> Metadata(bool system = false)
        {
            if (system)
            {
                var sysResponse = await _mediator.Send(new GetSystemCapabilitiesRequest(), HttpContext.RequestAborted);

                return(FhirResult.Create(sysResponse.CapabilityStatement));
            }

            var response = await _mediator.Send(new GetCapabilitiesRequest(), HttpContext.RequestAborted);

            return(FhirResult.Create(response.CapabilityStatement));
        }
        public IActionResult CustomError(int?statusCode = null)
        {
            HttpStatusCode returnCode;

            OperationOutcome.IssueType issueType;
            string diagnosticInfo;

            switch (statusCode)
            {
            case (int)HttpStatusCode.Unauthorized:
                issueType      = OperationOutcome.IssueType.Login;
                returnCode     = HttpStatusCode.Unauthorized;
                diagnosticInfo = Resources.Unauthorized;
                break;

            case (int)HttpStatusCode.Forbidden:
                issueType      = OperationOutcome.IssueType.Forbidden;
                returnCode     = HttpStatusCode.Forbidden;
                diagnosticInfo = Resources.Forbidden;
                break;

            case (int)HttpStatusCode.NotFound:
                issueType      = OperationOutcome.IssueType.NotFound;
                returnCode     = HttpStatusCode.NotFound;
                diagnosticInfo = Resources.NotFoundException;
                break;

            default:
                issueType      = OperationOutcome.IssueType.Exception;
                returnCode     = HttpStatusCode.InternalServerError;
                diagnosticInfo = Resources.GeneralInternalError;
                break;
            }

            return(FhirResult.Create(
                       new OperationOutcome
            {
                Id = _fhirRequestContextAccessor.FhirRequestContext.CorrelationId,
                Issue = new List <OperationOutcome.IssueComponent>
                {
                    new OperationOutcome.IssueComponent
                    {
                        Severity = OperationOutcome.IssueSeverity.Error,
                        Code = issueType,
                        Diagnostics = diagnosticInfo,
                    },
                },
            }.ToResourceElement(),
                       returnCode));
        }
        public async Task <IActionResult> CreateReindexJob([FromBody] Parameters inputParams)
        {
            CheckIfReindexIsEnabledAndRespond();

            ValidateParams(inputParams);

            ushort?maximumConcurrency = ReadNumericParameter(inputParams, JobRecordProperties.MaximumConcurrency);
            string scope = ReadStringParameter(inputParams, JobRecordProperties.Scope);

            ResourceElement response = await _mediator.CreateReindexJobAsync(maximumConcurrency, scope, HttpContext.RequestAborted);

            return(FhirResult.Create(response, HttpStatusCode.Created)
                   .SetETagHeader()
                   .SetLastModifiedHeader());
        }
Exemple #24
0
        public async Task <IActionResult> CreateReindexJob([FromBody] Parameters inputParams)
        {
            CheckIfReindexIsEnabledAndRespond();

            ValidateParams(inputParams);

            ushort?maximumConcurrency = ReadNumericParameter(inputParams, JobRecordProperties.MaximumConcurrency);

            ResourceElement response = await _mediator.CreateReindexJobAsync(maximumConcurrency, HttpContext.RequestAborted);

            var result = FhirResult.Create(response, HttpStatusCode.Created)
                         .SetETagHeader()
                         .SetLastModifiedHeader();

            result.SetContentLocationHeader(_urlResolver, OperationsConstants.Reindex, response.Id);
            return(result);
        }
Exemple #25
0
        private IActionResult ToSaveOutcomeResult(SaveOutcome saveOutcome)
        {
            switch (saveOutcome.Outcome)
            {
                case SaveOutcomeType.Created:
                    return FhirResult.Create(saveOutcome.RawResourceElement, HttpStatusCode.Created)
                        .SetETagHeader()
                        .SetLastModifiedHeader()
                        .SetLocationHeader(_urlResolver);
                case SaveOutcomeType.Updated:
                    return FhirResult.Create(saveOutcome.RawResourceElement, HttpStatusCode.OK)
                        .SetETagHeader()
                        .SetLastModifiedHeader();
            }

            return FhirResult.Create(saveOutcome.RawResourceElement, HttpStatusCode.BadRequest);
        }
Exemple #26
0
        public void WhenAddingStringEtag_ThenStringETagIsReturned()
        {
            var fhirResult = FhirResult.Create(_mockResource).SetETagHeader(WeakETag.FromVersionId("etag"));

            Assert.Equal("W/\"etag\"", fhirResult.Headers[HeaderNames.ETag]);
        }
Exemple #27
0
 public void WhenAddingSameHeaderTwice_ThenOnlyOneHeaderIsPresent()
 {
     Assert.Throws <ArgumentException>(() => FhirResult.Create(_mockResource)
                                       .SetLastModifiedHeader()
                                       .SetLastModifiedHeader());
 }
Exemple #28
0
        public void WhenCreatingAFhirResultAndNotSettingHeaders_ThenThereIsNoHeaders()
        {
            var fhirResult = FhirResult.Create(_mockResource);

            Assert.Empty(fhirResult.Headers);
        }
Exemple #29
0
        public void WhenAddingTwoHeaders_ThenFhirResultHasAtLeastTwoHeaders()
        {
            var fhirResult = FhirResult.Create(_mockResource).SetLastModifiedHeader().SetETagHeader();

            Assert.Equal(2, fhirResult.Headers.Count);
        }
Exemple #30
0
        public void WhenSettingALastModifiedHeader_ThenFhirResultHasALastModifierHeader()
        {
            var fhirResult = FhirResult.Create(_mockResource).SetLastModifiedHeader();

            Assert.Equal(_mockResource.LastUpdated?.ToString("r", CultureInfo.InvariantCulture), fhirResult.Headers[HeaderNames.LastModified]);
        }