private List <DtoServiceSearchParameterLight> GetSupportedSearchParameters(SearchParameterServiceType SearchParameterServiceType, OperationClass OperationClass, string ResourceType) { List <DtoServiceSearchParameterLight> DtoSupportedServiceSearchParameterList = new List <DtoServiceSearchParameterLight>(); //For non Resource URL values, e.g _format, _summary if ((SearchParameterServiceType & SearchParameterServiceType.Base) == SearchParameterServiceType.Base) { DtoSupportedServiceSearchParameterList.AddRange(ServiceSearchParameterFactory.BaseSearchParameters()); } //For Bundle URL Parameters e.g page, _sort if ((SearchParameterServiceType & SearchParameterServiceType.Bundle) == SearchParameterServiceType.Bundle) { DtoSupportedServiceSearchParameterList.AddRange(ServiceSearchParameterFactory.BundleSearchParameters()); } //For $Operation URL Parameters e.g profile, mode if ((SearchParameterServiceType & SearchParameterServiceType.Operation) == SearchParameterServiceType.Operation) { DtoSupportedServiceSearchParameterList.AddRange(ServiceSearchParameterFactory.OperationSearchParameters(OperationClass)); } //For Resource search parameters if ((SearchParameterServiceType & SearchParameterServiceType.Resource) == SearchParameterServiceType.Resource) { DtoSupportedServiceSearchParameterList.AddRange(IServiceSearchParameterCache.GetSearchParameterForResource(ResourceType)); } return(DtoSupportedServiceSearchParameterList); }
private DtoServiceSearchParameterLight GetTagSearchParameters(string ResourceName) { List <DtoServiceSearchParameterLight> SearchParamList = IServiceSearchParameterCache.GetSearchParameterForResource(ResourceName); var Tag = SearchParamList.SingleOrDefault(x => x.Name == "_tag"); if (Tag != null) { return(Tag); } else { throw new Exception($"Internal Server Error: No _tag search parameter found for Resource Type {ResourceName}"); } }
private void AddIncludeResourceInstanceForIncludes(List <DtoResource> IncludeResourceList, HashSet <string> CacheResourceIDsAlreadyCollected, string FhirId) { //Don't source the same resource again from the Database if we already have it if (!CacheResourceIDsAlreadyCollected.Contains($"{IResourceRepository.RepositoryResourceType.GetLiteral()}-{FhirId}")) { IDatabaseOperationOutcome DatabaseOperationOutcomeIncludes = null; //Here we need to add compartment search, if we have a Compartment and id if (!string.IsNullOrWhiteSpace(this._Compartment) && !string.IsNullOrWhiteSpace(this._CompartmentId)) { //Here we need create a search parameter for _id={FhirId) DtoServiceSearchParameterLight _IdSearchParamLight = IServiceSearchParameterCache.GetSearchParameterForResource(Hl7.Fhir.Model.ResourceType.Resource.GetLiteral()).SingleOrDefault(x => x.Name == "_id"); //var IdSearchParameter = ServiceSearchParameterFactory.BaseResourceSearchParameters().SingleOrDefault(x => x.Name == "_id"); var IdParameterString = new Tuple <string, string>(_IdSearchParamLight.Name, FhirId); //var IdParameterString = new Tuple<string, string>(IdSearchParameter.Name, FhirId); ISearchParameterBase SearchParam = ISearchParameterFactory.CreateSearchParameter(_IdSearchParamLight, IdParameterString); //ISearchParameterBase SearchParam = ISearchParameterFactory.CreateSearchParameter(IdSearchParameter, IdParameterString); PyroSearchParameters FhirIdSearchParameter = new PyroSearchParameters(); FhirIdSearchParameter.SearchParametersList = new List <ISearchParameterBase>(); FhirIdSearchParameter.SearchParametersList.Add(SearchParam); //And now the Compartmnet Search parameters PyroSearchParameters CompartmentSearchParameter = ICompartmentSearchParameterService.GetSearchParameters(this._Compartment, this._CompartmentId, IResourceRepository.RepositoryResourceType.GetLiteral()); DatabaseOperationOutcomeIncludes = IResourceRepository.GetResourceByCompartmentSearch(CompartmentSearchParameter, FhirIdSearchParameter, true); } else { DatabaseOperationOutcomeIncludes = IResourceRepository.GetResourceByFhirID(FhirId, true, false); } var DtoIncludeResourceList = new List <DtoIncludeResource>(); DatabaseOperationOutcomeIncludes.ReturnedResourceList.ForEach(x => DtoIncludeResourceList.Add(new DtoIncludeResource(x))); IncludeResourceList.AddRange(DtoIncludeResourceList); CacheResourceIDsAlreadyCollected.Add($"{IResourceRepository.RepositoryResourceType.GetLiteral()}-{FhirId}"); } }
//public void GetResourceHistoryEntityList(LinqKit.ExpressionStarter<ResCurrentType> Predicate, int StartRecord, List<DtoResource> DtoResourceList) //{ // var HistoryEntityList = DbGetAll<ResCurrentType, ResIndexStringType, ResIndexTokenType, ResIndexUriType, ResIndexReferenceType, ResIndexQuantityType, ResIndexDateTimeType>(Predicate) // .OrderByDescending(x => x.LastUpdated) // .Skip(StartRecord) // .Take(_NumberOfRecordsPerPage) // .ToList(); // if (HistoryEntityList != null) // HistoryEntityList.ForEach(x => DtoResourceList.Add(IndexSettingSupport.SetDtoResource(x, this.RepositoryResourceType))); //} public void PopulateResourceEntity(ResCurrentType ResourceEntity, Resource Resource, IPyroRequestUri FhirRequestUri) { IList <DtoServiceSearchParameterLight> SearchParmeters = IServiceSearchParameterCache.GetSearchParameterForResource(Resource.ResourceType.GetLiteral()); _PopulateResourceEntity(ResourceEntity, Resource, FhirRequestUri, SearchParmeters); }
public ISearchParameterBase CreateSearchParameter(DtoServiceSearchParameterLight DtoSupportedSearchParametersResource, Tuple <string, string> Parameter, bool IsChainedReferance = false) { ISearchParameterBase oSearchParameter = InitalizeSearchParameter(DtoSupportedSearchParametersResource.Type); string ParameterName = Parameter.Item1; string ParameterValue = Parameter.Item2; oSearchParameter.Id = DtoSupportedSearchParametersResource.Id; oSearchParameter.Resource = DtoSupportedSearchParametersResource.Resource; oSearchParameter.Name = DtoSupportedSearchParametersResource.Name; oSearchParameter.TargetResourceTypeList = DtoSupportedSearchParametersResource.TargetResourceTypeList; oSearchParameter.CompositeList = DtoSupportedSearchParametersResource.CompositeList; if (IsChainedReferance) { oSearchParameter.RawValue = ParameterName + SearchParams.SEARCH_CHAINSEPARATOR; } else { oSearchParameter.RawValue = ParameterName + _ParameterNameParameterValueDilimeter + ParameterValue; } _RawSearchParameterAndValueString = oSearchParameter.RawValue; if (!ParseModifier(ParameterName, oSearchParameter)) { oSearchParameter.IsValid = false; oSearchParameter.InvalidMessage = $"Unable to parse the given search parameter's Modifier: {ParameterName}', "; } if (oSearchParameter.Type == SearchParamType.Reference) { (oSearchParameter as SearchParameterReferance).AllowedReferanceResourceList = ServiceSearchParameterFactory.GetSearchParameterTargetResourceList(oSearchParameter); (oSearchParameter as SearchParameterReferance).IsChained = IsChainedReferance; } if (oSearchParameter.Modifier == SearchParameter.SearchModifierCode.Type) { if (!oSearchParameter.TryParseValue($"{oSearchParameter.TypeModifierResource}/{ParameterValue}")) { oSearchParameter.IsValid = false; } } else if (DtoSupportedSearchParametersResource.Type == SearchParamType.Composite) { var SearchParameterComposite = oSearchParameter as SearchParameterComposite; List <ISearchParameterBase> SearchParameterBaseList = new List <ISearchParameterBase>(); var SearchListForResource = IServiceSearchParameterCache.GetSearchParameterForResource(DtoSupportedSearchParametersResource.Resource); //Note we OrderBy SequentialOrder as they must be processed in this specific order foreach (DtoServiceSearchParameterComposite Composite in DtoSupportedSearchParametersResource.CompositeList.OrderBy(x => x.SequentialOrder)) { DtoServiceSearchParameterLight CompositeSearchParamter = SearchListForResource.SingleOrDefault(x => x.Id == Composite.ChildServiceSearchParameterId); if (CompositeSearchParamter != null) { ISearchParameterBase CompositeSubSearchParameter = InitalizeSearchParameter(CompositeSearchParamter.Type); CompositeSubSearchParameter.Id = CompositeSearchParamter.Id; CompositeSubSearchParameter.Resource = CompositeSearchParamter.Resource; CompositeSubSearchParameter.Name = CompositeSearchParamter.Name; CompositeSubSearchParameter.TargetResourceTypeList = CompositeSearchParamter.TargetResourceTypeList; CompositeSubSearchParameter.CompositeList = CompositeSearchParamter.CompositeList; SearchParameterBaseList.Add(CompositeSubSearchParameter); } else { //This should not ever happen, but have message in case it does. We should never have a Composite //search parameter loaded like this as on load it is checked, but you never know! string Message = $"Unable to locate one of the SearchParameters referenced in a Composite SearchParametrer type. " + $"The Composite SearchParametrer name was '{DtoSupportedSearchParametersResource.Name}' for the resource type '{DtoSupportedSearchParametersResource.Resource}'. " + $"This SearchParamter references another SearchParamter with the Canonical Url of {Composite.Url}. " + $"This SearchParamter can not be located in the FHIR Server. This is most likely a server error that will require investigation to resolve"; var OpOut = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.Informational, Message); throw new Common.Exceptions.PyroException(System.Net.HttpStatusCode.InternalServerError, OpOut, Message); } } if (!SearchParameterComposite.TryParseCompositeValue(SearchParameterBaseList, ParameterValue)) { oSearchParameter.IsValid = false; } } else { if (!oSearchParameter.TryParseValue(ParameterValue)) { oSearchParameter.IsValid = false; } } return(oSearchParameter); }
public IResourceServiceOutcome SetActive(OperationClass OperationClass, IRequestMeta RequestMeta, string FhirId) { if (OperationClass == null) { throw new NullReferenceException("OperationClass cannot be null."); } if (IResourceServices == null) { throw new NullReferenceException("ResourceServices 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 (RequestMeta.SearchParameterGeneric == null) { throw new NullReferenceException("SearchParameterGeneric cannot be null."); } ResourceServiceOutcome = IResourceServiceOutcomeFactory.CreateResourceServiceOutcome(); Hl7.Fhir.Model.CompartmentDefinition CompartDef = GetCompartmentResource(FhirId); if (CompartDef != null) { if (CompartDef.Status != PublicationStatus.Active) { ResourceServiceOutcome.ResourceResult = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, $"The {ResourceType.CompartmentDefinition.GetLiteral()} resource status must be {PublicationStatus.Active.GetLiteral()}. The resource supplied has a status of {CompartDef.Status.GetLiteral()}."); ResourceServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.BadRequest; ResourceServiceOutcome.SuccessfulTransaction = true; return(ResourceServiceOutcome); } if (string.IsNullOrWhiteSpace(CompartDef.Id)) { ResourceServiceOutcome.ResourceResult = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, $"The {ResourceType.CompartmentDefinition.GetLiteral()} resource must have a resource id."); ResourceServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.BadRequest; ResourceServiceOutcome.SuccessfulTransaction = true; return(ResourceServiceOutcome); } if (CompartDef.Url.StartsWith(HL7OrgUrl) || CompartDef.Url.StartsWith(PyroOrgUrl)) { DtoServiceCompartment NewServiceCompartment = new DtoServiceCompartment(); NewServiceCompartment.CompartmentDefinitionResourceId = CompartDef.Id; NewServiceCompartment.CompartmentDefinitionResourceVersion = CompartDef.Meta.VersionId; NewServiceCompartment.Code = CompartDef.Code.GetLiteral(); NewServiceCompartment.LastUpdated = DateTimeOffset.Now; NewServiceCompartment.Name = CompartDef.Name; NewServiceCompartment.Title = CompartDef.Title; NewServiceCompartment.Url = CompartDef.Url; NewServiceCompartment.ResourceList = new List <DtoServiceCompartmentResource>(); foreach (var ResourceComponent in CompartDef.Resource) { List <Search.DtoServiceSearchParameterLight> SupportedSerachParamList = IServiceSearchParameterCache.GetSearchParameterForResource(ResourceComponent.Code.GetLiteral()); if (ResourceComponent.Param.Count() == 0) { var CompatmentResource = new DtoServiceCompartmentResource() { Code = ResourceComponent.Code.GetLiteral(), // '*' means no paramerter, which means all Resource of this type //are in the compartment. //If there is no 'ResourceComponent' at all then that Resources type and all its instances //are not in the compartment Param = "*" }; NewServiceCompartment.ResourceList.Add(CompatmentResource); } foreach (var Param in ResourceComponent.Param) { //The Resource param value equals {def} then thnis shoudl be the same Resource as that of the Compartment its self //in this case there are no search parameters if (Param.ToLower() == "{def}") { if (ResourceComponent.Code.GetLiteral() != CompartDef.Code.GetLiteral()) { ResourceServiceOutcome.ResourceResult = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, $"The {ResourceType.CompartmentDefinition.GetLiteral()} resource has a search parameter that has a value of '{{def}}' which should indicate that this Resource is the target of the Compatment it's self, Yet they do not match, Compartment is: '{ResourceComponent.Code.GetLiteral()}' and '{{def}}' parametrer is found for ResourceType {ResourceComponent.Code.GetLiteral()}"); ResourceServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.BadRequest; ResourceServiceOutcome.SuccessfulTransaction = true; return(ResourceServiceOutcome); } } else { var FoundParam = SupportedSerachParamList.SingleOrDefault(x => x.Name == Param.Split('.')[0].Split(':')[0]); if (FoundParam != null) { if (FoundParam.Type != SearchParamType.Reference) { ResourceServiceOutcome.ResourceResult = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, $"The {ResourceType.CompartmentDefinition.GetLiteral()} resource has a search parameter that is not a Reference search parameter type. The parameter in question is '{Param}' for the resource '{ResourceComponent.Code.GetLiteral()}'"); ResourceServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.BadRequest; ResourceServiceOutcome.SuccessfulTransaction = true; return(ResourceServiceOutcome); } } else { ResourceServiceOutcome.ResourceResult = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, $"The {ResourceType.CompartmentDefinition.GetLiteral()} resource has a search parameter that is not supported by the server. The parameter in question is '{Param}' for the resource '{ResourceComponent.Code.GetLiteral()}'"); ResourceServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.BadRequest; ResourceServiceOutcome.SuccessfulTransaction = true; return(ResourceServiceOutcome); } var CompatmentResource = new DtoServiceCompartmentResource() { Code = ResourceComponent.Code.GetLiteral(), Param = Param }; NewServiceCompartment.ResourceList.Add(CompatmentResource); } } } //Commit or Update the compartment NewServiceCompartment = IServiceCompartmentRepository.UpdateServiceCompartment(NewServiceCompartment); ClearCompartmentCache(NewServiceCompartment.Code); AddCompartmentActiveTag(CompartDef); //Commit CompartmentDefinition with Active tag, disable triggers on doing so as the triggers will block //the update. IRequestMeta RequestMetaUpdateCompartmentDef = IRequestMetaFactory.CreateRequestMeta().Set($"{FHIRAllTypes.CompartmentDefinition}/{CompartDef.Id}"); //IResourceServices.TriggersActive = false; this.IResourceTriggerService.TriggersActive = false; var IResourceServicesOutcome = IResourceServices.Put(CompartDef.Id, CompartDef, RequestMetaUpdateCompartmentDef); this.IResourceTriggerService.TriggersActive = true; ResourceServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.OK; ResourceServiceOutcome.IsDeleted = false; ResourceServiceOutcome.OperationType = RestEnum.CrudOperationType.Update; ResourceServiceOutcome.SuccessfulTransaction = true; return(ResourceServiceOutcome); } else { ResourceServiceOutcome.ResourceResult = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, $"The {ResourceType.CompartmentDefinition.GetLiteral()} resource url property must start with either: '{HL7OrgUrl}' or '{PyroOrgUrl}'. The resource supplied has a url property of '{CompartDef.Url}'."); ResourceServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.BadRequest; ResourceServiceOutcome.SuccessfulTransaction = true; return(ResourceServiceOutcome); } } else { //Not CompartmentDefinition Resource found ResourceServiceOutcome.ResourceResult = Common.Tools.FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Fatal, OperationOutcome.IssueType.NotSupported, $"The resource id supplied to the ${FhirOperationEnum.OperationType.xSetCompartmentActive.GetPyroLiteral()} operation was not found in the server at: {ResourceType.CompartmentDefinition.GetLiteral()}/{FhirId}"); ResourceServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.NotFound; ResourceServiceOutcome.FhirResourceId = null; ResourceServiceOutcome.LastModified = null; ResourceServiceOutcome.IsDeleted = null; ResourceServiceOutcome.OperationType = RestEnum.CrudOperationType.Read; ResourceServiceOutcome.ResourceVersionNumber = null; ResourceServiceOutcome.RequestUri = RequestMeta.PyroRequestUri.FhirRequestUri; ResourceServiceOutcome.HttpStatusCode = System.Net.HttpStatusCode.NotFound; ResourceServiceOutcome.SuccessfulTransaction = true; return(ResourceServiceOutcome); } }
public void Index(Resource Resource, PyroSearchParameters DtoSearchParameters = null) { this.ResourceType = Resource.ResourceType; this.FhirID = Resource.Id; string ResourceName = Resource.ResourceType.GetLiteral(); IList <DtoServiceSearchParameterLight> SearchParametersList = IServiceSearchParameterCache.GetSearchParameterForResource(ResourceName); //Filter the list by only the searech parameters provided, do not inex for all if (DtoSearchParameters != null) { SearchParametersList = SearchParametersList.Where(x => DtoSearchParameters.SearchParametersList.Any(d => d.Id == x.Id)).ToList(); } PocoNavigator Navigator = new PocoNavigator(Resource); string Resource_ResourceName = FHIRAllTypes.Resource.GetLiteral(); foreach (DtoServiceSearchParameterLight SearchParameter in SearchParametersList) { //Todo: Composite searchParameters are not supported as yet, need to do work to read // the sub search parameters of the composite directly fro the SearchParameter resources. if (SearchParameter.Type != SearchParamType.Composite) { bool SetSearchParameterIndex = true; //if ((SearchParameter.Resource == Resource_ResourceName && SearchParameter.Name == "_id") || // (SearchParameter.Resource == Resource_ResourceName && SearchParameter.Name == "_lastUpdated")) //{ // SetSearchParameterIndex = false; //} if (SetSearchParameterIndex) { string Expression = SearchParameter.Expression; if (SearchParameter.Resource == Resource_ResourceName) { //If the Expression is one with a parent resource of Resource then swap it for the actual current resource name //For example make 'Resource._tag' be 'Observation._tag' for Observation resources. Expression = Resource.TypeName + SearchParameter.Expression.TrimStart(Resource_ResourceName.ToCharArray()); } IEnumerable <IElementNavigator> ResultList = Navigator.Select(Expression, new EvaluationContext(Navigator)); foreach (IElementNavigator oElement in ResultList) { if (oElement != null) { switch (SearchParameter.Type) { case SearchParamType.Number: { this.IndexQuantityList.AddRange(IIndexSetterFactory.CreateNumberSetter().Set(oElement, SearchParameter)); break; } case SearchParamType.Date: { this.IndexDateTimeList.AddRange(IIndexSetterFactory.CreateDateTimeSetter().Set(oElement, SearchParameter)); break; } case SearchParamType.String: { this.IndexStringList.AddRange(IIndexSetterFactory.CreateStringSetter().Set(oElement, SearchParameter)); break; } case SearchParamType.Token: { this.IndexTokenList.AddRange(IIndexSetterFactory.CreateTokenSetter().Set(oElement, SearchParameter)); break; } case SearchParamType.Reference: { this.IndexReferenceList.AddRange(IIndexSetterFactory.CreateReferenceSetter().Set(oElement, SearchParameter)); break; } case SearchParamType.Composite: { break; } case SearchParamType.Quantity: { this.IndexQuantityList.AddRange(IIndexSetterFactory.CreateQuantitySetter().Set(oElement, SearchParameter)); break; } case SearchParamType.Uri: { this.IndexUriList.AddRange(IIndexSetterFactory.CreateUriSetter().Set(oElement, SearchParameter)); break; } default: throw new System.ComponentModel.InvalidEnumArgumentException(SearchParameter.Type.ToString(), (int)SearchParameter.Type, typeof(SearchParamType)); } } } } } } }