Exemplo n.º 1
0
        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();
            }
        }
Exemplo n.º 2
0
        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");
        }
Exemplo n.º 3
0
        /// <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);
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        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());
            });
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
		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);
			}
		}
Exemplo n.º 8
0
        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);
        }