use of org.cdshooks.CdsRequest in project CRD by HL7-DaVinci.
the class QueryBatchRequest method performQueryBatchRequest.
/**
* Backfills the missing required values of the response that prefetch may have missed.
* This implementation pulls the IDs of the required references from the request object's draft
* orders, checks which of those values are missing from the current CRD response, builds the
* Query Batch JSON request using
* http://build.fhir.org/ig/HL7/davinci-crd/hooks.html#fhir-resource-access,
* then populates the CRD response with the response from the Query Batch.
*/
public void performQueryBatchRequest(CdsRequest<?, ?> cdsRequest, CrdPrefetch crdPrefetch) {
logger.info("***** ***** Performing Query Batch Request.");
CrdPrefetch crdResponse = crdPrefetch;
// The list of references that should be queried in the batch request.
List<String> requiredReferences = new ArrayList<String>();
// Get the IDs of references in the request's draft orders.
Bundle draftOrdersBundle = cdsRequest.getContext().getDraftOrders();
// This assumes that only the first draft order is relevant.
Resource initialRequestResource = draftOrdersBundle.getEntry().get(0).getResource();
ResourceType requestType = initialRequestResource.getResourceType();
// Extract the references by iterating through the JSON.
Gson gson = new Gson();
final JsonObject jsonObject = gson.toJsonTree(initialRequestResource).getAsJsonObject();
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
FhirRequestProcessor.extractReferenceIds(requiredReferences, entry.getValue());
}
// Filter out references that already exist in the CRD Response.
requiredReferences = requiredReferences.stream().filter(referenceId -> !crdResponse.containsRequestResourceId(referenceId)).collect(Collectors.toList());
logger.info("References to query: " + requiredReferences);
if (requiredReferences.isEmpty()) {
logger.info("A Query Batch Request is not needed: all references have already already fetched.");
return;
}
// Build the Query Batch Request JSON.
Bundle queryBatchRequestBundle = buildQueryBatchRequestBundle(requiredReferences);
String queryBatchRequestBody = FhirContext.forR4().newJsonParser().encodeResourceToString(queryBatchRequestBundle);
// Make the query batch request to the EHR server.
Bundle queryResponseBundle = null;
try {
logger.info("Executing Query Batch Request: " + queryBatchRequestBody);
queryResponseBundle = (Bundle) FhirRequestProcessor.executeFhirQueryBody(queryBatchRequestBody, cdsRequest, this.fhirComponents, HttpMethod.POST);
queryResponseBundle = extractNestedBundledResources(queryResponseBundle);
logger.info("Extracted Query Batch Resources: " + (queryResponseBundle).getEntry().stream().map(entry -> entry.getResource()).collect(Collectors.toList()));
} catch (Exception e) {
logger.error("Failed to backfill prefetch with Query Batch Request " + queryBatchRequestBody, e);
}
if (queryResponseBundle == null) {
logger.error("No response recieved from the Query Batch Request.");
return;
}
// Add the request resource to the query batch response as it may be missing.
// Coverage and Subject are not automatically being
// linked to the request object. It seems to somehow automatically link during
// standard prefetch, but not here so we're doing it manually.
List<Coverage> coverages = FhirRequestProcessor.extractCoverageFromBundle(queryResponseBundle);
List<Patient> patients = FhirRequestProcessor.extractPatientsFromBundle(queryResponseBundle);
FhirRequestProcessor.addInsuranceAndSubject(initialRequestResource, patients, coverages);
BundleEntryComponent newEntry = new BundleEntryComponent();
newEntry.setResource(initialRequestResource);
queryResponseBundle.addEntry(newEntry);
// Add the query batch response resources to the CRD Prefetch request.
logger.info("Query Batch Response Entries: " + queryResponseBundle.getEntry());
FhirRequestProcessor.addToCrdPrefetchRequest(crdResponse, requestType, queryResponseBundle.getEntry());
logger.info("Post-Query Batch CRDResponse: " + crdResponse);
}
Aggregations