public static async IAsyncEnumerable <T> GetAll <T>( this FhirClient client, string url, [EnumeratorCancellation] CancellationToken cancellationToken = default) where T : Resource { var allResources = await client.GetAsync(url).ConfigureAwait(false) as Bundle; foreach (var resource in allResources.GetResources().OfType <T>()) { cancellationToken.ThrowIfCancellationRequested(); yield return(resource); } while (allResources != null && allResources.NextLink != null) { cancellationToken.ThrowIfCancellationRequested(); allResources = await client.ContinueAsync(allResources).ConfigureAwait(false); if (allResources == null) { yield break; } foreach (var resource in allResources.GetResources().OfType <T>()) { yield return(resource); } } }
public static async Task <IEnumerable <TResource> > GetWithContinuationAsync <TResource>(this FhirClient fhirClient, Uri resourceUri, int?count = null) where TResource : Resource { EnsureArg.IsNotNull(fhirClient, nameof(fhirClient)); var result = await fhirClient.GetAsync(resourceUri).ConfigureAwait(false) as Bundle; return(await result.ReadFromBundleWithContinuationAsync <TResource>(fhirClient, count).ConfigureAwait(false)); }
public async Task <ActionResult <string> > GetPsPatient() { FhirClient fhirClient = await _client.ConfigureClient(); try { Resource patient = await fhirClient.GetAsync("/Patient"); return(patient.ToJson()); } catch (Exception exception) { return(OperationOutcome.ForException(exception, OperationOutcome.IssueType.Processing, OperationOutcome.IssueSeverity.Fatal).ToJson()); } }
public async Task VerifyServerMetaInfoForEverythingOperation() { string baseURL = "http://localhost:4080"; // Send metaprofile request to server to verify that the metadata contains the Patient-everywhere operation var client = new FhirClient(baseURL); client.PreferredFormat = ResourceFormat.Json; client.UseFormatParam = true; // Read the Vonk server's metadata (NOT working!! - getting error: // System.NotSupportedException : Cannot read the conformance statement of the server to verify FHIR version compatibility //var capabilityStatement = await client.CapabilityStatementAsync(); string metadata = $"{baseURL}/metadata"; var capabilityStatement = await client.GetAsync(metadata); // Now checke that the "Patient-everything" operation is there var everythigOperation = capabilityStatement.ToJObject(); }
public async Task <JObject> GetAsync( string url, EventHandler <BeforeRequestEventArgs> onBefore = null, EventHandler <AfterResponseEventArgs> onAfter = null ) { // setup TLS and SSL (moved to static constructor) ServicePointManager.ServerCertificateValidationCallback = (message, cert, chain, errors) => (errors == System.Net.Security.SslPolicyErrors.None) || reIsASEEndpoint.IsMatch(_endpoint); ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // use using(s) to handle disposing of objects. Needs more research. using (var op = _client.StartOperation <DependencyTelemetry>("Dependency Name")) using (FhirClient fhirClient = new FhirClient(_endpoint) { PreferredFormat = ResourceFormat.Json, UseFormatParam = true }) { var dep = op.Telemetry; dep.SetLogLocation(); // location is not really the most accurate metric but has been helpful before dep.Type = "GET"; // type will always be a get // request ID is used for linking logging in dependencies to this call var requestId = RandomID(15); dep.Id = requestId; // stopwatch for logging duration. Stopwatch sw = new Stopwatch(); // add dependency logging, blob logging, etc. fhirClient.OnBeforeRequest += delegate(object sender, BeforeRequestEventArgs e) { // add client information and "helpful" headers e.RawRequest.ClientCertificates.Add(_certificate); e.RawRequest.Timeout = _timeout; e.RawRequest.Headers.SetLinkingHeaders(requestId, RandomID(12)); sw.Start(); }; fhirClient.OnAfterResponse += delegate(object sender, AfterResponseEventArgs e) { sw.Stop(); // log generic response inforation dep.Duration = sw.Elapsed; dep.ResultCode = e.RawResponse.StatusCode.ToString(); dep.Success = e.RawResponse.StatusCode.IsSuccessful(); // ToDo: log response to blob storage }; // add user defined before and after actions if (onBefore != null) { fhirClient.OnBeforeRequest += onBefore; } if (onAfter != null) { fhirClient.OnAfterResponse += onAfter; } // invoke fhir url. if error occurs, cast exception to operation outcome try { Resource resp = await fhirClient.GetAsync(url); return(resp.ToJObject()); } catch (Exception ex) { _client.TrackException(ex); return(OperationOutcome.ForException( ex, OperationOutcome.IssueType.Processing, OperationOutcome.IssueSeverity.Fatal ).ToJObject()); } } }
public override async Tasks.Task <OperationResultEnum> Execute() { FhirJsonSerializer serializer = new FhirJsonSerializer(); FhirClient sourceClient = new FhirClient(_arguments.SourceEnvironment.FhirBaseUrl) { Settings = new FhirClientSettings { ParserSettings = new Hl7.Fhir.Serialization.ParserSettings { PermissiveParsing = false } } }; HttpClient destClient = new HttpClient() { BaseAddress = new Uri(_arguments.DestinationEnvironment.FhirBaseUrl), }; string relativeUrl = $"{_arguments.ResourceType.GetLiteral()}"; if (_arguments.SearchCount > 0) { relativeUrl += $"?_count={_arguments.SearchCount}"; } Bundle sourceBundle = await sourceClient.GetAsync(relativeUrl) as Bundle; foreach (Bundle.EntryComponent entry in sourceBundle.Entry) { Resource resource = entry.Resource; string resourceType = resource.ResourceType(FhirVersion.R3).GetLiteral(); if (resource is Questionnaire questionnaire) { // This part gets rid of some legacy // TODO: Remove when we have gotten rid of the legacy if (string.IsNullOrWhiteSpace(questionnaire.ApprovalDate)) { questionnaire.ApprovalDate = null; } if (string.IsNullOrWhiteSpace(questionnaire.LastReviewDate)) { questionnaire.LastReviewDate = null; } if (questionnaire.Copyright != null && string.IsNullOrWhiteSpace(questionnaire.Copyright.Value)) { questionnaire.Copyright = null; } // Update known properties and extensions with urls that points to the old source instance. // TODO: The lines referring FhirBaseUrl is legacy and can be removed in a future version. questionnaire.Url = questionnaire.Url.Replace(_arguments.SourceEnvironment.ProxyBaseUrl, string.Empty); questionnaire.Url = questionnaire.Url.Replace(_arguments.SourceEnvironment.FhirBaseUrl, string.Empty); IEnumerable <Extension> extensions = questionnaire.GetExtensions(Constants.EndPointUri); foreach (Extension extension in extensions) { if (extension.Value is ResourceReference v) { v.Reference = v.Reference.Replace(_arguments.SourceEnvironment.ProxyBaseUrl, string.Empty); v.Reference = v.Reference.Replace(_arguments.SourceEnvironment.FhirBaseUrl, string.Empty); } } extensions = questionnaire.GetExtensions(Constants.OptionReferenceUri); foreach (Extension extension in extensions) { if (extension.Value is ResourceReference v) { v.Reference = v.Reference.Replace(_arguments.SourceEnvironment.ProxyBaseUrl, string.Empty); v.Reference = v.Reference.Replace(_arguments.SourceEnvironment.FhirBaseUrl, string.Empty); } } } _logger.LogInformation($"Preparing to write resource of type '{resourceType}' to '{_arguments.DestinationEnvironment.FhirBaseUrl}'"); HttpContent content = new StringContent(serializer.SerializeToString(resource)); content.Headers.ContentType = new MediaTypeHeaderValue("application/fhir+json"); HttpResponseMessage response; if (string.IsNullOrWhiteSpace(resource.Id)) { response = await destClient.PostAsync($"{resource.ResourceType(FhirVersion.R3).GetLiteral()}", content); } else { response = await destClient.PutAsync($"{resource.ResourceType(FhirVersion.R3).GetLiteral()}/{resource.Id}", content); } _logger.LogInformation($"{response.StatusCode} - {response.RequestMessage.Method} {response.RequestMessage.RequestUri}"); } return(_issues.Any(issue => issue.Severity == IssueSeverityEnum.Error) ? OperationResultEnum.Failed : OperationResultEnum.Succeeded); }