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);
        }
예제 #2
0
        private List <DtoResource> GetIncludes(List <SearchParameterInclude> IncludeList, List <DtoResource> CurrentScourceResourceList, HashSet <string> CacheResourceIDsAlreadyCollected)
        {
            var ReturnResourceList = new List <DtoResource>();

            if (IncludeList == null || IncludeList.Count == 0)
            {
                return(ReturnResourceList);
            }

            if (CurrentScourceResourceList == null || CurrentScourceResourceList.Count == 0)
            {
                return(ReturnResourceList);
            }

            foreach (var Resource in CurrentScourceResourceList)
            {
                //Now process each include
                foreach (var include in IncludeList)
                {
                    if (Resource.ResourceType.Value == include.SourceResourceType)
                    {
                        IResourceRepository = IRepositorySwitcher.GetRepository(Resource.ResourceType.Value);

                        //We only want to get the include target Resources
                        if (include.SearchParameterTargetResourceType.HasValue)
                        {
                            //Get the Search parameter Ids where the search parameter target list can contain the include's Resource target type
                            int[] IdArray = include.SearchParameterList.Where(z => z.TargetResourceTypeList.Any(c => c.ResourceType.GetLiteral() == include.SearchParameterTargetResourceType.Value.GetLiteral())).Select(x => x.Id).ToArray();
                            //Now only get the FhirId of the resources that have Search Index References that have these include target resource
                            string[] FhirIdList = IResourceRepository.GetResourceFhirIdByResourceIdAndIndexReferance(Resource.Id, IdArray, include.SearchParameterTargetResourceType.Value.GetLiteral());
                            //Set the repository to the include's target resource in order to get the include resources
                            IResourceRepository = IRepositorySwitcher.GetRepository(include.SearchParameterTargetResourceType.Value);
                            //Get each as long as it is not already gotten based on CacheResourceIDsAlreadyCollected list
                            foreach (string FhirId in FhirIdList)
                            {
                                AddIncludeResourceInstanceForIncludes(ReturnResourceList, CacheResourceIDsAlreadyCollected, FhirId);
                            }
                        }
                        else
                        {
                            //There is no include target so try and get all
                            foreach (var IncludeItemSearchParameter in include.SearchParameterList)
                            {
                                foreach (var SearchParameterResourceTarget in IncludeItemSearchParameter.TargetResourceTypeList)
                                {
                                    //Switch source resource repository to get reference FhirIds
                                    IResourceRepository = IRepositorySwitcher.GetRepository(Resource.ResourceType.Value);
                                    string[] FhirIdList = IResourceRepository.GetResourceFhirIdByResourceIdAndIndexReferance(Resource.Id, new int[] { IncludeItemSearchParameter.Id }, SearchParameterResourceTarget.ResourceType.GetLiteral());
                                    if (FhirIdList.Count() > 0)
                                    {
                                        //Switch to SearchParameterResourceTarget resource repository to get the include resource if found
                                        IResourceRepository = IRepositorySwitcher.GetRepository(ResourceNameResolutionSupport.GetResourceFhirAllType(SearchParameterResourceTarget.ResourceType));
                                        foreach (string FhirId in FhirIdList)
                                        {
                                            //Don't source the same resource again from the Database if we already have it
                                            AddIncludeResourceInstanceForIncludes(ReturnResourceList, CacheResourceIDsAlreadyCollected, FhirId);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(ReturnResourceList);
        }
예제 #3
0
        private List <DtoResource> GetRevIncludes(List <SearchParameterInclude> RevIncludeList, List <DtoResource> CurrentScourceResourceList, HashSet <string> CacheResourceIDsAlreadyCollected)
        {
            var ReturnResourceList = new List <DtoResource>();

            if (RevIncludeList == null || RevIncludeList.Count == 0)
            {
                return(ReturnResourceList);
            }

            if (CurrentScourceResourceList == null || CurrentScourceResourceList.Count == 0)
            {
                return(ReturnResourceList);
            }

            foreach (var Resource in CurrentScourceResourceList)
            {
                //Now process each include
                foreach (var RevInclude in RevIncludeList)
                {
                    PyroSearchParameters SearchParameters = new PyroSearchParameters();
                    SearchParameters.SearchParametersList = new List <ISearchParameterBase>();

                    //Does the include have a target Resource type
                    if (RevInclude.SearchParameterTargetResourceType.HasValue)
                    {
                        //Is the target Resource type of the include == to the current Resource we are targeting
                        if (Resource.ResourceType.Value == RevInclude.SearchParameterTargetResourceType.Value)
                        {
                            IResourceRepository = IRepositorySwitcher.GetRepository(RevInclude.SourceResourceType);
                            foreach (DtoServiceSearchParameterLight p in RevInclude.SearchParameterList)
                            {
                                //Check the current search Parameter has a Target == to the Resource we are targeting
                                if (p.TargetResourceTypeList.Any(x => x.ResourceType.GetLiteral() == Resource.ResourceType.Value.GetLiteral()))
                                {
                                    //Construct the search parameter string
                                    var ParameterString = new Tuple <string, string>(p.Name, $"{RevInclude.SearchParameterTargetResourceType.GetLiteral()}/{Resource.FhirId}");
                                    ISearchParameterBase SearchParam = ISearchParameterFactory.CreateSearchParameter(p, ParameterString);
                                    SearchParameters.SearchParametersList.Clear();
                                    SearchParameters.SearchParametersList.Add(SearchParam);
                                    //Get from the database and only add if we don't already have it
                                    AddIncludeResourceInstanceForRevIncludes(ReturnResourceList, CacheResourceIDsAlreadyCollected, SearchParameters);
                                }
                            }
                        }
                    }
                    else
                    {
                        foreach (DtoServiceSearchParameterLight p in RevInclude.SearchParameterList)
                        {
                            if (p.TargetResourceTypeList.Any(x => x.ResourceType.GetLiteral() == Resource.ResourceType.Value.GetLiteral()))
                            {
                                IResourceRepository = IRepositorySwitcher.GetRepository(ResourceNameResolutionSupport.GetResourceFhirAllType(p.Resource));
                                //Construct the search parameter string
                                var ParameterString = new Tuple <string, string>(p.Name, $"{Resource.ResourceType.Value.GetLiteral()}/{Resource.FhirId}");
                                ISearchParameterBase SearchParam = ISearchParameterFactory.CreateSearchParameter(p, ParameterString);
                                SearchParameters.SearchParametersList.Clear();
                                SearchParameters.SearchParametersList.Add(SearchParam);
                                //Get from the database and only add if we don't already have it
                                AddIncludeResourceInstanceForRevIncludes(ReturnResourceList, CacheResourceIDsAlreadyCollected, SearchParameters);
                            }
                        }
                    }
                }
            }
            return(ReturnResourceList);
        }
예제 #4
0
        public bool ResolveChain(ISearchParameterReferance SearchParameterReferance)
        {
            bool ChainTargetFound = true;

            if (!SearchParameterReferance.IsChained)
            {
                throw new Exception("Server Error: SearchParameterReferance.IsChained must be true for ChainSearchingService.");
            }

            IEnumerable <string> FhirIdList = null;
            //Work through each chain parameter in reverse
            bool PrimarySearchPerfomed = false;

            for (int i = SearchParameterReferance.ChainedSearchParameterList.Count - 1; i >= 0; i--)
            {
                ISearchParameterBase SearchParameterBase = SearchParameterReferance.ChainedSearchParameterList[i];
                //When the Chained parameter is a parameter for all resource types we need to switch the TypeModifierResource given for the
                //previous chain parameter or the root parameter
                //for example 'Observation?subject:Patient._id=FCC-PAT-0001'
                //Here the _id is an all Resource type search parameter so it's SearchParameterBase.Resource = Resource, we need here to refer to the
                //given SearchParameterReferance.TypeModifierResource as seen in the search string ':Patient'
                //Another example is 'DiagnosticReport?result:Observation.subject:Patient._id=FCC-PAT-00001' where the need to get the previous TypeModifierResource
                //from the list of chain parameters or the root parameter when i = 0.
                //so for this last example we need ':Patient' for the '_id' and ':Observation' for the 'subject'
                string ResourceRequiredForRepository = string.Empty;
                if (i > 0)
                {
                    ResourceRequiredForRepository = ResolveResourceTypeFromSearchParameterResourceModifier(SearchParameterBase.Resource, SearchParameterReferance.ChainedSearchParameterList[i - 1].TypeModifierResource);
                }
                else
                {
                    ResourceRequiredForRepository = ResolveResourceTypeFromSearchParameterResourceModifier(SearchParameterBase.Resource, SearchParameterReferance.TypeModifierResource);
                }

                if (!PrimarySearchPerfomed)
                {
                    IResourceRepository = IRepositorySwitcher.GetRepository(ResourceNameResolutionSupport.GetResourceFhirAllType(ResourceRequiredForRepository));
                    PyroSearchParameters SearchParameters = new PyroSearchParameters();
                    SearchParameters.SearchParametersList = new List <ISearchParameterBase>()
                    {
                        SearchParameterBase
                    };
                    FhirIdList            = IResourceRepository.GetResourceFhirIdBySearchNoPaging(SearchParameters);
                    PrimarySearchPerfomed = true;
                    if (FhirIdList.Count() == 0)
                    {
                        ChainTargetFound = false;
                        break;
                    }
                }
                else
                {
                    IResourceRepository = IRepositorySwitcher.GetRepository(ResourceNameResolutionSupport.GetResourceFhirAllType(ResourceRequiredForRepository));
                    string ReferenceResourceTargetName = string.Empty;
                    if (string.IsNullOrWhiteSpace(SearchParameterBase.TypeModifierResource))
                    {
                        ReferenceResourceTargetName = SearchParameterBase.TargetResourceTypeList[0].ResourceType.GetLiteral();
                    }
                    else
                    {
                        ReferenceResourceTargetName = SearchParameterBase.TypeModifierResource;
                    }
                    FhirIdList = IResourceRepository.GetResourceFhirIdByReferanceIndex(FhirIdList, ReferenceResourceTargetName, SearchParameterBase.Id);
                    if (FhirIdList.Count() == 0)
                    {
                        ChainTargetFound = false;
                        break;
                    }
                }
            }

            if (ChainTargetFound)
            {
                //We use the resource type from the first in the list which was the last above because we Reversed the list in the for each loop above.
                string ResourceType = ResolveResourceTypeFromSearchParameterResourceModifier(SearchParameterReferance.ChainedSearchParameterList[0].Resource, SearchParameterReferance.TypeModifierResource);
                SetSearchParameterValueList(FhirIdList, ResourceType, SearchParameterReferance);
            }
            return(ChainTargetFound);
        }
예제 #5
0
 /// <summary>
 /// Primarily used for Create & Update actions where a Resource is given in the API call
 /// Previous resource version can be sccourced from the database by version if required
 /// </summary>
 /// <param name="CrudOperationType"></param>
 /// <param name="Resource"></param>
 public ITriggerOutcome Trigger(RestEnum.CrudOperationType CrudOperationType, TriggerRaisedType TriggerRaised, Resource Resource)
 {
     return(ProcessTrigger(CrudOperationType, TriggerRaised, Resource.Id, ResourceNameResolutionSupport.GetResourceFhirAllType(Resource.ResourceType), Resource));
 }