private bool GetProcessing(Bundle.EntryComponent GetEntry, int GetEntryIndex) { IRequestMeta RequestMeta = IRequestMetaFactory.CreateRequestMeta(); RequestMeta.Set(GetEntry.Request); RequestMeta.RequestHeader.Prefer = _RequestHeader.Prefer; IResourceServiceOutcome ResourceServiceOutcome = null; if (RequestMeta.SearchParameterGeneric.ParameterList.Count > 0) { ResourceServiceOutcome = IResourceServices.GetSearch(RequestMeta); } else { ResourceServiceOutcome = IResourceServices.GetRead(RequestMeta.PyroRequestUri.FhirRequestUri.ResourceId, RequestMeta); } if (ResourceServiceOutcome.SuccessfulTransaction) { GetEntry.FullUrl = CreateFullUrl(ResourceServiceOutcome); GetEntry.Response = new Bundle.ResponseComponent(); GetEntry.Response.Status = FormatHTTPStatusCodeAsString(ResourceServiceOutcome.HttpStatusCode); if (ResourceServiceOutcome.ResourceResult != null) { if (ResourceServiceOutcome.ResourceResult.ResourceType == ResourceType.OperationOutcome) { GetEntry.Response.Outcome = ResourceServiceOutcome.ResourceResult; } else { GetEntry.Resource = ResourceServiceOutcome.ResourceResult; } } if (ResourceServiceOutcome.LastModified.HasValue) { GetEntry.Response.Etag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber).ToString(); if (ResourceServiceOutcome.IsDeleted.HasValue && !ResourceServiceOutcome.IsDeleted.Value) { GetEntry.Response.LastModified = ResourceServiceOutcome.LastModified; } GetEntry.Response.Location = FormatResponseLocation(RequestMeta.PyroRequestUri.FhirRequestUri.OriginalString, ResourceServiceOutcome.FhirResourceId, ResourceServiceOutcome.ResourceVersionNumber); } return(true); } else { if (ResourceServiceOutcome.ResourceResult != null && ResourceServiceOutcome.ResourceResult is OperationOutcome Op) { IdentifieBatchEntityToClient(Op, GetEntry.FullUrl, "GET", GetEntryIndex); } _ServiceOperationOutcome = ResourceServiceOutcome; return(false); } }
private bool DeleteProcessing(Bundle.EntryComponent DeleteEntry, int DeleteEntryIndex) { IRequestMeta RequestMeta = IRequestMetaFactory.CreateRequestMeta().Set(DeleteEntry.Request); RequestMeta.RequestHeader.Prefer = _RequestHeader.Prefer; IResourceServiceOutcome ResourceServiceOutcome = null; if (RequestMeta.SearchParameterGeneric.ParameterList.Count > 0) { ResourceServiceOutcome = IResourceServices.ConditionalDelete(RequestMeta); } else { ResourceServiceOutcome = IResourceServices.Delete(RequestMeta.PyroRequestUri.FhirRequestUri.ResourceId, RequestMeta); } if (ResourceServiceOutcome.SuccessfulTransaction) { DeleteEntry.Response = new Bundle.ResponseComponent(); DeleteEntry.Response.Status = FormatHTTPStatusCodeAsString(ResourceServiceOutcome.HttpStatusCode); DeleteEntry.FullUrl = null; if (ResourceServiceOutcome.ResourceResult != null) { if (ResourceServiceOutcome.ResourceResult.ResourceType == ResourceType.OperationOutcome) { DeleteEntry.Response.Outcome = ResourceServiceOutcome.ResourceResult; } else { DeleteEntry.Resource = ResourceServiceOutcome.ResourceResult; } } if (ResourceServiceOutcome.LastModified != null && ResourceServiceOutcome.ResourceVersionNumber != null) { DeleteEntry.Response.Etag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber).ToString(); DeleteEntry.Response.LastModified = ResourceServiceOutcome.LastModified; } return(true); } else { if (ResourceServiceOutcome.ResourceResult != null && ResourceServiceOutcome.ResourceResult is OperationOutcome Op) { IdentifieBatchEntityToClient(Op, DeleteEntry.FullUrl, "DELETE", DeleteEntryIndex); } _ServiceOperationOutcome = ResourceServiceOutcome; return(false); } }
public HttpResponseMessage GetHttpResponseMessage(IResourceServiceOutcome ResourceServiceOutcome, HttpRequestMessage Request, Hl7.Fhir.Rest.SummaryType?SummaryType) { _HttpStatusCode = ResourceServiceOutcome.HttpStatusCode; Resource Resource = ResourceServiceOutcome.ResourceResult; HttpResponseMessage Response = Request.CreateResponse(_HttpStatusCode); if (Resource != null) { //If the Resource is an OperationOutcome then we auto generate its narrative here if (Resource.ResourceType == ResourceType.OperationOutcome) { IFhirResourceNarrative.CreateNarrative(Resource as OperationOutcome); } //Set the media formatter as per search parameter _format Response = ResolveReturnAcceptTypeJsonOrXml(ResourceServiceOutcome.FormatMimeType, Request, Resource); //Annotate the Resource with the _summary, will get the annotation in MediaTypeFormatter XML or JSON AnnotateResourceWithSummaryType(SummaryType, Resource); } switch (_HttpStatusCode) { case HttpStatusCode.OK: { switch (ResourceServiceOutcome.OperationType) { case RestEnum.CrudOperationType.None: break; case RestEnum.CrudOperationType.Create: { //LastModified Header && ETag Version if (ResourceServiceOutcome.LastModified != null) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); //If we have a conditional Create where the Resource is found then we return OK but no Resource so no Content if (Response.Content != null) { Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } } return(Response); } case RestEnum.CrudOperationType.Read: { //LastModified Header & ETagVersion &Location Header if (ResourceServiceOutcome.LastModified.HasValue) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); if (Response.Content != null && ResourceServiceOutcome.IsDeleted.HasValue && !ResourceServiceOutcome.IsDeleted.Value) { Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri); } return(Response); } case RestEnum.CrudOperationType.Update: { //Location Header if (Response.Content != null) { Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri); } //LastModified Header && ETagVersion if (ResourceServiceOutcome.LastModified.HasValue) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } return(Response); } case RestEnum.CrudOperationType.Delete: { //LastModified Header && ETag Version if (ResourceServiceOutcome.LastModified != null) { if (!string.IsNullOrWhiteSpace(ResourceServiceOutcome.ResourceVersionNumber)) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); } Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } return(Response); } default: { var oIssueComponent = new OperationOutcome.IssueComponent { Severity = OperationOutcome.IssueSeverity.Fatal, Code = OperationOutcome.IssueType.Exception, Diagnostics = "Internal Error. FhirRestResponse contains no FHIR Resource or Id." }; var oOperationOutcome = new OperationOutcome { Issue = new List <OperationOutcome.IssueComponent>() { oIssueComponent } }; throw new PyroException(HttpStatusCode.InternalServerError, oOperationOutcome, "Internal Error. FhirRestResponse contains no FHIR Resource or Id."); } } if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Read) { //LastModified Header & ETagVersion &Location Header if (ResourceServiceOutcome.LastModified.HasValue) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); if (Response.Content != null && ResourceServiceOutcome.IsDeleted.HasValue && !ResourceServiceOutcome.IsDeleted.Value) { Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri); } return(Response); } else if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Update) { //Location Header if (Response.Content != null) { Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri); } //LastModified Header && ETagVersion if (ResourceServiceOutcome.LastModified.HasValue) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } return(Response); } else if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Delete && ResourceServiceOutcome.ResourceVersionNumber != null) { //LastModified Header && ETag Version if (ResourceServiceOutcome.LastModified != null) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } return(Response); } else if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Create) { //LastModified Header && ETag Version if (ResourceServiceOutcome.LastModified != null) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); //If we have a conditional Create where the Resource is found then we return OK but no Resource so no Content if (Response.Content != null) { Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } } return(Response); } else { var oIssueComponent = new OperationOutcome.IssueComponent { Severity = OperationOutcome.IssueSeverity.Fatal, Code = OperationOutcome.IssueType.Exception, Diagnostics = "Internal Error. FhirRestResponse contains no FHIR Resource or Id." }; var oOperationOutcome = new OperationOutcome { Issue = new List <OperationOutcome.IssueComponent>() { oIssueComponent } }; throw new PyroException(HttpStatusCode.InternalServerError, oOperationOutcome, "Internal Error. FhirRestResponse contains no FHIR Resource or Id."); } } case HttpStatusCode.Created: { //Location Header if (Response.Content != null) { Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri, ResourceServiceOutcome.FhirResourceId); } //LastModified Header && ETagVersion if (ResourceServiceOutcome.LastModified.HasValue) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } return(Response); } case HttpStatusCode.Gone: { //LastModified Header && ETagVersion if (ResourceServiceOutcome.LastModified.HasValue) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); } return(Response); } case HttpStatusCode.NoContent: { //LastModified Header && ETagVersion if (ResourceServiceOutcome.LastModified.HasValue) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); if (Response.Content != null) { Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } } return(Response); } case HttpStatusCode.NotFound: { //No need to process _format as not returning a body of type resource return(Response); } case HttpStatusCode.PreconditionFailed: { return(Response); } case HttpStatusCode.NotModified: { return(Response); } case HttpStatusCode.UnsupportedMediaType: { return(Response); } default: { if (Resource != null) { return(Response); } else { var OpOutComeIssueComp = new OperationOutcome.IssueComponent { Severity = OperationOutcome.IssueSeverity.Fatal, Code = OperationOutcome.IssueType.Exception, Diagnostics = "Internal Server Error: An unexpected HttpStatusCode has been encountered with a null resource to return. This is most likely a server bug." }; var OpOutCome = new OperationOutcome(); OpOutCome.Issue.Add(OpOutComeIssueComp); FhirOperationOutcomeSupport.EscapeOperationOutComeContent(OpOutCome); IFhirResourceNarrative.CreateNarrative(OpOutCome); if (_FhirMediaTypeFormatter != null) { Response.Content = new ObjectContent(typeof(Resource), OpOutCome, _FhirMediaTypeFormatter); } else { Response = Request.CreateResponse(_HttpStatusCode, OpOutCome); } return(Response); } } } }
private bool PostProcessing(Bundle.EntryComponent PostEntry, int PostEntryIndex) { IRequestMeta RequestMeta = IRequestMetaFactory.CreateRequestMeta().Set(PostEntry.Request); if (RequestMeta.PyroRequestUri.FhirRequestUri.IsOperation) { var Message = $"The FHIR server does not support the use of Operations within Transaction Bundles, found Operation request type of : '{RequestMeta.PyroRequestUri.FhirRequestUri.OperationName}'."; var OpOutcome = FhirOperationOutcomeSupport.Create(OperationOutcome.IssueSeverity.Error, OperationOutcome.IssueType.Invalid, Message); _ServiceOperationOutcome.ResourceResult = OpOutcome; _ServiceOperationOutcome.HttpStatusCode = System.Net.HttpStatusCode.Forbidden; _ServiceOperationOutcome.OperationType = Enum.RestEnum.CrudOperationType.Create; return(false); } IPyroFhirUri ResourceIdToForce = IPyroFhirUriFactory.CreateFhirRequestUri(); if (String.IsNullOrEmpty(PostEntry.FullUrl)) { //Assgin a new GUID as there is not FullURL GUID to lookup from refererancing ResourceIdToForce.Parse($"{PostEntry.Resource.TypeName}/{Common.Tools.FhirGuid.FhirGuid.NewFhirGuid()}"); } else { //Use the new Resource id that we assigned when updating all referances by looking it up in the GetUUIDfromFullURL dic ResourceIdToForce.Parse(OldNewResourceReferanceMap[GetUUIDfromFullURL(PostEntry.FullUrl)]); } //Remove the Resource Id in the resource as this is a POST and no id should be present in the resource, we do force the new id given this is a transaction operation if (!String.IsNullOrEmpty(PostEntry.Resource.Id)) { PostEntry.Resource.Id = String.Empty; } IResourceServiceOutcome ResourceServiceOutcome = IResourceServices.Post(PostEntry.Resource, RequestMeta, ResourceIdToForce.ResourceId); if (ResourceServiceOutcome.SuccessfulTransaction) { PostEntry.FullUrl = CreateFullUrl(ResourceServiceOutcome); PostEntry.Response = new Bundle.ResponseComponent(); PostEntry.Response.Status = FormatHTTPStatusCodeAsString(ResourceServiceOutcome.HttpStatusCode); if (ResourceServiceOutcome.ResourceResult != null) { if (ResourceServiceOutcome.ResourceResult.ResourceType == ResourceType.OperationOutcome) { PostEntry.Response.Outcome = ResourceServiceOutcome.ResourceResult; } else { PostEntry.Resource = ResourceServiceOutcome.ResourceResult; } } if (ResourceServiceOutcome.LastModified != null) { PostEntry.Response.Etag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber).ToString(); PostEntry.Response.LastModified = ResourceServiceOutcome.LastModified; } PostEntry.Response.Status = $"{((int)ResourceServiceOutcome.HttpStatusCode).ToString()} {ResourceServiceOutcome.HttpStatusCode.ToString()}"; PostEntry.Response.Location = FormatResponseLocation(ResourceServiceOutcome.RequestUri.OriginalString, ResourceServiceOutcome.FhirResourceId, ResourceServiceOutcome.ResourceVersionNumber); return(true); } else { if (ResourceServiceOutcome.ResourceResult != null && ResourceServiceOutcome.ResourceResult is OperationOutcome Op) { IdentifieBatchEntityToClient(Op, PostEntry.FullUrl, "POST", PostEntryIndex); } _ServiceOperationOutcome = ResourceServiceOutcome; return(false); } }
public static HttpResponseMessage GetHttpResponseMessage(IResourceServiceOutcome ResourceServiceOutcome, HttpRequestMessage Request, Hl7.Fhir.Rest.SummaryType?SummaryType) { HttpStatusCode HttpStatusCode = ResourceServiceOutcome.HttpStatusCode; Resource Resource = ResourceServiceOutcome.ResourceResult; Pyro.Common.Formatters.FhirMediaTypeFormatter FhirMediaTypeFormatter = null; HttpResponseMessage Response = Request.CreateResponse(HttpStatusCode); if (Resource != null) { if (ResourceServiceOutcome.FormatMimeType == null) { Response = Request.CreateResponse(HttpStatusCode, Resource); } else { Pyro.Common.Formatters.FhirMediaTypeFormatter Formater = GetFhirMediaFormatter(Request, ResourceServiceOutcome.FormatMimeType); if (Formater != null) { FhirMediaTypeFormatter = Formater; Response = new HttpResponseMessage(HttpStatusCode); Response.Content = new ObjectContent(typeof(Resource), Resource, Formater); } else { Response = Request.CreateResponse(HttpStatusCode, Resource); } } //Annotate the Resource with the _summary, will get the annotation in MediaTypeFormatter XML or JSON if (Resource is Hl7.Fhir.Utility.IAnnotatable AnnotatableResource) { if (SummaryType.HasValue) { AnnotatableResource.AddAnnotation(SummaryType.Value); } else { AnnotatableResource.AddAnnotation(Hl7.Fhir.Rest.SummaryType.False); } } } //OK: 200 if (HttpStatusCode == HttpStatusCode.OK) { if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Read) { //LastModified Header & ETagVersion &Location Header if (ResourceServiceOutcome.LastModified.HasValue) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); if (Response.Content != null && ResourceServiceOutcome.IsDeleted.HasValue && !ResourceServiceOutcome.IsDeleted.Value) { Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri); } return(Response); } else if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Update) { //Location Header if (Response.Content != null) { Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri); } //LastModified Header && ETagVersion if (ResourceServiceOutcome.LastModified.HasValue) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } return(Response); } else if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Delete && ResourceServiceOutcome.ResourceVersionNumber != null) { //LastModified Header && ETag Version if (ResourceServiceOutcome.LastModified != null) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } return(Response); } else if (ResourceServiceOutcome.OperationType == RestEnum.CrudOperationType.Create) { //LastModified Header && ETag Version if (ResourceServiceOutcome.LastModified != null) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); //If we have a conditional Create where the Resource is found then we return OK but no Resource so no Content if (Response.Content != null) { Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } } return(Response); } else { var oIssueComponent = new OperationOutcome.IssueComponent(); oIssueComponent.Severity = OperationOutcome.IssueSeverity.Fatal; oIssueComponent.Code = OperationOutcome.IssueType.Exception; oIssueComponent.Diagnostics = "Internal Error. FhirRestResponse contains no FHIR Resource or Id."; var oOperationOutcome = new OperationOutcome(); oOperationOutcome.Issue = new List <OperationOutcome.IssueComponent>() { oIssueComponent }; throw new PyroException(HttpStatusCode.InternalServerError, oOperationOutcome, "Internal Error. FhirRestResponse contains no FHIR Resource or Id."); } } //Created: 201 else if (HttpStatusCode == HttpStatusCode.Created) { //Location Header if (Response.Content != null) { Response.Headers.Location = HttpHeaderSupport.AddResponseLocation(Request.RequestUri, ResourceServiceOutcome.FhirResourceId); } //LastModified Header && ETagVersion if (ResourceServiceOutcome.LastModified.HasValue) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } return(Response); } //Gone: 410 - Search for a resource that no longer there, it is deleted or has never existed. else if (HttpStatusCode == HttpStatusCode.Gone) { //LastModified Header && ETagVersion if (ResourceServiceOutcome.LastModified.HasValue) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); //Support.HttpHeaderSupport.AddLastModified(Response, oPyroServiceOperationOutcome.LastModified.Value); } return(Response); } //No Content: 204 else if (HttpStatusCode == HttpStatusCode.NoContent) { //LastModified Header && ETagVersion if (ResourceServiceOutcome.LastModified.HasValue) { Response.Headers.ETag = HttpHeaderSupport.GetEntityTagHeaderValueFromVersion(ResourceServiceOutcome.ResourceVersionNumber); if (Response.Content != null) { Response.Content.Headers.LastModified = ResourceServiceOutcome.LastModified; } } return(Response); } else if (HttpStatusCode == System.Net.HttpStatusCode.NotFound) { //No need to process _format as not returning a body of type resource return(Response); } else if (HttpStatusCode == System.Net.HttpStatusCode.PreconditionFailed) { return(Response); } else if (HttpStatusCode == System.Net.HttpStatusCode.NotModified) { return(Response); } //Forbidden: 403..and others else { if (Resource != null) { return(Response); } else { var OpOutComeIssueComp = new OperationOutcome.IssueComponent(); OpOutComeIssueComp.Severity = OperationOutcome.IssueSeverity.Fatal; OpOutComeIssueComp.Code = OperationOutcome.IssueType.Exception; OpOutComeIssueComp.Diagnostics = "Internal Server Error: An unexpected HttpStatusCode has been encountered with a null resource to return. This is most likely a server bug."; var OpOutCome = new OperationOutcome(); OpOutCome.Issue.Add(OpOutComeIssueComp); FhirOperationOutcomeSupport.EscapeOperationOutComeContent(OpOutCome); if (FhirMediaTypeFormatter != null) { Response.Content = new ObjectContent(typeof(Resource), OpOutCome, FhirMediaTypeFormatter); } else { Response = Request.CreateResponse(HttpStatusCode, OpOutCome); } return(Response); } } }