Пример #1
0
        public void Test_NegativeRecursiveChainSearchNoResourceModifier()
        {
            var SearchParameterService = SetupMockedSearchParameterService();
            //string UrlSearchParametersString = "?subject:Patient.organization.endpoint:Endpoint.name=AcmeMail,AcmeMail2&identifier=123";
            string UrlSearchParametersString = "?subject.organization.endpoint.name=AcmeMail,AcmeMail2&identifier=123";
            var    DtoSearchParameterGeneric = new SearchParameterGeneric();

            DtoSearchParameterGeneric.Parse(UrlSearchParametersString);

            //Act
            ISearchParametersServiceOutcome Result = SearchParameterService.ProcessResourceSearchParameters(DtoSearchParameterGeneric, SearchParameterService.SearchParameterServiceType.Resource, FHIRAllTypes.DiagnosticReport);

            //Assert
            Assert.NotNull(Result, "Test returned null");
            Assert.NotNull(Result.SearchParameters, "SearchParameters returned null");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList.Count, 1, "SearchParametersList must have 3 items");
            Assert.IsNotNull(Result.FhirOperationOutcome, "There should be an operationoutcome as this is a hard fault");
            Assert.AreEqual(Result.FhirOperationOutcome.Issue.Count, 1, "There should 1 Issue ");

            //DiagnosticReport.identifier
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].Type, SearchParamType.Token, "First chain should be type Token");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].Name, "identifier", "First chain must have name of identifier");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].Resource, FHIRAllTypes.DiagnosticReport.GetLiteral(), $"First chain should be Resource of {FHIRAllTypes.Organization.GetLiteral()}");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0] is SearchParameterToken), true, "Expected SearchParameterToken type cast");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0] as SearchParameterToken).ValueList.Count, 1, "Expected ValueList count = 1");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0] as SearchParameterToken).ValueList[0].Code, "123", "Expected ValueList[0] to be '123'");
            Assert.IsNull(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter, "The root search  should not have a child chain parameter");
        }
Пример #2
0
        public void Test_RecursiveChainSearchNoResourceModifier()
        {
            var SearchParameterService = SetupMockedSearchParameterService();
            //string UrlSearchParametersString = "?subject:Patient.organization.endpoint:Endpoint.name=AcmeMail,AcmeMail2&identifier=123";
            string UrlSearchParametersString = "?subject.organization.endpoint:Endpoint.name=AcmeMail,AcmeMail2&identifier=123";
            var    DtoSearchParameterGeneric = new SearchParameterGeneric();

            DtoSearchParameterGeneric.Parse(UrlSearchParametersString);

            //Act
            ISearchParametersServiceOutcome Result = SearchParameterService.ProcessResourceSearchParameters(DtoSearchParameterGeneric, SearchParameterService.SearchParameterServiceType.Resource, FHIRAllTypes.DiagnosticReport);

            //Assert
            Assert.NotNull(Result, "Test returned null");
            Assert.NotNull(Result.SearchParameters, "SearchParameters returned null");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList.Count, 2, "SearchParametersList must have 3 items");

            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].Type, SearchParamType.Reference);
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].Name, "subject");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].Resource, FHIRAllTypes.DiagnosticReport.GetLiteral());
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].TypeModifierResource, FHIRAllTypes.Patient.GetLiteral());
            Assert.IsNotNull(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter, "The root search  paramerter does not have a child chain parameter");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0] is SearchParameterReferance), true, "Expected SearchParameterReferance type cast");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0] as SearchParameterReferance).IsChained, true, "Expected IsChained = true");

            //Patient.organization
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.Type, SearchParamType.Reference, "First chain should be type Referance");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.Name, "organization", "First chain must have name of organization");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.Resource, FHIRAllTypes.Patient.GetLiteral(), $"First chain should be Resource of {FHIRAllTypes.Patient.GetLiteral()}");
            Assert.IsNotNull(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter, "The 'organization' search  paramerter does not have a child chain parameter");

            //Organization.endpoint
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter.TypeModifierResource, FHIRAllTypes.Endpoint.GetLiteral());
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter.Type, SearchParamType.Reference, "First chain should be type Reference");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter.Name, "endpoint", "First chain must have name of endpoint");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter.Resource, FHIRAllTypes.Organization.GetLiteral(), $"First chain should be Resource of {FHIRAllTypes.Organization.GetLiteral()}");
            Assert.IsNotNull(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter.ChainedSearchParameter, "The 'endpoint' search  paramerter does not have a child chain parameter");

            //Endpoint.name=AcmeMail
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter.ChainedSearchParameter.Type, SearchParamType.String, "First chain should be type String");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter.ChainedSearchParameter.Name, "name", "First chain must have name of name");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter.ChainedSearchParameter.Resource, FHIRAllTypes.Endpoint.GetLiteral(), $"First chain should be Resource of {FHIRAllTypes.Endpoint.GetLiteral()}");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter.ChainedSearchParameter as SearchParameterString).ValueList.Count, 2, $"Must 1 and only one value");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter.ChainedSearchParameter as SearchParameterString).ValueList[0].Value, "acmemail", $"Value should be a string of 'acmemail'");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter.ChainedSearchParameter as SearchParameterString).ValueList[1].Value, "acmemail2", $"Value should be a string of 'acmemail2'");
            Assert.IsNull(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameter.ChainedSearchParameter.ChainedSearchParameter.ChainedSearchParameter, "The 'endpoint' search  paramerter does not have a child chain parameter");

            //DiagnosticReport.identifier
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[1].Type, SearchParamType.Token, "First chain should be type Token");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[1].Name, "identifier", "First chain must have name of identifier");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[1].Resource, FHIRAllTypes.DiagnosticReport.GetLiteral(), $"First chain should be Resource of {FHIRAllTypes.Organization.GetLiteral()}");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[1] is SearchParameterToken), true, "Expected SearchParameterToken type cast");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[1] as SearchParameterToken).ValueList.Count, 1, "Expected ValueList count = 1");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[1] as SearchParameterToken).ValueList[0].Code, "123", "Expected ValueList[0] to be '123'");
        }
        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);
        }
        private void ObtainOperationItemsFromSearchParameters(ISearchParametersServiceOutcome SearchParametersServiceOutcome, ValidationOperationItems ValidationOperationItems)
        {
            var ProFileSearchParameter = SearchParametersServiceOutcome.SearchParameters.SearchParametersList.SingleOrDefault(x => x.Name == "profile");

            if (ProFileSearchParameter is SearchParameterUri ProfileSearchUri)
            {
                if (ProfileSearchUri.ValueList != null && ProfileSearchUri.ValueList.Count > 0)
                {
                    ValidationOperationItems.ProfileUri = ProfileSearchUri.ValueList[0].Value.OriginalString;
                }
            }

            var ModeSearchParameter = SearchParametersServiceOutcome.SearchParameters.SearchParametersList.SingleOrDefault(x => x.Name == "mode");

            if (ModeSearchParameter != null &&
                ModeSearchParameter is SearchParameterToken ModeSearchUri)
            {
                if (ModeSearchUri.ValueList != null && ModeSearchUri.ValueList.Count > 0)
                {
                    string Mode = ModeSearchUri.ValueList[0].Code;
                    switch (Mode.ToLower())
                    {
                    case "create":
                        ValidationOperationItems.ValidationMode = ResourceValidationModeType.Create;
                        break;

                    case "update":
                        ValidationOperationItems.ValidationMode = ResourceValidationModeType.Update;
                        break;

                    case "delete":
                        ValidationOperationItems.ValidationMode = ResourceValidationModeType.Delete;
                        break;

                    default:
                        ValidationOperationItems.ValidationMode = null;
                        break;
                    }
                }
            }
            else
            {
                ValidationOperationItems.ValidationMode = ResourceValidationModeType.None;
            }
        }
Пример #5
0
        public IResourceServiceOutcome GetServersConformanceResource(IRequestMeta RequestMeta)
        {
            if (RequestMeta == null)
            {
                throw new NullReferenceException("RequestMeta can not be null.");
            }
            if (RequestMeta.SearchParameterGeneric == null)
            {
                throw new NullReferenceException("SearchParameterGeneric can not be null.");
            }

            IResourceServiceOutcome         ServiceOperationOutcome        = IResourceServiceOutcomeFactory.CreateResourceServiceOutcome();
            ISearchParameterService         SearchService                  = ISearchParameterServiceFactory.CreateSearchParameterService();
            ISearchParametersServiceOutcome SearchParametersServiceOutcome = SearchService.ProcessBaseSearchParameters(RequestMeta.SearchParameterGeneric);

            if (SearchParametersServiceOutcome.FhirOperationOutcome != null)
            {
                ServiceOperationOutcome.ResourceResult = SearchParametersServiceOutcome.FhirOperationOutcome;
                ServiceOperationOutcome.HttpStatusCode = SearchParametersServiceOutcome.HttpStatusCode;
                ServiceOperationOutcome.FormatMimeType = SearchParametersServiceOutcome.SearchParameters.Format;
                return(ServiceOperationOutcome);
            }

            var    Conformance            = new CapabilityStatement();
            var    ApplicationReleaseDate = new DateTimeOffset(2017, 10, 17, 6, 00, 00, new TimeSpan(8, 0, 0));
            string ServerName             = "Pyro Server";
            string Https = "https://";

            Conformance.Id               = "metadata";
            Conformance.Url              = $"{Https}{IPrimaryServiceRootCache.GetPrimaryRootUrlFromDatabase().Url}/metadata";
            Conformance.Version          = $"V{IGlobalProperties.ApplicationVersionInfo}";
            Conformance.Meta             = new Meta();
            Conformance.Meta.LastUpdated = ApplicationReleaseDate;
            Conformance.Name             = ServerName;
            Conformance.Status           = PublicationStatus.Active;
            Conformance.Experimental     = true;
            Conformance.Date             = (new FhirDateTime(ApplicationReleaseDate)).Value;
            Conformance.Publisher        = "PyroHealth.net";
            var AngusContactDetail = Common.PyroHealthInformation.PyroHealthContactDetailAngusMillar.GetContactDetail();

            Conformance.Contact = new List <ContactDetail>()
            {
                AngusContactDetail
            };

            Conformance.Description = new Markdown("Conformance statement for the " + ServerName);

            var Australia = new CodeableConcept("urn:iso:std:iso:3166", "AU", "Australia");

            Conformance.Jurisdiction = new List <CodeableConcept>()
            {
                Australia
            };

            Conformance.Purpose = new Markdown("FHIR Server reference implementation");

            Conformance.Copyright = new Markdown("Copyright: PyroHealth.net");
            Conformance.Kind      = CapabilityStatement.CapabilityStatementKind.Instance;

            Conformance.Software             = new CapabilityStatement.SoftwareComponent();
            Conformance.Software.Name        = ServerName;
            Conformance.Software.Version     = IGlobalProperties.ApplicationVersionInfo; //To align with FHIR version only use number no prefix of 'V'
            Conformance.Software.ReleaseDate = (new FhirDateTime(ApplicationReleaseDate)).Value;

            Conformance.Implementation             = new CapabilityStatement.ImplementationComponent();
            Conformance.Implementation.Description = $"{ServerName} is an implementation of a FHIR server supporting V{Hl7.Fhir.Model.ModelInfo.Version} of the specification. This instance is a publicly available testing server and its resource may be cleared at any time.";
            Conformance.Implementation.Url         = $"{Https}{IPrimaryServiceRootCache.GetPrimaryRootUrlFromDatabase().Url}";

            Conformance.FhirVersion   = Hl7.Fhir.Model.ModelInfo.Version; //Must be formated as just the number '3.0.1' as touchstone does not like the V3.0.1
            Conformance.AcceptUnknown = CapabilityStatement.UnknownContentCode.Extensions;

            var ContentFormatList = new List <string>();

            foreach (var mediaType in Hl7.Fhir.Rest.ContentType.XML_CONTENT_HEADERS)
            {
                ContentFormatList.Add(mediaType);
            }
            foreach (var mediaType in Hl7.Fhir.Rest.ContentType.JSON_CONTENT_HEADERS)
            {
                ContentFormatList.Add(mediaType);
            }
            Conformance.Format = ContentFormatList;

            Conformance.Rest = new List <CapabilityStatement.RestComponent>();
            var RestComponent = new CapabilityStatement.RestComponent();

            Conformance.Rest.Add(RestComponent);
            RestComponent.Mode                 = CapabilityStatement.RestfulCapabilityMode.Server;
            RestComponent.Documentation        = $"STU{Hl7.Fhir.Model.ModelInfo.Version.Split('.')[0]} V{Hl7.Fhir.Model.ModelInfo.Version} FHIR Server";
            RestComponent.Security             = new CapabilityStatement.SecurityComponent();
            RestComponent.Security.Description = "No Security has been implemented, server if publicly open";

            RestComponent.Interaction = new List <CapabilityStatement.SystemInteractionComponent>();
            var SystemInteractionComponent = new CapabilityStatement.SystemInteractionComponent();

            RestComponent.Interaction.Add(SystemInteractionComponent);
            SystemInteractionComponent.Code          = CapabilityStatement.SystemRestfulInteraction.Transaction;
            SystemInteractionComponent.Documentation = "Batch Transaction supports all request methods (Delete, POST, PUT, GET) including conditional create/update/delete. Operatons are not supported within Transaction bundles.";

            var CompartmentList = IServiceCompartmentRepository.GetAllServiceCompartments();

            if (CompartmentList != null && CompartmentList.Count > 0)
            {
                var CompartmentUrlList = new List <string>();
                CompartmentList.ForEach(x => CompartmentUrlList.Add(x.Url));
                RestComponent.Compartment = CompartmentUrlList;
            }

            RestComponent.Resource = new List <CapabilityStatement.ResourceComponent>();

            List <DtoServiceSearchParameterHeavy> DtoServiceSearchParameterHeavyList = IServiceSearchParameterService.GetServiceSearchParametersHeavy(false);

            var ResourceTypeList = Enum.GetValues(typeof(ResourceType));

            foreach (ResourceType ResourceType in ResourceTypeList)
            {
                string       CurrentResourceString = ResourceType.GetLiteral();
                FHIRAllTypes?FhirType          = Hl7.Fhir.Model.ModelInfo.FhirTypeNameToFhirType(CurrentResourceString);
                var          ResourceComponent = new CapabilityStatement.ResourceComponent();
                RestComponent.Resource.Add(ResourceComponent);
                ResourceComponent.Type        = ResourceType;
                ResourceComponent.Interaction = new List <CapabilityStatement.ResourceInteractionComponent>()
                {
                    new CapabilityStatement.ResourceInteractionComponent()
                    {
                        Code = CapabilityStatement.TypeRestfulInteraction.Create
                    },
                    new CapabilityStatement.ResourceInteractionComponent()
                    {
                        Code = CapabilityStatement.TypeRestfulInteraction.Delete
                    },
                    new CapabilityStatement.ResourceInteractionComponent()
                    {
                        Code = CapabilityStatement.TypeRestfulInteraction.Read
                    },
                    new CapabilityStatement.ResourceInteractionComponent()
                    {
                        Code = CapabilityStatement.TypeRestfulInteraction.Update
                    },
                    new CapabilityStatement.ResourceInteractionComponent()
                    {
                        Code = CapabilityStatement.TypeRestfulInteraction.Vread
                    },
                    new CapabilityStatement.ResourceInteractionComponent()
                    {
                        Code = CapabilityStatement.TypeRestfulInteraction.SearchType
                    },
                    new CapabilityStatement.ResourceInteractionComponent()
                    {
                        Code = CapabilityStatement.TypeRestfulInteraction.HistoryInstance
                    },
                    new CapabilityStatement.ResourceInteractionComponent()
                    {
                        Code = CapabilityStatement.TypeRestfulInteraction.HistoryType
                    }
                    //new Conformance.ResourceInteractionComponent() { Code = Conformance.TypeRestfulInteraction.HistoryType},
                };
                ResourceComponent.Versioning        = CapabilityStatement.ResourceVersionPolicy.Versioned;
                ResourceComponent.ReadHistory       = true;
                ResourceComponent.UpdateCreate      = true;
                ResourceComponent.ConditionalCreate = true;
                ResourceComponent.ConditionalRead   = CapabilityStatement.ConditionalReadStatus.FullSupport;
                ResourceComponent.ConditionalUpdate = true;
                ResourceComponent.ConditionalDelete = CapabilityStatement.ConditionalDeleteStatus.Multiple;


                var ReferenceHandlingPolicyList = new List <CapabilityStatement.ReferenceHandlingPolicy?>();
                ReferenceHandlingPolicyList.Add(CapabilityStatement.ReferenceHandlingPolicy.Literal);
                ReferenceHandlingPolicyList.Add(CapabilityStatement.ReferenceHandlingPolicy.Local);
                ResourceComponent.ReferencePolicy = ReferenceHandlingPolicyList;

                List <DtoServiceSearchParameterHeavy> DtoServiceSearchParameterHeavyForResourceList = DtoServiceSearchParameterHeavyList.Where(x => x.Resource == CurrentResourceString || x.Resource == FHIRAllTypes.Resource.GetLiteral()).ToList();

                //List<ServiceSearchParameterHeavy> DtoServiceSearchParameterHeavyForResourceList = ICommonServices.GetServiceSearchParametersHeavyForResource(FhirType.Value.GetLiteral());
                //DtoServiceSearchParameterHeavyForResourceList.AddRange(ICommonServices.GetServiceSearchParametersHeavyForResource(FHIRAllTypes.Resource.GetLiteral()));
                ResourceComponent.SearchParam = new List <CapabilityStatement.SearchParamComponent>();
                List <string> IncludesList    = null;
                List <string> RevIncludesList = null;
                foreach (var SupportedSearchParam in DtoServiceSearchParameterHeavyForResourceList)
                {
                    if (SupportedSearchParam.IsIndexed && SupportedSearchParam.Status == PublicationStatus.Active)
                    {
                        //Include (RevIncludes are below)
                        if (SupportedSearchParam.Type == SearchParamType.Reference)
                        {
                            if (IncludesList == null)
                            {
                                IncludesList = new List <string>();
                            }
                            if (SupportedSearchParam.TargetResourceTypeList.Count > 1)
                            {
                                foreach (var Target in SupportedSearchParam.TargetResourceTypeList)
                                {
                                    IncludesList.Add($"{SupportedSearchParam.Resource}:{SupportedSearchParam.Name}:{Target.ResourceType.GetLiteral()}");
                                }
                            }
                            else
                            {
                                IncludesList.Add($"{SupportedSearchParam.Resource}:{SupportedSearchParam.Name}");
                            }
                        }

                        CapabilityStatement.SearchParamComponent SearchParamComponent = new CapabilityStatement.SearchParamComponent();
                        ResourceComponent.SearchParam.Add(SearchParamComponent);

                        SearchParamComponent.Name       = SupportedSearchParam.Name;
                        SearchParamComponent.Type       = SupportedSearchParam.Type;
                        SearchParamComponent.Definition = SupportedSearchParam.Url;
                        if (!string.IsNullOrWhiteSpace(SupportedSearchParam.Description))
                        {
                            SearchParamComponent.Documentation = SupportedSearchParam.Description;
                        }
                    }
                }
                ResourceComponent.SearchInclude = IncludesList;

                //RevIncludes
                var RevIncludeSearchParameterList = DtoServiceSearchParameterHeavyList.Where(x => x.Type == SearchParamType.Reference && x.TargetResourceTypeList.Any(c => c.ResourceType == ResourceType));
                foreach (var Rev in RevIncludeSearchParameterList)
                {
                    if (RevIncludesList == null)
                    {
                        RevIncludesList = new List <string>();
                    }
                    if (Rev.TargetResourceTypeList.Count > 1)
                    {
                        RevIncludesList.Add($"{Rev.Resource}:{Rev.Name}:{CurrentResourceString}");
                    }
                    else
                    {
                        RevIncludesList.Add($"{Rev.Resource}:{Rev.Name}");
                    }
                }

                ResourceComponent.SearchRevInclude = RevIncludesList;
            }
            ConstructConformanceResourceNarrative(Conformance);

            IDatabaseOperationOutcome DatabaseOperationOutcome = IDatabaseOperationOutcomeFactory.CreateDatabaseOperationOutcome();

            ServiceOperationOutcome.FhirResourceId        = Conformance.Id;
            ServiceOperationOutcome.ResourceVersionNumber = Conformance.Version;
            ServiceOperationOutcome.LastModified          = Conformance.Meta.LastUpdated;
            ServiceOperationOutcome.OperationType         = Common.Enum.RestEnum.CrudOperationType.Read;
            ServiceOperationOutcome.IsDeleted             = false;
            ServiceOperationOutcome.RequestUri            = null;
            ServiceOperationOutcome.ResourceResult        = Conformance;
            ServiceOperationOutcome.FormatMimeType        = SearchParametersServiceOutcome.SearchParameters.Format;
            ServiceOperationOutcome.HttpStatusCode        = System.Net.HttpStatusCode.OK;
            return(ServiceOperationOutcome);
        }
Пример #6
0
        public IResourceServiceOutcome Process(string OperationName, Resource Resource, IRequestMeta RequestMeta)
        {
            if (string.IsNullOrWhiteSpace(OperationName))
            {
                throw new NullReferenceException("OperationName cannot be null.");
            }
            if (Resource == null)
            {
                throw new NullReferenceException("Resource cannot be null.");
            }
            if (RequestMeta == null)
            {
                throw new NullReferenceException("RequestMeta cannot be null.");
            }
            if (RequestMeta.PyroRequestUri == null)
            {
                throw new NullReferenceException("RequestUri cannot be null.");
            }
            if (RequestMeta.RequestHeader == null)
            {
                throw new NullReferenceException("RequestHeaders cannot be null.");
            }
            if (ICommonFactory == null)
            {
                throw new NullReferenceException("ICommonFactory cannot be null.");
            }
            if (RequestMeta.SearchParameterGeneric == null)
            {
                throw new NullReferenceException("SearchParameterGeneric cannot be null.");
            }

            IResourceServiceOutcome ResourceServiceOutcome = IResourceServiceOutcomeFactory.CreateResourceServiceOutcome();

            ISearchParameterService         SearchService = ISearchParameterServiceFactory.CreateSearchParameterService();
            ISearchParametersServiceOutcome SearchParametersServiceOutcome = SearchService.ProcessBaseSearchParameters(RequestMeta.SearchParameterGeneric);

            if (SearchParametersServiceOutcome.FhirOperationOutcome != null)
            {
                ResourceServiceOutcome.ResourceResult = SearchParametersServiceOutcome.FhirOperationOutcome;
                ResourceServiceOutcome.HttpStatusCode = SearchParametersServiceOutcome.HttpStatusCode;
                ResourceServiceOutcome.FormatMimeType = SearchParametersServiceOutcome.SearchParameters.Format;
                return(ResourceServiceOutcome);
            }

            var OperationDic = FhirOperationEnum.GetOperationTypeByString();

            if (!OperationDic.ContainsKey(Pyro.Common.Tools.StringSupport.ToLowerFast(OperationName)))
            {
                string Message = $"The resource operation named ${OperationName} is not supported by the server.";
                ResourceServiceOutcome.ResourceResult        = Common.Tools.FhirOperationOutcomeSupport.Create(Hl7.Fhir.Model.OperationOutcome.IssueSeverity.Error, Hl7.Fhir.Model.OperationOutcome.IssueType.NotSupported, Message);
                ResourceServiceOutcome.FormatMimeType        = SearchParametersServiceOutcome.SearchParameters.Format;
                ResourceServiceOutcome.HttpStatusCode        = System.Net.HttpStatusCode.BadRequest;
                ResourceServiceOutcome.SuccessfulTransaction = false;
                return(ResourceServiceOutcome);
            }

            var            Op             = OperationDic[Pyro.Common.Tools.StringSupport.ToLowerFast(OperationName)];
            OperationClass OperationClass = OperationClassFactory.OperationClassList.SingleOrDefault(x => x.Scope == FhirOperationEnum.OperationScope.Resource && x.Type == Op);

            if (OperationClass == null)
            {
                string Message = $"The resource operation named ${OperationName} is not supported by the server as a resource service operation type.";
                ResourceServiceOutcome.ResourceResult        = Common.Tools.FhirOperationOutcomeSupport.Create(Hl7.Fhir.Model.OperationOutcome.IssueSeverity.Error, Hl7.Fhir.Model.OperationOutcome.IssueType.NotSupported, Message);
                ResourceServiceOutcome.FormatMimeType        = SearchParametersServiceOutcome.SearchParameters.Format;
                ResourceServiceOutcome.HttpStatusCode        = System.Net.HttpStatusCode.BadRequest;
                ResourceServiceOutcome.SuccessfulTransaction = false;
                return(ResourceServiceOutcome);
            }

            switch (OperationClass.Type)
            {
            case FhirOperationEnum.OperationType.Validate:
            {
                IFhirValidateOperation FhirValidateOperation = ICommonFactory.CreateFhirValidateOperation();
                return(FhirValidateOperation.ValidateResource(OperationClass, Resource, RequestMeta));
            }

            case FhirOperationEnum.OperationType.xIHISearchOrValidate:
            {
                IIHISearchOrValidateOperation IHISearchOrValidateOperation = ICommonFactory.CreateIHISearchOrValidateOperation();
                return(IHISearchOrValidateOperation.IHISearchOrValidate(OperationClass, Resource, RequestMeta));
            }

            default:
                throw new System.ComponentModel.InvalidEnumArgumentException(OperationClass.Type.GetPyroLiteral(), (int)OperationClass.Type, typeof(FhirOperationEnum.OperationType));
            }
        }
Пример #7
0
        public IResourceServiceOutcome Process(
            string OperationName, Resource Resource, IRequestMeta RequestMeta)
        {
            if (string.IsNullOrWhiteSpace(OperationName))
            {
                throw new NullReferenceException("OperationName cannot be null.");
            }
            if (RequestMeta == null)
            {
                throw new NullReferenceException("RequestMeta cannot be null.");
            }
            if (RequestMeta.PyroRequestUri == null)
            {
                throw new NullReferenceException("PyroRequestUri cannot be null.");
            }
            if (RequestMeta.RequestHeader == null)
            {
                throw new NullReferenceException("RequestHeaders cannot be null.");
            }
            if (RequestMeta.SearchParameterGeneric == null)
            {
                throw new NullReferenceException("SearchPrameterGeneric cannot be null.");
            }

            IResourceServiceOutcome ResourceServiceOutcome = IResourceServiceOutcomeFactory.CreateResourceServiceOutcome();

            ISearchParameterService         SearchService = ISearchParameterServiceFactory.CreateSearchParameterService();
            ISearchParametersServiceOutcome SearchParametersServiceOutcome = SearchService.ProcessBaseSearchParameters(RequestMeta.SearchParameterGeneric);

            if (SearchParametersServiceOutcome.FhirOperationOutcome != null)
            {
                ResourceServiceOutcome.ResourceResult = SearchParametersServiceOutcome.FhirOperationOutcome;
                ResourceServiceOutcome.HttpStatusCode = SearchParametersServiceOutcome.HttpStatusCode;
                ResourceServiceOutcome.FormatMimeType = SearchParametersServiceOutcome.SearchParameters.Format;
                return(ResourceServiceOutcome);
            }

            var OperationDic = FhirOperationEnum.GetOperationTypeByString();

            if (!OperationDic.ContainsKey(OperationName))
            {
                string Message = $"The base operation named ${OperationName} is not supported by the server.";
                ResourceServiceOutcome.ResourceResult        = Common.Tools.FhirOperationOutcomeSupport.Create(Hl7.Fhir.Model.OperationOutcome.IssueSeverity.Error, Hl7.Fhir.Model.OperationOutcome.IssueType.NotSupported, Message);
                ResourceServiceOutcome.FormatMimeType        = SearchParametersServiceOutcome.SearchParameters.Format;
                ResourceServiceOutcome.HttpStatusCode        = System.Net.HttpStatusCode.BadRequest;
                ResourceServiceOutcome.SuccessfulTransaction = false;
                return(ResourceServiceOutcome);
            }

            var            Op             = OperationDic[OperationName];
            OperationClass OperationClass = OperationClassFactory.OperationClassList.SingleOrDefault(x => x.Scope == FhirOperationEnum.OperationScope.Base && x.Type == Op);

            if (OperationClass == null)
            {
                string Message = $"The base operation named ${OperationName} is not supported by the server as a service base operation type.";
                ResourceServiceOutcome.ResourceResult        = Common.Tools.FhirOperationOutcomeSupport.Create(Hl7.Fhir.Model.OperationOutcome.IssueSeverity.Error, Hl7.Fhir.Model.OperationOutcome.IssueType.NotSupported, Message);
                ResourceServiceOutcome.FormatMimeType        = SearchParametersServiceOutcome.SearchParameters.Format;
                ResourceServiceOutcome.HttpStatusCode        = System.Net.HttpStatusCode.BadRequest;
                ResourceServiceOutcome.SuccessfulTransaction = false;
                return(ResourceServiceOutcome);
            }

            switch (OperationClass.Type)
            {
            case FhirOperationEnum.OperationType.ServerIndexesDeleteHistoryIndexes:
            {
                IDeleteHistoryIndexesOperation DeleteManyHistoryIndexesService = ICommonFactory.CreateDeleteHistoryIndexesOperation();
                return(DeleteManyHistoryIndexesService.DeleteMany(RequestMeta.PyroRequestUri, RequestMeta.SearchParameterGeneric, Resource));
            }

            case FhirOperationEnum.OperationType.ServerIndexesSet:
            {
                IServerSearchParameterOperation ServerSearchParameterService = IServerSearchParameterServiceFactory.CreateServerSearchParameterService();
                return(ServerSearchParameterService.ProcessSet(RequestMeta.PyroRequestUri, RequestMeta.SearchParameterGeneric, Resource));
            }

            case FhirOperationEnum.OperationType.ServerSearchParameterIndexReport:
            {
                IServerSearchParameterOperation ServerSearchParameterService = IServerSearchParameterServiceFactory.CreateServerSearchParameterService();
                return(ServerSearchParameterService.ProcessReport(RequestMeta.PyroRequestUri, RequestMeta.SearchParameterGeneric, Resource));
            }

            case FhirOperationEnum.OperationType.ServerIndexesIndex:
            {
                IServerSearchParameterOperation ServerSearchParameterService = IServerSearchParameterServiceFactory.CreateServerSearchParameterService();
                return(ServerSearchParameterService.ProcessIndex(RequestMeta.PyroRequestUri, RequestMeta.SearchParameterGeneric, Resource));
            }

            case FhirOperationEnum.OperationType.ConnectathonAnswer:
            {
                IConnectathonAnswerOperation ConnectathonAnswerService = ICommonFactory.CreateConnectathonAnswerOperation();
                return(ConnectathonAnswerService.Process(RequestMeta.PyroRequestUri, RequestMeta.SearchParameterGeneric, Resource));
            }

            case FhirOperationEnum.OperationType.ServerResourceReport:
            {
                IResourceReportOperation ServerResourceReportService = ICommonFactory.CreateResourceReportOperation();
                return(ServerResourceReportService.Process(RequestMeta.SearchParameterGeneric));
            }

            default:
                throw new System.ComponentModel.InvalidEnumArgumentException(OperationClass.Type.GetPyroLiteral(), (int)OperationClass.Type, typeof(FhirOperationEnum.OperationType));
            }
        }
        public ISearchParametersServiceOutcome ProcessSearchParameters(
            ISearchParameterGeneric SearchParameterGeneric,
            SearchParameterServiceType SearchParameterServiceType,
            FHIRAllTypes?ResourceType,
            OperationClass OperationClass)
        {
            if (SearchParameterServiceType == SearchParameterServiceType.None)
            {
                throw new NullReferenceException("Server error: SearchParameterServiceType can not be 'None'.");
            }

            if (SearchParameterGeneric == null)
            {
                throw new NullReferenceException("Server error: SearchParameterGeneric can not be null.");
            }

            if (((SearchParameterServiceType & SearchParameterServiceType.Resource) == SearchParameterServiceType.Resource) &&
                ResourceType == null)
            {
                throw new NullReferenceException("Server error: ResourceType can not be null when enum SearchParameterServiceType is set to Resource.");
            }

            if (((SearchParameterServiceType & SearchParameterServiceType.Operation) == SearchParameterServiceType.Operation) &&
                OperationClass == null)
            {
                throw new NullReferenceException("Server error: OperationClass can not be null when enum SearchParameterServiceType is set to Operation.");
            }

            _ResourceType               = ResourceType;
            _OperationClass             = OperationClass;
            _SearchParameterServiceType = SearchParameterServiceType;

            _SearchParametersServiceOutcome = ISearchParametersServiceOutcomeFactory.CreateSearchParametersServiceOutcome();
            _SearchParametersServiceOutcome.SearchParameters = new PyroSearchParameters();
            _SearchParametersServiceOutcome.SearchParameters.ResourceTarget                = _ResourceType;
            _SearchParametersServiceOutcome.SearchParameters.SearchParametersList          = new List <ISearchParameterBase>();
            _SearchParametersServiceOutcome.SearchParameters.UnspportedSearchParameterList = new List <UnspportedSearchParameter>();
            _SearchParametersServiceOutcome.SearchParameters.CountOfRecordsRequested       = SearchParameterGeneric.Count;
            _SearchParametersServiceOutcome.SearchParameters.SummaryType = SearchParameterGeneric.SummaryType;

            //Parse Include and RevInclude parameters
            ProcessIncludeSearchParameters(SearchParameterGeneric.Include);
            ProcessIncludeSearchParameters(SearchParameterGeneric.RevInclude);

            foreach (var Parameter in SearchParameterGeneric.ParameterList)
            {
                //We will just ignore an empty parameter such as this last '&' URL?family=Smith&given=John&
                if (Parameter.Item1 + Parameter.Item2 != string.Empty)
                {
                    if (Parameter.Item1.Contains(SearchParams.SEARCH_CHAINSEPARATOR))
                    {
                        ChainSearchProcessing(Parameter);
                    }
                    else
                    {
                        NormalSearchProcessing(Parameter);
                    }
                }
            }

            //resolve Sort order parameters
            if (SearchParameterGeneric.Sort != null)
            {
                _SearchParametersServiceOutcome.SearchParameters.SortList = new List <PyroSearchParameters.Sort>();
                foreach (var SortItem in SearchParameterGeneric.Sort)
                {
                    string SearchParameterName = SortItem.Item1.Trim();
                    DtoServiceSearchParameterLight oSupportedSearchParameter = _DtoSupportedSearchParametersList.SingleOrDefault(x => x.Name == SearchParameterName);
                    _SearchParametersServiceOutcome.SearchParameters.SortList.Add(new PyroSearchParameters.Sort()
                    {
                        Value = oSupportedSearchParameter, SortOrderType = SortItem.Item2
                    });
                }
            }

            return(_SearchParametersServiceOutcome);
        }
        private bool IsSingularSearchParameter(ISearchParameterBase oSearchParameter, ISearchParametersServiceOutcome _SearchParametersServiceOutcome)
        {
            if (oSearchParameter.Name == "page")
            {
                if (oSearchParameter is SearchParameterNumber)
                {
                    var PageSearchParameter = oSearchParameter as SearchParameterNumber;
                    _SearchParametersServiceOutcome.SearchParameters.RequiredPageNumber = Convert.ToInt32(PageSearchParameter.ValueList[0].Value);
                    return(true);
                }
            }

            if (oSearchParameter.Name == Hl7.Fhir.Rest.HttpUtil.RESTPARAM_FORMAT)
            {
                if (oSearchParameter is SearchParameterString)
                {
                    var FormatSearchParameter = oSearchParameter as SearchParameterString;
                    _SearchParametersServiceOutcome.SearchParameters.Format = FormatSearchParameter.ValueList[0].Value.Trim();
                    return(true);
                }
            }

            if (oSearchParameter.Name == Hl7.Fhir.Rest.SearchParams.SEARCH_PARAM_SUMMARY)
            {
                if (oSearchParameter is SearchParameterToken FormatSearchParameter)
                {
                    var SummaryDic = Common.Enum.FhirSearchEnum.GetSummaryTypeDictionary();
                    if (SummaryDic.ContainsKey(FormatSearchParameter.ValueList[0].Code.Trim()))
                    {
                        _SearchParametersServiceOutcome.SearchParameters.SummaryType = SummaryDic[FormatSearchParameter.ValueList[0].Code.Trim()];
                    }
                }
                return(true);
            }

            return(false);
        }
        public IResourceServiceOutcome Process(ISearchParameterGeneric SearchParameterGeneric)
        {
            if (SearchParameterGeneric == null)
            {
                throw new NullReferenceException("SearchParameterGeneric cannot be null.");
            }
            if (IResourceServices == null)
            {
                throw new NullReferenceException("ResourceServices cannot be null.");
            }

            try
            {
                IResourceServiceOutcome ResourceServiceOutcome = IResourceServiceOutcomeFactory.CreateResourceServiceOutcome();

                ISearchParameterService         SearchService = ISearchParameterServiceFactory.CreateSearchParameterService();
                ISearchParametersServiceOutcome SearchParametersServiceOutcome = SearchService.ProcessBaseSearchParameters(SearchParameterGeneric);
                if (SearchParametersServiceOutcome.FhirOperationOutcome != null)
                {
                    ResourceServiceOutcome.ResourceResult = SearchParametersServiceOutcome.FhirOperationOutcome;
                    ResourceServiceOutcome.HttpStatusCode = SearchParametersServiceOutcome.HttpStatusCode;
                    ResourceServiceOutcome.FormatMimeType = SearchParametersServiceOutcome.SearchParameters.Format;
                    return(ResourceServiceOutcome);
                }

                var ReturnParametersResource = new Parameters();
                ReturnParametersResource.Parameter = new List <Parameters.ParameterComponent>();
                foreach (string ResourceName in ModelInfo.SupportedResources)
                {
                    var ResourceReportParameter = new Parameters.ParameterComponent();
                    ResourceReportParameter.Name = ResourceName;
                    ResourceReportParameter.Part = new List <Parameters.ParameterComponent>();
                    ReturnParametersResource.Parameter.Add(ResourceReportParameter);

                    ResourceType CurrentResourceType = Pyro.Common.Tools.ResourceNameResolutionSupport.GetResourceType(ResourceName);
                    int          TotalCount          = IResourceServices.GetTotalCurrentResourceCount(CurrentResourceType);

                    var TotalCountParameter = new Parameters.ParameterComponent();
                    TotalCountParameter.Name  = $"TotalCount";
                    TotalCountParameter.Value = new FhirDecimal(TotalCount);
                    ResourceReportParameter.Part.Add(TotalCountParameter);

                    if (TotalCount > 0)
                    {
                        DateTimeOffset?LastUpdated = IResourceServices.GetLastCurrentResourceLastUpdatedValue(CurrentResourceType);
                        if (LastUpdated.HasValue)
                        {
                            var LastUpdatedParameter = new Parameters.ParameterComponent();
                            LastUpdatedParameter.Name  = $"LastUpdated";
                            LastUpdatedParameter.Value = new FhirDateTime(LastUpdated.Value);
                            ResourceReportParameter.Part.Add(LastUpdatedParameter);
                        }
                    }
                }

                ResourceServiceOutcome.HttpStatusCode        = System.Net.HttpStatusCode.OK;
                ResourceServiceOutcome.ResourceResult        = ReturnParametersResource;
                ResourceServiceOutcome.OperationType         = Enum.RestEnum.CrudOperationType.Update;
                ResourceServiceOutcome.SuccessfulTransaction = true;
                return(ResourceServiceOutcome);
            }

            catch (Exception Exec)
            {
                throw new Exception("ServerResourceReport exception thrown", Exec);
            }
        }
        public IResourceServiceOutcome ValidateResource(OperationClass OperationClass, Resource Resource, IRequestMeta RequestMeta)
        {
            if (OperationClass == null)
            {
                throw new NullReferenceException("OperationClass cannot be null.");
            }
            if (Resource == null)
            {
                throw new NullReferenceException("Resource cannot be null.");
            }
            if (RequestMeta == null)
            {
                throw new NullReferenceException("RequestMeta cannot be null.");
            }
            if (RequestMeta.PyroRequestUri == null)
            {
                throw new NullReferenceException("RequestUri cannot be null.");
            }
            if (RequestMeta.RequestHeader == null)
            {
                throw new NullReferenceException("RequestHeader cannot be null.");
            }
            if (RequestMeta.SearchParameterGeneric == null)
            {
                throw new NullReferenceException("SearchParameterGeneric cannot be null.");
            }
            if (IResourceServices == null)
            {
                throw new NullReferenceException("ResourceServices cannot be null.");
            }
            if (IFhirValidationSupport == null)
            {
                throw new NullReferenceException("IFhirValidationSupport cannot be null.");
            }


            IssueList = new List <OperationOutcome.IssueComponent>();

            ResourceServiceOutcome = IResourceServiceOutcomeFactory.CreateResourceServiceOutcome();

            ISearchParametersServiceOutcome SearchParametersServiceOutcome = ParseUrlSearchParameters(RequestMeta.SearchParameterGeneric, OperationClass);

            FormatMimeType = SearchParametersServiceOutcome.SearchParameters.Format;
            if (SearchParametersServiceOutcome.FhirOperationOutcome != null)
            {
                IssueList.AddRange(SearchParametersServiceOutcome.FhirOperationOutcome.Issue);
                return(FinalResourceServiceOutcome(IssueList));
            }

            //Get ValidationOperationItems from URL
            ValidationOperationItems ValidationOperationItemsFromUrl = new ValidationOperationItems();

            ObtainOperationItemsFromSearchParameters(SearchParametersServiceOutcome, ValidationOperationItemsFromUrl);

            //Get ValidationOperationItems from Parameter Resource
            ValidationOperationItems ValidationOperationItemsFromParametersResource = new ValidationOperationItems();

            if (Resource.ResourceType == ResourceType.Parameters)
            {
                ValidationOperationItemsFromParametersResource = ValidateParameterResource(Resource as Parameters);
            }
            else
            {
                ValidationOperationItemsFromUrl.ResourceToValidate = Resource;
            }

            ValidationOperationItems FinalValidationOperationItems = ConsoladateValidationOperationItems(ValidationOperationItemsFromUrl, ValidationOperationItemsFromParametersResource);

            if (FinalValidationOperationItems == null)
            {
                return(FinalResourceServiceOutcome(IssueList));
            }

            if (FinalValidationOperationItems.ValidationMode == ResourceValidationModeType.Delete)
            {
                var OpOutCome = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.NotSupported,
                                                                                $"A mode parameter equal to 'delete' can only be used against a Resource instance URL.");
                IssueList.AddRange(OpOutCome.Issue);
                return(FinalResourceServiceOutcome(IssueList));
            }
            else if (FinalValidationOperationItems.ResourceToValidate != null)
            {
                if (!CheckResourceEndpointMatchesResourceToBeValidated(FinalValidationOperationItems.ResourceToValidate.ResourceType, RequestMeta.PyroRequestUri))
                {
                    return(FinalResourceServiceOutcome(IssueList));
                }

                if (FinalValidationOperationItems.FhirRequestUriProfileUri != null)
                {
                    OperationOutcome ProfileValidationOpOutCome = PerformValidation(FinalValidationOperationItems);
                    PerformModeValidation(ProfileValidationOpOutCome, FinalValidationOperationItems, RequestMeta);
                    IssueList.AddRange(ProfileValidationOpOutCome.Issue);
                    return(FinalResourceServiceOutcome(IssueList));
                }
                else
                {
                    OperationOutcome ModeValidationOpOutCome = new OperationOutcome();
                    PerformModeValidation(ModeValidationOpOutCome, FinalValidationOperationItems, RequestMeta);
                    // There is no profile given to validate against.
                    var OpOutCome = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.NotSupported,
                                                                                    $"The Resource provided for validation '{FinalValidationOperationItems.ResourceToValidate.ResourceType.GetLiteral()}' must match the resource endpoint in the URL '{RequestMeta.PyroRequestUri.FhirRequestUri.ResourseName}'");
                    IssueList.AddRange(OpOutCome.Issue);
                    return(FinalResourceServiceOutcome(IssueList));
                }
            }
            else
            {
                var OpOutCome = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.NotSupported,
                                                                                $"No Resource provided for validation, if mode equal (None, Create or Update) then a Resource must be provided to validate against.");
                IssueList.AddRange(OpOutCome.Issue);
                return(FinalResourceServiceOutcome(IssueList));
            }
        }
Пример #12
0
        public IResourceServiceOutcome DeleteMany(
            IPyroRequestUri RequestUri,
            ISearchParameterGeneric SearchParameterGeneric,
            Resource Resource)
        {
            if (RequestUri == null)
            {
                throw new NullReferenceException("RequestUri cannot be null.");
            }
            if (Resource == null)
            {
                throw new NullReferenceException("Resource cannot be null.");
            }
            if (SearchParameterGeneric == null)
            {
                throw new NullReferenceException("SearchParameterGeneric cannot be null.");
            }
            if (IResourceServices == null)
            {
                throw new NullReferenceException("ResourceServices cannot be null.");
            }

            IResourceServiceOutcome ResourceServiceOutcome = IResourceServiceOutcomeFactory.CreateResourceServiceOutcome();

            ISearchParameterService         SearchService = ISearchParameterServiceFactory.CreateSearchParameterService();
            ISearchParametersServiceOutcome SearchParametersServiceOutcome = SearchService.ProcessBaseSearchParameters(SearchParameterGeneric);

            if (SearchParametersServiceOutcome.FhirOperationOutcome != null)
            {
                ResourceServiceOutcome.HttpStatusCode = SearchParametersServiceOutcome.HttpStatusCode;
                ResourceServiceOutcome.ResourceResult = SearchParametersServiceOutcome.FhirOperationOutcome;
                ResourceServiceOutcome.FormatMimeType = SearchParametersServiceOutcome.SearchParameters.Format;
                return(ResourceServiceOutcome);
            }

            List <string> _ResourceList = new List <string>();

            if (Resource != null && Resource is Parameters ParametersResource)
            {
                var DeleteAll = ParametersResource.Parameter.SingleOrDefault(x => x.Name.ToLower() == _ParameterName.ToLower() && x.Value is FhirString a && a.Value == "*");
                if (DeleteAll != null)
                {
                    if (ParametersResource.Parameter.Count > 1)
                    {
                        var Op = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Warning, OperationOutcome.IssueType.BusinessRule, $"Operation: ${FhirOperationEnum.OperationType.ServerIndexesDeleteHistoryIndexes.GetPyroLiteral()} can not have a mixture of ResourceType = * and ResourceType = [ResourceName], only one or the other.");
                        ResourceServiceOutcome.HttpStatusCode        = System.Net.HttpStatusCode.BadRequest;
                        ResourceServiceOutcome.ResourceResult        = Op;
                        ResourceServiceOutcome.OperationType         = Enum.RestEnum.CrudOperationType.Update;
                        ResourceServiceOutcome.SuccessfulTransaction = false;
                        return(ResourceServiceOutcome);
                    }
                    //Loop through and Delete all resource indexes
                    _ResourceList = ModelInfo.SupportedResources;
                }
                else
                {
                    //Collect from the parameters the Resources to have indexes deleted from
                    _ResourceList = new List <string>();
                    foreach (var Parameter in ParametersResource.Parameter)
                    {
                        if (Parameter.Name.Trim().ToLower() == _ParameterName.ToLower() && Parameter.Value is FhirString ParamValue && ModelInfo.IsKnownResource(ParamValue.Value.Trim()))
                        {
                            _ResourceList.Add(ParamValue.Value.Trim());
                        }
                        else
                        {
                            var Op = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Warning, OperationOutcome.IssueType.BusinessRule, $"Operation: ${FhirOperationEnum.OperationType.ServerIndexesDeleteHistoryIndexes.GetPyroLiteral()} unknown parameter found. Name = {Parameter.Name}, Value = {Parameter.Value}");
                            ResourceServiceOutcome.HttpStatusCode        = System.Net.HttpStatusCode.BadRequest;
                            ResourceServiceOutcome.ResourceResult        = Op;
                            ResourceServiceOutcome.OperationType         = Enum.RestEnum.CrudOperationType.Update;
                            ResourceServiceOutcome.SuccessfulTransaction = false;
                            return(ResourceServiceOutcome);
                        }
                    }
Пример #13
0
        public IResourceServiceOutcome Process(
            IPyroRequestUri RequestUri,
            ISearchParameterGeneric SearchParameterGeneric,
            Resource Resource)
        {
            IResourceServiceOutcome ResourceServiceOutcome = IResourceServiceOutcomeFactory.CreateResourceServiceOutcome();
            var IssueList = new List <OperationOutcome.IssueComponent>();

            ISearchParameterService         SearchService = ISearchParameterServiceFactory.CreateSearchParameterService();
            ISearchParametersServiceOutcome SearchParametersServiceOutcome = SearchService.ProcessBaseSearchParameters(SearchParameterGeneric);

            if (SearchParametersServiceOutcome.FhirOperationOutcome != null)
            {
                ResourceServiceOutcome.ResourceResult = SearchParametersServiceOutcome.FhirOperationOutcome;
                ResourceServiceOutcome.HttpStatusCode = SearchParametersServiceOutcome.HttpStatusCode;
                ResourceServiceOutcome.FormatMimeType = SearchParametersServiceOutcome.SearchParameters.Format;
                return(ResourceServiceOutcome);
            }

            if (Resource is Parameters Parameters)
            {
                if (Parameters.Parameter != null && Parameters.Parameter.Count > 0)
                {
                    if (Parameters.Parameter[0].Name.ToLower() == _ParameterName)
                    {
                        if (Parameters.Parameter[0].Resource != null)
                        {
                            if (Parameters.Parameter[0].Resource is QuestionnaireResponse QuestionnaireResponse)
                            {
                                if (QuestionnaireResponse.Meta == null)
                                {
                                    QuestionnaireResponse.Meta = new Meta();
                                }
                                if (QuestionnaireResponse.Meta.Tag == null)
                                {
                                    QuestionnaireResponse.Meta.Tag = new List <Coding>();
                                }
                                QuestionnaireResponse.Meta.Tag.Add(new Coding("https://pyrohealth.net/fhir/CodeSystem/connectathon-answer", "hidden"));

                                if (QuestionnaireResponse.Id == null || string.IsNullOrWhiteSpace(QuestionnaireResponse.Id))
                                {
                                    IRequestMeta RequestMeta = IRequestMetaFactory.CreateRequestMeta().Set($"{FHIRAllTypes.QuestionnaireResponse.GetLiteral()}");
                                    ResourceServiceOutcome = this.IResourceServices.Post(QuestionnaireResponse, RequestMeta);
                                }
                                else
                                {
                                    IRequestMeta RequestMeta = IRequestMetaFactory.CreateRequestMeta().Set($"{FHIRAllTypes.QuestionnaireResponse.GetLiteral()}/{QuestionnaireResponse.Id}");
                                    ResourceServiceOutcome = this.IResourceServices.Put(QuestionnaireResponse.Id, QuestionnaireResponse, RequestMeta);
                                }
                                if (ResourceServiceOutcome.SuccessfulTransaction)
                                {
                                    Parameters ParametersResult = new Parameters();
                                    ParametersResult.Parameter = new List <Parameters.ParameterComponent>();
                                    var Param = new Parameters.ParameterComponent();
                                    Param.Name = "You answers have been submitted.";
                                    ParametersResult.Parameter.Add(Param);
                                    var Param2 = new Parameters.ParameterComponent();
                                    Param2.Name     = FHIRAllTypes.QuestionnaireResponse.GetLiteral();
                                    Param2.Resource = ResourceServiceOutcome.ResourceResult;
                                    ParametersResult.Parameter.Add(Param2);
                                    ResourceServiceOutcome.HttpStatusCode        = System.Net.HttpStatusCode.OK;
                                    ResourceServiceOutcome.ResourceResult        = ParametersResult;
                                    ResourceServiceOutcome.OperationType         = Enum.RestEnum.CrudOperationType.Update;
                                    ResourceServiceOutcome.SuccessfulTransaction = true;

                                    IRequestMeta RequestMeta = IRequestMetaFactory.CreateRequestMeta().Set($"{FHIRAllTypes.QuestionnaireResponse.GetLiteral()}/{_PrimaryQuestionnaireResponseAnswerResourceId}");
                                    var          Answers     = this.IResourceServices.GetRead("AngusA1", RequestMeta);

                                    QuestionnaireResults QuestionnaireResults = QuestionnaireResponseChecker.Check(Answers.ResourceResult as QuestionnaireResponse, QuestionnaireResponse);
                                }
                                else
                                {
                                    Parameters ParametersResult = new Parameters();
                                    ParametersResult.Parameter = new List <Parameters.ParameterComponent>();
                                    var Param = new Parameters.ParameterComponent();
                                    Param.Name = "Oh no, there was an error is submitting your answers.";
                                    ParametersResult.Parameter.Add(Param);
                                    var Param2 = new Parameters.ParameterComponent();
                                    Param2.Name     = FHIRAllTypes.OperationOutcome.GetLiteral();
                                    Param2.Resource = ResourceServiceOutcome.ResourceResult;
                                    ParametersResult.Parameter.Add(Param2);
                                    ResourceServiceOutcome.HttpStatusCode        = System.Net.HttpStatusCode.BadRequest;
                                    ResourceServiceOutcome.ResourceResult        = ParametersResult;
                                    ResourceServiceOutcome.OperationType         = Enum.RestEnum.CrudOperationType.Update;
                                    ResourceServiceOutcome.SuccessfulTransaction = false;
                                }
                            }
                            else
                            {
                                IssueList.Add(Pyro.Common.Tools.FhirOperationOutcomeSupport.CreateIssue(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, $"The ${_OperationName} expects the {FHIRAllTypes.Parameters.GetLiteral()} resource to have one parameter with the 'Name' element equal to '{_ParameterName}' where the Resource element is set to a {FHIRAllTypes.QuestionnaireResponse.GetLiteral()} FHIR Resource. The server found here a Resource of type {Parameters.Parameter[0].Resource.ResourceType}."));
                            }
                        }
                        else
                        {
                            IssueList.Add(Pyro.Common.Tools.FhirOperationOutcomeSupport.CreateIssue(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, $"The ${_OperationName} expects the {FHIRAllTypes.Parameters.GetLiteral()} resource to have one Parameter with the Name element equal to '{_ParameterName}' where the Resource element is set to a {FHIRAllTypes.QuestionnaireResponse.GetLiteral()} FHIR Resource. The server found no {FHIRAllTypes.QuestionnaireResponse.GetLiteral()} Resource"));
                        }
                    }
                    else
                    {
                        IssueList.Add(Pyro.Common.Tools.FhirOperationOutcomeSupport.CreateIssue(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, $"The ${_OperationName} expects the {FHIRAllTypes.Parameters.GetLiteral()} resource to have one Parameter with the Name element equal to '{_ParameterName}'."));
                    }
                }
                else
                {
                    IssueList.Add(Pyro.Common.Tools.FhirOperationOutcomeSupport.CreateIssue(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, $"The ${_OperationName} expects the {FHIRAllTypes.Parameters.GetLiteral()} resource to have one Parameter element."));
                }
            }
            else
            {
                IssueList.Add(Pyro.Common.Tools.FhirOperationOutcomeSupport.CreateIssue(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, $"The ${_OperationName} expects a FHIR {FHIRAllTypes.Parameters.GetLiteral()} resource as the call body."));
            }

            if (IssueList.Count > 0)
            {
                var Op = Common.Tools.FhirOperationOutcomeSupport.Generate(IssueList);
                ResourceServiceOutcome.HttpStatusCode        = System.Net.HttpStatusCode.BadRequest;
                ResourceServiceOutcome.ResourceResult        = Op;
                ResourceServiceOutcome.OperationType         = Enum.RestEnum.CrudOperationType.Update;
                ResourceServiceOutcome.SuccessfulTransaction = false;
                return(ResourceServiceOutcome);
            }
            else
            {
                return(ResourceServiceOutcome);
            }
        }
Пример #14
0
        public void Test_RecursiveChainSearch()
        {
            //Arrange
            Moq.Mock <ISearchParameterGenericFactory> MokISearchParameterGenericFactory = new Moq.Mock <ISearchParameterGenericFactory>();
            MokISearchParameterGenericFactory.Setup(x => x.CreateDtoSearchParameterGeneric()).Returns(new SearchParameterGeneric());

            Moq.Mock <ISearchParameterReferanceFactory> MokISearchParameterReferanceFactory = new Moq.Mock <ISearchParameterReferanceFactory>();
            MokISearchParameterReferanceFactory.Setup(x => x.CreateDtoSearchParameterReferance()).Returns(GetMokedSearchParameterReferance());


            // SearchParameterServiceFactory Set-up =======================
            // These are the actual supported search parameters that come from the database.
            var MokISearchParametersServiceOutcomeFactory = new Moq.Mock <ISearchParametersServiceOutcomeFactory>();

            MokISearchParametersServiceOutcomeFactory.Setup(x => x.CreateSearchParametersServiceOutcome()).Returns(new SearchParametersServiceOutcome());

            var MokIServiceSearchParameterCache = new Moq.Mock <IServiceSearchParameterCache>();

            //Search Parameters for DiagnosticReport Resource ---------------------------------------
            List <DtoServiceSearchParameterLight> DiagnosticReportServiceSearchParameterLightList = new List <DtoServiceSearchParameterLight>();

            DtoServiceSearchParameterLight ServiceSearchParameterLight_DiagnosticReportSubject = new DtoServiceSearchParameterLight();

            ServiceSearchParameterLight_DiagnosticReportSubject.Expression = "Test_Expression for subject";
            ServiceSearchParameterLight_DiagnosticReportSubject.Id         = 1;
            ServiceSearchParameterLight_DiagnosticReportSubject.Name       = "subject";
            ServiceSearchParameterLight_DiagnosticReportSubject.Resource   = "DiagnosticReport";
            var oTargetResourceTypeListDiagnosticReport = new List <IServiceSearchParameterTargetResource>();

            oTargetResourceTypeListDiagnosticReport.Add(
                new _ServiceSearchParameterTargetResource()
            {
                Id                       = 11,
                ResourceType             = ResourceType.Patient,
                ServiceSearchParameter   = null,
                ServiceSearchParameterId = 111
            });
            oTargetResourceTypeListDiagnosticReport.Add(new _ServiceSearchParameterTargetResource()
            {
                Id                       = 111,
                ResourceType             = ResourceType.Location,
                ServiceSearchParameter   = null,
                ServiceSearchParameterId = 112
            });
            ServiceSearchParameterLight_DiagnosticReportSubject.TargetResourceTypeList = oTargetResourceTypeListDiagnosticReport;
            ServiceSearchParameterLight_DiagnosticReportSubject.Type = SearchParamType.Reference;
            DiagnosticReportServiceSearchParameterLightList.Add(ServiceSearchParameterLight_DiagnosticReportSubject);

            DtoServiceSearchParameterLight ServiceSearchParameterLight_DiagnosticReportIdentifier = new DtoServiceSearchParameterLight();

            ServiceSearchParameterLight_DiagnosticReportIdentifier.Expression = "Test_Expression for identifier";
            ServiceSearchParameterLight_DiagnosticReportIdentifier.Id         = 11;
            ServiceSearchParameterLight_DiagnosticReportIdentifier.Name       = "identifier";
            ServiceSearchParameterLight_DiagnosticReportIdentifier.Resource   = "DiagnosticReport";
            ServiceSearchParameterLight_DiagnosticReportIdentifier.Type       = SearchParamType.Token;
            DiagnosticReportServiceSearchParameterLightList.Add(ServiceSearchParameterLight_DiagnosticReportIdentifier);

            MokIServiceSearchParameterCache.Setup(x => x.GetSearchParameterForResource("DiagnosticReport")).Returns(DiagnosticReportServiceSearchParameterLightList);

            //Search Parameters for Patient Resource ---------------------------------------
            List <DtoServiceSearchParameterLight> PatientServiceSearchParameterLightList = new List <DtoServiceSearchParameterLight>();

            DtoServiceSearchParameterLight ServiceSearchParameterLight_PatientOrganization = new DtoServiceSearchParameterLight();

            ServiceSearchParameterLight_PatientOrganization.Expression = "Test_Expression for organization";
            ServiceSearchParameterLight_PatientOrganization.Id         = 2;
            ServiceSearchParameterLight_PatientOrganization.Name       = "organization";
            ServiceSearchParameterLight_PatientOrganization.Resource   = "Patient";
            var oTargetResourceTypeListOrganization = new List <IServiceSearchParameterTargetResource>();

            oTargetResourceTypeListOrganization.Add(new _ServiceSearchParameterTargetResource()
            {
                Id = 22, ResourceType = ResourceType.Organization, ServiceSearchParameter = null, ServiceSearchParameterId = 222
            });
            ServiceSearchParameterLight_PatientOrganization.TargetResourceTypeList = oTargetResourceTypeListOrganization;
            ServiceSearchParameterLight_PatientOrganization.Type = SearchParamType.Reference;
            PatientServiceSearchParameterLightList.Add(ServiceSearchParameterLight_PatientOrganization);

            DtoServiceSearchParameterLight ServiceSearchParameterLight_PatientFamily = new DtoServiceSearchParameterLight();

            ServiceSearchParameterLight_PatientFamily.Expression = "Test_Expression for family";
            ServiceSearchParameterLight_PatientFamily.Id         = 22;
            ServiceSearchParameterLight_PatientFamily.Name       = "family";
            ServiceSearchParameterLight_PatientFamily.Resource   = "Patient";
            ServiceSearchParameterLight_PatientFamily.Type       = SearchParamType.String;
            PatientServiceSearchParameterLightList.Add(ServiceSearchParameterLight_PatientFamily);

            MokIServiceSearchParameterCache.Setup(x => x.GetSearchParameterForResource("Patient")).Returns(PatientServiceSearchParameterLightList);

            //Search Parameters for Organization Resource ---------------------------------------
            List <DtoServiceSearchParameterLight> OrganizationServiceSearchParameterLightList = new List <DtoServiceSearchParameterLight>();

            DtoServiceSearchParameterLight ServiceSearchParameterLight_OrganizationEndpoint = new DtoServiceSearchParameterLight();

            ServiceSearchParameterLight_OrganizationEndpoint.Expression = "Test_Expression for endpoint";
            ServiceSearchParameterLight_OrganizationEndpoint.Id         = 3;
            ServiceSearchParameterLight_OrganizationEndpoint.Name       = "endpoint";
            ServiceSearchParameterLight_OrganizationEndpoint.Resource   = "Organization";
            var oTargetResourceTypeListEndpoint = new List <IServiceSearchParameterTargetResource>();

            oTargetResourceTypeListEndpoint.Add(new _ServiceSearchParameterTargetResource()
            {
                Id = 33, ResourceType = ResourceType.Endpoint, ServiceSearchParameter = null, ServiceSearchParameterId = 333
            });
            oTargetResourceTypeListEndpoint.Add(new _ServiceSearchParameterTargetResource()
            {
                Id = 32, ResourceType = ResourceType.Location, ServiceSearchParameter = null, ServiceSearchParameterId = 332
            });
            ServiceSearchParameterLight_OrganizationEndpoint.TargetResourceTypeList = oTargetResourceTypeListEndpoint;
            ServiceSearchParameterLight_OrganizationEndpoint.Type = SearchParamType.Reference;
            OrganizationServiceSearchParameterLightList.Add(ServiceSearchParameterLight_OrganizationEndpoint);

            MokIServiceSearchParameterCache.Setup(x => x.GetSearchParameterForResource("Organization")).Returns(OrganizationServiceSearchParameterLightList);

            //Search Parameters for Endpoint Resource ---------------------------------------
            List <DtoServiceSearchParameterLight> EndpointServiceSearchParameterLightList = new List <DtoServiceSearchParameterLight>();

            DtoServiceSearchParameterLight ServiceSearchParameterLight_EndpointName = new DtoServiceSearchParameterLight();

            ServiceSearchParameterLight_EndpointName.Expression             = "Test_Expression for Endpoint";
            ServiceSearchParameterLight_EndpointName.Id                     = 4;
            ServiceSearchParameterLight_EndpointName.Name                   = "name";
            ServiceSearchParameterLight_EndpointName.Resource               = "Endpoint";
            ServiceSearchParameterLight_EndpointName.TargetResourceTypeList = null;
            ServiceSearchParameterLight_EndpointName.Type                   = SearchParamType.String;
            EndpointServiceSearchParameterLightList.Add(ServiceSearchParameterLight_EndpointName);

            MokIServiceSearchParameterCache.Setup(x => x.GetSearchParameterForResource("Endpoint")).Returns(EndpointServiceSearchParameterLightList);

            //--------------------------------------------------------------------------------

            Moq.Mock <ISearchParameterServiceFactory> MokISearchParameterServiceFactory = new Moq.Mock <ISearchParameterServiceFactory>();

            //The SearchParameterFactory returns individual search parameters
            SearchParameterFactory SearchParameterFactory = new SearchParameterFactory(MokISearchParameterServiceFactory.Object, MokISearchParameterGenericFactory.Object, MokISearchParameterReferanceFactory.Object);
            // The SearchParameterService wraps the factory above and processes all search parameters for a single URL
            SearchParameterService SearchParameterService = new SearchParameterService(MokISearchParametersServiceOutcomeFactory.Object, SearchParameterFactory, MokIServiceSearchParameterCache.Object);

            // A factor used by the SearchParameterService when processing chained parameters recursively
            MokISearchParameterServiceFactory.Setup(x => x.CreateSearchParameterService()).Returns(SearchParameterService);
            //====================================================

            string UrlSearchParametersString = "?subject:Patient.organization.endpoint:Endpoint.name=AcmeMail,AcmeMail2&identifier=123";
            var    DtoSearchParameterGeneric = new SearchParameterGeneric();

            DtoSearchParameterGeneric.Parse(UrlSearchParametersString);

            //Act
            ISearchParametersServiceOutcome Result = SearchParameterService.ProcessResourceSearchParameters(DtoSearchParameterGeneric, SearchParameterService.SearchParameterServiceType.Resource, FHIRAllTypes.DiagnosticReport);

            //Assert
            Assert.NotNull(Result, "Test returned null");
            Assert.NotNull(Result.SearchParameters, "SearchParameters returned null");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList.Count, 2, "SearchParametersList must have 3 items");

            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].Type, SearchParamType.Reference);
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].Name, "subject");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].Resource, FHIRAllTypes.DiagnosticReport.GetLiteral());
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].TypeModifierResource, FHIRAllTypes.Patient.GetLiteral());
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList.Count, 3, "Should have 3 chained search parameters");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0] is SearchParameterReferance), true, "Expected SearchParameterReferance type cast");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0] as SearchParameterReferance).IsChained, true, "Expected IsChained = true");

            //Patient.organization
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList[0].Type, SearchParamType.Reference, "First chain should be type Referance");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList[0].Name, "organization", "First chain must have name of organization");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList[0].Resource, FHIRAllTypes.Patient.GetLiteral(), $"First chain should be Resource of {FHIRAllTypes.Patient.GetLiteral()}");

            //Organization.endpoint
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList[1].Type, SearchParamType.Reference, "First chain should be type Reference");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList[1].Name, "endpoint", "First chain must have name of endpoint");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList[1].Resource, FHIRAllTypes.Organization.GetLiteral(), $"First chain should be Resource of {FHIRAllTypes.Organization.GetLiteral()}");

            //Endpoint.name=AcmeMail
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList[2].Type, SearchParamType.String, "First chain should be type String");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList[2].Name, "name", "First chain must have name of name");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList[2].Resource, FHIRAllTypes.Endpoint.GetLiteral(), $"First chain should be Resource of {FHIRAllTypes.Endpoint.GetLiteral()}");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList[2] as SearchParameterString).ValueList.Count, 2, $"Must 1 and only one value");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList[2] as SearchParameterString).ValueList[0].Value, "AcmeMail", $"Value should be a string of 'AcmeMail'");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[0].ChainedSearchParameterList[2] as SearchParameterString).ValueList[1].Value, "AcmeMail2", $"Value should be a string of 'AcmeMail2'");

            //DiagnosticReport.identifier
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[1].Type, SearchParamType.Token, "First chain should be type Token");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[1].Name, "identifier", "First chain must have name of identifier");
            Assert.AreEqual(Result.SearchParameters.SearchParametersList[1].Resource, FHIRAllTypes.DiagnosticReport.GetLiteral(), $"First chain should be Resource of {FHIRAllTypes.Organization.GetLiteral()}");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[1] is SearchParameterToken), true, "Expected SearchParameterToken type cast");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[1] as SearchParameterToken).ValueList.Count, 1, "Expected ValueList count = 1");
            Assert.AreEqual((Result.SearchParameters.SearchParametersList[1] as SearchParameterToken).ValueList[0].Code, "123", "Expected ValueList[0] to be '123'");
        }