/// <summary> /// This method validates if transaction bundle contains multiple entries that are modifying the same resource. /// It also validates if the request operations within a entry is a valid operation. /// </summary> /// <param name="bundle"> The input bundle</param> /// <param name="cancellationToken"> The cancellation token</param> public async Task ValidateBundle(Hl7.Fhir.Model.Bundle bundle, CancellationToken cancellationToken) { EnsureArg.IsNotNull(bundle, nameof(bundle)); var resourceIdList = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (var entry in bundle.Entry) { if (ShouldValidateBundleEntry(entry)) { string resourceId = await GetResourceId(entry, cancellationToken); string conditionalCreateQuery = entry.Request.IfNoneExist; if (!string.IsNullOrEmpty(resourceId)) { // Throw exception if resourceId is already present in the hashset. if (resourceIdList.Contains(resourceId)) { string requestUrl = BuildRequestUrlForConditionalQueries(entry, conditionalCreateQuery); throw new RequestNotValidException(string.Format(Api.Resources.ResourcesMustBeUnique, requestUrl)); } resourceIdList.Add(resourceId); } } } }
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))); } }
private async Task ExecuteAllRequests(Hl7.Fhir.Model.Bundle responseBundle) { await ExecuteRequests(responseBundle, Hl7.Fhir.Model.Bundle.HTTPVerb.DELETE); await ExecuteRequests(responseBundle, Hl7.Fhir.Model.Bundle.HTTPVerb.POST); await ExecuteRequests(responseBundle, Hl7.Fhir.Model.Bundle.HTTPVerb.PUT); await ExecuteRequests(responseBundle, Hl7.Fhir.Model.Bundle.HTTPVerb.GET); }
/// <inheritdoc/> public async Task <RequestResult <IEnumerable <ImmunizationView> > > GetImmunizations(string hdid) { this.logger.LogDebug($"Getting immunization from Immunization Service... {hdid}"); RequestResult <IEnumerable <ImmunizationView> > result = new RequestResult <IEnumerable <ImmunizationView> >(); string jwtString = this.httpContextAccessor.HttpContext.Request.Headers["Authorization"][0]; RequestResult <Patient> patientResult = this.patientDelegate.GetPatient(hdid, jwtString); if (patientResult.ResultStatus == ResultType.Success && patientResult.ResourcePayload != null) { ImmunizationRequest request = new ImmunizationRequest() { PersonalHealthNumber = patientResult.ResourcePayload.PersonalHealthNumber, DateOfBirth = patientResult.ResourcePayload.Birthdate, }; Hl7.Fhir.Model.Bundle fhirBundle = await this.immunizationDelegate.GetImmunizationBundle(request).ConfigureAwait(true); IEnumerable <Hl7.Fhir.Model.Immunization> immmsLiist = fhirBundle.Entry .Where(r => r.Resource is Hl7.Fhir.Model.Immunization) .Select(f => (Hl7.Fhir.Model.Immunization)f.Resource); List <ImmunizationView> immunizations = new List <ImmunizationView>(); foreach (Hl7.Fhir.Model.Immunization entry in immmsLiist) { ImmunizationView immunizationView = new ImmunizationView { Id = entry.Id, Name = entry.VaccineCode.Text, Status = entry.Status.ToString() !, OccurrenceDateTime = System.DateTime.Parse(entry.Occurrence.ToString() !, CultureInfo.InvariantCulture), }; foreach (Hl7.Fhir.Model.Coding code in entry.VaccineCode.Coding) { ImmunizationAgent immunizationAgent = new ImmunizationAgent { Code = code.Code, Name = code.Display, }; immunizationView.ImmunizationAgents.Add(immunizationAgent); } immunizations.Add(immunizationView); } result.ResultStatus = ResultType.Success; result.PageIndex = 0; result.PageSize = immunizations.Count; result.TotalResultCount = immunizations.Count; result.ResourcePayload = immunizations; } else { result.ResultError = patientResult.ResultError; } this.logger.LogDebug($"Finished getting immunization records {result.TotalResultCount}"); return(result); }
static void Main(string[] args) { //The fhir server end point address string ServiceRootUrl = "https://api-v5-stu3.hspconsortium.org/MX1STU3/open"; //string ServiceRootUrl = "http://sqlonfhir-stu3.azurewebsites.net/fhir"; //Create a client to send to the server at a given endpoint. var FhirClient = new Hl7.Fhir.Rest.FhirClient(ServiceRootUrl); // increase timeouts since the server might be powered down FhirClient.Timeout = (60 * 1000); Console.WriteLine("Press any key to send to server: " + ServiceRootUrl); Console.WriteLine(); Console.ReadKey(); try { //Attempt to send the resource to the server endpoint UriBuilder UriBuilderx = new UriBuilder(ServiceRootUrl); UriBuilderx.Path = "Patient/MY_PATIENT_ID"; Hl7.Fhir.Model.Resource ReturnedResource = FhirClient.InstanceOperation(UriBuilderx.Uri, "everything"); if (ReturnedResource is Hl7.Fhir.Model.Bundle) { Hl7.Fhir.Model.Bundle ReturnedBundle = ReturnedResource as Hl7.Fhir.Model.Bundle; Console.WriteLine("Received: " + ReturnedBundle.Total + " results, the resources are: "); foreach (var Entry in ReturnedBundle.Entry) { Console.WriteLine(string.Format("{0}/{1}", Entry.Resource.TypeName, Entry.Resource.Id)); } } else { throw new Exception("Operation call must return a bundle resource"); } Console.WriteLine(); } catch (Hl7.Fhir.Rest.FhirOperationException FhirOpExec) { //Process any Fhir Errors returned as OperationOutcome resource Console.WriteLine(); Console.WriteLine("An error message: " + FhirOpExec.Message); Console.WriteLine(); string xml = Hl7.Fhir.Serialization.FhirSerializer.SerializeResourceToXml(FhirOpExec.Outcome); XDocument xDoc = XDocument.Parse(xml); Console.WriteLine(xDoc.ToString()); } catch (Exception GeneralException) { Console.WriteLine(); Console.WriteLine("An error message: " + GeneralException.Message); Console.WriteLine(); } Console.WriteLine("Press any key to end."); Console.ReadKey(); }
private Hl7.Fhir.Model.Bundle GetFhirSubBundle(Hl7.Fhir.Model.Bundle bundle) { foreach (Hl7.Fhir.Model.Bundle.EntryComponent ec in bundle.Entry) { if (ec?.Resource is Hl7.Fhir.Model.Bundle) { return(ec.Resource as Hl7.Fhir.Model.Bundle); } } return(null); }
/// <summary>Writes a saner.</summary> /// <param name="outputDirectory">Directory to use for export files.</param> /// <param name="data"> The data.</param> private static void WriteSanerJson( string outputDirectory, ReportData data) { Hl7.Fhir.Model.Bundle bundle = SanerMeasureReport.GetBundle(data, true, true); string filename = Path.Combine(outputDirectory, $"{data.Reporter.Name}-saner.json"); File.WriteAllText( filename, _jsonSerializer.SerializeToString(bundle)); }
private Immunization GetImmunization(Hl7.Fhir.Model.Bundle bundle) { Hl7.Fhir.Model.Immunization fhirImmunization = GetFhirImmunization(bundle); Hl7.Fhir.Model.Patient fhirPatient = GetFhirPatient(bundle); return(new Immunization { RecordIdentifier = fhirImmunization.Id, Patient = GetPatient(fhirPatient), LotNumber = fhirImmunization.LotNumber, DoseNumber = GetDoseNumber(fhirImmunization), CountryOfVaccination = "CA", VaccinationDate = DateTime.Parse(fhirImmunization.Date).ToString("yyyy-MM-dd") }); }
static void Main(string[] args) { //The fhir server end point address //string ServiceRootUrl = "https://api-v5-stu3.hspconsortium.org/MX1STU3/open"; string ServiceRootUrl = "http://PyroHealth.net/test/stu3/fhir"; //Create a client to send to the server at a given endpoint. var FhirClient = new Hl7.Fhir.Rest.FhirClient(ServiceRootUrl); // increase timeouts since the server might be powered down FhirClient.Timeout = (60 * 1000); Console.WriteLine("Press any key to send to server: " + ServiceRootUrl); Console.WriteLine(); Console.ReadKey(); try { //Attempt to send the resource to the server endpoint Hl7.Fhir.Model.Bundle ReturnedSearchBundle = FhirClient.Search <Hl7.Fhir.Model.Patient>(new string[] { "family=Fhirman" }); Console.WriteLine(string.Format("Found: {0} Fhirman patients.", ReturnedSearchBundle.Total.ToString())); Console.WriteLine("Their logical IDs are:"); foreach (var Entry in ReturnedSearchBundle.Entry) { Console.WriteLine("ID: " + Entry.Resource.Id); } Console.WriteLine(); } catch (Hl7.Fhir.Rest.FhirOperationException FhirOpExec) { //Process any Fhir Errors returned as OperationOutcome resource Console.WriteLine(); Console.WriteLine("An error message: " + FhirOpExec.Message); Console.WriteLine(); string xml = Hl7.Fhir.Serialization.FhirSerializer.SerializeResourceToXml(FhirOpExec.Outcome); XDocument xDoc = XDocument.Parse(xml); Console.WriteLine(xDoc.ToString()); } catch (Exception GeneralException) { Console.WriteLine(); Console.WriteLine("An error message: " + GeneralException.Message); Console.WriteLine(); } Console.WriteLine("Press any key to end."); Console.ReadKey(); }
private (Hl7.Fhir.Model.Bundle rawBundle, Hl7.Fhir.Model.Bundle bundle) CreateBundle(params ResourceElement[] resources) { string id = Guid.NewGuid().ToString(); var rawBundle = new Hl7.Fhir.Model.Bundle(); var bundle = new Hl7.Fhir.Model.Bundle(); rawBundle.Id = bundle.Id = id; rawBundle.Type = bundle.Type = BundleType.Searchset; rawBundle.Entry = new List <EntryComponent>(); rawBundle.Total = resources.Count(); bundle.Entry = new List <EntryComponent>(); bundle.Total = resources.Count(); foreach (var resource in resources) { var poco = resource.ToPoco(); poco.VersionId = "1"; poco.Meta.LastUpdated = Clock.UtcNow; poco.Meta.Tag = new List <Hl7.Fhir.Model.Coding> { new Hl7.Fhir.Model.Coding { System = "testTag", Code = Guid.NewGuid().ToString() }, }; var wrapper = _wrapperFactory.Create(poco.ToResourceElement(), deleted: false, keepMeta: true); wrapper.Version = "1"; var requestComponent = new RequestComponent { Method = HTTPVerb.POST, Url = "patient/" }; var responseComponent = new ResponseComponent { Etag = "W/\"1\"", LastModified = DateTimeOffset.UtcNow, Status = "201 Created" }; rawBundle.Entry.Add(new RawBundleEntryComponent(wrapper) { Request = requestComponent, Response = responseComponent, }); bundle.Entry.Add(new EntryComponent { Resource = poco, Request = requestComponent, Response = responseComponent }); } return(rawBundle, bundle); }
private Hl7.Fhir.Model.Immunization GetFhirImmunization(Hl7.Fhir.Model.Bundle bundle) { foreach (Hl7.Fhir.Model.Bundle.EntryComponent ec in bundle.Entry) { if (ec != null && ec.Resource is Hl7.Fhir.Model.Bundle) { Hl7.Fhir.Model.Bundle subBundle = ec.Resource as Hl7.Fhir.Model.Bundle; foreach (Hl7.Fhir.Model.Bundle.EntryComponent ec2 in subBundle.Entry) { if (ec2?.Resource is Hl7.Fhir.Model.Immunization) { return(ec2.Resource as Hl7.Fhir.Model.Immunization); } } } } return(null); }
public List <Patient> SearchPatients(string searchString) { var patientResults = new List <Patient>(); Hl7.Fhir.Rest.FhirClient fhirClient = FhirClientManager.CreateClientConnection(Configuration); fhirClient = FhirClientManager.CreateClientConnection(Configuration); Hl7.Fhir.Model.Bundle ReturnedSearchBundle = fhirClient.Search <Hl7.Fhir.Model.Patient>(new string[] { $"name={searchString}" }); foreach (var resource in ReturnedSearchBundle.Entry) { patientResults.Add((Patient)resource.Resource); } return(patientResults); }
public List <Prescription> FindMedication(string patientId) { var prescriptionResults = new List <Prescription>(); Hl7.Fhir.Rest.FhirClient fhirClient = FhirClientManager.CreateClientConnection(Configuration); fhirClient = FhirClientManager.CreateClientConnection(Configuration); Hl7.Fhir.Model.Bundle ReturnedSearchBundle = fhirClient.Search <Hl7.Fhir.Model.MedicationRequest>(new string[] { $"patient={patientId}" }); foreach (var resource in ReturnedSearchBundle.Entry) { var prescription = (Prescription)resource.Resource; prescriptionResults.Add(prescription); } return(prescriptionResults); }
private async Task Validate(Hl7.Fhir.Model.Bundle rawBundle, Hl7.Fhir.Model.Bundle bundle) { string serialized; using (var ms = new MemoryStream()) using (var sr = new StreamReader(ms)) { await _bundleSerializer.Serialize(rawBundle, ms); ms.Seek(0, SeekOrigin.Begin); serialized = await sr.ReadToEndAsync(); } string originalSerializer = bundle.ToJson(); Assert.Equal(originalSerializer, serialized); var deserializedBundle = new FhirJsonParser(DefaultParserSettings.Settings).Parse(serialized) as Hl7.Fhir.Model.Bundle; Assert.True(deserializedBundle.IsExactly(bundle)); }
public async Task <IEnumerable <Immunization> > GetImmunizations(string patientId, string accessToken = null) { IList <Immunization> immunizations = new List <Immunization>(); MedicalLogResponse response = await _medicalLogClient.GetMedicalLogAsync(new Guid(patientId)); FhirJsonParser fjp = new(); Hl7.Fhir.Model.Bundle bundle = fjp.Parse <Hl7.Fhir.Model.Bundle>(response.FhirBundle); if (bundle != null) { Hl7.Fhir.Model.Patient fhirPatient = GetFhirPatient(bundle); Hl7.Fhir.Model.Bundle subBundle = GetFhirSubBundle(bundle); if (subBundle != null) { foreach (Hl7.Fhir.Model.Bundle.EntryComponent ec in subBundle.Entry) { if (ec?.Resource is Hl7.Fhir.Model.Immunization) { Hl7.Fhir.Model.Immunization fhirImmunization = ec.Resource as Hl7.Fhir.Model.Immunization; Immunization immunization = new Immunization { RecordIdentifier = patientId + "_" + fhirImmunization.Id, Patient = GetPatient(fhirPatient), LotNumber = fhirImmunization.LotNumber, DoseNumber = GetDoseNumber(fhirImmunization), CountryOfVaccination = "CA", VaccinationDate = DateTime.Parse(fhirImmunization.Date).ToString("yyyy-MM-dd"), Vaccine = GetVaccine(), Facility = fhirImmunization.Location.Display }; immunizations.Add(immunization); } } } } return(immunizations); }
/// <summary> /// Validates if transaction bundle contains multiple entries that are modifying the same resource. /// </summary> /// <param name="bundle"> The input bundle</param> public static void ValidateTransactionBundle(Hl7.Fhir.Model.Bundle bundle) { var resourceIdList = new HashSet <string>(StringComparer.Ordinal); foreach (var entry in bundle.Entry) { if (ShouldValidateBundleEntry(entry)) { string resourceId = GetResourceUrl(entry); if (!string.IsNullOrEmpty(resourceId)) { // Throw exception if resourceId is already present in the hashset. if (resourceIdList.Contains(resourceId)) { throw new RequestNotValidException(string.Format(Api.Resources.ResourcesMustBeUnique, resourceId)); } resourceIdList.Add(resourceId); } } } }
private void GetPatientsFromBundle(Hl7.Fhir.Model.Bundle bundle) { Bundle = bundle; CanMoveFirst = Bundle.FirstLink == null; CanMovePrevious = Bundle.PreviousLink == null; CanMoveNext = Bundle.NextLink == null; CanMoveLast = Bundle.LastLink == null; if (Patients.Count > 0) { Patients.Clear(); } foreach (var e in Bundle.Entry) { var patient = new LockStepPatient(); Hl7.Fhir.Model.Patient p = (Hl7.Fhir.Model.Patient)e.Resource; //var meds = PatientService.GetMedicationRequestsAsync(p.Id).GetAwaiter().GetResult(); patient.FhirPatient = p; // patient.Medications = meds.Requests; Patients.Add(patient); } }
static Hl7.Fhir.Model.Bundle GetPatient() { var baseUrl = "https://testapp.hospitalitaliano.org.ar/masterfile-federacion-service/fhir"; var client = new Hl7.Fhir.Rest.FhirClient(baseUrl); client.OnBeforeRequest += OnBeforeRequestFhirServer; client.OnAfterResponse += OnAfterResponseFhirServer; Hl7.Fhir.Model.Bundle ret = null; try { var qp = new Hl7.Fhir.Rest.SearchParams(); qp.Add("identifier", "http://www.msal.gov.ar|2222222"); ret = client.Search <Hl7.Fhir.Model.Patient>(qp); } catch (Exception ex) { Log.Error(ex.ToString()); } return(ret); }
/// <summary> /// This method validates if transaction bundle contains multiple entries that are modifying the same resource. /// It also validates if the request operations within a entry is a valid operation. /// If a conditional create or update is executed and a resource exists, the value is populated in the idDictionary. /// </summary> /// <param name="bundle"> The input bundle</param> /// <param name="idDictionary">The id dictionary that stores fullUrl to actual ids.</param> /// <param name="cancellationToken"> The cancellation token</param> public async Task ValidateBundle(Hl7.Fhir.Model.Bundle bundle, IDictionary <string, (string resourceId, string resourceType)> idDictionary, CancellationToken cancellationToken)
public Hl7.Fhir.Model.Bundle GetPatientByIdentifier(string system, string value) { if (string.IsNullOrWhiteSpace(system)) { throw new ArgumentException("message", nameof(system)); } if (string.IsNullOrWhiteSpace(value)) { throw new ArgumentException("message", nameof(value)); } var activity = new ActivityLog { ActivityTypeDescriptorId = (int)Entities.Activity.ActivityType.GET_PACIENTE_EN_BUS_BY_IDENTIFIER }; //var baseUrl = "https://testapp.hospitalitaliano.org.ar/masterfile-federacion-service/fhir"; var baseUrl = _integrationServicesConfiguration.Services .First(x => x.ServiceName == "BUS").BaseURL; var client = new FhirClient(baseUrl); client.PreferredFormat = ResourceFormat.Json; client.OnBeforeRequest += (object sender, BeforeRequestEventArgs e) => { var requestAdderss = e.RawRequest.Address.ToString(); activity.RequestIsURL = true; activity.ActivityRequestUI = requestAdderss; _logger.LogInformation($"Send Request Address:{requestAdderss}"); }; client.OnAfterResponse += (object sender, AfterResponseEventArgs e) => { if (e.Body != null) { var responseBody = Encoding.UTF8.GetString(e.Body, 0, e.Body.Length); //Prettify !!! responseBody = JToken.Parse(responseBody).ToString(); activity.ResponseIsJson = true; activity.ActivityResponse = $"Status: {e.RawResponse.StatusCode}"; activity.ActivityResponseBody = responseBody; _logger.LogInformation($"Received response with status: {e.RawResponse.StatusCode}"); _logger.LogInformation($"Received response with body: {responseBody}"); } }; Hl7.Fhir.Model.Bundle ret = null; try { var qp = new SearchParams(); qp.Add("identifier", $"{system}|{value}"); ret = client.Search <Hl7.Fhir.Model.Patient>(qp); _currentContext.RegisterActivityLog(activity); } catch (Exception ex) { _logger.LogError(ex.ToString()); throw ex; } return(ret); }
public async Task Serialize(Hl7.Fhir.Model.Bundle bundle, Stream outputStream, bool pretty = false) { await using Utf8JsonWriter writer = new Utf8JsonWriter(outputStream, pretty ? _indentedWriterOptions : _writerOptions); await using StreamWriter streamWriter = new StreamWriter(outputStream, leaveOpen: true); writer.WriteStartObject(); writer.WriteString("resourceType", bundle.TypeName); writer.WriteString("id", bundle.Id); SerializeMetadata(); writer.WriteString("type", bundle.Type?.GetLiteral()); SerializeLinks(); if (bundle.Total.HasValue) { writer.WriteNumber("total", bundle.Total.Value); } await SerializeEntries(); writer.WriteEndObject(); await writer.FlushAsync(); void SerializeMetadata() { if (bundle.Meta != null) { writer.WriteStartObject("meta"); writer.WriteString("lastUpdated", bundle.Meta?.LastUpdated?.ToInstantString()); writer.WriteEndObject(); } } void SerializeLinks() { if (bundle.Link?.Any() == true) { writer.WriteStartArray("link"); foreach (var link in bundle.Link) { writer.WriteStartObject(); writer.WritePropertyName("relation"); writer.WriteStringValue(link.Relation); writer.WritePropertyName("url"); writer.WriteStringValue(link.Url); writer.WriteEndObject(); } writer.WriteEndArray(); } } async Task SerializeEntries() { if (bundle.Entry?.Any() == true) { writer.WriteStartArray("entry"); foreach (var entry in bundle.Entry) { if (!(entry is RawBundleEntryComponent rawBundleEntry)) { throw new ArgumentException("BundleSerializer can only be used when all Entry elements are of type RawBundleEntryComponent.", nameof(bundle)); } bool wroteFullUrl = false; writer.WriteStartObject(); if (!string.IsNullOrEmpty(rawBundleEntry.FullUrl)) { writer.WriteString("fullUrl", rawBundleEntry.FullUrl); await writer.FlushAsync(); await streamWriter.WriteAsync(","); wroteFullUrl = true; } await writer.FlushAsync(); await streamWriter.WriteAsync("\"resource\":"); await streamWriter.FlushAsync(); await rawBundleEntry.ResourceElement.SerializeToStreamAsUtf8Json(outputStream); if (!wroteFullUrl && (rawBundleEntry?.Search?.Mode != null || rawBundleEntry.Request != null || rawBundleEntry.Response != null)) { // If fullUrl was written, the Utf8JsonWriter knows it needs to write a comma before the next property since a comma is needed, and will do so. // If fullUrl wasn't written, since we are writing resource in a separate writer, we need to add this comma manually. await streamWriter.WriteAsync(","); await streamWriter.FlushAsync(); } if (rawBundleEntry?.Search?.Mode != null) { writer.WriteStartObject("search"); writer.WriteString("mode", rawBundleEntry.Search?.Mode?.GetLiteral()); writer.WriteEndObject(); } if (rawBundleEntry.Request != null) { writer.WriteStartObject("request"); writer.WriteString("method", rawBundleEntry.Request.Method.GetLiteral()); writer.WriteString("url", rawBundleEntry.Request.Url); writer.WriteEndObject(); } if (rawBundleEntry.Response != null) { writer.WriteStartObject("response"); writer.WriteString("status", rawBundleEntry.Response.Status); writer.WriteString("etag", rawBundleEntry.Response.Etag); writer.WriteString("lastModified", rawBundleEntry.Response.LastModified?.ToInstantString()); writer.WriteEndObject(); } writer.WriteEndObject(); } writer.WriteEndArray(); } } }