Exemplo n.º 1
0
        public async Task GivenABundleWithAGet_WhenNotAuthorized_ReturnsABundleResponseWithCorrectEntry()
        {
            var bundle = new Hl7.Fhir.Model.Bundle
            {
                Type  = Hl7.Fhir.Model.Bundle.BundleType.Batch,
                Entry = new List <Hl7.Fhir.Model.Bundle.EntryComponent>
                {
                    new Hl7.Fhir.Model.Bundle.EntryComponent
                    {
                        Request = new Hl7.Fhir.Model.Bundle.RequestComponent
                        {
                            Method = Hl7.Fhir.Model.Bundle.HTTPVerb.GET,
                            Url    = "/Patient",
                        },
                    },
                },
            };

            _router.When(r => r.RouteAsync(Arg.Any <RouteContext>()))
            .Do(RouteAsyncFunction);

            var bundleRequest = new BundleRequest(bundle.ToResourceElement());

            BundleResponse bundleResponse = await _bundleHandler.Handle(bundleRequest, CancellationToken.None);

            var bundleResource = bundleResponse.Bundle.ToPoco <Hl7.Fhir.Model.Bundle>();

            Assert.Equal(Hl7.Fhir.Model.Bundle.BundleType.BatchResponse, bundleResource.Type);
            Assert.Single(bundleResource.Entry);

            Hl7.Fhir.Model.Bundle.EntryComponent entryComponent = bundleResource.Entry.First();
            Assert.Equal("403", entryComponent.Response.Status);

            var operationOutcome = entryComponent.Response.Outcome as OperationOutcome;

            Assert.NotNull(operationOutcome);
            Assert.Single(operationOutcome.Issue);

            var issueComponent = operationOutcome.Issue.First();

            Assert.Equal(OperationOutcome.IssueSeverity.Error, issueComponent.Severity);
            Assert.Equal(OperationOutcome.IssueType.Forbidden, issueComponent.Code);
            Assert.Equal("Authorization failed.", issueComponent.Diagnostics);

            void RouteAsyncFunction(CallInfo callInfo)
            {
                var routeContext = callInfo.Arg <RouteContext>();

                routeContext.Handler = context =>
                {
                    context.Response.StatusCode = 403;

                    return(Task.CompletedTask);
                };
            }
        }
Exemplo n.º 2
0
        private async Task ExecuteRequests(Hl7.Fhir.Model.Bundle responseBundle, Hl7.Fhir.Model.Bundle.HTTPVerb httpVerb)
        {
            foreach (RouteContext request in _requests[httpVerb])
            {
                var entryComponent = new Hl7.Fhir.Model.Bundle.EntryComponent();

                if (request.Handler != null)
                {
                    HttpContext httpContext = request.HttpContext;
                    await request.Handler.Invoke(httpContext);

                    httpContext.Response.Body.Seek(0, SeekOrigin.Begin);
                    string bodyContent = new StreamReader(httpContext.Response.Body).ReadToEnd();

                    ResponseHeaders responseHeaders = httpContext.Response.GetTypedHeaders();
                    entryComponent.Response = new Hl7.Fhir.Model.Bundle.ResponseComponent
                    {
                        Status       = httpContext.Response.StatusCode.ToString(),
                        Location     = responseHeaders.Location?.OriginalString,
                        Etag         = responseHeaders.ETag?.ToString(),
                        LastModified = responseHeaders.LastModified,
                    };

                    if (!string.IsNullOrWhiteSpace(bodyContent))
                    {
                        var entryComponentResource = _fhirJsonParser.Parse <Resource>(bodyContent);

                        if (entryComponentResource.ResourceType == ResourceType.OperationOutcome)
                        {
                            entryComponent.Response.Outcome = entryComponentResource;
                        }
                        else
                        {
                            entryComponent.Resource = entryComponentResource;
                        }
                    }
                }
                else
                {
                    entryComponent.Response = new Hl7.Fhir.Model.Bundle.ResponseComponent {
                        Status = ((int)HttpStatusCode.NotFound).ToString()
                    };
                }

                responseBundle.Entry.Add(entryComponent);
            }
        }
        private async Task ExecuteRequests(Hl7.Fhir.Model.Bundle responseBundle, Hl7.Fhir.Model.Bundle.HTTPVerb httpVerb)
        {
            foreach (RouteContext request in _requests[httpVerb])
            {
                var entryComponent = new Hl7.Fhir.Model.Bundle.EntryComponent();

                if (request.Handler != null)
                {
                    HttpContext httpContext = request.HttpContext;

                    IFhirRequestContext originalFhirRequestContext = _fhirRequestContextAccessor.FhirRequestContext;

                    request.RouteData.Values.TryGetValue(KnownActionParameterNames.ResourceType, out object resourceType);
                    var newFhirRequestContext = new FhirRequestContext(
                        httpContext.Request.Method,
                        httpContext.Request.GetDisplayUrl(),
                        originalFhirRequestContext.BaseUri.OriginalString,
                        originalFhirRequestContext.CorrelationId,
                        httpContext.Request.Headers,
                        httpContext.Response.Headers,
                        resourceType?.ToString())
                    {
                        Principal = originalFhirRequestContext.Principal,
                    };
                    _fhirRequestContextAccessor.FhirRequestContext = newFhirRequestContext;

                    _bundleHttpContextAccessor.HttpContext = httpContext;

                    await request.Handler.Invoke(httpContext);

                    httpContext.Response.Body.Seek(0, SeekOrigin.Begin);
                    string bodyContent = new StreamReader(httpContext.Response.Body).ReadToEnd();

                    ResponseHeaders responseHeaders = httpContext.Response.GetTypedHeaders();
                    entryComponent.Response = new Hl7.Fhir.Model.Bundle.ResponseComponent
                    {
                        Status       = httpContext.Response.StatusCode.ToString(),
                        Location     = responseHeaders.Location?.OriginalString,
                        Etag         = responseHeaders.ETag?.ToString(),
                        LastModified = responseHeaders.LastModified,
                    };

                    if (!string.IsNullOrWhiteSpace(bodyContent))
                    {
                        var entryComponentResource = _fhirJsonParser.Parse <Resource>(bodyContent);

                        if (entryComponentResource.ResourceType == ResourceType.OperationOutcome)
                        {
                            entryComponent.Response.Outcome = entryComponentResource;

                            if (responseBundle.Type == Hl7.Fhir.Model.Bundle.BundleType.TransactionResponse)
                            {
                                ThrowTransactionException(httpContext, (OperationOutcome)entryComponentResource);
                            }
                        }
                        else
                        {
                            entryComponent.Resource = entryComponentResource;
                        }
                    }
                    else
                    {
                        if (httpContext.Response.StatusCode == (int)HttpStatusCode.Forbidden)
                        {
                            entryComponent.Response.Outcome = CreateOperationOutcome(
                                OperationOutcome.IssueSeverity.Error,
                                OperationOutcome.IssueType.Forbidden,
                                Api.Resources.Forbidden);
                        }
                    }
                }
                else
                {
                    entryComponent.Response = new Hl7.Fhir.Model.Bundle.ResponseComponent
                    {
                        Status  = ((int)HttpStatusCode.NotFound).ToString(),
                        Outcome = CreateOperationOutcome(
                            OperationOutcome.IssueSeverity.Error,
                            OperationOutcome.IssueType.NotFound,
                            string.Format(Api.Resources.BundleNotFound, $"{request.HttpContext.Request.Path}{request.HttpContext.Request.QueryString}")),
                    };
                }

                responseBundle.Entry.Add(entryComponent);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Deserialize JSON into a FHIR Bundle
        /// </summary>
        public static void DeserializeJsonProperty(this Bundle current, ref Utf8JsonReader reader, JsonSerializerOptions options, string propertyName)
        {
            switch (propertyName)
            {
            case "identifier":
                current.Identifier = new Hl7.Fhir.Model.Identifier();
                ((Hl7.Fhir.Model.Identifier)current.Identifier).DeserializeJson(ref reader, options);
                break;

            case "type":
                if (reader.TokenType == JsonTokenType.Null)
                {
                    current.TypeElement = new Code <Hl7.Fhir.Model.Bundle.BundleType>();
                    reader.Skip();
                }
                else
                {
                    current.TypeElement = new Code <Hl7.Fhir.Model.Bundle.BundleType>(Hl7.Fhir.Utility.EnumUtility.ParseLiteral <Hl7.Fhir.Model.Bundle.BundleType>(reader.GetString()));
                }
                break;

            case "_type":
                if (current.TypeElement == null)
                {
                    current.TypeElement = new Code <Hl7.Fhir.Model.Bundle.BundleType>();
                }
                ((Hl7.Fhir.Model.Element)current.TypeElement).DeserializeJson(ref reader, options);
                break;

            case "timestamp":
                if (reader.TokenType == JsonTokenType.Null)
                {
                    current.TimestampElement = new Instant();
                    reader.Skip();
                }
                else
                {
                    current.TimestampElement = new Instant(DateTimeOffset.Parse(reader.GetString()));
                }
                break;

            case "_timestamp":
                if (current.TimestampElement == null)
                {
                    current.TimestampElement = new Instant();
                }
                ((Hl7.Fhir.Model.Element)current.TimestampElement).DeserializeJson(ref reader, options);
                break;

            case "total":
                if (reader.TokenType == JsonTokenType.Null)
                {
                    current.TotalElement = new UnsignedInt();
                    reader.Skip();
                }
                else
                {
                    current.TotalElement = new UnsignedInt(reader.GetInt32());
                }
                break;

            case "_total":
                if (current.TotalElement == null)
                {
                    current.TotalElement = new UnsignedInt();
                }
                ((Hl7.Fhir.Model.Element)current.TotalElement).DeserializeJson(ref reader, options);
                break;

            case "link":
                if ((reader.TokenType != JsonTokenType.StartArray) || (!reader.Read()))
                {
                    throw new JsonException($"Bundle error reading 'link' expected StartArray, found {reader.TokenType}! depth: {reader.CurrentDepth}, pos: {reader.BytesConsumed}");
                }

                current.Link = new List <Bundle.LinkComponent>();

                while (reader.TokenType != JsonTokenType.EndArray)
                {
                    Hl7.Fhir.Model.Bundle.LinkComponent v_Link = new Hl7.Fhir.Model.Bundle.LinkComponent();
                    v_Link.DeserializeJson(ref reader, options);
                    current.Link.Add(v_Link);

                    if (!reader.Read())
                    {
                        throw new JsonException($"Bundle error reading 'link' array, read failed! depth: {reader.CurrentDepth}, pos: {reader.BytesConsumed}");
                    }
                    if (reader.TokenType == JsonTokenType.EndObject)
                    {
                        reader.Read();
                    }
                }

                if (current.Link.Count == 0)
                {
                    current.Link = null;
                }
                break;

            case "entry":
                if ((reader.TokenType != JsonTokenType.StartArray) || (!reader.Read()))
                {
                    throw new JsonException($"Bundle error reading 'entry' expected StartArray, found {reader.TokenType}! depth: {reader.CurrentDepth}, pos: {reader.BytesConsumed}");
                }

                current.Entry = new List <Bundle.EntryComponent>();

                while (reader.TokenType != JsonTokenType.EndArray)
                {
                    Hl7.Fhir.Model.Bundle.EntryComponent v_Entry = new Hl7.Fhir.Model.Bundle.EntryComponent();
                    v_Entry.DeserializeJson(ref reader, options);
                    current.Entry.Add(v_Entry);

                    if (!reader.Read())
                    {
                        throw new JsonException($"Bundle error reading 'entry' array, read failed! depth: {reader.CurrentDepth}, pos: {reader.BytesConsumed}");
                    }
                    if (reader.TokenType == JsonTokenType.EndObject)
                    {
                        reader.Read();
                    }
                }

                if (current.Entry.Count == 0)
                {
                    current.Entry = null;
                }
                break;

            case "signature":
                current.Signature = new Hl7.Fhir.Model.Signature();
                ((Hl7.Fhir.Model.Signature)current.Signature).DeserializeJson(ref reader, options);
                break;

            // Complex: Bundle, Export: Bundle, Base: Resource
            default:
                ((Hl7.Fhir.Model.Resource)current).DeserializeJsonProperty(ref reader, options, propertyName);
                break;
            }
        }