private async Task RetrieveViaDicomWeb(InferenceRequest inferenceRequest, RequestInputDataResource source, Dictionary <string, InstanceStorageInfo> retrievedInstance) { Guard.Against.Null(inferenceRequest, nameof(inferenceRequest)); Guard.Against.Null(retrievedInstance, nameof(retrievedInstance)); var authenticationHeaderValue = GenerateAuthenticationHeader(source.ConnectionDetails.AuthType, source.ConnectionDetails.AuthId); var dicomWebClient = _dicomWebClientFactory.CreateDicomWebClient( new Uri(source.ConnectionDetails.Uri), authenticationHeaderValue, null, null, null, null); switch (inferenceRequest.InputMetadata.Details.Type) { case InferenceRequestType.DicomUid: await RetrieveStudies(inferenceRequest.InputMetadata.Details.Studies, inferenceRequest.StoragePath, dicomWebClient, retrievedInstance); break; default: throw new InferenceRequestException($"The 'inputMetadata' type '{inferenceRequest.InputMetadata.Details.Type}' specified is not supported."); } }
private async Task RetrieveViaFhir(InferenceRequest inferenceRequest, RequestInputDataResource source, Dictionary <string, string> retrievedResources) { Guard.Against.Null(inferenceRequest, nameof(inferenceRequest)); Guard.Against.Null(retrievedResources, nameof(retrievedResources)); foreach (var input in inferenceRequest.InputMetadata.Inputs) { if (input.Resources.IsNullOrEmpty()) { continue; } await RetrieveFhirResources(input, source, retrievedResources, _fileSystem.Path.GetFhirStoragePath(inferenceRequest.StoragePath)); } }
private async Task RetrieveViaDicomWeb(InferenceRequest inferenceRequest, RequestInputDataResource source, Dictionary <string, InstanceStorageInfo> retrievedInstance) { Guard.Against.Null(inferenceRequest, nameof(inferenceRequest)); Guard.Against.Null(retrievedInstance, nameof(retrievedInstance)); var authenticationHeaderValue = AuthenticationHeaderValueExtensions.ConvertFrom(source.ConnectionDetails.AuthType, source.ConnectionDetails.AuthId); var dicomWebClient = new DicomWebClient(_httpClientFactory.CreateClient("dicomweb"), _loggerFactory.CreateLogger <DicomWebClient>()); dicomWebClient.ConfigureServiceUris(new Uri(source.ConnectionDetails.Uri, UriKind.Absolute)); if (!(authenticationHeaderValue is null)) { dicomWebClient.ConfigureAuthentication(authenticationHeaderValue); } foreach (var input in inferenceRequest.InputMetadata.Inputs) { switch (input.Type) { case InferenceRequestType.DicomUid: await RetrieveStudies(dicomWebClient, input.Studies, _fileSystem.Path.GetDicomStoragePath(inferenceRequest.StoragePath), retrievedInstance); break; case InferenceRequestType.DicomPatientId: await QueryStudies(dicomWebClient, inferenceRequest, retrievedInstance, $"{DicomTag.PatientID.Group:X4}{DicomTag.PatientID.Element:X4}", input.PatientId); break; case InferenceRequestType.AccessionNumber: foreach (var accessionNumber in input.AccessionNumber) { await QueryStudies(dicomWebClient, inferenceRequest, retrievedInstance, $"{DicomTag.AccessionNumber.Group:X4}{DicomTag.AccessionNumber.Element:X4}", accessionNumber); } break; case InferenceRequestType.FhireResource: continue; default: throw new InferenceRequestException($"The 'inputMetadata' type '{input.Type}' specified is not supported."); } } }
private async Task <bool> RetrieveFhirResource(HttpClient httpClient, FhirResource resource, RequestInputDataResource source, Dictionary <string, string> retrievedResources, string storagePath, FhirStorageFormat fhirFormat, string acceptHeader) { Guard.Against.Null(httpClient, nameof(httpClient)); Guard.Against.Null(resource, nameof(resource)); Guard.Against.Null(source, nameof(source)); Guard.Against.Null(retrievedResources, nameof(retrievedResources)); Guard.Against.NullOrWhiteSpace(storagePath, nameof(storagePath)); Guard.Against.NullOrWhiteSpace(acceptHeader, nameof(acceptHeader)); _logger.Log(LogLevel.Debug, $"Retriving FHIR resource {resource.Type}/{resource.Id} with media format {acceptHeader} and file format {fhirFormat}."); var request = new HttpRequestMessage(HttpMethod.Get, $"{source.ConnectionDetails.Uri}{resource.Type}/{resource.Id}"); request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse(acceptHeader)); var response = await Policy .HandleResult <HttpResponseMessage>(p => !p.IsSuccessStatusCode) .WaitAndRetryAsync(3, (retryAttempt) => { return(retryAttempt == 1 ? TimeSpan.FromMilliseconds(250) : TimeSpan.FromMilliseconds(500)); }, (result, timeSpan, retryCount, context) => { _logger.Log(LogLevel.Error, result.Exception, $"Failed to retrieve resource {resource.Type}/{resource.Id} with status code {result.Result.StatusCode}, retry count={retryCount}."); }) .ExecuteAsync(async() => await httpClient.SendAsync(request)); if (response.IsSuccessStatusCode) { var json = await response.Content.ReadAsStringAsync(); var filename = _fileSystem.Path.Combine(storagePath, $"{resource.Type}-{resource.Id}.{fhirFormat}".ToLowerInvariant()); await _fileSystem.File.WriteAllTextAsync(filename, json); retrievedResources.Add(_fileSystem.Path.GetFileName(filename), filename); return(true); } else { _logger.Log(LogLevel.Error, $"Error retriving FHIR resource {resource.Type}/{resource.Id}. Recevied HTTP status code {response.StatusCode}."); return(false); } }
private async Task RetrieveFhirResources(InferenceRequestDetails requestDetails, RequestInputDataResource source, Dictionary <string, string> retrievedResources, string storagePath) { Guard.Against.Null(requestDetails, nameof(requestDetails)); Guard.Against.Null(source, nameof(source)); Guard.Against.Null(retrievedResources, nameof(retrievedResources)); Guard.Against.NullOrWhiteSpace(storagePath, nameof(storagePath)); var pendingResources = new Queue <FhirResource>(requestDetails.Resources.Where(p => !p.IsRetrieved)); if (pendingResources.Count == 0) { return; } var authenticationHeaderValue = AuthenticationHeaderValueExtensions.ConvertFrom(source.ConnectionDetails.AuthType, source.ConnectionDetails.AuthId); var httpClient = _httpClientFactory.CreateClient("fhir"); httpClient.DefaultRequestHeaders.Clear(); httpClient.DefaultRequestHeaders.Authorization = authenticationHeaderValue; _fileSystem.Directory.CreateDirectory(storagePath); FhirResource resource = null; try { while (pendingResources.Count > 0) { resource = pendingResources.Dequeue(); resource.IsRetrieved = await RetrieveFhirResource( httpClient, resource, source, retrievedResources, storagePath, requestDetails.FhirFormat, requestDetails.FhirAcceptHeader); } } catch (System.Exception ex) { _logger.Log(LogLevel.Error, ex, $"Error retrieving FHIR resource {resource?.Type}/{resource?.Id}"); } }