public async Task <Resource> Find <T>(FhirRequest request) where T : Resource { ValidateResource(request.StrResourceType); request.ProfileUri = _resourceProfile; return(await _fhirSearch.Find <T>(request)); }
public async Task <Bundle> Find(FhirRequest request) { ValidateResource(request.StrResourceType); request.ProfileUri = _resourceProfile; return(await _fhirSearch.Find <Patient>(request)); }
public Task <Bundle> Find(FhirRequest request) { ValidateResource(request.StrResourceType); request.ProfileUri = _resourceProfile; return(_fhirSearch.Find <Organization>(request)); }
/// <summary> /// Search for Documents or Get one by _id /// </summary> /// <remarks> /// As the NRLS is implemented with just a search and not read, to read a document the _id parameter is supplied /// </remarks> public async Task <Bundle> Find(FhirRequest request) { ValidateResource(request.StrResourceType); request.ProfileUri = _resourceProfile; var id = request.IdParameter; //We are going to be strict hear for search and only proceed if we have valid parameters if (request.InvalidParameters.Count() > 0) { throw new HttpFhirException("Invalid parameters", OperationOutcomeFactory.CreateInvalidParameter($"Invalid parameter: {string.Join(", ", request.InvalidParameters)}"), HttpStatusCode.BadRequest); } //If we have an _id param it should be the only param so check for that here. if (request.HasIdParameter) { ObjectId mongoId; if (!ObjectId.TryParse(id, out mongoId)) { throw new HttpFhirException("Invalid _id parameter", OperationOutcomeFactory.CreateNotFound(id), HttpStatusCode.NotFound); } if (request.QueryParameters.Count() > 1) { throw new HttpFhirException("Invalid _id parameter combination", OperationOutcomeFactory.CreateInvalidParameter("Invalid parameter: _id"), HttpStatusCode.BadRequest); } request.Id = id; request.IsIdQuery = true; var results = await _fhirSearch.GetAsBundle <DocumentReference>(request); var response = ParseRead(results, id) as Bundle; return(response); } //If we are here then it is a standard search query var patient = request.QueryParameters.FirstOrDefault(x => x.Item1 == "subject"); if (patient != null) { var invalidPatient = _fhirValidation.ValidatePatientParameter(patient.Item2); if (invalidPatient != null) { throw new HttpFhirException("Missing or Invalid patient parameter", invalidPatient, HttpStatusCode.BadRequest); } var nhsNumber = _fhirValidation.GetSubjectReferenceParameterId(patient.Item2); var patientRequest = NrlsPointerHelper.CreatePatientSearch(request, nhsNumber); var patients = await _fhirSearch.Find <Patient>(patientRequest); if (patients.Entry.Count == 0) { throw new HttpFhirException("Unknown patient", OperationOutcomeFactory.CreatePatientNotFound(nhsNumber), HttpStatusCode.NotFound); } } else { throw new HttpFhirException("Missing or Invalid patient parameter", OperationOutcomeFactory.CreateInvalidParameter("Missing parameter: subject"), HttpStatusCode.BadRequest); } var custodian = request.QueryParameters.FirstOrDefault(x => x.Item1 == "custodian"); var useCustodianIdentifierValidation = false; if (custodian == null) { //temporarily also support the incorrectly spec'd custodian.identifier parameter //custodian is a reference type and should not be used in this way custodian = request.QueryParameters.FirstOrDefault(x => x.Item1 == "custodian.identifier"); useCustodianIdentifierValidation = custodian != null; } if (custodian != null) { //temporarily also support the incorrectly spec'd custodian.identifier parameter var invalidCustodian = useCustodianIdentifierValidation ? _fhirValidation.ValidateCustodianIdentifierParameter(custodian.Item2) : _fhirValidation.ValidateCustodianParameter(custodian.Item2); if (invalidCustodian != null) { throw new HttpFhirException("Missing or Invalid custodian parameter", invalidCustodian, HttpStatusCode.BadRequest); } var custodianOrgCode = useCustodianIdentifierValidation? _fhirValidation.GetOrganizationParameterIdentifierId(custodian.Item2) : _fhirValidation.GetOrganizationParameterId(custodian.Item2); var custodianRequest = NrlsPointerHelper.CreateOrgSearch(request, custodianOrgCode); var custodians = await _fhirSearch.Find <Organization>(custodianRequest); if (custodians.Entry.Count == 0) { var invalidOrg = OperationOutcomeFactory.CreateOrganizationNotFound(custodianOrgCode); throw new HttpFhirException("Missing or Invalid custodian parameter", invalidOrg, HttpStatusCode.NotFound); } //This is now out of scope //var invalidOrgInteraction = ValidateOrganisationInteraction(request.RequestingAsid, custodianOrgCode, true); //if (invalidOrgInteraction != null) //{ // throw new HttpFhirException("Invalid Provider Request Exception", invalidOrgInteraction, HttpStatusCode.Unauthorized); //} } var type = request.QueryParameters.FirstOrDefault(x => x.Item1 == "type.coding"); if (type != null) { var invalidType = _fhirValidation.ValidTypeParameter(type.Item2); if (invalidType != null) { throw new HttpFhirException("Missing or Invalid type parameter", invalidType, HttpStatusCode.BadRequest); } } var summary = request.QueryParameters.FirstOrDefault(x => x.Item1 == "_summary"); if (summary != null) { var validSummaryParams = new string[] { "subject", "_format", "_summary" }; var invalidSummaryParams = request.QueryParameters.Where(x => !validSummaryParams.Contains(x.Item1)); OperationOutcome invalidSummary = null; if (invalidSummaryParams.Any()) { var invalidSummaryParamsList = string.Join(", ", invalidSummaryParams.Select(x => $"{x.Item1}={x.Item2}")); invalidSummary = OperationOutcomeFactory.CreateInvalidParameter("Invalid parameter", $"Unsupported search parameter - {invalidSummaryParamsList}"); throw new HttpFhirException("Missing or Invalid type parameter", invalidSummary, HttpStatusCode.BadRequest); } invalidSummary = _fhirValidation.ValidSummaryParameter(summary.Item2); if (invalidSummary != null) { throw new HttpFhirException("Missing or Invalid type parameter", invalidSummary, HttpStatusCode.BadRequest); } request.IsSummary = true; } //Only allow current pointers var queryParameters = request.QueryParameters.ToList(); queryParameters.Add(new Tuple <string, string>("status", "current")); request.QueryParameters = queryParameters; request.AllowedParameters = request.AllowedParameters.Concat(new string[] { "status" }).ToArray(); return(await _fhirSearch.Find <DocumentReference>(request)); }
public async SystemTasks.Task <OperationOutcome> ValidateCreate(FhirRequest request) { ValidateResource(request.StrResourceType); request.ProfileUri = _resourceProfile; // NRLS Layers of validation before Fhir Search Call var document = request.Resource as DocumentReference; //NRL Pointer validation var validProfile = _fhirValidation.ValidPointer(document); if (!validProfile.Success) { throw new HttpFhirException("Invalid NRLS Pointer", validProfile, HttpStatusCode.BadRequest); } //Now we need to do some additional validation on ODS codes && Master Ids //We need to use an external source (in reality yes but we are just going to do an internal query to fake ods & pointer search) if (document.MasterIdentifier != null) { var nhsNumber = _fhirValidation.GetSubjectReferenceId(document.Subject); var masterIdentifierRequest = NrlsPointerHelper.CreateMasterIdentifierSearch(request, document.MasterIdentifier, nhsNumber); var miPointers = await _fhirSearch.GetByMasterId <DocumentReference>(masterIdentifierRequest); if (miPointers.Entry.Count > 0) { return(OperationOutcomeFactory.CreateDuplicateRequest(document.MasterIdentifier)); } } var custodianOrgCode = _fhirValidation.GetOrganizationReferenceId(document.Custodian); var invalidAsid = InvalidAsid(custodianOrgCode, request.RequestingAsid); if (invalidAsid != null) { return(invalidAsid); } var custodianRequest = NrlsPointerHelper.CreateOrgSearch(request, custodianOrgCode); var custodians = await _fhirSearch.Find <Organization>(custodianRequest); if (custodians.Entry.Count == 0) { return(OperationOutcomeFactory.CreateOrganizationNotFound(custodianOrgCode)); } var authorOrgCode = _fhirValidation.GetOrganizationReferenceId(document.Author?.FirstOrDefault()); var authorRequest = NrlsPointerHelper.CreateOrgSearch(request, authorOrgCode); var authors = await _fhirSearch.Find <Organization>(authorRequest); if (authors.Entry.Count == 0) { return(OperationOutcomeFactory.CreateOrganizationNotFound(authorOrgCode)); } //To better mimic NRL here we would create a new patient record for a patient that is not currently know (aka no clinical record) return(null); }