public static Resource ToPoco(this RawResourceElement resource, ResourceDeserializer deserializer) { EnsureArg.IsNotNull(resource, nameof(resource)); EnsureArg.IsNotNull(deserializer, nameof(deserializer)); return(resource.ToPoco <Resource>(deserializer)); }
public SaveOutcome(RawResourceElement rawResourceElement, SaveOutcomeType outcome) { EnsureArg.IsNotNull(rawResourceElement, nameof(rawResourceElement)); RawResourceElement = rawResourceElement; Outcome = outcome; }
public async Task <IActionResult> VRead(string typeParameter, string idParameter, string vidParameter) { RawResourceElement response = await _mediator.GetResourceAsync(new ResourceKey(typeParameter, idParameter, vidParameter), HttpContext.RequestAborted); return(FhirResult.Create(response, HttpStatusCode.OK) .SetETagHeader() .SetLastModifiedHeader()); }
public async Task <IActionResult> Create([FromBody] Resource resource) { RawResourceElement response = await _mediator.CreateResourceAsync(resource.ToResourceElement(), HttpContext.RequestAborted); return(FhirResult.Create(response, HttpStatusCode.Created) .SetETagHeader() .SetLastModifiedHeader() .SetLocationHeader(_urlResolver)); }
public static T ToPoco <T>(this RawResourceElement resource, ResourceDeserializer deserializer) where T : Resource { EnsureArg.IsNotNull(resource, nameof(resource)); EnsureArg.IsNotNull(deserializer, nameof(deserializer)); var deserialized = deserializer.DeserializeRawResourceElement(resource); return(deserialized.ToPoco <T>()); }
private async Task <string> SerializeToJsonString(RawResourceElement rawResourceElement) { using (var ms = new MemoryStream()) using (var sr = new StreamReader(ms)) { await rawResourceElement.SerializeToStreamAsUtf8Json(ms); ms.Seek(0, SeekOrigin.Begin); return(await sr.ReadToEndAsync()); } }
public async Task <IActionResult> ValidateById([FromRoute] string typeParameter, [FromRoute] string idParameter, [FromQuery] string profile) { Uri profileUri = GetProfile(profile); // Read resource from storage. RawResourceElement response = await _mediator.GetResourceAsync(new ResourceKey(typeParameter, idParameter), HttpContext.RequestAborted); // Convert it to fhir object. var resource = _resourceDeserializer.Deserialize(response); return(await RunValidationAsync(resource, profileUri)); }
public async Task GivenAResourceTypeWithVersionedUpdateVersioningPolicy_WhenUpsertingWithoutSpecifyingVersion_ThenABadRequestExceptionIsThrown() { // 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); // Do not pass in the eTag of the resource being updated // This simulates a request where the most recent version of the resource is not specified in the if-match header var exception = await Assert.ThrowsAsync <BadRequestException>(async() => await Mediator.UpsertResourceAsync(newResourceValues, weakETag: null)); Assert.Equal(string.Format(Core.Resources.IfMatchHeaderRequiredForResource, KnownResourceTypes.Medication), exception.Message); }
public async Task GivenAResourceTypeWithVersionedUpdateVersioningPolicy_WhenPutCreatingWithNoVersion_ThenResourceIsCreatedSuccessfully() { // The FHIR storage fixture configures medication resources to have the "versioned-update" versioning policy var randomId = Guid.NewGuid().ToString(); // Upserting a resource that does not already exist in the database simulates a PUT create // Do not pass in the eTag to mock a request where no if-match header is provided await Mediator.UpsertResourceAsync(Samples.GetDefaultMedication().UpdateId(randomId), weakETag : null); // Confirm the resource is successfully created and has the id specified on creation RawResourceElement medicationSearchResult = await Mediator.GetResourceAsync(new ResourceKey <Medication>(randomId)); Assert.Equal(randomId, medicationSearchResult.Id); }
public async Task GivenAResourceTypeWithVersionedUpdateVersioningPolicy_WhenUpsertingWithNonMatchingVersion_ThenAPreconditionFailedExceptionIsThrown() { // 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); // Pass in a version that does not match the most recent version of the resource being updated // This simulates a request where a non-matching version is specified in the if-match header const string incorrectVersion = "2"; var exception = await Assert.ThrowsAsync <PreconditionFailedException>(async() => await Mediator.UpsertResourceAsync(newResourceValues, WeakETag.FromVersionId(incorrectVersion))); Assert.Equal(string.Format(Core.Resources.ResourceVersionConflict, incorrectVersion), exception.Message); }
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 <IActionResult> ConditionalCreate([FromBody] Resource resource) { StringValues conditionalCreateHeader = HttpContext.Request.Headers[KnownHeaders.IfNoneExist]; Tuple <string, string>[] conditionalParameters = QueryHelpers.ParseQuery(conditionalCreateHeader) .SelectMany(query => query.Value, (query, value) => Tuple.Create(query.Key, value)).ToArray(); UpsertResourceResponse createResponse = await _mediator.Send <UpsertResourceResponse>(new ConditionalCreateResourceRequest(resource.ToResourceElement(), conditionalParameters), HttpContext.RequestAborted); if (createResponse == null) { return(Ok()); } RawResourceElement response = createResponse.Outcome.RawResourceElement; return(FhirResult.Create(response, HttpStatusCode.Created) .SetETagHeader() .SetLastModifiedHeader() .SetLocationHeader(_urlResolver)); }
public async Task <IActionResult> ValidateByIdPost([FromBody] Resource resource, [FromRoute] string typeParameter, [FromRoute] string idParameter, [FromQuery] string profile) { ProcessResource(ref resource, ref profile); Uri profileUri = GetProfile(profile); ResourceElement resourceElement; if (resource == null) { // Read resource from storage. RawResourceElement serverResource = await _mediator.GetResourceAsync(new ResourceKey(typeParameter, idParameter), HttpContext.RequestAborted); // Convert it to fhir object. resourceElement = _resourceDeserializer.Deserialize(serverResource); } else { resourceElement = resource.ToResourceElement(); } return(await RunValidationAsync(resourceElement, profileUri)); }
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 RawBundleEntryComponent(ResourceWrapper resourceWrapper) { EnsureArg.IsNotNull(resourceWrapper, nameof(resourceWrapper)); ResourceElement = new RawResourceElement(resourceWrapper); }
public GetResourceResponse(RawResourceElement resourceElement) { EnsureArg.IsNotNull(resourceElement, nameof(resourceElement)); Resource = resourceElement; }
/// <summary> /// Get the raw data from resourceWrapper as a string and JsonDocument. /// If the RawResource's VersionSet or LastUpdatedSet are false, then the RawResource's data will be updated /// to have them set to the values in the ResourceWrapper /// </summary> /// <param name="rawResource">Input RawResourceElement to convert to a JsonDocument</param> /// <param name="outputStream">Stream to serialize to</param> public static async Task SerializeToStreamAsUtf8Json(this RawResourceElement rawResource, Stream outputStream) { EnsureArg.IsNotNull(rawResource, nameof(rawResource)); if (rawResource.RawResource.IsMetaSet) { await using var sw = new StreamWriter(outputStream, leaveOpen: true); await sw.WriteAsync(rawResource.RawResource.Data); return; } var jsonDocument = JsonDocument.Parse(rawResource.RawResource.Data); await using Utf8JsonWriter writer = new Utf8JsonWriter(outputStream, WriterOptions); writer.WriteStartObject(); bool foundMeta = false; var enumerator = jsonDocument.RootElement.EnumerateObject(); while (enumerator.MoveNext()) { var current = enumerator.Current; if (current.NameEquals("meta")) { foundMeta = true; writer.WriteStartObject("meta"); bool versionIdFound = false, lastUpdatedFound = false; foreach (var metaEntry in current.Value.EnumerateObject()) { if (metaEntry.Name == "lastUpdated" && rawResource.LastUpdated.HasValue) { string toWrite = rawResource.LastUpdated.HasValue ? rawResource.LastUpdated.Value.ToInstantString() : metaEntry.Value.GetString(); writer.WriteString("lastUpdated", toWrite); lastUpdatedFound = true; } else if (metaEntry.Name == "versionId") { writer.WriteString("versionId", rawResource.VersionId); versionIdFound = true; } else { metaEntry.WriteTo(writer); } } if (!lastUpdatedFound && rawResource.LastUpdated.HasValue) { writer.WriteString("lastUpdated", rawResource.LastUpdated.Value.ToInstantString()); } if (!versionIdFound) { writer.WriteString("versionId", rawResource.VersionId); } writer.WriteEndObject(); break; } else { current.WriteTo(writer); } } while (enumerator.MoveNext()) { enumerator.Current.WriteTo(writer); } if (!foundMeta) { writer.WriteStartObject("meta"); writer.WriteString("lastUpdated", rawResource.LastUpdated.Value.ToInstantString()); writer.WriteString("versionId", rawResource.VersionId); writer.WriteEndObject(); } writer.WriteEndObject(); await writer.FlushAsync(); }
public static ResourceElement ToResourceElement(this RawResourceElement resource, ResourceDeserializer deserializer) { EnsureArg.IsNotNull(resource, nameof(resource)); return(resource.ToPoco(deserializer).ToResourceElement()); }