예제 #1
0
        public override void OnException(HttpActionExecutedContext context)
        {
            HttpResponseMessage response = null;

            if (context.Exception is PyroException PyroException)
            {
                if (PyroException.OperationOutcome != null)
                {
                    IFhirResourceNarrative.CreateNarrative(PyroException.OperationOutcome);
                    response = context.Request.CreateResponse <Resource>(PyroException.HttpStatusCode, PyroException.OperationOutcome);
                }
                else
                {
                    OperationOutcome OpOutCome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.Unknown, PyroException.Message);
                    IFhirResourceNarrative.CreateNarrative(OpOutCome);
                    response = context.Request.CreateResponse(PyroException.HttpStatusCode, OpOutCome);
                }
            }
            else if (context.Exception is SqlException oSqlException)
            {
                PyroException PyroSqlException = SqlExceptionSupport.GenerateDtoPyroException(oSqlException, System.Diagnostics.Debugger.IsAttached);
                IFhirResourceNarrative.CreateNarrative(PyroSqlException.OperationOutcome);
                response = context.Request.CreateResponse <Resource>(PyroSqlException.HttpStatusCode, PyroSqlException.OperationOutcome);
            }
            else if (context.Exception is Exception)
            {
                OperationOutcome OpOutCome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.Unknown, context.Exception.ToString());
                IFhirResourceNarrative.CreateNarrative(OpOutCome);
                response = context.Request.CreateResponse <Resource>(HttpStatusCode.InternalServerError, OpOutCome);
            }

            throw new HttpResponseException(response);
        }
        private ITriggerOutcome ProcessUpdateOrDelete(ITriggerInput TriggerInput)
        {
            //Get any Compartment with the same FhirId
            DtoServiceSearchParameterLight TagSearchParameter = GetTagSearchParameters(TriggerInput.ResourceType.GetLiteral());

            if (TriggerInput.DbTokenIndexList.Any(x => x.ServiceSearchParameterId == TagSearchParameter.Id && x.Code == _ProtectedCoding.Code && x.System == _ProtectedCoding.System))
            {
                //The Resource is protected
                string Message = "Error Message Not Set";
                if (TriggerInput.CrudOperationType == RestEnum.CrudOperationType.Update)
                {
                    Message = $"The {TriggerInput.ResourceType.GetLiteral()} resource instance with Id: {TriggerInput.InboundResourceId} cannot be updated because it is a {_ProtectedCoding.Display}.";
                }
                else if (TriggerInput.CrudOperationType == RestEnum.CrudOperationType.Delete)
                {
                    Message = $"The {TriggerInput.ResourceType.GetLiteral()} resource instance with Id: {TriggerInput.InboundResourceId} cannot be deleted because it is a {_ProtectedCoding.Display}.";
                }
                var ReturnOperationOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.BusinessRule, Message);
                var TriggerOutcome         = new TriggerOutcome();
                TriggerOutcome.Report         = true;
                TriggerOutcome.HttpStatusCode = System.Net.HttpStatusCode.Conflict;
                TriggerOutcome.Resource       = ReturnOperationOutcome;
                return(TriggerOutcome);
            }
            else
            {
                //The resource is not Protected
                return(new TriggerOutcome()
                {
                    Report = false
                });
            }
        }
예제 #3
0
        private ITriggerOutcome ProcessCreateUpdateOrDelete(ITriggerInput triggerInput)
        {
            if (IGlobalProperties.ServerReadOnlyMode)
            {
                //The Resource is protected
                string Message = $"The FHIR Server is currently in a read only mode. ";
                if (!string.IsNullOrWhiteSpace(IGlobalProperties.ServerReadOnlyModeMessage))
                {
                    Message += $"Administrator's Message: {IGlobalProperties.ServerReadOnlyModeMessage}";
                }

                var ReturnOperationOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Information, OperationOutcome.IssueType.Informational, Message);
                var TriggerOutcome         = new TriggerOutcome();
                TriggerOutcome.Report         = true;
                TriggerOutcome.HttpStatusCode = System.Net.HttpStatusCode.ServiceUnavailable;
                TriggerOutcome.Resource       = ReturnOperationOutcome;
                return(TriggerOutcome);
            }
            else
            {
                //The resource is not Protected
                return(new TriggerOutcome()
                {
                    Report = false
                });
            }
        }
        public PyroSearchParameters GetSearchParameters(string Compartment, string CompartmentId, string ResourceName)
        {
            //I need to check that Compartment and ResourceName are actual FHIR Resource Types, the two lines
            //below do that and throw Pyro Exception if they are not.
            FHIRAllTypes CompartmentType  = ResourceNameResolutionSupport.GetResourceFhirAllType(Compartment);
            FHIRAllTypes ResourceNameType = ResourceNameResolutionSupport.GetResourceFhirAllType(ResourceName);

            //Now to contruct the Container search parameters, these are cached from the database Conatiner Resource
            DtoServiceCompartmentResourceCached ServiceCompartmentResource = IServiceCompartmentCache.GetServiceCompartmentResourceForCompartmentCodeAndResource(Compartment, ResourceName);
            string ConatinerSerachString = string.Empty;

            if (ServiceCompartmentResource != null)
            {
                var CompartmentParamQuery = new List <string>();
                foreach (var CompartmentSearchParameter in ServiceCompartmentResource.ParamList)
                {
                    if (CompartmentSearchParameter.Param == "*")
                    {
                        // if the param="*" then all instances of this Resource Type are in the container and there are no
                        // actualy parameters that it needs to be restricted by. So the ConatinerSerachString remains as empty string.
                        break;
                    }
                    else
                    {
                        CompartmentParamQuery.Add($"{CompartmentSearchParameter.Param}:{Compartment}={CompartmentId}");
                    }
                }
                ConatinerSerachString = String.Join("&", CompartmentParamQuery.ToArray());
            }
            else
            {
                DtoServiceCompartmentCached ServiceCompartment = IServiceCompartmentCache.GetServiceCompartmentForCompartmentCode(Compartment);
                if (ServiceCompartment == null)
                {
                    string Message = $"No active {Compartment} Compartment exist in this server. Perhaps you could create one using a {FHIRAllTypes.CompartmentDefinition.GetLiteral()} resource and the resource instance ${Pyro.Common.Enum.FhirOperationEnum.OperationType.xSetCompartmentActive} Operation. " +
                                     $"For example: '[base]/{FHIRAllTypes.CompartmentDefinition.GetLiteral()}/[id]/${Pyro.Common.Enum.FhirOperationEnum.OperationType.xSetCompartmentActive}' ";
                    var OpOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, Message);
                    throw new PyroException(System.Net.HttpStatusCode.BadRequest, OpOutcome, Message);
                }
                else
                {
                    string Message   = $"The {Compartment} Compartment defined by the {FHIRAllTypes.CompartmentDefinition.GetLiteral()} with the resource id of '{ServiceCompartment.CompartmentDefinitionResourceId}' does not allow access to any {ResourceName} resource type instances.";
                    var    OpOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, Message);
                    throw new PyroException(System.Net.HttpStatusCode.BadRequest, OpOutcome, Message);
                }
            }

            ISearchParameterGeneric         ContainerSearchParameterGeneric = ISearchParameterGenericFactory.CreateDtoSearchParameterGeneric().Parse(ConatinerSerachString);
            ISearchParameterService         SearchService = ISearchParameterServiceFactory.CreateSearchParameterService();
            ISearchParametersServiceOutcome ContainerSearchParametersServiceOutcome = SearchService.ProcessSearchParameters(ContainerSearchParameterGeneric, SearchParameterService.SearchParameterServiceType.Resource, ResourceNameType, null);

            return(ContainerSearchParametersServiceOutcome.SearchParameters);
        }
예제 #5
0
        private void IdentifieBatchEntityToClient(OperationOutcome op, string FullURL, string OperationType, int EntityIndexInType)
        {
            EntityIndexInType = EntityIndexInType + 1;
            string Message = string.Empty;

            if (String.IsNullOrWhiteSpace(FullURL))
            {
                Message = $"The Issue/s were found in the {EntityIndexInType.Ordinal()} {OperationType} bundel entry";
            }
            else
            {
                Message = $"The Issue/s were found in the bundel entry identified by the FullURL: {FullURL}";
            }
            OperationOutcome NewOp = FhirOperationOutcomeSupport.Append(OperationOutcome.IssueSeverity.Information, OperationOutcome.IssueType.Informational, Message, op);
        }
예제 #6
0
        private ITriggerOutcome ProcessUpdateOrDelete(RestEnum.CrudOperationType crudOperationType, ResourceTriggerService.TriggerRaisedType triggerRaised, string resourceId, FHIRAllTypes resourceType, Resource resource)
        {
            //Get any Compartment with the same FhirId
            var ServiceCompartment = IServiceCompartmentRepository.GetServiceCompartmentByFhirId(resourceId);

            if (ServiceCompartment != null)
            {
                string Message = "Error Message Not Set";
                if (crudOperationType == RestEnum.CrudOperationType.Update)
                {
                    //If so do not allow the update
                    Message = $"The {FHIRAllTypes.CompartmentDefinition.GetLiteral()} resource cannot be updated because it is an active Compartment in the server. " +
                              $"You must first set this compartment to Inactive before you can updated this resource. " +
                              $"To do this you will need to call the server Operation ${FhirOperationEnum.OperationType.xSetCompartmentInActive.GetPyroLiteral()} on this resource instance. " +
                              $"For example '[base]/{FHIRAllTypes.CompartmentDefinition.GetLiteral()}/{resourceId}/${FhirOperationEnum.OperationType.xSetCompartmentInActive.GetPyroLiteral()}' " +
                              $"Once Inactive you will then be able to update this resource in the server. " +
                              $"Caution should be taken as active Compartments affect how users interact with the server and the resources they have access to. " +
                              $"To re-activate the Compartment after updating you must call the Operation ${FhirOperationEnum.OperationType.xSetCompartmentActive.GetPyroLiteral()}. " +
                              $"For example '[base]/{FHIRAllTypes.CompartmentDefinition.GetLiteral()}/{resourceId}/${FhirOperationEnum.OperationType.xSetCompartmentActive.GetPyroLiteral()}' ";
                }
                else if (crudOperationType == RestEnum.CrudOperationType.Delete)
                {
                    Message = $"The {FHIRAllTypes.CompartmentDefinition.GetLiteral()} resource cannot be deleted because it is an active Compartment in the server. " +
                              $"You must first set this compartment to Inactive before you can delete this resource. " +
                              $"To do this you will need to call the server Operation ${FhirOperationEnum.OperationType.xSetCompartmentInActive.GetPyroLiteral()} on this resource instance. " +
                              $"For example '[base]/{FHIRAllTypes.CompartmentDefinition.GetLiteral()}/{resourceId}/${FhirOperationEnum.OperationType.xSetCompartmentInActive.GetPyroLiteral()}' " +
                              $"Once Inactive you will then be able to delete this resource from the server. " +
                              $"Caution should be taken as active Compartments affect how users interact with the server and the resources they have access to.";
                }
                var ReturnOperationOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.BusinessRule, Message);
                var TriggerOutcome         = new TriggerOutcome();
                TriggerOutcome.HttpStatusCode       = System.Net.HttpStatusCode.Conflict;
                TriggerOutcome.TriggerOutcomeResult = TriggerOutcome.TriggerOutcomeType.Report;
                TriggerOutcome.Resource             = ReturnOperationOutcome;
                return(TriggerOutcome);
            }
            else
            {
                //the Compartmentdefinition is not active so can be Updated or deleted, if updating then ensure
                //the active tags are not present and remove if they are
                RemoveActiveCompartmentTag(resource);
            }

            return(new TriggerOutcome()
            {
                TriggerOutcomeResult = TriggerOutcome.TriggerOutcomeType.Contiune
            });
        }
예제 #7
0
        private OperationOutcome GenerateUnsupportedParameterOperationOutcome()
        {
            if (this.SearchParameters == null || this.SearchParameters.UnspportedSearchParameterList == null || this.SearchParameters.UnspportedSearchParameterList.Count == 0)
            {
                string ExceptionMessage = "Server Internal Error: Attempt to generate unsupported search parameter OperationOutcome when there were no unsupported search parameters to process.";
                throw new Pyro.Common.Exceptions.PyroException(HttpStatusCode.Forbidden, FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.Exception, ExceptionMessage), ExceptionMessage);
            }

            var OpOut = new OperationOutcome();

            foreach (UnspportedSearchParameter Parameter in SearchParameters.UnspportedSearchParameterList)
            {
                string Message = $"Unable to process a search parameter: {Parameter.ReasonMessage}";
                FhirOperationOutcomeSupport.Append(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Processing, Message, OpOut);
            }
            return(OpOut);
        }
예제 #8
0
        private HttpResponseMessage ResolveReturnAcceptTypeJsonOrXml(string _FormatMimeType, HttpRequestMessage Request, Resource Resource)
        {
            HttpResponseMessage Response;

            //If no _format=application/fhir%2Bjson parameter
            if (_FormatMimeType == null)
            {
                //below returns Null if ok or an Operationoutcome if not ok
                OperationOutcome FailedAcceptHeaderOperationOutcome = null;
                FailedAcceptHeaderOperationOutcome = CheckAcceptHeaderValid(Request);
                if (FailedAcceptHeaderOperationOutcome != null)
                {
                    IFhirResourceNarrative.CreateNarrative(FailedAcceptHeaderOperationOutcome);
                    _HttpStatusCode = HttpStatusCode.UnsupportedMediaType;
                    Response        = Request.CreateResponse(_HttpStatusCode, FailedAcceptHeaderOperationOutcome);
                }
                else
                {
                    //Then send the Accept type as specified by the Accept Header, or the default of JSON if no header at all
                    Response = Request.CreateResponse(_HttpStatusCode, Resource);
                }
            }
            else
            {
                //Parse the _format=application/fhir%2Bjson parameter and switch formater if valid.
                _FhirMediaTypeFormatter = GetFhirMediaFormatter(_FormatMimeType);
                if (_FhirMediaTypeFormatter != null)
                {
                    Response = new HttpResponseMessage(_HttpStatusCode)
                    {
                        Content = new ObjectContent(typeof(Resource), Resource, _FhirMediaTypeFormatter)
                    };
                }
                else
                {
                    string Message = $"The _format search parameter value was {_FormatMimeType} which is not a supported media type. The simplest supported meda types to use are _format=xml or _format=json";
                    var    FaledFormatParameterOperationOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, Message);
                    IFhirResourceNarrative.CreateNarrative(FaledFormatParameterOperationOutcome);
                    _HttpStatusCode = HttpStatusCode.UnsupportedMediaType;
                    Response        = Request.CreateResponse(_HttpStatusCode, FaledFormatParameterOperationOutcome);
                }
            }
            return(Response);
        }
예제 #9
0
 private static OperationOutcome CheckAcceptHeaderValid(HttpRequestMessage Request)
 {
     //first test the Accept header is valid
     if (Request?.Headers?.Accept?.Count > 0)
     {
         bool IsOk = false;
         foreach (var AcceptHeaderValue in Request.Headers.Accept)
         {
             if (!string.IsNullOrWhiteSpace(Common.Tools.HttpHeaderSupport.GetFhirMediaTypeString(AcceptHeaderValue.MediaType)))
             {
                 IsOk = true;
                 break;
             }
         }
         if (!IsOk)
         {
             string Message = $"None of the Http Accept header values are suported by the server. The primary values that are supported are {Hl7.Fhir.Rest.ContentType.JSON_CONTENT_HEADER} and {Hl7.Fhir.Rest.ContentType.XML_CONTENT_HEADER}";
             return(FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, Message));
         }
     }
     return(null);
 }
예제 #10
0
        public HttpResponseMessage GetHttpResponseMessage(IResourceServiceOutcome ResourceServiceOutcome, HttpRequestMessage Request, Hl7.Fhir.Rest.SummaryType?SummaryType)
        {
            _HttpStatusCode = ResourceServiceOutcome.HttpStatusCode;
            Resource            Resource = ResourceServiceOutcome.ResourceResult;
            HttpResponseMessage Response = Request.CreateResponse(_HttpStatusCode);

            if (Resource != null)
            {
                //If the Resource is an OperationOutcome then we auto generate its narrative here
                if (Resource.ResourceType == ResourceType.OperationOutcome)
                {
                    IFhirResourceNarrative.CreateNarrative(Resource as OperationOutcome);
                }

                //Set the media formatter as per search parameter _format
                Response = ResolveReturnAcceptTypeJsonOrXml(ResourceServiceOutcome.FormatMimeType, Request, Resource);

                //Annotate the Resource with the _summary, will get the annotation in MediaTypeFormatter XML or JSON
                AnnotateResourceWithSummaryType(SummaryType, Resource);
            }

            switch (_HttpStatusCode)
            {
            case HttpStatusCode.OK:
            {
                switch (ResourceServiceOutcome.OperationType)
                {
                case RestEnum.CrudOperationType.None:
                    break;

                case RestEnum.CrudOperationType.Create:
                {
                    //LastModified Header && ETag Version
                    if (ResourceServiceOutcome.LastModified != null)
                    {
                        Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                        //If we have a conditional Create where the Resource is found then we return OK but no Resource so no Content
                        if (Response.Content != null)
                        {
                            Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                        }
                    }
                    return(Response);
                }

                case RestEnum.CrudOperationType.Read:
                {
                    //LastModified Header & ETagVersion &Location Header
                    if (ResourceServiceOutcome.LastModified.HasValue)
                    {
                        Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                        if (Response.Content != null && ResourceServiceOutcome.IsDeleted.HasValue && !ResourceServiceOutcome.IsDeleted.Value)
                        {
                            Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                        }
                        Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri);
                    }
                    return(Response);
                }

                case RestEnum.CrudOperationType.Update:
                {
                    //Location Header
                    if (Response.Content != null)
                    {
                        Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri);
                    }
                    //LastModified Header && ETagVersion
                    if (ResourceServiceOutcome.LastModified.HasValue)
                    {
                        Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                        Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                    }
                    return(Response);
                }

                case RestEnum.CrudOperationType.Delete:
                {
                    //LastModified Header && ETag Version
                    if (ResourceServiceOutcome.LastModified != null)
                    {
                        if (!string.IsNullOrWhiteSpace(ResourceServiceOutcome.ResourceVersionNumber))
                        {
                            Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                        }
                        Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                    }
                    return(Response);
                }

                default:
                {
                    var oIssueComponent = new OperationOutcome.IssueComponent
                    {
                        Severity    = OperationOutcome.IssueSeverity.Fatal,
                        Code        = OperationOutcome.IssueType.Exception,
                        Diagnostics = "Internal Error. FhirRestResponse contains no FHIR Resource or Id."
                    };
                    var oOperationOutcome = new OperationOutcome
                    {
                        Issue = new List <OperationOutcome.IssueComponent>()
                        {
                            oIssueComponent
                        }
                    };
                    throw new PyroException(HttpStatusCode.InternalServerError, oOperationOutcome, "Internal Error. FhirRestResponse contains no FHIR Resource or Id.");
                }
                }
                if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Read)
                {
                    //LastModified Header & ETagVersion &Location Header
                    if (ResourceServiceOutcome.LastModified.HasValue)
                    {
                        Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                        if (Response.Content != null && ResourceServiceOutcome.IsDeleted.HasValue && !ResourceServiceOutcome.IsDeleted.Value)
                        {
                            Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                        }
                        Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri);
                    }
                    return(Response);
                }
                else if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Update)
                {
                    //Location Header
                    if (Response.Content != null)
                    {
                        Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri);
                    }
                    //LastModified Header && ETagVersion
                    if (ResourceServiceOutcome.LastModified.HasValue)
                    {
                        Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                        Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                    }
                    return(Response);
                }
                else if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Delete && ResourceServiceOutcome.ResourceVersionNumber != null)
                {
                    //LastModified Header && ETag Version
                    if (ResourceServiceOutcome.LastModified != null)
                    {
                        Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                        Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                    }
                    return(Response);
                }
                else if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Create)
                {
                    //LastModified Header && ETag Version
                    if (ResourceServiceOutcome.LastModified != null)
                    {
                        Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                        //If we have a conditional Create where the Resource is found then we return OK but no Resource so no Content
                        if (Response.Content != null)
                        {
                            Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                        }
                    }
                    return(Response);
                }
                else
                {
                    var oIssueComponent = new OperationOutcome.IssueComponent
                    {
                        Severity    = OperationOutcome.IssueSeverity.Fatal,
                        Code        = OperationOutcome.IssueType.Exception,
                        Diagnostics = "Internal Error. FhirRestResponse contains no FHIR Resource or Id."
                    };
                    var oOperationOutcome = new OperationOutcome
                    {
                        Issue = new List <OperationOutcome.IssueComponent>()
                        {
                            oIssueComponent
                        }
                    };
                    throw new PyroException(HttpStatusCode.InternalServerError, oOperationOutcome, "Internal Error. FhirRestResponse contains no FHIR Resource or Id.");
                }
            }

            case HttpStatusCode.Created:
            {
                //Location Header
                if (Response.Content != null)
                {
                    Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri, ResourceServiceOutcome.FhirResourceId);
                }

                //LastModified Header && ETagVersion
                if (ResourceServiceOutcome.LastModified.HasValue)
                {
                    Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                    Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                }
                return(Response);
            }

            case HttpStatusCode.Gone:
            {
                //LastModified Header && ETagVersion
                if (ResourceServiceOutcome.LastModified.HasValue)
                {
                    Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                }
                return(Response);
            }

            case HttpStatusCode.NoContent:
            {
                //LastModified Header && ETagVersion
                if (ResourceServiceOutcome.LastModified.HasValue)
                {
                    Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                    if (Response.Content != null)
                    {
                        Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                    }
                }
                return(Response);
            }

            case HttpStatusCode.NotFound:
            {
                //No need to process _format as not returning a body of type resource
                return(Response);
            }

            case HttpStatusCode.PreconditionFailed:
            {
                return(Response);
            }

            case HttpStatusCode.NotModified:
            {
                return(Response);
            }

            case HttpStatusCode.UnsupportedMediaType:
            {
                return(Response);
            }

            default:
            {
                if (Resource != null)
                {
                    return(Response);
                }
                else
                {
                    var OpOutComeIssueComp = new OperationOutcome.IssueComponent
                    {
                        Severity    = OperationOutcome.IssueSeverity.Fatal,
                        Code        = OperationOutcome.IssueType.Exception,
                        Diagnostics = "Internal Server Error: An unexpected HttpStatusCode has been encountered with a null resource to return. This is most likely a server bug."
                    };
                    var OpOutCome = new OperationOutcome();
                    OpOutCome.Issue.Add(OpOutComeIssueComp);
                    FhirOperationOutcomeSupport.EscapeOperationOutComeContent(OpOutCome);
                    IFhirResourceNarrative.CreateNarrative(OpOutCome);
                    if (_FhirMediaTypeFormatter != null)
                    {
                        Response.Content = new ObjectContent(typeof(Resource), OpOutCome, _FhirMediaTypeFormatter);
                    }
                    else
                    {
                        Response = Request.CreateResponse(_HttpStatusCode, OpOutCome);
                    }
                    return(Response);
                }
            }
            }
        }
예제 #11
0
        public IResourceServiceOutcome Transact(Resource Resource, IRequestMeta RequestMeta)
        {
            if (IResourceServices == null)
            {
                throw new ArgumentNullException("IResourceServices can not be null.");
            }
            if (Resource == null)
            {
                throw new ArgumentNullException("Resource can not be null.");
            }
            if (RequestMeta == null)
            {
                throw new ArgumentNullException("RequestMeta can not be null.");
            }

            _RequestHeader = RequestMeta.RequestHeader ?? throw new ArgumentNullException("RequestHeaders can not be null.");
            _RequestUri    = RequestMeta.PyroRequestUri ?? throw new ArgumentNullException("RequestUri can not be null.");

            _ServiceOperationOutcome = IResourceServiceOutcomeFactory.CreateResourceServiceOutcome();
            _ServiceOperationOutcome.HttpStatusCode = System.Net.HttpStatusCode.OK;
            Bundle bundle = Resource as Bundle;

            if (bundle == null)
            {
                var Message   = $"The FHIR server's service root endpoint can only accept 'Bundle' resources. Resource received was: {Resource.ResourceType.ToString()}";
                var OpOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, Message);
                _ServiceOperationOutcome.ResourceResult = OpOutcome;
                _ServiceOperationOutcome.HttpStatusCode = System.Net.HttpStatusCode.Forbidden;
                _ServiceOperationOutcome.OperationType  = Enum.RestEnum.CrudOperationType.Create;
                return(_ServiceOperationOutcome);
            }
            else if (bundle.Type != Bundle.BundleType.Transaction || (bundle.Type != Bundle.BundleType.Transaction && bundle.Type != Bundle.BundleType.Batch))
            {
                var Message   = $"The FHIR server's service root endpoint can only accept Bundle resources of Bundle.type = 'Transaction' or Bundle.type = 'Batch'. Type found was {bundle.Type.ToString()}";
                var OpOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, Message);
                _ServiceOperationOutcome.ResourceResult = OpOutcome;
                _ServiceOperationOutcome.HttpStatusCode = System.Net.HttpStatusCode.Forbidden;
                _ServiceOperationOutcome.OperationType  = Enum.RestEnum.CrudOperationType.Create;
                return(_ServiceOperationOutcome);
            }
            else
            {
                bundle.Type = Bundle.BundleType.TransactionResponse;
                bundle.Id   = Guid.NewGuid().ToString();
                if (bundle.Meta == null)
                {
                    bundle.Meta = new Meta();
                }
                bundle.Meta.LastUpdated = DateTimeOffset.Now;


                //FHIR Spec: http://build.fhir.org/bundle.html#transaction
                //  If there is no request element, then there SHALL be a resource and the server must infer
                //  whether this is a create or an update from the resource identity supplied.
                //  NO Request Processing
                foreach (var NoRequestEntry in bundle.Entry.Where(x => x.Request == null || !x.Request.Method.HasValue))
                {
                    NoRequestEntry.Request = GenerateRequestComponentForEntry(NoRequestEntry);
                }

                //All entries with a Request, should be all at this point
                var EntryWithRequestList            = bundle.Entry.Where(x => x.Request != null && x.Request.Method.HasValue);
                var EntryWithResourceAndRequestList = EntryWithRequestList.Where(x => x.Resource != null);

                var DeleteEntries = EntryWithRequestList.Where(x => x.Request.Method == Bundle.HTTPVerb.DELETE);
                var POSTEntries   = EntryWithResourceAndRequestList.Where(x => x.Request.Method == Bundle.HTTPVerb.POST);
                var PUTEntries    = EntryWithResourceAndRequestList.Where(x => x.Request.Method == Bundle.HTTPVerb.PUT);
                var GETEntries    = EntryWithRequestList.Where(x => x.Request.Method == Bundle.HTTPVerb.GET);

                try
                {
                    //DELETE Processing
                    for (int i = 0; i < DeleteEntries.Count(); i++)
                    {
                        if (!DeleteProcessing(DeleteEntries.ElementAt(i), i))
                        {
                            return(_ServiceOperationOutcome);
                        }
                    }

                    //Assign new id's for POSTs and then update all POST and PUT entrie referances
                    AssignResourceIdsAndUpdateReferances(POSTEntries, PUTEntries);

                    //POST Processing
                    for (int i = 0; i < POSTEntries.Count(); i++)
                    {
                        if (!PostProcessing(POSTEntries.ElementAt(i), i))
                        {
                            _ServiceOperationOutcome.SuccessfulTransaction = false;
                            return(_ServiceOperationOutcome);
                        }
                    }

                    //PUT Processing
                    for (int i = 0; i < PUTEntries.Count(); i++)
                    {
                        if (!PutProcessing(PUTEntries.ElementAt(i), i))
                        {
                            _ServiceOperationOutcome.SuccessfulTransaction = false;
                            return(_ServiceOperationOutcome);
                        }
                    }

                    //GET Processing
                    for (int i = 0; i < GETEntries.Count(); i++)
                    {
                        if (!GetProcessing(GETEntries.ElementAt(i), i))
                        {
                            _ServiceOperationOutcome.SuccessfulTransaction = false;
                            return(_ServiceOperationOutcome);
                        }
                    }

                    _ServiceOperationOutcome.ResourceResult        = bundle;
                    _ServiceOperationOutcome.HttpStatusCode        = System.Net.HttpStatusCode.OK;
                    _ServiceOperationOutcome.OperationType         = Enum.RestEnum.CrudOperationType.Update;
                    _ServiceOperationOutcome.SuccessfulTransaction = true;
                }
                catch (Exception Exec)
                {
                    throw new PyroException(System.Net.HttpStatusCode.InternalServerError, FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Exception, Exec.Message), Exec.Message);
                }
            }

            return(_ServiceOperationOutcome);
        }
예제 #12
0
        private bool PostProcessing(Bundle.EntryComponent PostEntry, int PostEntryIndex)
        {
            IRequestMeta RequestMeta = IRequestMetaFactory.CreateRequestMeta().Set(PostEntry.Request);

            if (RequestMeta.PyroRequestUri.FhirRequestUri.IsOperation)
            {
                var Message   = $"The FHIR server does not support the use of Operations within Transaction Bundles, found Operation request type of : '{RequestMeta.PyroRequestUri.FhirRequestUri.OperationName}'.";
                var OpOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, Message);
                _ServiceOperationOutcome.ResourceResult = OpOutcome;
                _ServiceOperationOutcome.HttpStatusCode = System.Net.HttpStatusCode.Forbidden;
                _ServiceOperationOutcome.OperationType  = Enum.RestEnum.CrudOperationType.Create;
                return(false);
            }

            IPyroFhirUri ResourceIdToForce = IPyroFhirUriFactory.CreateFhirRequestUri();

            if (String.IsNullOrEmpty(PostEntry.FullUrl))
            {
                //Assgin a new GUID as there is not FullURL GUID to lookup from refererancing
                ResourceIdToForce.Parse($"{PostEntry.Resource.TypeName}/{Common.Tools.FhirGuid.FhirGuid.NewFhirGuid()}");
            }
            else
            {
                //Use the new Resource id that we assigned when updating all referances by looking it up in the GetUUIDfromFullURL dic
                ResourceIdToForce.Parse(OldNewResourceReferanceMap[GetUUIDfromFullURL(PostEntry.FullUrl)]);
            }
            //Remove the Resource Id in the resource as this is a POST and no id should be present in the resource, we do force the new id given this is a transaction operation
            if (!String.IsNullOrEmpty(PostEntry.Resource.Id))
            {
                PostEntry.Resource.Id = String.Empty;
            }

            IResourceServiceOutcome ResourceServiceOutcome = IResourceServices.Post(PostEntry.Resource, RequestMeta, ResourceIdToForce.ResourceId);

            if (ResourceServiceOutcome.SuccessfulTransaction)
            {
                PostEntry.FullUrl         = CreateFullUrl(ResourceServiceOutcome);
                PostEntry.Response        = new Bundle.ResponseComponent();
                PostEntry.Response.Status = FormatHTTPStatusCodeAsString(ResourceServiceOutcome.HttpStatusCode);

                if (ResourceServiceOutcome.ResourceResult != null)
                {
                    if (ResourceServiceOutcome.ResourceResult.ResourceType == ResourceType.OperationOutcome)
                    {
                        PostEntry.Response.Outcome = ResourceServiceOutcome.ResourceResult;
                    }
                    else
                    {
                        PostEntry.Resource = ResourceServiceOutcome.ResourceResult;
                    }
                }
                if (ResourceServiceOutcome.LastModified != null)
                {
                    PostEntry.Response.Etag         = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber).ToString();
                    PostEntry.Response.LastModified = ResourceServiceOutcome.LastModified;
                }
                PostEntry.Response.Status   = $"{((int)ResourceServiceOutcome.HttpStatusCode).ToString()} {ResourceServiceOutcome.HttpStatusCode.ToString()}";
                PostEntry.Response.Location = FormatResponseLocation(ResourceServiceOutcome.RequestUri.OriginalString, ResourceServiceOutcome.FhirResourceId, ResourceServiceOutcome.ResourceVersionNumber);
                return(true);
            }
            else
            {
                if (ResourceServiceOutcome.ResourceResult != null && ResourceServiceOutcome.ResourceResult is OperationOutcome Op)
                {
                    IdentifieBatchEntityToClient(Op, PostEntry.FullUrl, "POST", PostEntryIndex);
                }
                _ServiceOperationOutcome = ResourceServiceOutcome;
                return(false);
            }
        }
예제 #13
0
        public static HttpResponseMessage GetHttpResponseMessage(IResourceServiceOutcome ResourceServiceOutcome, HttpRequestMessage Request, Hl7.Fhir.Rest.SummaryType?SummaryType)
        {
            HttpStatusCode HttpStatusCode = ResourceServiceOutcome.HttpStatusCode;
            Resource       Resource       = ResourceServiceOutcome.ResourceResult;

            Pyro.Common.Formatters.FhirMediaTypeFormatter FhirMediaTypeFormatter = null;

            HttpResponseMessage Response = Request.CreateResponse(HttpStatusCode);

            if (Resource != null)
            {
                if (ResourceServiceOutcome.FormatMimeType == null)
                {
                    Response = Request.CreateResponse(HttpStatusCode, Resource);
                }
                else
                {
                    Pyro.Common.Formatters.FhirMediaTypeFormatter Formater = GetFhirMediaFormatter(Request, ResourceServiceOutcome.FormatMimeType);
                    if (Formater != null)
                    {
                        FhirMediaTypeFormatter = Formater;
                        Response         = new HttpResponseMessage(HttpStatusCode);
                        Response.Content = new ObjectContent(typeof(Resource), Resource, Formater);
                    }
                    else
                    {
                        Response = Request.CreateResponse(HttpStatusCode, Resource);
                    }
                }

                //Annotate the Resource with the _summary, will get the annotation in MediaTypeFormatter XML or JSON
                if (Resource is Hl7.Fhir.Utility.IAnnotatable AnnotatableResource)
                {
                    if (SummaryType.HasValue)
                    {
                        AnnotatableResource.AddAnnotation(SummaryType.Value);
                    }
                    else
                    {
                        AnnotatableResource.AddAnnotation(Hl7.Fhir.Rest.SummaryType.False);
                    }
                }
            }

            //OK: 200
            if (HttpStatusCode == HttpStatusCode.OK)
            {
                if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Read)
                {
                    //LastModified Header & ETagVersion &Location Header
                    if (ResourceServiceOutcome.LastModified.HasValue)
                    {
                        Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                        if (Response.Content != null && ResourceServiceOutcome.IsDeleted.HasValue && !ResourceServiceOutcome.IsDeleted.Value)
                        {
                            Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                        }
                        Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri);
                    }
                    return(Response);
                }
                else if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Update)
                {
                    //Location Header
                    if (Response.Content != null)
                    {
                        Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri);
                    }
                    //LastModified Header && ETagVersion
                    if (ResourceServiceOutcome.LastModified.HasValue)
                    {
                        Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                        Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                    }
                    return(Response);
                }
                else if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Delete && ResourceServiceOutcome.ResourceVersionNumber != null)
                {
                    //LastModified Header && ETag Version
                    if (ResourceServiceOutcome.LastModified != null)
                    {
                        Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                        Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                    }
                    return(Response);
                }
                else if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Create)
                {
                    //LastModified Header && ETag Version
                    if (ResourceServiceOutcome.LastModified != null)
                    {
                        Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                        //If we have a conditional Create where the Resource is found then we return OK but no Resource so no Content
                        if (Response.Content != null)
                        {
                            Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                        }
                    }
                    return(Response);
                }
                else
                {
                    var oIssueComponent = new OperationOutcome.IssueComponent();
                    oIssueComponent.Severity    = OperationOutcome.IssueSeverity.Fatal;
                    oIssueComponent.Code        = OperationOutcome.IssueType.Exception;
                    oIssueComponent.Diagnostics = "Internal Error. FhirRestResponse contains no FHIR Resource or Id.";
                    var oOperationOutcome = new OperationOutcome();
                    oOperationOutcome.Issue = new List <OperationOutcome.IssueComponent>()
                    {
                        oIssueComponent
                    };
                    throw new PyroException(HttpStatusCode.InternalServerError, oOperationOutcome, "Internal Error. FhirRestResponse contains no FHIR Resource or Id.");
                }
            }
            //Created: 201
            else if (HttpStatusCode == HttpStatusCode.Created)
            {
                //Location Header
                if (Response.Content != null)
                {
                    Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri, ResourceServiceOutcome.FhirResourceId);
                }

                //LastModified Header && ETagVersion
                if (ResourceServiceOutcome.LastModified.HasValue)
                {
                    Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                    Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                }

                return(Response);
            }
            //Gone: 410 - Search for a resource that no longer there, it is deleted or has never existed.
            else if (HttpStatusCode == HttpStatusCode.Gone)
            {
                //LastModified Header && ETagVersion
                if (ResourceServiceOutcome.LastModified.HasValue)
                {
                    Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                    //Support.HttpHeaderSupport.AddLastModified(Response, oPyroServiceOperationOutcome.LastModified.Value);
                }
                return(Response);
            }
            //No Content: 204
            else if (HttpStatusCode == HttpStatusCode.NoContent)
            {
                //LastModified Header && ETagVersion
                if (ResourceServiceOutcome.LastModified.HasValue)
                {
                    Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber);
                    if (Response.Content != null)
                    {
                        Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified;
                    }
                }
                return(Response);
            }
            else if (HttpStatusCode == System.Net.HttpStatusCode.NotFound)
            {
                //No need to process _format as not returning a body of type resource
                return(Response);
            }
            else if (HttpStatusCode == System.Net.HttpStatusCode.PreconditionFailed)
            {
                return(Response);
            }
            else if (HttpStatusCode == System.Net.HttpStatusCode.NotModified)
            {
                return(Response);
            }
            //Forbidden: 403..and others
            else
            {
                if (Resource != null)
                {
                    return(Response);
                }
                else
                {
                    var OpOutComeIssueComp = new OperationOutcome.IssueComponent();
                    OpOutComeIssueComp.Severity    = OperationOutcome.IssueSeverity.Fatal;
                    OpOutComeIssueComp.Code        = OperationOutcome.IssueType.Exception;
                    OpOutComeIssueComp.Diagnostics = "Internal Server Error: An unexpected HttpStatusCode has been encountered with a null resource to return. This is most likely a server bug.";
                    var OpOutCome = new OperationOutcome();
                    OpOutCome.Issue.Add(OpOutComeIssueComp);
                    FhirOperationOutcomeSupport.EscapeOperationOutComeContent(OpOutCome);
                    if (FhirMediaTypeFormatter != null)
                    {
                        Response.Content = new ObjectContent(typeof(Resource), OpOutCome, FhirMediaTypeFormatter);
                    }
                    else
                    {
                        Response = Request.CreateResponse(HttpStatusCode, OpOutCome);
                    }
                    return(Response);
                }
            }
        }
예제 #14
0
        public static Bundle CreateBundle(ICollection <DtoResource> ResourceList, Bundle.BundleType BundleType, IPyroRequestUri RequestUri, int SearchTotal, int PagesTotal, int PageRequested, Paging.IPagingSupport IPagingSupport, Uri SearchPerformedUri = null)
        {
            var FhirBundle = new Bundle()
            {
                Type = Bundle.BundleType.Searchset
            };

            FhirBundle.Type  = BundleType;
            FhirBundle.Total = SearchTotal;

            //Paging
            IPagingSupport.SetBundlePagnation(FhirBundle, RequestUri.FhirRequestUri.OriginalString, PagesTotal, PageRequested, SearchPerformedUri);

            foreach (DtoResource DtoResource in ResourceList)
            {
                Bundle.EntryComponent oResEntry = new Bundle.EntryComponent();

                if (DtoResource.IsDeleted == false)
                {
                    try
                    {
                        oResEntry.Resource = FhirResourceSerializationSupport.DeSerializeFromXml(DtoResource.Xml);
                    }
                    catch (Exception oExec)
                    {
                        string           Message   = string.Format("Internal Server Error: Serialization of a Resource retrieved from the servers database failed. The record details were: Key: {0}, ResourceVersion: {1}, Received: {2}. The parser exception error was '{3}", DtoResource.FhirId, DtoResource.Version, DtoResource.Received.ToString(), oExec.Message);
                        OperationOutcome OpOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.Exception, Message);
                        throw new PyroException(System.Net.HttpStatusCode.InternalServerError, OpOutcome, Message);
                    }
                }

                oResEntry.FullUrl = string.Join("/", RequestUri.FhirRequestUri.UriPrimaryServiceRoot.OriginalString, DtoResource.ResourceType.GetLiteral(), DtoResource.FhirId);

                if (BundleType == Bundle.BundleType.History)
                {
                    oResEntry.FullUrl = string.Join("/", oResEntry.FullUrl);
                    if (DtoResource.ResourceType.HasValue && DtoResource.ResourceType.HasValue)
                    {
                        oResEntry.Request        = new Bundle.RequestComponent();
                        oResEntry.Request.Method = DtoResource.Method;
                        switch (DtoResource.Method)
                        {
                        case Bundle.HTTPVerb.GET:
                            oResEntry.Request.Url = string.Join("/", ModelInfo.FhirTypeToFhirTypeName(DtoResource.ResourceType.Value), DtoResource.FhirId, "_history", DtoResource.Version);
                            break;

                        case Bundle.HTTPVerb.POST:
                            oResEntry.Request.Url = string.Join("/", ModelInfo.FhirTypeToFhirTypeName(DtoResource.ResourceType.Value), DtoResource.FhirId, "_history", DtoResource.Version);
                            break;

                        case Bundle.HTTPVerb.PUT:
                            oResEntry.Request.Url = string.Join("/", ModelInfo.FhirTypeToFhirTypeName(DtoResource.ResourceType.Value), DtoResource.FhirId, "_history", DtoResource.Version);
                            break;

                        case Bundle.HTTPVerb.DELETE:
                            oResEntry.Request.Url = string.Join("/", ModelInfo.FhirTypeToFhirTypeName(DtoResource.ResourceType.Value), DtoResource.FhirId, "_history", DtoResource.Version);
                            break;

                        default:
                            throw new System.ComponentModel.InvalidEnumArgumentException(DtoResource.Method.ToString(), (int)DtoResource.Method, typeof(Bundle.HTTPVerb));
                        }
                    }
                }
                if (BundleType == Bundle.BundleType.Searchset)
                {
                    oResEntry.Search      = new Bundle.SearchComponent();
                    oResEntry.Search.Mode = Bundle.SearchEntryMode.Match;
                    if (DtoResource is DtoIncludeResource)
                    {
                        oResEntry.Search.Mode = Bundle.SearchEntryMode.Include;
                    }
                    oResEntry.Link = new List <Bundle.LinkComponent>();
                }

                FhirBundle.Entry.Add(oResEntry);
            }
            return(FhirBundle);
        }