public async Task <ActionResult <IEnumerable <CustomDiagnostic> > > GetDiagnosticsAsync() { List <CustomDiagnostic> diagnostics = new List <CustomDiagnostic>(); var filterParams = new SearchParams() .Where("identifier=UPTValue"); Bundle result = await _client.SearchAsync <DiagnosticReport>(filterParams); while (result != null) { foreach (var item in result.Entry) { var diagnosticReceived = (DiagnosticReport)item.Resource; var customDiagnostic = new CustomDiagnostic { Id = diagnosticReceived.Id, PatientRef = diagnosticReceived.Performer.FirstOrDefault().ToString(), PractitionerRef = diagnosticReceived.Subject.ToString(), IssueDate = diagnosticReceived.Issued.Value }; diagnostics.Add(customDiagnostic); } result = _client.Continue(result, PageDirection.Next); } return(Ok(diagnostics)); }
public async Task SearchWithCriteria_SyncContinue_SearchReturned() { var client = new FhirClient(_endpoint) { PreferredFormat = ResourceFormat.Json, ReturnFullResource = true }; var result1 = await client.SearchAsync <Patient>(new[] { "family=clark" }); Assert.IsTrue(result1.Entry.Count >= 1); while (result1 != null) { foreach (var e in result1.Entry) { Patient p = (Patient)e.Resource; if (p.Name.Any()) { Console.WriteLine( $"NAME: {p.Name[0].Given.FirstOrDefault()} {p.Name[0].Family.FirstOrDefault()}"); } } result1 = client.Continue(result1, PageDirection.Next); } Console.WriteLine("Test Completed"); }
/// <summary> /// Executes the specified arguments. /// </summary> /// <param name="arguments">The arguments.</param> /// <returns>System.Int32.</returns> /// <remarks>N/A</remarks> public override int Execute(Arguments arguments) { // Get us the needed parameters first // var url = arguments["url"]; var text = new [] { "name=" + arguments["text"] }; // Query FHIR server for a list of matching patient resources // try { var client = new FhirClient(url); var result = client.SearchAsync("Patient", text).Result; if (result.Entries.Count == 0) { Console.WriteLine("Server {0} returned not results for search criteria [{1}]", url, text[0]); return(1); } foreach (var entry in result.Entries) { var rid = new ResourceIdentity(entry.Id); Console.WriteLine("Found patient {0} that matches {1} on {2}", rid.Id, text[0], url); } return(0); } catch (Exception e) { Console.WriteLine(e.Message); return(1); } }
public async Task SearchUsingPostWithCriteria_AsyncContinue_SearchReturned() { var client = new FhirClient(_endpointSupportingSearchUsingPost) { PreferredFormat = ResourceFormat.Json, ReturnFullResource = true }; var result1 = await client.SearchAsync <Patient>(new[] { "family=Chalmers" }, null, 1); Assert.IsTrue(result1.Entry.Count >= 1); while (result1 != null) { foreach (var e in result1.Entry) { Patient p = (Patient)e.Resource; if (p.Name.Any()) { Console.WriteLine( $"NAME: {p.Name[0].Given.FirstOrDefault()} {p.Name[0].Family.FirstOrDefault()}"); } } Console.WriteLine("Fetching more results..."); result1 = await client.ContinueAsync(result1); } Console.WriteLine("Test Completed"); }
public async Task <ActionResult <IEnumerable <CustomPatient> > > GetPatientsAsync() { List <CustomPatient> patientList = new List <CustomPatient>(); var filterParams = new SearchParams() .Where("identifier=UPTValue"); Bundle result = await _client.SearchAsync <Patient>(filterParams); while (result != null) { foreach (var item in result.Entry) { var patientRetrieved = (Patient)item.Resource; var customPatient = new CustomPatient() { Name = patientRetrieved.Name.FirstOrDefault().Family, FirstNames = patientRetrieved.Name.FirstOrDefault().Given.ToList(), Id = patientRetrieved.Id }; patientList.Add(customPatient); } result = _client.Continue(result, PageDirection.Next); } return(Ok(patientList)); }
protected virtual async Task <Model.Observation> GetObservationFromServerAsync(Model.Identifier identifier) { var searchParams = identifier.ToSearchParams(); var result = await _client.SearchAsync <Model.Observation>(searchParams).ConfigureAwait(false); return(await result.ReadOneFromBundleWithContinuationAsync <Model.Observation>(_client)); }
public override async Task <FhirHealthCheckStatus> CheckHealth(CancellationToken token = default) { try { while (!token.IsCancellationRequested) { SearchParams search = new SearchParams().SetCount(1); Hl7.Fhir.Model.Bundle result = await _client.SearchAsync <Hl7.Fhir.Model.StructureDefinition>(search); return(await Task.FromResult(new FhirHealthCheckStatus(string.Empty, 200))); } token.ThrowIfCancellationRequested(); return(await Task.FromResult(new FhirHealthCheckStatus(token.ToString(), 500))); } catch (FhirOperationException ex) { return(await Task.FromResult(new FhirHealthCheckStatus(ex.Message, (int)ex.Status))); } catch (IdentityModel.Clients.ActiveDirectory.AdalServiceException ex) { return(await Task.FromResult(new FhirHealthCheckStatus(ex.Message, ex.StatusCode))); } #pragma warning disable CA1031 catch (Exception ex) #pragma warning restore CA1031 { return(await Task.FromResult(new FhirHealthCheckStatus(ex.Message, 500))); } }
public async Task Search_UsingSearchParams_SearchReturned() { var client = new FhirClient(_endpoint) { PreferredFormat = ResourceFormat.Json, ReturnFullResource = true }; var srch = new SearchParams() .Where("name=Daniel") .LimitTo(10) .SummaryOnly() .OrderBy("birthdate", SortOrder.Descending); var result1 = await client.SearchAsync <Patient>(srch); Assert.IsTrue(result1.Entry.Count >= 1); while (result1 != null) { foreach (var e in result1.Entry) { Patient p = (Patient)e.Resource; Console.WriteLine( $"NAME: {p.Name[0].Given.FirstOrDefault()} {p.Name[0].Family.FirstOrDefault()}"); } result1 = client.Continue(result1, PageDirection.Next); } Console.WriteLine("Test Completed"); }
/// <summary> /// Get Practitioner by ID /// </summary> /// <param name="practitionerId"> ID of practitioner to be fetched </param> /// <returns> Practitioner </returns> public static async Task <Models.Practitioner> GetPractitioner(string practitionerId) { Models.Practitioner practitioner = null; Hl7.Fhir.Model.Practitioner fhirPractitioner = null; try { // limit to 1 to avoid huge response Bundle var PractitionerQuery = new SearchParams() .Where("identifier=http://hl7.org/fhir/sid/us-npi|" + practitionerId) .LimitTo(1); Bundle PractitionerResult = await Client.SearchAsync <Hl7.Fhir.Model.Practitioner>(PractitionerQuery); if (PractitionerResult.Entry.Count > 0) { // Map the FHIR Practitioner object to App's Practitioner object fhirPractitioner = (Hl7.Fhir.Model.Practitioner)PractitionerResult.Entry[0].Resource; PractitionerMapper mapper = new PractitionerMapper(); practitioner = mapper.Map(fhirPractitioner); } } catch (FhirOperationException FhirException) { System.Diagnostics.Debug.WriteLine("Fhir error message: " + FhirException.Message); } catch (Exception GeneralException) { System.Diagnostics.Debug.WriteLine("General error message: " + GeneralException.Message); } return(practitioner); }
/// <summary> /// Gets Patient's hemoglobin observations /// </summary> /// <param name="patientId">Patient resource Id</param> /// <returns>List of hemoglobin observations</returns> public async Task <List <Observation> > GetHemoglobinObservationsForPatientAsync(string patientId) { List <Observation> result = new List <Observation>(); var searchParameters = new SearchParams(); searchParameters.Parameters.Add(new Tuple <string, string>("patient", patientId)); var responsBundle = await _fhirClient.SearchAsync <Observation>(searchParameters).ConfigureAwait(false); foreach (var entry in responsBundle.Entry) { var observation = (Observation)entry.Resource; if (observation.Code.Coding.Exists(coding => coding.Code == Hemoglobin.CODE)) { result.Add(observation); } } return(result); }
public static async Task <IEnumerable <TResource> > SearchWithContinuationAsync <TResource>(this FhirClient fhirClient, SearchParams searchParams) where TResource : Resource { EnsureArg.IsNotNull(fhirClient, nameof(fhirClient)); EnsureArg.IsNotNull(searchParams, nameof(searchParams)); var result = await fhirClient.SearchAsync <TResource>(searchParams).ConfigureAwait(false); return(await result.ReadFromBundleWithContinuationAsync <TResource>(fhirClient, searchParams.Count).ConfigureAwait(false)); }
protected static async Task <TResource> GetResourceByIdentityAsync <TResource>(FhirClient client, Model.Identifier identifier) where TResource : Model.Resource, new() { EnsureArg.IsNotNull(client, nameof(client)); EnsureArg.IsNotNull(identifier, nameof(identifier)); var searchParams = identifier.ToSearchParams(); var result = await client.SearchAsync <TResource>(searchParams).ConfigureAwait(false); return(await result.ReadOneFromBundleWithContinuationAsync <TResource>(client)); }
/// <summary> /// Get Organization by identifier /// </summary> /// <param name="identifier"></param> /// <returns>Organization</returns> public async Task <Organization> SearchByIdentifierAsync(string identifier) { Organization result = null; var bundle = await _fhirClient.SearchAsync <Organization>(new[] { $"identifier={identifier}" }).ConfigureAwait(false); if (bundle.Entry.Any()) { result = (Organization)bundle.Entry.First().Resource; } return(result); }
public void SearchAsync() { FhirClient client = new FhirClient(testEndpoint); Bundle result; result = client.SearchAsync <DiagnosticReport>().Result; Assert.IsNotNull(result); Assert.IsTrue(result.Entry.Count() > 10, "Test should use testdata with more than 10 reports"); result = client.SearchAsync <DiagnosticReport>(pageSize: 10).Result; Assert.IsNotNull(result); Assert.IsTrue(result.Entry.Count <= 10); var withSubject = result.Entry.ByResourceType <DiagnosticReport>().FirstOrDefault(dr => dr.Resource.Subject != null); Assert.IsNotNull(withSubject, "Test should use testdata with a report with a subject"); ResourceIdentity ri = new ResourceIdentity(withSubject.Id); result = client.SearchByIdAsync <DiagnosticReport>(ri.Id, includes: new string[] { "DiagnosticReport.subject" }).Result; Assert.IsNotNull(result); Assert.AreEqual(2, result.Entry.Count); // should have subject too Assert.IsNotNull(result.Entry.Single(entry => new ResourceIdentity(entry.Id).Collection == typeof(DiagnosticReport).GetCollectionName())); Assert.IsNotNull(result.Entry.Single(entry => new ResourceIdentity(entry.Id).Collection == typeof(Patient).GetCollectionName())); result = client.SearchAsync <Patient>(new string[] { "name=Everywoman", "name=Eve" }).Result; Assert.IsNotNull(result); Assert.IsTrue(result.Entry.Count > 0); }
public async Task <GetPatientList.Model> Handle(GetPatientList.Query request, CancellationToken cancellationToken) { var paramsList = new List <string>(); var queryNames = new SearchParams(); if (!string.IsNullOrEmpty(request.FirstName)) { request.FirstName = request.FirstName?.ToLower(); request.FirstName = request.FirstName?.Trim(); queryNames.Where($"given={request.FirstName}").SummaryOnly(SummaryType.Text); paramsList.Add($"given:contains={request.FirstName}"); // queryNames.Where($"given={request.FirstName}").SummaryOnly(SummaryType.Count); //use this for a execute batch but for Medicaions } if (!string.IsNullOrEmpty(request.LastName)) { request.LastName = request.LastName?.ToLower(); request.LastName = request.LastName?.Trim(); queryNames.Where($"family={request.LastName}").SummaryOnly(SummaryType.Text); //var p = queryNames.ToParameters().; paramsList.Add($"name:contains={request.LastName}"); } // var trans = new TransactionBuilder(client.Endpoint); // trans = trans.Search(q, "MedicationRequest").Search(t, "MedicationStatement"); // //var result = await _client.SearchAsync<MedicationRequest>(q); // var tResult = _client.TransactionAsync(trans.ToBundle()); // var result = // PatientList // .Where(x => // x.GivenNames.Select(n=> n.ToLower()).Contains(term) || // x.LastName.ToLower().Contains(term) // ) // .ToList(); //these shpuld be identical // var pats = await client.SearchAsync<Patient>(paramsList.ToArray(), default, 10/*, SummaryType.Text*/); var pats = await client.SearchAsync <Patient>(queryNames.LimitTo(10)); return(new GetPatientList.Model() { Patients = pats }); }
private async Task <List <Organization> > GetOrganizationsFromFHIRAsync() { List <Organization> organizations = new List <Organization>(); var result = await _client.SearchAsync <Organization>().ConfigureAwait(false); while (result != null) { if (result.Entry != null) { foreach (var e in result.Entry) { organizations.Add((Organization)e.Resource); } } // get the next page of results result = _client.Continue(result); } return(organizations); }
public async virtual Task <List <Patient> > Search(string term = null) { if (!string.IsNullOrEmpty(term)) { term = term.ToLower(); term = term.Trim(); // var trans = new TransactionBuilder(client.Endpoint); // trans = trans.Search(q, "MedicationRequest").Search(t, "MedicationStatement"); // //var result = await _client.SearchAsync<MedicationRequest>(q); // var tResult = _client.TransactionAsync(trans.ToBundle()); // var result = // PatientList // .Where(x => // x.GivenNames.Select(n=> n.ToLower()).Contains(term) || // x.LastName.ToLower().Contains(term) // ) // .ToList(); var queryNames = new SearchParams() .Where($"given={term}") .Where($"last={term}") .LimitTo(50); var searchCall = await client.SearchAsync <Patient>(queryNames); List <Patient> patients = new List <Patient>(); while (searchCall != null) { foreach (var e in searchCall.Entry) { Patient p = (Patient)e.Resource; patients.Add(p); } searchCall = client.Continue(searchCall, PageDirection.Next); } return(patients); } return(PatientList); }
/// <summary> /// Get patient's medications /// </summary> /// <param name="patientId">Patient id</param> /// <returns>List of medications</returns> public async Task <List <Medication> > GetMedicationDataForPatientAsync(string patientId) { List <Medication> result; var searchParameters = new SearchParams(); searchParameters.Parameters.Add(new Tuple <string, string>("patient", patientId)); try { // https://fhir.cerner.com/millennium/r4/medications/medication-request/#example var searchResultResponse = await _client.SearchAsync <MedicationRequest>(searchParameters); result = searchResultResponse.Entry.AsParallel() // As parallel since we are making network requests .Select(entry => { var medOrders = _client.Read <MedicationRequest>("MedicationRequest/" + entry.Resource.Id); var safeCast = (medOrders?.Medication as ResourceReference)?.Reference; if (string.IsNullOrWhiteSpace(safeCast)) { return(null); } ; return(_client.Read <Medication>(safeCast)); }) .Where(med => med != null).ToList(); } catch (AggregateException ex) { throw ex.Flatten(); } catch (FhirOperationException) { // Error 404 - no medication orders result = new List <Medication>(); } return(result); }
/// <summary> /// /// </summary>Get Patients page /// <param name="pageSize">Page size (default 10)</param> /// <returns>List of Patients</returns> public async Task <IEnumerable <Patient> > GetPatientsAsync(int pageSize = 10) { var result = await _fhirClient.SearchAsync <Patient>(pageSize : pageSize).ConfigureAwait(false); return(result.Entry.Select(x => (Patient)x.Resource)); }
public void SearchAsync() { FhirClient client = new FhirClient(testEndpoint); Bundle result; result = client.SearchAsync<DiagnosticReport>().Result; Assert.IsNotNull(result); Assert.IsTrue(result.Entry.Count() > 10, "Test should use testdata with more than 10 reports"); result = client.SearchAsync<DiagnosticReport>(pageSize: 10).Result; Assert.IsNotNull(result); Assert.IsTrue(result.Entry.Count <= 10); var withSubject = result.Entry.ByResourceType<DiagnosticReport>().FirstOrDefault(dr => dr.Resource.Subject != null); Assert.IsNotNull(withSubject, "Test should use testdata with a report with a subject"); ResourceIdentity ri = new ResourceIdentity(withSubject.Id); result = client.SearchByIdAsync<DiagnosticReport>(ri.Id, includes: new string[] { "DiagnosticReport.subject" }).Result; Assert.IsNotNull(result); Assert.AreEqual(2, result.Entry.Count); // should have subject too Assert.IsNotNull(result.Entry.Single(entry => new ResourceIdentity(entry.Id).Collection == typeof(DiagnosticReport).GetCollectionName())); Assert.IsNotNull(result.Entry.Single(entry => new ResourceIdentity(entry.Id).Collection == typeof(Patient).GetCollectionName())); result = client.SearchAsync<Patient>(new string[] { "name=Everywoman", "name=Eve" }).Result; Assert.IsNotNull(result); Assert.IsTrue(result.Entry.Count > 0); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { var port = config.GetValue <int>("MetricsPort"); var fetchInterval = TimeSpan.FromSeconds(config.GetValue <int>("FetchIntervalSeconds")); using var server = new MetricServer(port: port); server.Start(); log.LogInformation( "FHIR Server Prometheus Exporter running on port {port} for {fhirServerUrl}", port, fhirClient.Endpoint); while (!stoppingToken.IsCancellationRequested) { fhirClient.RequestHeaders.Authorization = await authHeaderProvider.GetAuthHeaderAsync(stoppingToken); using (FetchResourceCountDuration.WithLabels(fhirServerName).NewTimer()) { foreach (var customMetric in customMetrics) { log.LogInformation("Querying custom metric {name} using {query}", customMetric.Name, customMetric.Query); var resourceTypeAndFilters = customMetric.Query.Split("?"); if (resourceTypeAndFilters.Length < 2) { log.LogWarning("Parsing custom metric query string failed. " + "Should look like: <resourceType>?<name>=<value>&..."); continue; } var resourceType = resourceTypeAndFilters[0]; var kv = HttpUtility.ParseQueryString(resourceTypeAndFilters[1]); var paramList = kv.AllKeys.Select(key => Tuple.Create(key, kv[key])); var sp = SearchParams.FromUriParamList(paramList); sp.Summary = SummaryType.Count; var result = await fhirClient.SearchAsync(sp, resourceType); if (result.Total.HasValue) { customGauges[customMetric.Name] .WithLabels(resourceType, fhirServerName) .Set(result.Total.Value); } else { log.LogWarning("No 'total' returned for {query}", customMetric.Query); } } foreach (var resourceType in resourceTypes) { await UpdateResourceCountAsync(resourceType); } } await Task.Delay(fetchInterval, stoppingToken); } await server.StopAsync(); }