public Task <Bundle> SystemHistory(ModelBaseInputs request, DateTimeOffset?since, DateTimeOffset?Till, int?Count, SummaryType summary) { Bundle result = new Bundle(); result.Meta = new Meta(); result.Meta.LastUpdated = DateTime.Now; result.Id = new Uri("urn:uuid:" + Guid.NewGuid().ToString("n")).OriginalString; result.Type = Bundle.BundleType.History; var parser = new Fhir.Serialization.FhirXmlParser(); var files = System.IO.Directory.EnumerateFiles(DirectorySystemService.Directory); foreach (var filename in files) { var resource = parser.Parse <Resource>(System.IO.File.ReadAllText(filename)); result.AddResourceEntry(resource, ResourceIdentity.Build(request.BaseUri, resource.ResourceType.ToString(), resource.Id, resource.Meta.VersionId).OriginalString); } result.Total = result.Entry.Count; // also need to set the page links return(System.Threading.Tasks.Task.FromResult(result)); }
public CapabilityStatement GetConformance(ModelBaseInputs request, SummaryType summary) { CapabilityStatement con = new CapabilityStatement { Url = request.BaseUri + "metadata", Description = new Markdown("CDR based FHIR server"), DateElement = new Hl7.Fhir.Model.FhirDateTime("2017-04-30"), Version = "1.0.0.0", Name = "CDR FHIR API", Experimental = true, Status = PublicationStatus.Active, FhirVersion = Hl7.Fhir.Model.ModelInfo.Version, AcceptUnknown = CapabilityStatement.UnknownContentCode.Extensions, Format = new string[] { "xml", "json" }, Kind = CapabilityStatement.CapabilityStatementKind.Instance, Meta = new Meta() }; con.Meta.LastUpdatedElement = Instant.Now(); con.Rest = new List <CapabilityStatement.RestComponent>() { new CapabilityStatement.RestComponent { Mode = CapabilityStatement.RestfulCapabilityMode.Server, Resource = new List <CapabilityStatement.ResourceComponent>(), Operation = new List <CapabilityStatement.OperationComponent>(), Security = new CapabilityStatement.SecurityComponent { Extension = new List <Extension>() { new Extension() { Url = "http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris", Extension = new List <Extension>() { new Extension { Url = "token", Value = new FhirString("https://teams-fhir-auth.dapasoft.com/connect/token") }, new Extension { Url = "authorize", Value = new FhirString("https://teams-fhir-auth.dapasoft.com/connect/authorize") } } } } } } }; //foreach (var model in ModelFactory.GetAllModels(GetInputs(buri))) //{ // con.Rest[0].Resource.Add(model.GetRestResourceComponent()); //} return(con); }
public IFhirResourceServiceSTU3 GetResourceService(ModelBaseInputs request, string resourceName) { switch (resourceName.ToUpper()) { case "PATIENT": return(new PatientService() { RequestDetails = request, ResourceName = resourceName }); case "OBSERVATION": return(new ObservationService() { RequestDetails = request, ResourceName = resourceName }); case "ALLERGYINTOLERANCE": return(new AllergyIntoleranceService() { RequestDetails = request, ResourceName = resourceName }); case "ENCOUNTER": return(new EncounterService() { RequestDetails = request, ResourceName = resourceName }); case "COVERAGE": return(new CoverageService() { RequestDetails = request, ResourceName = resourceName }); case "CONDITION": return(new ConditionService() { RequestDetails = request, ResourceName = resourceName }); case "MEDICATIONREQUEST": return(new MedicationRequestService() { RequestDetails = request, ResourceName = resourceName }); } throw new Exception("Resource not found"); }
public IFhirResourceServiceSTU3 GetResourceService(ModelBaseInputs request, string resourceName) { if (string.Compare(resourceName, "endpoint", true) == 0) { if (request.RequestUri.Query.Contains("administer-federation")) { return(new DirectoryResourceService() { RequestDetails = request, ResourceName = resourceName }); } } return(new FederatedResourceService(Members()) { RequestDetails = request, ResourceName = resourceName }); }
public Bundle SystemHistory(ModelBaseInputs request, DateTimeOffset?since, DateTimeOffset?Till, int?Count, SummaryType summary) { throw new NotImplementedException(); }
public Bundle Search(ModelBaseInputs request, IEnumerable <KeyValuePair <string, string> > parameters, int?Count, SummaryType summary) { throw new NotImplementedException(); }
public Bundle ProcessBatch(ModelBaseInputs request, Bundle bundle) { throw new NotImplementedException(); }
public Resource PerformOperation(ModelBaseInputs request, string operation, Parameters operationParameters, SummaryType summary) { throw new NotImplementedException(); }
// Process request and craft response. public override CefReturnValue ProcessRequestAsync(IRequest request, ICallback callback) { if (request.Method == "OPTIONS") { // This is the CORS request, and that's good base.StatusCode = 200; // base.Headers.Add("Access-Control-Allow-Origin", "*"); base.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,OPTIONS"); base.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept, authorization"); callback.Continue(); return(CefReturnValue.Continue); } var uri = new Uri(request.Url); Console.WriteLine($"-----------------\r\n{request.Url}"); // Check the bearer header if (!string.IsNullOrEmpty(_launchContext.Bearer)) { string bearer = request.GetHeaderByName("authorization"); if (bearer != "Bearer " + _launchContext.Bearer) { base.StatusCode = (int)HttpStatusCode.Unauthorized; callback.Continue(); return(CefReturnValue.Continue); } } try { // This is a regular request Hl7.Fhir.Rest.FhirClient server = new Hl7.Fhir.Rest.FhirClient("http://localhost:4178"); server.OnAfterResponse += (sender, args) => { base.Charset = args.RawResponse.CharacterSet; foreach (string header in args.RawResponse.Headers.AllKeys) { base.Headers.Add(header, args.RawResponse.Headers[header]); } }; server.PreferredFormat = Hl7.Fhir.Rest.ResourceFormat.Json; string redirectedUrl = server.Endpoint.OriginalString.TrimEnd('/') + uri.PathAndQuery; System.Diagnostics.Trace.WriteLine($"{redirectedUrl}"); var headers = new List <KeyValuePair <string, IEnumerable <string> > >(); ModelBaseInputs <IServiceProvider> requestDetails = new ModelBaseInputs <IServiceProvider>(null, null, request.Method, uri, new Uri($"https://{AuthProtocolSchemeHandlerFactory.FhirFacadeAddress(_launchContext)}"), null, headers, null); if (request.Method == "GET") { if (uri.LocalPath == "/metadata") { _facade.GetConformance(requestDetails, Rest.SummaryType.False).ContinueWith <CapabilityStatement>(r => { if (r.Exception != null) { System.Diagnostics.Trace.WriteLine($"Error: {r.Exception.Message}"); if (r.Exception.InnerException is Hl7.Fhir.Rest.FhirOperationException fe) { base.StatusCode = (int)fe.Status; if (fe.Outcome != null) { base.Stream = new MemoryStream(new Hl7.Fhir.Serialization.FhirJsonSerializer(new Hl7.Fhir.Serialization.SerializerSettings() { Pretty = true }).SerializeToBytes(fe.Outcome)); base.MimeType = "application/fhir+json"; } callback.Continue(); System.Diagnostics.Trace.WriteLine($"Error (inner): {fe.Message}"); return(null); } } base.StatusCode = 200; // As per the documentation http://hl7.org/fhir/smart-app-launch/conformance/index.html CapabilityStatement cs = r.Result; // Update the security node with our internal security node if (cs.Rest[0].Security == null) { cs.Rest[0].Security = new Hl7.Fhir.Model.CapabilityStatement.SecurityComponent(); } Hl7.Fhir.Model.CapabilityStatement.SecurityComponent security = cs.Rest[0].Security; if (!security.Service.Any(cc => cc.Coding.Any(c => c.System == "http://hl7.org/fhir/restful-security-service" && c.Code == "SMART-on-FHIR"))) { security.Service.Add(new Hl7.Fhir.Model.CodeableConcept("http://hl7.org/fhir/restful-security-service", "SMART-on-FHIR")); } var extension = security.GetExtension("http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris"); if (extension == null) { extension = new Extension() { Url = "http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris" }; security.Extension.Add(extension); } // remove the existing authentications, and put in our own extension.Extension.Clear(); extension.AddExtension("token", new FhirUri($"https://{AuthProtocolSchemeHandlerFactory.AuthAddress(_launchContext)}/token")); extension.AddExtension("authorize", new FhirUri($"https://{AuthProtocolSchemeHandlerFactory.AuthAddress(_launchContext)}/authorize")); base.Stream = new MemoryStream(new Hl7.Fhir.Serialization.FhirJsonSerializer(new Hl7.Fhir.Serialization.SerializerSettings() { Pretty = true }).SerializeToBytes(r.Result)); Console.WriteLine($"Success: {base.Stream.Length}"); base.MimeType = "application/fhir+json"; callback.Continue(); return(r.Result); }); return(CefReturnValue.ContinueAsync); } if (!uri.LocalPath.StartsWith("/$") && !uri.LocalPath.StartsWith("/_") && uri.LocalPath.Length > 2) { // This is not an operation or history, so it must be a resource type string resourceType = uri.LocalPath.Substring(1); if (resourceType.Contains("/")) { resourceType = resourceType.Substring(0, resourceType.IndexOf("/")); } var rs = _facade.GetResourceService(requestDetails, resourceType); if (rs == null) { System.Diagnostics.Trace.WriteLine($"Error: resource type not handled {resourceType}"); base.StatusCode = (int)HttpStatusCode.BadRequest; // base.Stream = new MemoryStream(new Hl7.Fhir.Serialization.FhirJsonSerializer(new Hl7.Fhir.Serialization.SerializerSettings() { Pretty = true }).SerializeToBytes(fe.Outcome)); // base.MimeType = "application/fhir+json"; callback.Continue(); return(CefReturnValue.Continue); } // GET for a specific resource ResourceIdentity ri = new ResourceIdentity(uri); if (ri.IsRestResourceIdentity()) { rs.Get(ri.Id, ri.VersionId, SummaryType.False).ContinueWith(r => { if (r.Exception != null) { System.Diagnostics.Trace.WriteLine($"Error: {r.Exception.Message}"); if (r.Exception.InnerException is Hl7.Fhir.Rest.FhirOperationException fe) { base.StatusCode = (int)fe.Status; if (fe.Outcome != null) { base.Stream = new MemoryStream(new Hl7.Fhir.Serialization.FhirJsonSerializer(new Hl7.Fhir.Serialization.SerializerSettings() { Pretty = true }).SerializeToBytes(fe.Outcome)); base.MimeType = "application/fhir+json"; } callback.Continue(); System.Diagnostics.Trace.WriteLine($"Error (inner): {fe.Message}"); return(null); } } if (r.Result.HasAnnotation <HttpStatusCode>()) { base.StatusCode = (int)r.Result.Annotation <HttpStatusCode>(); } else { base.StatusCode = 200; } base.Stream = new MemoryStream(new Hl7.Fhir.Serialization.FhirJsonSerializer(new Hl7.Fhir.Serialization.SerializerSettings() { Pretty = true }).SerializeToBytes(r.Result)); Console.WriteLine($"Success: {base.Stream.Length}"); base.MimeType = "application/fhir+json"; callback.Continue(); return(r.Result); }); return(CefReturnValue.ContinueAsync); } // Search for the resource type var parameters = TupledParameters(uri, SearchQueryParameterNames); int?pagesize = GetIntParameter(uri, FhirParameter.COUNT); var summary = GetSummaryParameter(uri); rs.Search(parameters, pagesize, summary).ContinueWith(r => { if (r.Exception != null) { System.Diagnostics.Trace.WriteLine($"Error: {r.Exception.Message}"); if (r.Exception.InnerException is Hl7.Fhir.Rest.FhirOperationException fe) { base.StatusCode = (int)fe.Status; if (fe.Outcome != null) { base.Stream = new MemoryStream(new Hl7.Fhir.Serialization.FhirJsonSerializer(new Hl7.Fhir.Serialization.SerializerSettings() { Pretty = true }).SerializeToBytes(fe.Outcome)); base.MimeType = "application/fhir+json"; } callback.Continue(); System.Diagnostics.Trace.WriteLine($"Error (inner): {fe.Message}"); return(null); } } if (r.Result.HasAnnotation <HttpStatusCode>()) { base.StatusCode = (int)r.Result.Annotation <HttpStatusCode>(); } else { base.StatusCode = 200; } base.Stream = new MemoryStream(new Hl7.Fhir.Serialization.FhirJsonSerializer(new Hl7.Fhir.Serialization.SerializerSettings() { Pretty = true }).SerializeToBytes(r.Result)); Console.WriteLine($"Success: {base.Stream.Length}"); base.MimeType = "application/fhir+json"; callback.Continue(); return(r.Result); }); return(CefReturnValue.ContinueAsync); } System.Threading.Tasks.Task <Hl7.Fhir.Model.Resource> t = server.GetAsync(redirectedUrl).ContinueWith <Hl7.Fhir.Model.Resource>(r => { if (r.Exception != null) { System.Diagnostics.Trace.WriteLine($"Error: {r.Exception.Message}"); if (r.Exception.InnerException is Hl7.Fhir.Rest.FhirOperationException fe) { base.StatusCode = (int)fe.Status; if (fe.Outcome != null) { base.Stream = new MemoryStream(new Hl7.Fhir.Serialization.FhirJsonSerializer(new Hl7.Fhir.Serialization.SerializerSettings() { Pretty = true }).SerializeToBytes(fe.Outcome)); base.MimeType = "application/fhir+json"; } callback.Continue(); System.Diagnostics.Trace.WriteLine($"Error (inner): {fe.Message}"); return(null); } } base.StatusCode = 200; if (r.Result is Hl7.Fhir.Model.CapabilityStatement cs) { // As per the documentation http://hl7.org/fhir/smart-app-launch/conformance/index.html // Update the security node with our internal security node if (cs.Rest[0].Security == null) { cs.Rest[0].Security = new Hl7.Fhir.Model.CapabilityStatement.SecurityComponent(); } Hl7.Fhir.Model.CapabilityStatement.SecurityComponent security = cs.Rest[0].Security; if (!security.Service.Any(cc => cc.Coding.Any(c => c.System == "http://hl7.org/fhir/restful-security-service" && c.Code == "SMART-on-FHIR"))) { security.Service.Add(new Hl7.Fhir.Model.CodeableConcept("http://hl7.org/fhir/restful-security-service", "SMART-on-FHIR")); } var extension = security.GetExtension("http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris"); if (extension == null) { extension = new Extension() { Url = "http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris" }; security.Extension.Add(extension); } // remove the existing authentications, and put in our own extension.Extension.Clear(); extension.AddExtension("token", new FhirUri($"https://{AuthProtocolSchemeHandlerFactory.AuthAddress(_launchContext)}/token")); extension.AddExtension("authorize", new FhirUri($"https://{AuthProtocolSchemeHandlerFactory.AuthAddress(_launchContext)}/authorize")); } base.Stream = new MemoryStream(new Hl7.Fhir.Serialization.FhirJsonSerializer(new Hl7.Fhir.Serialization.SerializerSettings() { Pretty = true }).SerializeToBytes(r.Result)); Console.WriteLine($"Success: {base.Stream.Length}"); base.MimeType = "application/fhir+json"; callback.Continue(); return(r.Result); }); } if (request.Method == "POST") { if (uri.LocalPath == "/") { Bundle b = null; if (request.PostData != null) { var data = request.PostData.Elements.FirstOrDefault(); var body = data.GetBody(); if (request.GetHeaderByName("Content-Type").Contains("xml")) { b = new Hl7.Fhir.Serialization.FhirXmlParser().Parse <Bundle>(body); } else { b = new Hl7.Fhir.Serialization.FhirJsonParser().Parse <Bundle>(body); } } _facade.ProcessBatch(requestDetails, b).ContinueWith(r => { if (r.Exception != null) { System.Diagnostics.Trace.WriteLine($"Error: {r.Exception.Message}"); if (r.Exception.InnerException is Hl7.Fhir.Rest.FhirOperationException fe) { base.StatusCode = (int)fe.Status; if (fe.Outcome != null) { base.Stream = new MemoryStream(new Hl7.Fhir.Serialization.FhirJsonSerializer(new Hl7.Fhir.Serialization.SerializerSettings() { Pretty = true }).SerializeToBytes(fe.Outcome)); base.MimeType = "application/fhir+json"; } callback.Continue(); System.Diagnostics.Trace.WriteLine($"Error (inner): {fe.Message}"); return(null); } } if (r.Result.HasAnnotation <HttpStatusCode>()) { base.StatusCode = (int)r.Result.Annotation <HttpStatusCode>(); } else { base.StatusCode = 200; } base.Stream = new MemoryStream(new Hl7.Fhir.Serialization.FhirJsonSerializer(new Hl7.Fhir.Serialization.SerializerSettings() { Pretty = true }).SerializeToBytes(r.Result)); Console.WriteLine($"Success: {base.Stream.Length}"); base.MimeType = "application/fhir+json"; callback.Continue(); return(r.Result); }); return(CefReturnValue.ContinueAsync); } System.Net.Http.HttpClient client = new System.Net.Http.HttpClient(); client.DefaultRequestHeaders.Add("Accept", request.GetHeaderByName("Accept")); // client.DefaultRequestHeaders.Add("Content-Type", request.GetHeaderByName("Content-Type")); HttpContent content = null; if (request.PostData != null) { var data = request.PostData.Elements.FirstOrDefault(); var body = data.GetBody(); content = new System.Net.Http.StringContent(body, System.Text.Encoding.UTF8, request.GetHeaderByName("Content-Type")); } else { content = new System.Net.Http.StreamContent(null); } client.PostAsync(redirectedUrl, content).ContinueWith((System.Threading.Tasks.Task <HttpResponseMessage> r) => { if (r.Exception != null) { Console.WriteLine($"Error: {r.Exception.Message}"); //if (r.Exception.InnerException is Hl7.Fhir.Rest.FhirOperationException fe) //{ // base.StatusCode = (int)fe.Status; // if (fe.Outcome != null) // base.Stream = new MemoryStream(r.Result.Content.ReadAsStringAsync().GetAwaiter().GetResult()); // callback.Continue(); // System.Diagnostics.Trace.WriteLine($"Error (inner): {fe.Message}"); // return; //} } base.StatusCode = (int)r.Result.StatusCode; base.Stream = r.Result.Content.ReadAsStreamAsync().GetAwaiter().GetResult(); Console.WriteLine($"Success: {base.Stream.Length}"); base.MimeType = r.Result.Content.Headers.ContentType.MediaType; callback.Continue(); return; }); } if (request.Method == "PUT") { System.Net.Http.HttpClient client = new System.Net.Http.HttpClient(); client.DefaultRequestHeaders.Add("Accept", request.GetHeaderByName("Accept")); // client.DefaultRequestHeaders.Add("Content-Type", request.GetHeaderByName("Content-Type")); HttpContent content = null; if (request.PostData != null) { var data = request.PostData.Elements.FirstOrDefault(); var body = data.GetBody(); content = new System.Net.Http.StringContent(body, System.Text.Encoding.UTF8, request.GetHeaderByName("Content-Type")); } else { content = new System.Net.Http.StreamContent(null); } client.PutAsync(redirectedUrl, content).ContinueWith((System.Threading.Tasks.Task <HttpResponseMessage> r) => { if (r.Exception != null) { Console.WriteLine($"Error: {r.Exception.Message}"); //if (r.Exception.InnerException is Hl7.Fhir.Rest.FhirOperationException fe) //{ // base.StatusCode = (int)fe.Status; // if (fe.Outcome != null) // base.Stream = new MemoryStream(r.Result.Content.ReadAsStringAsync().GetAwaiter().GetResult()); // callback.Continue(); // System.Diagnostics.Trace.WriteLine($"Error (inner): {fe.Message}"); // return; //} } base.StatusCode = (int)r.Result.StatusCode; base.Stream = r.Result.Content.ReadAsStreamAsync().GetAwaiter().GetResult(); Console.WriteLine($"Success: {base.Stream.Length}"); base.MimeType = r.Result.Content.Headers.ContentType.MediaType; callback.Continue(); return; }); } return(CefReturnValue.ContinueAsync); } catch (Exception ex) { Console.WriteLine($"{ex.Message}"); callback.Dispose(); return(CefReturnValue.Cancel); } }
public Task <CapabilityStatement> GetConformance(ModelBaseInputs request, SummaryType summary) { Hl7.Fhir.Model.CapabilityStatement con = new Hl7.Fhir.Model.CapabilityStatement(); con.Url = request.BaseUri + "metadata"; con.Description = new Markdown("Demonstration Directory based FHIR server"); con.DateElement = new Hl7.Fhir.Model.FhirDateTime("2017-04-30"); con.Version = "1.0.0.0"; con.Name = ""; con.Experimental = true; con.Status = PublicationStatus.Active; con.FhirVersion = Hl7.Fhir.Model.ModelInfo.Version; con.AcceptUnknown = CapabilityStatement.UnknownContentCode.Extensions; con.Format = new string[] { "xml", "json" }; con.Kind = CapabilityStatement.CapabilityStatementKind.Instance; con.Meta = new Meta(); con.Meta.LastUpdatedElement = Instant.Now(); con.Rest = new List <Hl7.Fhir.Model.CapabilityStatement.RestComponent> { new Hl7.Fhir.Model.CapabilityStatement.RestComponent() { Operation = new List <Hl7.Fhir.Model.CapabilityStatement.OperationComponent>() } }; con.Rest[0].Mode = CapabilityStatement.RestfulCapabilityMode.Server; con.Rest[0].Resource = new List <Hl7.Fhir.Model.CapabilityStatement.ResourceComponent>(); //foreach (var model in ModelFactory.GetAllModels(GetInputs(buri))) //{ // con.Rest[0].Resource.Add(model.GetRestResourceComponent()); //} foreach (var member in Members()) { try { // create a connection with the supported format type FhirClient server = new FhirClient(member.Url); member.PrepareFhirClientSecurity(server); System.Diagnostics.Trace.WriteLine($"Retrieving CapabilityStatement {member.Url} {member.Name}"); server.PreferCompressedResponses = true; server.PreferredFormat = member.Format; CapabilityStatement csMember = server.CapabilityStatement(); if (con.Rest[0].Resource.Count == 0) { // just clone all the resources from this one! // a great start foreach (var item in csMember.Rest?.FirstOrDefault()?.Resource) { item.AddExtension("http://example.org/Federation-member-name", new FhirString(member.Name)); con.Rest[0].Resource.Add(item); // remove the non supported actions item.ConditionalCreate = null; item.ConditionalUpdate = null; item.ConditionalDelete = null; item.UpdateCreate = null; if (item.Type != ResourceType.Endpoint) { item.Interaction.RemoveAll(i => i.Code == CapabilityStatement.TypeRestfulInteraction.Create || i.Code == CapabilityStatement.TypeRestfulInteraction.Update || i.Code == CapabilityStatement.TypeRestfulInteraction.Delete ); } } } else { // Tag all these with others foreach (var item in con.Rest?.FirstOrDefault()?.Resource) { if (csMember.Rest[0].Resource.Where(c => c.Type == item.Type).Any()) { item.AddExtension("http://example.org/Federation-member-name", new FhirString(member.Name)); } } } } catch (FhirOperationException ex) { System.Diagnostics.Trace.WriteLine(ex.Message); //if (ex.Outcome != null) // result.Entry.Add(new Bundle.EntryComponent() // { // Search = new Bundle.SearchComponent() { Mode = Bundle.SearchEntryMode.Outcome }, // Resource = ex.Outcome // }); } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.Message); //// some other weirdness went on //OperationOutcome oe = new OperationOutcome(); //oe.Issue.Add(new OperationOutcome.IssueComponent() //{ // Severity = OperationOutcome.IssueSeverity.Error, // Code = OperationOutcome.IssueType.Exception, // Diagnostics = ex.Message //}); //result.Entry.Add(new Bundle.EntryComponent() //{ // Search = new Bundle.SearchComponent() { Mode = Bundle.SearchEntryMode.Outcome }, // Resource = oe //}); } } return(System.Threading.Tasks.Task.FromResult(con)); }