/// <summary>Process an HTTP GET in FHIR R5</summary> /// <param name="context"> [in,out] The context.</param> /// <param name="response">[in,out] The response.</param> internal static void ProcessGet(ref HttpContext context, ref HttpResponseMessage response) { // check for an ID string requestUrl = context.Request.Path; if (requestUrl.EndsWith('/')) { requestUrl = requestUrl.Substring(0, requestUrl.Length - 1); } string id = requestUrl.Substring(requestUrl.LastIndexOf('/') + 1); if (id.ToLowerInvariant() == "subscription") { ProcessorUtils.SerializeR5(ref response, SubscriptionManagerR5.GetSubscriptionsBundle()); } else if (SubscriptionManagerR5.TryGetSubscription(id, out Subscription foundSub)) { ProcessorUtils.SerializeR5(ref response, foundSub); } else { response.StatusCode = HttpStatusCode.NotFound; } }
/// <summary>Process the operation get ws binding token described by response.</summary> /// <param name="context"> [in,out] The context.</param> /// <param name="response"> [in,out] The response.</param> /// <param name="previousComponent">The previous component.</param> internal static void ProcessOperationGetWsBindingToken( ref HttpContext context, ref HttpResponseMessage response, string previousComponent) { List <string> ids = new List <string>(); if (previousComponent != "Subscription") { ids.Add(previousComponent); } else { try { using (TextReader reader = new StreamReader(context.Request.Body)) { string requestContent = reader.ReadToEnd(); Parameters opParams = _fhirParser.Parse <Parameters>(requestContent); foreach (Parameters.ParameterComponent param in opParams.Parameter) { if (param.Name == "ids") { ids.Add((param.Value as Id).ToString()); } } } } catch (Exception) { response.StatusCode = HttpStatusCode.BadRequest; return; } } foreach (string id in ids) { if (!SubscriptionManagerR5.Exists(id)) { response.StatusCode = HttpStatusCode.BadRequest; response.Content = new StringContent($"Invalid subscription id: {id}"); return; } } SubscriptionWsBindingToken token = SubscriptionWsBindingToken.GetTokenR5(ids); WebsocketManager.RegisterToken(token); Parameters parameters = new Parameters(); parameters.Add("token", new FhirString(token.Token.ToString())); parameters.Add("expiration", new FhirDateTime(new DateTimeOffset(token.ExpiresAt))); parameters.Add("subscriptions", new FhirString(string.Join(',', ids))); ProcessorUtils.SerializeR5(ref response, parameters); }
/// <summary>Process the operation status R5.</summary> /// <param name="context"> [in,out] The context.</param> /// <param name="response"> [in,out] The response.</param> /// <param name="previousComponent">The previous component.</param> internal static void ProcessOperationStatus( ref HttpContext context, ref HttpResponseMessage response, string previousComponent) { List <string> ids = new List <string>(); if (previousComponent != "Subscription") { ids.Add(previousComponent); } else { foreach (KeyValuePair <string, StringValues> query in context.Request.Query) { if (query.Key == "ids") { ids.AddRange(query.Value); } } } // create a bundle for this message message Bundle bundle = new Bundle() { Type = Bundle.BundleType.Searchset, Timestamp = new DateTimeOffset(DateTime.Now), Meta = new Meta(), Entry = new List <Bundle.EntryComponent>(), }; foreach (string id in ids) { if (SubscriptionManagerR5.TryGetSubscriptionStatus(id, out SubscriptionStatus status, 0, true)) { bundle.Entry.Add(new Bundle.EntryComponent() { FullUrl = Program.UrlForR5ResourceId(status.TypeName, status.Id), Resource = status, Search = new Bundle.SearchComponent() { Mode = Bundle.SearchEntryMode.Match, }, }); } } ProcessorUtils.SerializeR5(ref response, bundle); }
/// <summary>Process an R5 metadata GET.</summary> /// <param name="context"> [in,out] The context.</param> /// <param name="response">[in,out] The response.</param> private static void ProcessGet( ref HttpContext context, ref HttpResponseMessage response) { // check for a valid capability statement try { // grab the message body to look at string responseContent = response.Content.ReadAsStringAsync().Result; CapabilityStatement capabilities = _fhirParser.Parse <CapabilityStatement>(responseContent); if (capabilities.Software == null) { capabilities.Software = new CapabilityStatement.SoftwareComponent() { Name = $"Argo-Proxy: {Program.FhirServerUrlR5}", Version = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).FileVersion.ToString(), }; } else { capabilities.Software.Name = $"Argo-Proxy: {capabilities.Software.Name}"; capabilities.Software.Version = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).FileVersion.ToString() + ": " + capabilities.Software.Version; } capabilities.Implementation = new CapabilityStatement.ImplementationComponent() { Description = $"Argonaut Subscription Proxy to: {Program.FhirServerUrlR5}", Url = Program.PublicUrl, }; // only support application/fhir+json capabilities.Format = new string[] { "application/fhir+json" }; // make sure resources we need are present bool foundSubscription = false; bool foundSubscriptionTopic = false; bool foundWebSocketUrl = false; for (int restIndex = 0; restIndex < capabilities.Rest.Count; restIndex++) { for (int resourceIndex = 0; resourceIndex < capabilities.Rest[restIndex].Resource.Count; resourceIndex++) { switch (capabilities.Rest[restIndex].Resource[resourceIndex].TypeName) { case "Subscription": foundSubscription = true; capabilities.Rest[restIndex].Resource[resourceIndex] = BuildSubscriptionResourceComponent(); break; case "SubscriptionTopic": foundSubscriptionTopic = true; capabilities.Rest[restIndex].Resource[resourceIndex] = BuildSubscriptionTopicResourceComponent(); break; } } if (capabilities.Rest[restIndex].Extension != null) { for (int extIndex = 0; extIndex < capabilities.Rest[restIndex].Extension.Count; extIndex++) { if (capabilities.Rest[restIndex].Extension[extIndex].Url == ExtensionCapabilityWebsocket) { foundWebSocketUrl = true; capabilities.Rest[restIndex].Extension[extIndex].Value = new Hl7.Fhir.Model.FhirUri(Program.WebsocketUrl); } } } } if (!foundSubscription) { capabilities.Rest[0].Resource.Add(BuildSubscriptionResourceComponent()); } if (!foundSubscriptionTopic) { capabilities.Rest[0].Resource.Add(BuildSubscriptionTopicResourceComponent()); } if (!foundWebSocketUrl) { if (capabilities.Rest[0].Extension == null) { capabilities.Rest[0].Extension = new System.Collections.Generic.List <Hl7.Fhir.Model.Extension>(); } capabilities.Rest[0].Extension.Add(new Hl7.Fhir.Model.Extension() { Url = ExtensionCapabilityWebsocket, Value = new Hl7.Fhir.Model.FhirUri(Program.WebsocketUrl), }); } // serialize and return ProcessorUtils.SerializeR5(ref response, capabilities); } catch (Exception ex) { // write to console Console.WriteLine($"Failed to parse capability statement, {ex.Message}"); } }
/// <summary>Process the get.</summary> /// <param name="context"> [in,out] The context.</param> /// <param name="response">[in,out] The response message.</param> internal static void ProcessGet(ref HttpContext context, ref HttpResponseMessage response) { ProcessorUtils.SerializeR5(ref response, SubscriptionTopicManager.GetTopicsBundle()); }