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); }
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); } } }
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); } } }
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); }
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); } } }
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); } } }
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)); }
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)); }
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)); }
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)); }
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)); }
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); }
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)); }); }
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); } } }
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)); }
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); }
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); } } }
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); } } }
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)); }
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)); }); }
public UpsertResourceResponse(SaveOutcome outcome) { EnsureArg.IsNotNull(outcome, nameof(outcome)); Outcome = outcome; }
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)); }