Esempio n. 1
0
        public async Task GivenACompletedTransaction_WhenStartingASecondTransactionCommitted_ThenTheResourceShouldBeCreated()
        {
            string createdId1;
            string createdId2;

            using (ITransactionScope transactionScope = _fixture.TransactionHandler.BeginTransaction())
            {
                SaveOutcome saveResult = await Mediator.UpsertResourceAsync(Samples.GetJsonSample("Weight"));

                createdId1 = saveResult.Resource.Id;

                Assert.NotEqual(string.Empty, createdId1);

                transactionScope.Complete();
            }

            using (ITransactionScope transactionScope = _fixture.TransactionHandler.BeginTransaction())
            {
                SaveOutcome saveResult = await Mediator.UpsertResourceAsync(Samples.GetJsonSample("Weight"));

                createdId2 = saveResult.Resource.Id;

                Assert.NotEqual(string.Empty, createdId2);

                transactionScope.Complete();
            }

            ResourceElement getResult1 = await Mediator.GetResourceAsync(new ResourceKey <Observation>(createdId1));

            Assert.Equal(createdId1, getResult1.Id);

            ResourceElement getResult2 = await Mediator.GetResourceAsync(new ResourceKey <Observation>(createdId2));

            Assert.Equal(createdId2, getResult2.Id);
        }
Esempio n. 2
0
        public async Task GivenUpdatedResourcesWithWrongWeakETag_WhenBulkUpdatingSearchParameterIndicesAsync_ThenExceptionIsThrown()
        {
            ResourceElement patientResource1 = CreatePatientResourceElement("Patient1", Guid.NewGuid().ToString());
            SaveOutcome     upsertResult1    = await Mediator.UpsertResourceAsync(patientResource1);

            ResourceElement patientResource2 = CreatePatientResourceElement("Patient2", Guid.NewGuid().ToString());
            SaveOutcome     upsertResult2    = await Mediator.UpsertResourceAsync(patientResource2);

            SearchParameter searchParam1     = null;
            const string    searchParamName1 = "newSearchParam1";

            SearchParameter searchParam2     = null;
            const string    searchParamName2 = "newSearchParam2";

            try
            {
                searchParam1 = await CreatePatientSearchParam(searchParamName1, SearchParamType.String, "Patient.name");

                ISearchValue searchValue1 = new StringSearchValue(searchParamName1);

                (ResourceWrapper original1, ResourceWrapper updated1) = await CreateUpdatedWrapperFromExistingPatient(upsertResult1, searchParam1, searchValue1);

                (ResourceWrapper original2, ResourceWrapper updated2) = await CreateUpdatedWrapperFromExistingPatient(upsertResult2, searchParam1, searchValue1);

                await _dataStore.UpsertAsync(updated1, WeakETag.FromVersionId(original1.Version), allowCreate : false, keepHistory : false, CancellationToken.None);

                await _dataStore.UpsertAsync(updated2, WeakETag.FromVersionId(original2.Version), allowCreate : false, keepHistory : false, CancellationToken.None);

                // Let's update the resources again with new information
                searchParam2 = await CreatePatientSearchParam(searchParamName2, SearchParamType.Token, "Patient.gender");

                ISearchValue searchValue2 = new TokenSearchValue("system", "code", "text");

                // Create the updated wrappers using the original resource and its outdated version
                (_, ResourceWrapper updated1WithSearchParam2) = await CreateUpdatedWrapperFromExistingPatient(upsertResult1, searchParam2, searchValue2, original1);

                (_, ResourceWrapper updated2WithSearchParam2) = await CreateUpdatedWrapperFromExistingPatient(upsertResult2, searchParam2, searchValue2, original2);

                var resources = new List <ResourceWrapper> {
                    updated1WithSearchParam2, updated2WithSearchParam2
                };

                // Attempt to reindex resources with the old versions
                await Assert.ThrowsAsync <PreconditionFailedException>(() => _dataStore.BulkUpdateSearchParameterIndicesAsync(resources, CancellationToken.None));
            }
            finally
            {
                if (searchParam1 != null)
                {
                    _searchParameterDefinitionManager.DeleteSearchParameter(searchParam1.ToTypedElement());
                    await _fixture.TestHelper.DeleteSearchParameterStatusAsync(searchParam1.Url, CancellationToken.None);
                }

                if (searchParam2 != null)
                {
                    _searchParameterDefinitionManager.DeleteSearchParameter(searchParam2.ToTypedElement());
                    await _fixture.TestHelper.DeleteSearchParameterStatusAsync(searchParam2.Url, CancellationToken.None);
                }
            }
        }
Esempio n. 3
0
        public async Task GivenAnUpdatedResourceWithWrongResourceId_WhenUpdatingSearchParameterIndexAsync_ThenExceptionIsThrown()
        {
            ResourceElement patientResource = CreatePatientResourceElement("Patient", Guid.NewGuid().ToString());
            SaveOutcome     upsertResult    = await Mediator.UpsertResourceAsync(patientResource);

            SearchParameter searchParam     = null;
            const string    searchParamName = "newSearchParam";

            try
            {
                searchParam = await CreatePatientSearchParam(searchParamName, SearchParamType.String, "Patient.name");

                ISearchValue searchValue = new StringSearchValue(searchParamName);

                // Update the resource wrapper, adding the new search parameter and a different ID
                (ResourceWrapper original, ResourceWrapper updated) = await CreateUpdatedWrapperFromExistingPatient(upsertResult, searchParam, searchValue, null, Guid.NewGuid().ToString());

                await Assert.ThrowsAsync <ResourceNotFoundException>(() => _dataStore.UpdateSearchParameterIndicesAsync(updated, WeakETag.FromVersionId(original.Version), CancellationToken.None));
            }
            finally
            {
                if (searchParam != null)
                {
                    _searchParameterDefinitionManager.DeleteSearchParameter(searchParam.ToTypedElement());
                    await _fixture.TestHelper.DeleteSearchParameterStatusAsync(searchParam.Url, CancellationToken.None);
                }
            }
        }
Esempio n. 4
0
        private async Task <(ResourceWrapper original, ResourceWrapper updated)> CreateUpdatedWrapperFromExistingResource(
            SaveOutcome upsertResult,
            string updatedId = null)
        {
            // Get wrapper from data store directly
            ResourceKey resourceKey = new ResourceKey(upsertResult.RawResourceElement.InstanceType, upsertResult.RawResourceElement.Id, upsertResult.RawResourceElement.VersionId);
            FhirCosmosResourceWrapper originalWrapper = (FhirCosmosResourceWrapper)await _dataStore.GetAsync(resourceKey, CancellationToken.None);

            // Add new search index entry to existing wrapper.
            SearchParameterInfo     searchParamInfo = new SearchParameterInfo("newSearchParam");
            SearchIndexEntry        searchIndex     = new SearchIndexEntry(searchParamInfo, new NumberSearchValue(12));
            List <SearchIndexEntry> searchIndices   = new List <SearchIndexEntry>()
            {
                searchIndex
            };

            var updatedWrapper = new ResourceWrapper(
                updatedId == null ? originalWrapper.Id : updatedId,
                originalWrapper.Version,
                originalWrapper.ResourceTypeName,
                originalWrapper.RawResource,
                originalWrapper.Request,
                originalWrapper.LastModified,
                deleted: false,
                searchIndices,
                originalWrapper.CompartmentIndices,
                originalWrapper.LastModifiedClaims);

            return(originalWrapper, updatedWrapper);
        }
Esempio n. 5
0
        public async Task GivenADeletedResource_WhenUpdatingSearchParameterIndexAsync_ThenExceptionIsThrown()
        {
            ResourceElement patientResource = CreatePatientResourceElement("Patient", Guid.NewGuid().ToString());
            SaveOutcome     upsertResult    = await Mediator.UpsertResourceAsync(patientResource);

            SearchParameter searchParam     = null;
            const string    searchParamName = "newSearchParam";

            try
            {
                searchParam = await CreatePatientSearchParam(searchParamName, SearchParamType.String, "Patient.name");

                ISearchValue searchValue = new StringSearchValue(searchParamName);

                // Update the resource wrapper, adding the new search parameter
                (ResourceWrapper original, ResourceWrapper updated) = await CreateUpdatedWrapperFromExistingPatient(upsertResult, searchParam, searchValue);

                ResourceWrapper deletedWrapper = CreateDeletedWrapper(original);
                await _dataStore.UpsertAsync(deletedWrapper, WeakETag.FromVersionId(deletedWrapper.Version), allowCreate : true, keepHistory : false, CancellationToken.None);

                // Attempt to reindex the version of the resource that hasn't been deleted
                await Assert.ThrowsAsync <PreconditionFailedException>(() => _dataStore.UpdateSearchParameterIndicesAsync(updated, WeakETag.FromVersionId(updated.Version), CancellationToken.None));
            }
            finally
            {
                if (searchParam != null)
                {
                    _searchParameterDefinitionManager.DeleteSearchParameter(searchParam.ToTypedElement());
                    await _fixture.TestHelper.DeleteSearchParameterStatusAsync(searchParam.Url, CancellationToken.None);
                }
            }
        }
Esempio n. 6
0
        public async Task GivenAnUpdatedResource_WhenUpdatingSearchParameterIndexAsync_ThenResourceMetadataIsUnchanged()
        {
            ResourceElement patientResource = CreatePatientResourceElement("Patient", Guid.NewGuid().ToString());
            SaveOutcome     upsertResult    = await Mediator.UpsertResourceAsync(patientResource);

            SearchParameter searchParam     = null;
            const string    searchParamName = "newSearchParam";

            try
            {
                searchParam = await CreatePatientSearchParam(searchParamName, SearchParamType.String, "Patient.name");

                ISearchValue searchValue = new StringSearchValue(searchParamName);

                (ResourceWrapper original, ResourceWrapper updated) = await CreateUpdatedWrapperFromExistingPatient(upsertResult, searchParam, searchValue);

                await _dataStore.UpdateSearchParameterIndicesAsync(updated, WeakETag.FromVersionId(original.Version), CancellationToken.None);

                // Get the reindexed resource from the database
                var             resourceKey1 = new ResourceKey(upsertResult.RawResourceElement.InstanceType, upsertResult.RawResourceElement.Id, upsertResult.RawResourceElement.VersionId);
                ResourceWrapper reindexed    = await _dataStore.GetAsync(resourceKey1, CancellationToken.None);

                VerifyReindexedResource(original, reindexed);
            }
            finally
            {
                if (searchParam != null)
                {
                    _searchParameterDefinitionManager.DeleteSearchParameter(searchParam.ToTypedElement());
                    await _fixture.TestHelper.DeleteSearchParameterStatusAsync(searchParam.Url, CancellationToken.None);
                }
            }
        }
Esempio n. 7
0
        public async Task <IActionResult> Update([FromBody] Resource resource)
        {
            var suppliedWeakETag = HttpContext.Request.Headers[HeaderNames.IfMatch];

            WeakETag weakETag = null;

            if (!string.IsNullOrWhiteSpace(suppliedWeakETag))
            {
                weakETag = WeakETag.FromWeakETag(suppliedWeakETag);
            }

            SaveOutcome response = await _mediator.UpsertResourceAsync(resource.ToResourceElement(), weakETag, HttpContext.RequestAborted);

            switch (response.Outcome)
            {
            case SaveOutcomeType.Created:
                return(FhirResult.Create(response.Resource, HttpStatusCode.Created)
                       .SetETagHeader()
                       .SetLastModifiedHeader()
                       .SetLocationHeader(_urlResolver));

            case SaveOutcomeType.Updated:
                return(FhirResult.Create(response.Resource, HttpStatusCode.OK)
                       .SetETagHeader()
                       .SetLastModifiedHeader());
            }

            return(FhirResult.Create(response.Resource, HttpStatusCode.BadRequest));
        }
Esempio n. 8
0
        public async Task GivenAnUpdatedResourceWithWrongWeakETag_WhenUpdateSearchIndexForResourceAsync_ThenExceptionIsThrown()
        {
            ResourceElement patientResource = Samples.GetJsonSample("Patient");
            SaveOutcome     upsertResult    = await Mediator.UpsertResourceAsync(patientResource);

            (ResourceWrapper originalWrapper, ResourceWrapper updatedWrapper) = await CreateUpdatedWrapperFromExistingResource(upsertResult);

            UpsertOutcome upsertOutcome = await _dataStore.UpsertAsync(updatedWrapper, WeakETag.FromVersionId(originalWrapper.Version), allowCreate : false, keepHistory : false, CancellationToken.None);

            // Let's update the resource again with new information.
            var searchParamInfo = new SearchParameterInfo("newSearchParam2");
            var searchIndex     = new SearchIndexEntry(searchParamInfo, new TokenSearchValue("system", "code", "text"));
            var searchIndices   = new List <SearchIndexEntry>()
            {
                searchIndex
            };

            updatedWrapper = new ResourceWrapper(
                originalWrapper.ResourceId,
                originalWrapper.Version,
                originalWrapper.ResourceTypeName,
                originalWrapper.RawResource,
                originalWrapper.Request,
                originalWrapper.LastModified,
                deleted: false,
                searchIndices,
                originalWrapper.CompartmentIndices,
                originalWrapper.LastModifiedClaims);

            // Attempt to replace resource with the old weaketag
            await Assert.ThrowsAsync <PreconditionFailedException>(() => _dataStore.UpdateSearchIndexForResourceAsync(updatedWrapper, WeakETag.FromVersionId(originalWrapper.Version), CancellationToken.None));
        }
Esempio n. 9
0
        public async Task GivenAnUpdatedResourceWithWrongResourceId_WhenUpdateSearchIndexForResourceAsync_ThenExceptionIsThrown()
        {
            ResourceElement patientResource = Samples.GetJsonSample("Patient");
            SaveOutcome     upsertResult    = await Mediator.UpsertResourceAsync(patientResource);

            (ResourceWrapper original, ResourceWrapper updated) = await CreateUpdatedWrapperFromExistingResource(upsertResult, Guid.NewGuid().ToString());

            await Assert.ThrowsAsync <ResourceNotFoundException>(() => _dataStore.UpdateSearchIndexForResourceAsync(updated, WeakETag.FromVersionId(original.Version), CancellationToken.None));
        }
Esempio n. 10
0
        public async Task <IActionResult> ConditionalPatch(string typeParameter, [FromBody] JsonPatchDocument patchDocument, [ModelBinder(typeof(WeakETagBinder))] WeakETag ifMatchHeader)
        {
            IReadOnlyList <Tuple <string, string> > conditionalParameters = GetQueriesForSearch();

            UpsertResourceResponse response = await _mediator.Send <UpsertResourceResponse>(
                new ConditionalPatchResourceRequest(typeParameter, patchDocument, conditionalParameters, ifMatchHeader),
                HttpContext.RequestAborted);

            SaveOutcome saveOutcome = response.Outcome;

            return(ToSaveOutcomeResult(saveOutcome));
        }
Esempio n. 11
0
        public async Task <IActionResult> ConditionalUpdate([FromBody] Resource resource)
        {
            IReadOnlyList <Tuple <string, string> > conditionalParameters = GetQueriesForSearch();

            UpsertResourceResponse response = await _mediator.Send <UpsertResourceResponse>(
                new ConditionalUpsertResourceRequest(resource.ToResourceElement(), conditionalParameters),
                HttpContext.RequestAborted);

            SaveOutcome saveOutcome = response.Outcome;

            return(ToSaveOutcomeResult(saveOutcome));
        }
Esempio n. 12
0
        public async Task GivenAnUpdatedResource_WhenUpdateSearchIndexForResourceAsync_ThenResourceGetsUpdated()
        {
            ResourceElement patientResource = Samples.GetJsonSample("Patient");
            SaveOutcome     upsertResult    = await Mediator.UpsertResourceAsync(patientResource);

            (FhirCosmosResourceWrapper original, ResourceWrapper updated) = await CreateUpdatedWrapperFromExistingResource(upsertResult);

            ResourceWrapper replaceResult = await _dataStore.UpdateSearchIndexForResourceAsync(updated, original.ETag, CancellationToken.None);

            Assert.Equal(original.ResourceId, replaceResult.ResourceId);
            Assert.Equal(original.Version, replaceResult.Version);
            Assert.Equal(original.ResourceTypeName, replaceResult.ResourceTypeName);
            Assert.Equal(original.LastModified, replaceResult.LastModified);
        }
Esempio n. 13
0
        public async Task GivenATransactionHandler_WhenATransactionIsNotCommitted_ThenNothingShouldBeCreated()
        {
            string createdId = string.Empty;

            using (_ = _fixture.TransactionHandler.BeginTransaction())
            {
                SaveOutcome saveResult = await Mediator.UpsertResourceAsync(Samples.GetJsonSample("Weight"));

                createdId = saveResult.Resource.Id;

                Assert.NotEqual(string.Empty, createdId);
            }

            await Assert.ThrowsAsync <ResourceNotFoundException>(
                async() => { await Mediator.GetResourceAsync(new ResourceKey <Observation>(createdId)); });
        }
Esempio n. 14
0
        public async Task GivenUpdatedResources_WhenBulkUpdatingSearchParameterIndicesAsync_ThenResourceMetadataIsUnchanged()
        {
            ResourceElement patientResource1 = CreatePatientResourceElement("Patient1", Guid.NewGuid().ToString());
            SaveOutcome     upsertResult1    = await Mediator.UpsertResourceAsync(patientResource1);

            ResourceElement patientResource2 = CreatePatientResourceElement("Patient2", Guid.NewGuid().ToString());
            SaveOutcome     upsertResult2    = await Mediator.UpsertResourceAsync(patientResource2);

            SearchParameter searchParam     = null;
            const string    searchParamName = "newSearchParam";

            try
            {
                searchParam = await CreatePatientSearchParam(searchParamName, SearchParamType.String, "Patient.name");

                ISearchValue searchValue = new StringSearchValue(searchParamName);

                (ResourceWrapper original1, ResourceWrapper updated1) = await CreateUpdatedWrapperFromExistingPatient(upsertResult1, searchParam, searchValue);

                (ResourceWrapper original2, ResourceWrapper updated2) = await CreateUpdatedWrapperFromExistingPatient(upsertResult2, searchParam, searchValue);

                var resources = new List <ResourceWrapper> {
                    updated1, updated2
                };

                await _dataStore.BulkUpdateSearchParameterIndicesAsync(resources, CancellationToken.None);

                // Get the reindexed resources from the database
                var             resourceKey1 = new ResourceKey(upsertResult1.RawResourceElement.InstanceType, upsertResult1.RawResourceElement.Id, upsertResult1.RawResourceElement.VersionId);
                ResourceWrapper reindexed1   = await _dataStore.GetAsync(resourceKey1, CancellationToken.None);

                var             resourceKey2 = new ResourceKey(upsertResult2.RawResourceElement.InstanceType, upsertResult2.RawResourceElement.Id, upsertResult2.RawResourceElement.VersionId);
                ResourceWrapper reindexed2   = await _dataStore.GetAsync(resourceKey2, CancellationToken.None);

                VerifyReindexedResource(original1, reindexed1);
                VerifyReindexedResource(original2, reindexed2);
            }
            finally
            {
                if (searchParam != null)
                {
                    _searchParameterDefinitionManager.DeleteSearchParameter(searchParam.ToTypedElement());
                    await _fixture.TestHelper.DeleteSearchParameterStatusAsync(searchParam.Url, CancellationToken.None);
                }
            }
        }
Esempio n. 15
0
        private IActionResult ToSaveOutcomeResult(SaveOutcome saveOutcome)
        {
            switch (saveOutcome.Outcome)
            {
                case SaveOutcomeType.Created:
                    return FhirResult.Create(saveOutcome.RawResourceElement, HttpStatusCode.Created)
                        .SetETagHeader()
                        .SetLastModifiedHeader()
                        .SetLocationHeader(_urlResolver);
                case SaveOutcomeType.Updated:
                    return FhirResult.Create(saveOutcome.RawResourceElement, HttpStatusCode.OK)
                        .SetETagHeader()
                        .SetLastModifiedHeader();
            }

            return FhirResult.Create(saveOutcome.RawResourceElement, HttpStatusCode.BadRequest);
        }
        public async Task GivenAResourceTypeWithNoVersionVersioningPolicy_WhenSearchingHistory_ThenOnlyLatestVersionIsReturned()
        {
            // The FHIR storage fixture configures organization resources to have the "no-version" versioning policy
            RawResourceElement organizationResource = await Mediator.CreateResourceAsync(Samples.GetDefaultOrganization());

            ResourceElement newResourceValues = Samples.GetDefaultOrganization().UpdateId(organizationResource.Id);

            SaveOutcome updateResult = await Mediator.UpsertResourceAsync(newResourceValues, WeakETag.FromVersionId(organizationResource.VersionId));

            ResourceElement historyResults = await Mediator.SearchResourceHistoryAsync(KnownResourceTypes.Organization, updateResult.RawResourceElement.Id);

            // The history bundle only has one entry because resource history is not kept
            Bundle bundle = historyResults.ToPoco <Bundle>();

            Assert.Single(bundle.Entry);

            Assert.Equal(WeakETag.FromVersionId(updateResult.RawResourceElement.VersionId).ToString(), bundle.Entry[0].Response.Etag);
        }
        public async Task GivenAResourceTypeWithVersionedUpdateVersioningPolicy_WhenSearchingHistory_ThenAllVersionsAreReturned()
        {
            // The FHIR storage fixture configures medication resources to have the "versioned-update" versioning policy
            RawResourceElement medicationResource = await Mediator.CreateResourceAsync(Samples.GetDefaultMedication());

            ResourceElement newResourceValues = Samples.GetDefaultMedication().UpdateId(medicationResource.Id);

            SaveOutcome updateResult = await Mediator.UpsertResourceAsync(newResourceValues, WeakETag.FromVersionId(medicationResource.VersionId));

            ResourceElement historyResults = await Mediator.SearchResourceHistoryAsync(KnownResourceTypes.Medication, updateResult.RawResourceElement.Id);

            // The history bundle has both versions because history is kept
            Bundle bundle = historyResults.ToPoco <Bundle>();

            Assert.Equal(2, bundle.Entry.Count);

            Assert.Equal(WeakETag.FromVersionId(updateResult.RawResourceElement.VersionId).ToString(), bundle.Entry.Max(entry => entry.Response.Etag));
            Assert.Equal(WeakETag.FromVersionId(medicationResource.VersionId).ToString(), bundle.Entry.Min(entry => entry.Response.Etag));
        }
Esempio n. 18
0
        public async Task GivenATransactionHandler_WhenATransactionIsCommitted_ThenTheResourceShouldBeCreated()
        {
            string createdId = string.Empty;

            using (ITransactionScope transactionScope = _fixture.TransactionHandler.BeginTransaction())
            {
                SaveOutcome saveResult = await Mediator.UpsertResourceAsync(Samples.GetJsonSample("Weight"));

                createdId = saveResult.Resource.Id;

                Assert.NotEqual(string.Empty, createdId);

                transactionScope.Complete();
            }

            ResourceElement getResult = await Mediator.GetResourceAsync(new ResourceKey <Observation>(createdId));

            Assert.Equal(createdId, getResult.Id);
        }
Esempio n. 19
0
        public async Task GivenDeletedResource_WhenBulkUpdatingSearchParameterIndicesAsync_ThenExceptionIsThrown()
        {
            ResourceElement patientResource1 = CreatePatientResourceElement("Patient1", Guid.NewGuid().ToString());
            SaveOutcome     upsertResult1    = await Mediator.UpsertResourceAsync(patientResource1);

            ResourceElement patientResource2 = CreatePatientResourceElement("Patient2", Guid.NewGuid().ToString());
            SaveOutcome     upsertResult2    = await Mediator.UpsertResourceAsync(patientResource2);

            SearchParameter searchParam     = null;
            const string    searchParamName = "newSearchParam";

            try
            {
                searchParam = await CreatePatientSearchParam(searchParamName, SearchParamType.String, "Patient.name");

                ISearchValue searchValue = new StringSearchValue(searchParamName);

                // Update the resource wrappers, adding the new search parameter
                (ResourceWrapper original1, ResourceWrapper updated1) = await CreateUpdatedWrapperFromExistingPatient(upsertResult1, searchParam, searchValue);

                (_, ResourceWrapper updated2) = await CreateUpdatedWrapperFromExistingPatient(upsertResult2, searchParam, searchValue);

                // Delete one of the two resources
                ResourceWrapper deletedWrapper = CreateDeletedWrapper(original1);
                await _dataStore.UpsertAsync(deletedWrapper, WeakETag.FromVersionId(deletedWrapper.Version), allowCreate : true, keepHistory : false, CancellationToken.None);

                var resources = new List <ResourceWrapper> {
                    updated1, updated2
                };

                // Attempt to reindex both resources, one of which has since been deleted and has a version that is out of date.
                await Assert.ThrowsAsync <PreconditionFailedException>(() => _dataStore.BulkUpdateSearchParameterIndicesAsync(resources, CancellationToken.None));
            }
            finally
            {
                if (searchParam != null)
                {
                    _searchParameterDefinitionManager.DeleteSearchParameter(searchParam.ToTypedElement());
                    await _fixture.TestHelper.DeleteSearchParameterStatusAsync(searchParam.Url, CancellationToken.None);
                }
            }
        }
Esempio n. 20
0
        public async Task GivenUpdatedResourcesWithWrongResourceId_WhenBulkUpdatingSearchParameterIndicesAsync_ThenExceptionIsThrown()
        {
            ResourceElement patientResource1 = CreatePatientResourceElement("Patient1", Guid.NewGuid().ToString());
            SaveOutcome     upsertResult1    = await Mediator.UpsertResourceAsync(patientResource1);

            ResourceElement patientResource2 = CreatePatientResourceElement("Patient2", Guid.NewGuid().ToString());
            SaveOutcome     upsertResult2    = await Mediator.UpsertResourceAsync(patientResource2);

            SearchParameter searchParam     = null;
            const string    searchParamName = "newSearchParam";

            try
            {
                searchParam = await CreatePatientSearchParam(searchParamName, SearchParamType.String, "Patient.name");

                ISearchValue searchValue = new StringSearchValue(searchParamName);

                // Update the resource wrappers, adding the new search parameter and a different ID
                (_, ResourceWrapper updated1) = await CreateUpdatedWrapperFromExistingPatient(upsertResult1, searchParam, searchValue, null, Guid.NewGuid().ToString());

                (_, ResourceWrapper updated2) = await CreateUpdatedWrapperFromExistingPatient(upsertResult2, searchParam, searchValue, null, Guid.NewGuid().ToString());

                var resources = new List <ResourceWrapper> {
                    updated1, updated2
                };

                await Assert.ThrowsAsync <ResourceNotFoundException>(() => _dataStore.BulkUpdateSearchParameterIndicesAsync(resources, CancellationToken.None));
            }
            finally
            {
                if (searchParam != null)
                {
                    _searchParameterDefinitionManager.DeleteSearchParameter(searchParam.ToTypedElement());
                    await _fixture.TestHelper.DeleteSearchParameterStatusAsync(searchParam.Url, CancellationToken.None);
                }
            }
        }
Esempio n. 21
0
        private async Task <(ResourceWrapper original, ResourceWrapper updated)> CreateUpdatedWrapperFromExistingPatient(
            SaveOutcome upsertResult,
            SearchParameter searchParam,
            ISearchValue searchValue,
            ResourceWrapper originalWrapper = null,
            string updatedId = null)
        {
            var searchIndex   = new SearchIndexEntry(searchParam.ToInfo(), searchValue);
            var searchIndices = new List <SearchIndexEntry> {
                searchIndex
            };

            if (originalWrapper == null)
            {
                // Get wrapper from data store directly
                var resourceKey = new ResourceKey(upsertResult.RawResourceElement.InstanceType, upsertResult.RawResourceElement.Id, upsertResult.RawResourceElement.VersionId);

                originalWrapper = await _dataStore.GetAsync(resourceKey, CancellationToken.None);
            }

            // Add new search index entry to existing wrapper
            var updatedWrapper = new ResourceWrapper(
                updatedId ?? originalWrapper.ResourceId,
                originalWrapper.Version,
                originalWrapper.ResourceTypeName,
                originalWrapper.RawResource,
                new ResourceRequest(HttpMethod.Post, null),
                originalWrapper.LastModified,
                deleted: false,
                searchIndices,
                originalWrapper.CompartmentIndices,
                originalWrapper.LastModifiedClaims,
                _searchParameterDefinitionManager.GetSearchParameterHashForResourceType("Patient"));

            return(originalWrapper, updatedWrapper);
        }
        public async Task GivenAResourceTypeWithVersionedVersioningPolicy_WhenSearchingHistory_ThenAllVersionsAreReturned()
        {
            // The FHIR storage fixture configures observation resources to have the "versioned" versioning policy
            RawResourceElement observationResource = await Mediator.CreateResourceAsync(Samples.GetDefaultObservation());

            ResourceElement newResourceValues = Samples.GetDefaultObservation().UpdateId(observationResource.Id);

            newResourceValues.ToPoco <Observation>().Text = new Narrative
            {
                Status = Narrative.NarrativeStatus.Generated,
                Div    = $"<div>{ContentUpdated}</div>",
            };
            SaveOutcome updateResult = await Mediator.UpsertResourceAsync(newResourceValues, WeakETag.FromVersionId(observationResource.VersionId));

            ResourceElement historyResults = await Mediator.SearchResourceHistoryAsync(KnownResourceTypes.Observation, updateResult.RawResourceElement.Id);

            // The history bundle has both versions because history is kept
            Bundle bundle = historyResults.ToPoco <Bundle>();

            Assert.Equal(2, bundle.Entry.Count);

            Assert.Equal(WeakETag.FromVersionId(updateResult.RawResourceElement.VersionId).ToString(), bundle.Entry.Max(entry => entry.Response.Etag));
            Assert.Equal(WeakETag.FromVersionId(observationResource.VersionId).ToString(), bundle.Entry.Min(entry => entry.Response.Etag));
        }
Esempio n. 23
0
        public async Task GivenATransactionHandler_WhenATransactionFailsFailedRequest_ThenNothingShouldCommit()
        {
            string createdId        = string.Empty;
            string randomNotFoundId = Guid.NewGuid().ToString();

            await Assert.ThrowsAsync <ResourceNotFoundException>(
                async() =>
            {
                using (ITransactionScope transactionScope = _fixture.TransactionHandler.BeginTransaction())
                {
                    SaveOutcome saveResult = await Mediator.UpsertResourceAsync(Samples.GetJsonSample("Weight"));
                    createdId = saveResult.Resource.Id;

                    Assert.NotEqual(string.Empty, createdId);

                    await Mediator.GetResourceAsync(new ResourceKey <Observation>(randomNotFoundId));

                    transactionScope.Complete();
                }
            });

            await Assert.ThrowsAsync <ResourceNotFoundException>(
                async() => { await Mediator.GetResourceAsync(new ResourceKey <Observation>(createdId)); });
        }
Esempio n. 24
0
        public UpsertResourceResponse(SaveOutcome outcome)
        {
            EnsureArg.IsNotNull(outcome, nameof(outcome));

            Outcome = outcome;
        }
Esempio n. 25
0
        public async Task <IActionResult> Update([FromBody] Resource resource, [ModelBinder(typeof(WeakETagBinder))] WeakETag ifMatchHeader)
        {
            SaveOutcome response = await _mediator.UpsertResourceAsync(resource.ToResourceElement(), ifMatchHeader, HttpContext.RequestAborted);

            return(ToSaveOutcomeResult(response));
        }