private static async System.Threading.Tasks.Task <Resource> UploadResourceAsync(Resource resource, FhirClient client, bool retry = true) { await semaphore.WaitAsync(); try { return(await client.UpdateAsync(resource)); } catch (FhirOperationException fhirEx) { if (fhirEx.Status == System.Net.HttpStatusCode.TooManyRequests && retry == true) { // Take a break and try again Thread.Sleep(200); return(await UploadResourceAsync(resource, client, false)); } else { Console.WriteLine($"Error uploading resource to FHIR server: {fhirEx.Message}"); return(null); } } catch (Exception ex) { Console.WriteLine($"Error uploading resource to FHIR server: {ex.Message}"); return(null); } finally { semaphore.Release(); } }
public async Task UpdateDelete_UsingResourceIdentity_ResultReturned() { var client = new FhirClient(_endpoint) { PreferredFormat = ResourceFormat.Json, ReturnFullResource = true }; var pat = new Patient() { Name = new List <HumanName>() { new HumanName() { Given = new List <string>() { "test_given" }, Family = new List <string>() { "test_family" }, } }, Id = "async-test-patient" }; // Create the patient Console.WriteLine("Creating patient..."); Patient p = await client.UpdateAsync <Patient>(pat); Assert.IsNotNull(p); // Refresh the patient Console.WriteLine("Refreshing patient..."); await client.RefreshAsync(p); // Delete the patient Console.WriteLine("Deleting patient..."); await client.DeleteAsync(p); Console.WriteLine("Reading patient..."); Func <Task> act = async() => { await client.ReadAsync <Patient>(new ResourceIdentity("/Patient/async-test-patient")); }; // VERIFY // Assert.ThrowsException <FhirOperationException>(act, "the patient is no longer on the server"); Console.WriteLine("Test Completed"); }
/// <summary> /// Ensures a patient and device resource exists and returns the relevant internal ids. /// </summary> /// <param name="input">IMeasurementGroup to retrieve device and patient identifiers from.</param> /// <returns>Internal reference id to the patient and device resources found or created.</returns> /// <exception cref="PatientIdentityNotDefinedException">Thrown when a unique patient identifier isn't found in the provided input.</exception> /// <exception cref="PatientDeviceMismatchException">Thrown when expected patient internal id of the device doesn't match the actual patient internal id.</exception> protected async virtual Task <(string DeviceId, string PatientId)> EnsureDeviceAndPatientExistsAsync(IMeasurementGroup input) { EnsureArg.IsNotNull(input, nameof(input)); // Verify one unique patient identity is present in the measurement group if (string.IsNullOrWhiteSpace(input.PatientId)) { throw new ResourceIdentityNotDefinedException(ResourceType.Patient); } // Begin critical section var patient = await ResourceManagementService.EnsureResourceByIdentityAsync <Model.Patient>( FhirClient, input.PatientId, null, (p, id) => p.Identifier = new List <Model.Identifier> { id }) .ConfigureAwait(false); var device = await ResourceManagementService.EnsureResourceByIdentityAsync <Model.Device>( FhirClient, GetDeviceIdentity(input), ResourceIdentityOptions?.DefaultDeviceIdentifierSystem, (d, id) => { d.Identifier = new List <Model.Identifier> { id }; d.Patient = patient.ToReference(); }) .ConfigureAwait(false); patient.ToReference(); if (device.Patient == null) { device.Patient = patient.ToReference(); device = await FhirClient.UpdateAsync <Model.Device>(device, true).ConfigureAwait(false); } else if (device.Patient.GetId <Model.Patient>() != patient.Id) { // Device is linked to a different patient. Current behavior is undefined, throw an exception. throw new PatientDeviceMismatchException(); } // End critical section return(device.Id, patient.Id); }
public virtual async Task <string> SaveObservationAsync(ILookupTemplate <IFhirTemplate> config, IObservationGroup observationGroup, IDictionary <ResourceType, string> ids) { var identifier = GenerateObservationIdentifier(observationGroup, ids); var cacheKey = $"{identifier.System}|{identifier.Value}"; if (!_observationCache.TryGetValue(cacheKey, out Model.Observation existingObservation)) { existingObservation = await GetObservationFromServerAsync(identifier).ConfigureAwait(false); } Model.Observation result; if (existingObservation == null) { var newObservation = GenerateObservation(config, observationGroup, identifier, ids); result = await _client.CreateAsync(newObservation).ConfigureAwait(false); _logger.LogMetric(IomtMetrics.FhirResourceSaved(ResourceType.Observation, ResourceOperation.Created), 1); } else { var policyResult = await Policy <Model.Observation> .Handle <FhirOperationException>(ex => ex.Status == System.Net.HttpStatusCode.Conflict || ex.Status == System.Net.HttpStatusCode.PreconditionFailed) .RetryAsync(2, async(polyRes, attempt) => { existingObservation = await GetObservationFromServerAsync(identifier).ConfigureAwait(false); }) .ExecuteAndCaptureAsync(async() => { var mergedObservation = MergeObservation(config, existingObservation, observationGroup); return(await _client.UpdateAsync(mergedObservation, versionAware: true).ConfigureAwait(false)); }).ConfigureAwait(false); var exception = policyResult.FinalException; if (exception != null) { throw exception; } result = policyResult.Result; _logger.LogMetric(IomtMetrics.FhirResourceSaved(ResourceType.Observation, ResourceOperation.Updated), 1); } _observationCache.CreateEntry(cacheKey) .SetAbsoluteExpiration(DateTimeOffset.UtcNow.AddHours(1)) .SetSize(1) .SetValue(result) .Dispose(); return(result.Id); }
public void PatientCreationUpdateDeletion() { Patient patient = null !; "When creating a patient resource".x( async() => patient = await _client.CreateAsync( new Patient { Active = true, Name = { new HumanName { Family = "Tester", Given = new[]{ "Anne" }, Use = HumanName.NameUse.Usual } } }).ConfigureAwait(false)); "Then patient has id".x(() => Assert.NotNull(patient.Id)); "And patient can be updated".x( async() => { patient.BirthDateElement = new Date(1970, 1, 1); patient = await _client.UpdateAsync(patient).ConfigureAwait(false); Assert.NotNull(patient.BirthDate); }); "and can be found when searched".x( async() => { var p = await _client.SearchByIdAsync <Patient>(patient.Id).ConfigureAwait(false); Assert.NotEmpty(p.GetResources()); }); "When patient can be deleted".x( async() => { await _client.DeleteAsync(patient).ConfigureAwait(false); }); "Then cannot be found".x( async() => { var p = await _client.SearchByIdAsync <Patient>(patient.Id).ConfigureAwait(false); Assert.Empty(p.GetResources()); }); }
public async Task <OrganizationCreationResponse> UpdateAsync(Guid id, OrganizationForCreation org) { var Result = new OrganizationCreationResponse { Data = new NewOrganization() }; Organization organization = await GetOrganizationFromFHIRAsync(id.ToString()).ConfigureAwait(false); organization.Name = org.name; organization.Address = GetFHIROrgAddresses(org); organization.Telecom = GetFHIROrgTelecoms(org); organization.Type = GetFHIROrgType(org); Organization FHIROrganization = await _client.UpdateAsync(organization).ConfigureAwait(false); Result.Data.OrganizationId = FHIROrganization.Id;//48fc2852-f0c3-4e94-af17-2bf57917eeb9 return(Result); }
public void CreateEditDeleteAsync() { var furore = new Organization { Name = "Furore", Identifier = new List<Identifier> { new Identifier("http://hl7.org/test/1", "3141") }, Telecom = new List<Contact> { new Contact { System = Contact.ContactSystem.Phone, Value = "+31-20-3467171" } } }; FhirClient client = new FhirClient(testEndpoint); var tags = new List<Tag> { new Tag("http://nu.nl/testname", Tag.FHIRTAGSCHEME_GENERAL, "TestCreateEditDelete") }; var fe = client.CreateAsync<Organization>(furore, tags: tags, refresh: true).Result; Assert.IsNotNull(furore); Assert.IsNotNull(fe); Assert.IsNotNull(fe.Id); Assert.IsNotNull(fe.SelfLink); Assert.AreNotEqual(fe.Id, fe.SelfLink); Assert.IsNotNull(fe.Tags); Assert.AreEqual(1, fe.Tags.Count(), "Tag count on new organization record don't match"); Assert.AreEqual(fe.Tags.First(), tags[0]); createdTestOrganizationUrl = fe.Id; fe.Resource.Identifier.Add(new Identifier("http://hl7.org/test/2", "3141592")); var fe2 = client.UpdateAsync(fe, refresh: true).Result; Assert.IsNotNull(fe2); Assert.AreEqual(fe.Id, fe2.Id); Assert.AreNotEqual(fe.SelfLink, fe2.SelfLink); Assert.AreEqual(2, fe2.Resource.Identifier.Count); Assert.IsNotNull(fe2.Tags); Assert.AreEqual(1, fe2.Tags.Count(), "Tag count on updated organization record don't match"); Assert.AreEqual(fe2.Tags.First(), tags[0]); fe.Resource.Identifier.Add(new Identifier("http://hl7.org/test/3", "3141592")); var fe3 = client.UpdateAsync(fe2.Id, fe.Resource, refresh: true).Result; Assert.IsNotNull(fe3); Assert.AreEqual(3, fe3.Resource.Identifier.Count); client.DeleteAsync(fe3).Wait(); try { // Get most recent version fe = client.ReadAsync<Organization>(new ResourceIdentity(fe.Id)).Result; Assert.Fail(); } catch { Assert.IsTrue(client.LastResponseDetails.Result == HttpStatusCode.Gone); } }
public void CreateEditDeleteAsync() { var furore = new Organization { Name = "Furore", Identifier = new List <Identifier> { new Identifier("http://hl7.org/test/1", "3141") }, Telecom = new List <Contact> { new Contact { System = Contact.ContactSystem.Phone, Value = "+31-20-3467171" } } }; FhirClient client = new FhirClient(testEndpoint); var tags = new List <Tag> { new Tag("http://nu.nl/testname", Tag.FHIRTAGSCHEME_GENERAL, "TestCreateEditDelete") }; var fe = client.CreateAsync <Organization>(furore, tags: tags, refresh: true).Result; Assert.IsNotNull(furore); Assert.IsNotNull(fe); Assert.IsNotNull(fe.Id); Assert.IsNotNull(fe.SelfLink); Assert.AreNotEqual(fe.Id, fe.SelfLink); Assert.IsNotNull(fe.Tags); Assert.AreEqual(1, fe.Tags.Count(), "Tag count on new organization record don't match"); Assert.AreEqual(fe.Tags.First(), tags[0]); createdTestOrganizationUrl = fe.Id; fe.Resource.Identifier.Add(new Identifier("http://hl7.org/test/2", "3141592")); var fe2 = client.UpdateAsync(fe, refresh: true).Result; Assert.IsNotNull(fe2); Assert.AreEqual(fe.Id, fe2.Id); Assert.AreNotEqual(fe.SelfLink, fe2.SelfLink); Assert.AreEqual(2, fe2.Resource.Identifier.Count); Assert.IsNotNull(fe2.Tags); Assert.AreEqual(1, fe2.Tags.Count(), "Tag count on updated organization record don't match"); Assert.AreEqual(fe2.Tags.First(), tags[0]); fe.Resource.Identifier.Add(new Identifier("http://hl7.org/test/3", "3141592")); var fe3 = client.UpdateAsync(fe2.Id, fe.Resource, refresh: true).Result; Assert.IsNotNull(fe3); Assert.AreEqual(3, fe3.Resource.Identifier.Count); client.DeleteAsync(fe3).Wait(); try { // Get most recent version fe = client.ReadAsync <Organization>(new ResourceIdentity(fe.Id)).Result; Assert.Fail(); } catch { Assert.IsTrue(client.LastResponseDetails.Result == HttpStatusCode.Gone); } }
/// <summary> /// Update existing Patient /// </summary> /// <param name="patientDto"></param> /// <returns>Updated Patient</returns> public async Task <Patient> UpdatePatientAsync(PatientDto patientDto) { Patient result = null; var patient = await SearchByIdentifierAsync(patientDto.Identifier).ConfigureAwait(false); if (patient != null) { patient.Gender = patientDto.Gender.ToUpper().Equals("MALE") ? AdministrativeGender.Male : patientDto.Gender.ToUpper().Equals("FEMALE") ? AdministrativeGender.Female : AdministrativeGender.Unknown; patient.Name = new List <HumanName> { new() { Prefix = new[] { patientDto.Prefix }, Family = patientDto.LastName, Given = new[] { patientDto.FirstName }, Use = HumanName.NameUse.Official } }; patient.BirthDate = patientDto.BirthDate; patient.Address = new List <Address>() { new() { City = patientDto.Address.City, Country = patientDto.Address.Country, PostalCode = patientDto.Address.PostalCode, Line = new[] { $"{patientDto.Address.StreetName} {patientDto.Address.StreetNo} {patientDto.Address.AppartmentNo}" }, Type = patientDto.Address.Type.ToUpper().Equals("BOTH") ? Address.AddressType.Both : patientDto.Address.Type.ToUpper().Equals("PHYSICAL") ? Address.AddressType.Physical : Address.AddressType.Postal } }; // BirthPlace var birthPlaceExtension = patient.Extension.FirstOrDefault(ext => ext.Url.EndsWith("patient-birthPlace")); if (birthPlaceExtension != null) { ((Address)birthPlaceExtension.Value).City = patientDto.BirthPlace; } // Citizenship var citizenship = _citizenshipService.GetCitizenship(patientDto.CitizenshipCode); if (citizenship != null) { var citizenshipExtension = patient.Extension.FirstOrDefault(ext => ext.Url.EndsWith("patient-citizenship")); var codeExt = (citizenshipExtension?.Extension)?.FirstOrDefault(ext => ext.Url.Equals("code")); var citizenshipConcept = (CodeableConcept)codeExt?.Value; if (citizenshipConcept != null) { if (citizenshipConcept.Coding.Any()) { citizenshipConcept.Coding.FirstOrDefault().Display = citizenship.Explanation; citizenshipConcept.Coding.FirstOrDefault().Code = citizenship.Code; } } } // Before updating the patient to the server, let's validate it first var success = ValidatePatient(patient); if (success) { result = await _fhirClient.UpdateAsync(patient).ConfigureAwait(false); } } return(result); }