use of org.hl7.elm.r1.VersionedIdentifier in project cqf-ruler by DBCG.
the class CqlExecutionProvider method evaluate.
/**
* Evaluates a CQL expression and returns the results as a Parameters resource.
*
* @param theRequestDetails the {@link RequestDetails RequestDetails}
* @param subject ***Only Patient is supported as of now*** Subject
* for which the expression will be
* evaluated. This corresponds to the context in
* which the expression will be evaluated and is
* represented as a relative FHIR id (e.g.
* Patient/123), which establishes both the context
* and context value for the evaluation
* @param expression Expression to be evaluated. Note that this is an
* expression of CQL, not the text of a library with
* definition statements.
* @param parameters Any input parameters for the expression.
* {@link Parameters} Parameters defined in this
* input will be made available by name to the CQL
* expression. Parameter types are mapped to CQL as
* specified in the Using CQL section of the CPG
* Implementation guide. If a parameter appears more
* than once in the input Parameters resource, it is
* represented with a List in the input CQL. If a
* parameter has parts, it is represented as a Tuple
* in the input CQL.
* @param library A library to be included. The {@link Library}
* library is resolved by url and made available by
* name within the expression to be evaluated.
* @param useServerData Whether to use data from the server performing the
* evaluation. If this parameter is true (the
* default), then the operation will use data first
* from any bundles provided as parameters (through
* the data and prefetch parameters), second data
* from the server performing the operation, and
* third, data from the dataEndpoint parameter (if
* provided). If this parameter is false, the
* operation will use data first from the bundles
* provided in the data or prefetch parameters, and
* second from the dataEndpoint parameter (if
* provided).
* @param data Data to be made available to the library
* evaluation. This parameter is exclusive with the
* prefetchData parameter (i.e. either provide all
* data as a single bundle, or provide data using
* multiple bundles with prefetch descriptions).
* @param prefetchData ***Not Yet Implemented***
* @param dataEndpoint An {@link Endpoint} endpoint to use to access data
* referenced by retrieve operations in the library.
* If provided, this endpoint is used after the data
* or prefetchData bundles, and the server, if the
* useServerData parameter is true.
* @param contentEndpoint An {@link Endpoint} endpoint to use to access
* content (i.e. libraries) referenced by the
* library. If no content endpoint is supplied, the
* evaluation will attempt to retrieve content from
* the server on which the operation is being
* performed.
* @param terminologyEndpoint An {@link Endpoint} endpoint to use to access
* terminology (i.e. valuesets, codesystems, and
* membership testing) referenced by the library. If
* no terminology endpoint is supplied, the
* evaluation will attempt to use the server on which
* the operation is being performed as the
* terminology server.
* @return The result of evaluating the given expression, returned as a FHIR
* type, either a {@link Resource} resource, or a FHIR-defined type
* corresponding to the CQL return type, as defined in the Using CQL
* section of the CPG Implementation guide. If the result is a List of
* resources, the result will be a {@link Bundle} Bundle . If the result
* is a CQL system-defined or FHIR-defined type, the result is returned
* as a {@link Parameters} Parameters resource
*/
@Operation(name = "$cql")
@Description(shortDefinition = "$cql", value = "Evaluates a CQL expression and returns the results as a Parameters resource. Defined: http://build.fhir.org/ig/HL7/cqf-recommendations/OperationDefinition-cpg-cql.html", example = "$cql?expression=5*5")
public Parameters evaluate(RequestDetails theRequestDetails, @OperationParam(name = "subject", max = 1) String subject, @OperationParam(name = "expression", min = 1, max = 1) String expression, @OperationParam(name = "parameters", max = 1) Parameters parameters, @OperationParam(name = "library") List<Parameters> library, @OperationParam(name = "useServerData", max = 1) BooleanType useServerData, @OperationParam(name = "data", max = 1) Bundle data, @OperationParam(name = "prefetchData") List<Parameters> prefetchData, @OperationParam(name = "dataEndpoint", max = 1) Endpoint dataEndpoint, @OperationParam(name = "contentEndpoint", max = 1) Endpoint contentEndpoint, @OperationParam(name = "terminologyEndpoint", max = 1) Endpoint terminologyEndpoint) {
if (prefetchData != null) {
throw new NotImplementedException("prefetchData is not yet supported.");
}
if (useServerData == null) {
useServerData = new BooleanType(true);
}
List<LibraryParameter> libraryParameters = new ArrayList<>();
if (library != null) {
for (Parameters libraryParameter : library) {
String url = null;
String name = null;
for (ParametersParameterComponent param : libraryParameter.getParameter()) {
switch(param.getName()) {
case "url":
url = ((StringType) param.getValue()).asStringValue();
break;
case "name":
name = ((StringType) param.getValue()).asStringValue();
break;
default:
throw new IllegalArgumentException("Only url and name parts are allowed for Parameter: library");
}
}
if (url == null) {
throw new IllegalArgumentException("If library parameter must provide a url parameter part.");
}
libraryParameters.add(new LibraryParameter().withUrl(url).withName(name));
}
// Remove LocalLibrary from cache first...
}
VersionedIdentifier localLibraryIdentifier = new VersionedIdentifier().withId("LocalLibrary").withVersion("1.0.0");
globalLibraryCache.remove(localLibraryIdentifier);
CqlEngine engine = setupEngine(localLibraryIdentifier, expression, libraryParameters, subject, parameters, contentEndpoint, dataEndpoint, terminologyEndpoint, data, useServerData.booleanValue(), theRequestDetails);
Map<String, Object> resolvedParameters = new HashMap<String, Object>();
if (parameters != null) {
for (Parameters.ParametersParameterComponent pc : parameters.getParameter()) {
resolvedParameters.put(pc.getName(), pc.getValue());
}
}
String contextType = subject != null ? subject.substring(0, subject.lastIndexOf("/") - 1) : null;
String subjectId = subject != null ? subject.substring(0, subject.lastIndexOf("/") - 1) : null;
EvaluationResult evalResult = engine.evaluate(localLibraryIdentifier, null, Pair.of(contextType != null ? contextType : "Unspecified", subjectId == null ? "null" : subject), resolvedParameters, this.getDebugMap());
if (evalResult != null && evalResult.expressionResults != null) {
if (evalResult.expressionResults.size() > 1) {
logger.debug("Evaluation resulted in more than one expression result. ");
}
Parameters result = new Parameters();
resolveResult(theRequestDetails, evalResult, result);
return result;
}
return null;
}
use of org.hl7.elm.r1.VersionedIdentifier in project cqf-ruler by DBCG.
the class CqlExecutionProvider method resolveLibraryName.
private String resolveLibraryName(RequestDetails requestDetails, JpaFhirDal jpaFhirDal, LibraryParameter libraryParameter, LibraryLoader libraryLoader) {
String libraryName;
if (libraryParameter.name == null) {
VersionedIdentifier libraryIdentifier = new VersionedIdentifier().withId(Canonicals.getIdPart(libraryParameter.url));
String version = Canonicals.getVersion(libraryParameter.url);
if (version != null) {
libraryIdentifier.setVersion(version);
}
org.cqframework.cql.elm.execution.Library executionLibrary = null;
try {
executionLibrary = libraryLoader.load(libraryIdentifier);
} catch (Exception e) {
logger.debug("Unable to load executable library {}", libraryParameter.name);
}
if (executionLibrary != null) {
libraryName = executionLibrary.getIdentifier().getId();
} else {
Library library = (Library) jpaFhirDal.read(new IdType("Library", libraryIdentifier.getId()));
libraryName = library.getName();
}
} else {
libraryName = libraryParameter.name;
}
return libraryName;
}
use of org.hl7.elm.r1.VersionedIdentifier in project cqf-ruler by DBCG.
the class CqlExecutionProvider method evaluate.
/**
* Evaluates a CQL expression and returns the results as a Parameters resource.
*
* @param theRequestDetails the {@link RequestDetails RequestDetails}
* @param subject Subject for which the expression will be
* evaluated. This corresponds to the context in
* which the expression will be evaluated and is
* represented as a relative FHIR id (e.g.
* Patient/123), which establishes both the context
* and context value for the evaluation
* @param expression Expression to be evaluated. Note that this is an
* expression of CQL, not the text of a library with
* definition statements.
* @param parameters Any input parameters for the expression.
* {@link Parameters} Parameters defined in this
* input will be made available by name to the CQL
* expression. Parameter types are mapped to CQL as
* specified in the Using CQL section of the CPG
* Implementation guide. If a parameter appears more
* than once in the input Parameters resource, it is
* represented with a List in the input CQL. If a
* parameter has parts, it is represented as a Tuple
* in the input CQL.
* @param library A library to be included. The {@link Library}
* library is resolved by url and made available by
* name within the expression to be evaluated.
* @param useServerData Whether to use data from the server performing the
* evaluation. If this parameter is true (the
* default), then the operation will use data first
* from any bundles provided as parameters (through
* the data and prefetch parameters), second data
* from the server performing the operation, and
* third, data from the dataEndpoint parameter (if
* provided). If this parameter is false, the
* operation will use data first from the bundles
* provided in the data or prefetch parameters, and
* second from the dataEndpoint parameter (if
* provided).
* @param data Data to be made available to the library
* evaluation. This parameter is exclusive with the
* prefetchData parameter (i.e. either provide all
* data as a single bundle, or provide data using
* multiple bundles with prefetch descriptions).
* @param prefetchData ***Not Yet Implemented***
* @param dataEndpoint An {@link Endpoint} endpoint to use to access data
* referenced by retrieve operations in the library.
* If provided, this endpoint is used after the data
* or prefetchData bundles, and the server, if the
* useServerData parameter is true.
* @param contentEndpoint An {@link Endpoint} endpoint to use to access
* content (i.e. libraries) referenced by the
* library. If no content endpoint is supplied, the
* evaluation will attempt to retrieve content from
* the server on which the operation is being
* performed.
* @param terminologyEndpoint An {@link Endpoint} endpoint to use to access
* terminology (i.e. valuesets, codesystems, and
* membership testing) referenced by the library. If
* no terminology endpoint is supplied, the
* evaluation will attempt to use the server on which
* the operation is being performed as the
* terminology server.
* @return The result of evaluating the given expression, returned as a FHIR
* type, either a {@link Resource} resource, or a FHIR-defined type
* corresponding to the CQL return type, as defined in the Using CQL
* section of the CPG Implementation guide. If the result is a List of
* resources, the result will be a {@link Bundle} Bundle . If the result
* is a CQL system-defined or FHIR-defined type, the result is returned
* as a {@link Parameters} Parameters resource
*/
@Operation(name = "$cql")
@Description(shortDefinition = "$cql", value = "Evaluates a CQL expression and returns the results as a Parameters resource. Defined: http://build.fhir.org/ig/HL7/cqf-recommendations/OperationDefinition-cpg-cql.html", example = "$cql?expression=5*5")
public Parameters evaluate(RequestDetails theRequestDetails, @OperationParam(name = "subject", max = 1) String subject, @OperationParam(name = "expression", min = 1, max = 1) String expression, @OperationParam(name = "parameters", max = 1) Parameters parameters, @OperationParam(name = "library") List<Parameters> library, @OperationParam(name = "useServerData", max = 1) BooleanType useServerData, @OperationParam(name = "data", max = 1) Bundle data, @OperationParam(name = "prefetchData") List<Parameters> prefetchData, @OperationParam(name = "dataEndpoint", max = 1) Endpoint dataEndpoint, @OperationParam(name = "contentEndpoint", max = 1) Endpoint contentEndpoint, @OperationParam(name = "terminologyEndpoint", max = 1) Endpoint terminologyEndpoint) {
if (prefetchData != null) {
throw new NotImplementedException("prefetchData is not yet supported.");
}
if (useServerData == null) {
useServerData = new BooleanType(true);
}
List<LibraryParameter> libraryParameters = new ArrayList<>();
if (library != null) {
for (Parameters libraryParameter : library) {
CanonicalType url = null;
String name = null;
for (ParametersParameterComponent param : libraryParameter.getParameter()) {
switch(param.getName()) {
case "url":
url = ((CanonicalType) param.getValue());
break;
case "name":
name = ((StringType) param.getValue()).asStringValue();
break;
default:
throw new IllegalArgumentException("Only url and name parts are allowed for Parameter: library");
}
}
if (url == null) {
throw new IllegalArgumentException("If library parameter must provide a url parameter part.");
}
libraryParameters.add(new LibraryParameter().withUrl(url).withName(name));
}
// Remove LocalLibrary from cache first...
}
VersionedIdentifier localLibraryIdentifier = new VersionedIdentifier().withId("LocalLibrary").withVersion("1.0.0");
globalLibraryCache.remove(localLibraryIdentifier);
CqlEngine engine = setupEngine(localLibraryIdentifier, expression, libraryParameters, subject, parameters, contentEndpoint, dataEndpoint, terminologyEndpoint, data, useServerData.booleanValue(), theRequestDetails);
Map<String, Object> resolvedParameters = new HashMap<>();
if (parameters != null) {
for (Parameters.ParametersParameterComponent pc : parameters.getParameter()) {
resolvedParameters.put(pc.getName(), pc.getValue());
}
}
String contextType = subject != null ? subject.substring(0, subject.lastIndexOf("/") - 1) : null;
String subjectId = subject != null ? subject.substring(0, subject.lastIndexOf("/") - 1) : null;
EvaluationResult evalResult = engine.evaluate(localLibraryIdentifier, null, Pair.of(contextType != null ? contextType : "Unspecified", subjectId == null ? "null" : subject), resolvedParameters, this.getDebugMap());
if (evalResult != null && evalResult.expressionResults != null) {
if (evalResult.expressionResults.size() > 1) {
logger.debug("Evaluation resulted in more than one expression result. ");
}
Parameters result = new Parameters();
resolveResult(theRequestDetails, evalResult, result);
return result;
}
return null;
}
use of org.hl7.elm.r1.VersionedIdentifier in project cqf-ruler by DBCG.
the class LibraryEvaluationProvider method evaluate.
@SuppressWarnings({ "unchecked" })
@Operation(name = "$evaluate", idempotent = true, type = Library.class)
public Bundle evaluate(@IdParam IdType theId, @OperationParam(name = "patientId") String patientId, @OperationParam(name = "periodStart") String periodStart, @OperationParam(name = "periodEnd") String periodEnd, @OperationParam(name = "productLine") String productLine, @OperationParam(name = "terminologyEndpoint") Endpoint terminologyEndpoint, @OperationParam(name = "dataEndpoint") Endpoint dataEndpoint, @OperationParam(name = "context") String contextParam, @OperationParam(name = "executionResults") String executionResults, @OperationParam(name = "parameters") Parameters parameters, @OperationParam(name = "additionalData") Bundle additionalData, RequestDetails theRequestDetails) {
log.info("Library evaluation started..");
if (patientId == null && contextParam != null && contextParam.equals("Patient")) {
log.error("Patient id null");
throw new IllegalArgumentException("Must specify a patientId when executing in Patient context.");
}
Bundle libraryBundle = new Bundle();
Library theResource = null;
if (additionalData != null) {
for (Bundle.BundleEntryComponent entry : additionalData.getEntry()) {
if (entry.getResource().fhirType().equals("Library")) {
libraryBundle.addEntry(entry);
if (entry.getResource().getIdElement().equals(theId)) {
theResource = (Library) entry.getResource();
}
}
}
}
if (theResource == null) {
theResource = read(theId, theRequestDetails);
}
VersionedIdentifier libraryIdentifier = new VersionedIdentifier().withId(theResource.getName()).withVersion(theResource.getVersion());
TerminologyProvider terminologyProvider;
if (terminologyEndpoint != null) {
IGenericClient client = Clients.forEndpoint(getFhirContext(), terminologyEndpoint);
terminologyProvider = new R4FhirTerminologyProvider(client);
} else {
terminologyProvider = myJpaTerminologyProviderFactory.create(new SystemRequestDetails());
}
DataProvider dataProvider;
if (dataEndpoint != null) {
List<RetrieveProvider> retrieveProviderList = new ArrayList<>();
IGenericClient client = Clients.forEndpoint(dataEndpoint);
RestFhirRetrieveProvider retriever = new RestFhirRetrieveProvider(new SearchParameterResolver(getFhirContext()), client);
retriever.setTerminologyProvider(terminologyProvider);
if (terminologyEndpoint == null || (terminologyEndpoint != null && !terminologyEndpoint.getAddress().equals(dataEndpoint.getAddress()))) {
retriever.setExpandValueSets(true);
}
retrieveProviderList.add(retriever);
if (additionalData != null) {
BundleRetrieveProvider bundleProvider = new BundleRetrieveProvider(getFhirContext(), additionalData);
bundleProvider.setTerminologyProvider(terminologyProvider);
retrieveProviderList.add(bundleProvider);
PriorityRetrieveProvider priorityProvider = new PriorityRetrieveProvider(retrieveProviderList);
dataProvider = new CompositeDataProvider(myModelResolver, priorityProvider);
} else {
dataProvider = new CompositeDataProvider(myModelResolver, retriever);
}
} else {
List<RetrieveProvider> retrieveProviderList = new ArrayList<>();
JpaFhirRetrieveProvider retriever = new JpaFhirRetrieveProvider(getDaoRegistry(), new SearchParameterResolver(getFhirContext()));
retriever.setTerminologyProvider(terminologyProvider);
// Assume it's a different server, therefore need to expand.
if (terminologyEndpoint != null) {
retriever.setExpandValueSets(true);
}
retrieveProviderList.add(retriever);
if (additionalData != null) {
BundleRetrieveProvider bundleProvider = new BundleRetrieveProvider(getFhirContext(), additionalData);
bundleProvider.setTerminologyProvider(terminologyProvider);
retrieveProviderList.add(bundleProvider);
PriorityRetrieveProvider priorityProvider = new PriorityRetrieveProvider(retrieveProviderList);
dataProvider = new CompositeDataProvider(myModelResolver, priorityProvider);
} else {
dataProvider = new CompositeDataProvider(myModelResolver, retriever);
}
}
LibraryContentProvider bundleLibraryProvider = new BundleFhirLibraryContentProvider(this.getFhirContext(), libraryBundle, adapterFactory, libraryVersionSelector);
LibraryContentProvider jpaLibraryContentProvider = this.myJpaLibraryContentProviderFactory.create(theRequestDetails);
List<LibraryContentProvider> sourceProviders = new ArrayList<LibraryContentProvider>(Arrays.asList(bundleLibraryProvider, jpaLibraryContentProvider));
LibraryLoader libraryLoader = this.myLibraryLoaderFactory.create(sourceProviders);
CqlEngine engine = new CqlEngine(libraryLoader, Collections.singletonMap("http://hl7.org/fhir", dataProvider), terminologyProvider);
Map<String, Object> resolvedParameters = new HashMap<>();
if (parameters != null) {
for (Parameters.ParametersParameterComponent pc : parameters.getParameter()) {
resolvedParameters.put(pc.getName(), pc.getValue());
}
}
if (periodStart != null && periodEnd != null) {
// resolve the measurement period
Interval measurementPeriod = new Interval(Operations.resolveRequestDate(periodStart, true), true, Operations.resolveRequestDate(periodEnd, false), true);
resolvedParameters.put("Measurement Period", new Interval(DateTime.fromJavaDate((Date) measurementPeriod.getStart()), true, DateTime.fromJavaDate((Date) measurementPeriod.getEnd()), true));
}
if (productLine != null) {
resolvedParameters.put("Product Line", productLine);
}
EvaluationResult evalResult = engine.evaluate(libraryIdentifier, null, Pair.of(contextParam != null ? contextParam : "Unspecified", patientId == null ? "null" : patientId), resolvedParameters, this.getDebugMap());
List<Resource> results = new ArrayList<>();
FhirMeasureBundler bundler = new FhirMeasureBundler();
if (evalResult != null && evalResult.expressionResults != null) {
for (Map.Entry<String, Object> def : evalResult.expressionResults.entrySet()) {
Parameters result = new Parameters();
try {
result.setId(def.getKey());
Object res = def.getValue();
if (res == null) {
result.addParameter().setName("value").setValue(new StringType("null"));
} else if (res instanceof List<?>) {
if (((List<?>) res).size() > 0 && ((List<?>) res).get(0) instanceof Resource) {
if (executionResults != null && executionResults.equals("Summary")) {
result.addParameter().setName("value").setValue(new StringType(((Resource) ((List<?>) res).get(0)).getIdElement().getResourceType() + "/" + ((Resource) ((List<?>) res).get(0)).getIdElement().getIdPart()));
} else {
result.addParameter().setName("value").setResource(bundler.bundle((Iterable<Resource>) res, theRequestDetails.getFhirServerBase()));
}
} else {
result.addParameter().setName("value").setValue(new StringType(res.toString()));
}
} else if (res instanceof Iterable) {
result.addParameter().setName("value").setResource(bundler.bundle((Iterable<Resource>) res, theRequestDetails.getFhirServerBase()));
} else if (res instanceof Resource) {
if (executionResults != null && executionResults.equals("Summary")) {
result.addParameter().setName("value").setValue(new StringType(((Resource) res).getIdElement().getResourceType() + "/" + ((Resource) res).getIdElement().getIdPart()));
} else {
result.addParameter().setName("value").setResource((Resource) res);
}
} else if (res instanceof Type) {
result.addParameter().setName("value").setValue((Type) res);
} else {
result.addParameter().setName("value").setValue(new StringType(res.toString()));
}
result.addParameter().setName("resultType").setValue(new StringType(resolveType(res)));
} catch (RuntimeException re) {
re.printStackTrace();
String message = re.getMessage() != null ? re.getMessage() : re.getClass().getName();
result.addParameter().setName("error").setValue(new StringType(message));
}
results.add(result);
}
}
return bundler.bundle(results, theRequestDetails.getFhirServerBase());
}
use of org.hl7.elm.r1.VersionedIdentifier in project cqf-ruler by DBCG.
the class CdsHooksServlet method doPost.
@Override
@SuppressWarnings("deprecation")
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
logger.info(request.getRequestURI());
try {
// validate that we are dealing with JSON
if (request.getContentType() == null || !request.getContentType().startsWith("application/json")) {
throw new ServletException(String.format("Invalid content type %s. Please use application/json.", request.getContentType()));
}
String baseUrl = this.myAppProperties.getServer_address();
String service = request.getPathInfo().replace("/", "");
JsonParser parser = new JsonParser();
JsonObject requestJson = parser.parse(request.getReader()).getAsJsonObject();
logger.info(requestJson.toString());
Request cdsHooksRequest = new Request(service, requestJson, JsonHelper.getObjectRequired(getService(service), "prefetch"));
Hook hook = HookFactory.createHook(cdsHooksRequest);
String hookName = hook.getRequest().getHook();
logger.info("cds-hooks hook: {}", hookName);
logger.info("cds-hooks hook instance: {}", hook.getRequest().getHookInstance());
logger.info("cds-hooks maxCodesPerQuery: {}", this.getProviderConfiguration().getMaxCodesPerQuery());
logger.info("cds-hooks expandValueSets: {}", this.getProviderConfiguration().getExpandValueSets());
logger.info("cds-hooks searchStyle: {}", this.getProviderConfiguration().getSearchStyle());
logger.info("cds-hooks prefetch maxUriLength: {}", this.getProviderConfiguration().getMaxUriLength());
logger.info("cds-hooks local server address: {}", baseUrl);
logger.info("cds-hooks fhir server address: {}", hook.getRequest().getFhirServerUrl());
logger.info("cds-hooks cql_logging_enabled: {}", this.getProviderConfiguration().getCqlLoggingEnabled());
PlanDefinition planDefinition = read(Ids.newId(PlanDefinition.class, hook.getRequest().getServiceName()));
AtomicBoolean planDefinitionHookMatchesRequestHook = new AtomicBoolean(false);
planDefinition.getAction().forEach(action -> {
action.getTriggerDefinition().forEach(triggerDefn -> {
if (hookName.equals(triggerDefn.getEventName())) {
planDefinitionHookMatchesRequestHook.set(true);
return;
}
});
if (planDefinitionHookMatchesRequestHook.get()) {
return;
}
});
if (!planDefinitionHookMatchesRequestHook.get()) {
throw new ServletException("ERROR: Request hook does not match the service called.");
}
// No tenant information available, so create local system request
RequestDetails requestDetails = new SystemRequestDetails();
LibraryLoader libraryLoader = libraryLoaderFactory.create(Lists.newArrayList(jpaLibraryContentProviderFactory.create(requestDetails)));
Reference reference = planDefinition.getLibrary().get(0);
Library library = read(reference.getReferenceElement());
org.cqframework.cql.elm.execution.Library elm = libraryLoader.load(new VersionedIdentifier().withId(library.getName()).withVersion(library.getVersion()));
Context context = new Context(elm);
context.setDebugMap(this.getDebugMap());
// provider case
// No tenant information available for cds-hooks
TerminologyProvider serverTerminologyProvider = myJpaTerminologyProviderFactory.create(requestDetails);
// TODO make sure tooling handles remote
context.registerDataProvider("http://hl7.org/fhir", fhirRetrieveProviderFactory.create(requestDetails, serverTerminologyProvider));
context.registerTerminologyProvider(serverTerminologyProvider);
context.registerLibraryLoader(libraryLoader);
context.setContextValue("Patient", hook.getRequest().getContext().getPatientId().replace("Patient/", ""));
context.setExpressionCaching(true);
EvaluationContext<PlanDefinition> evaluationContext = new Stu3EvaluationContext(hook, FhirContext.forCached(FhirVersionEnum.DSTU3).newRestfulGenericClient(baseUrl), context, elm, planDefinition, this.getProviderConfiguration(), this.modelResolver);
this.setAccessControlHeaders(response);
response.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType());
Stu3HookEvaluator evaluator = new Stu3HookEvaluator(this.modelResolver);
String jsonResponse = toJsonResponse(evaluator.evaluate(evaluationContext));
logger.info(jsonResponse);
response.getWriter().println(jsonResponse);
} catch (BaseServerResponseException e) {
this.setAccessControlHeaders(response);
// This will be overwritten with the correct status code downstream if needed.
response.setStatus(500);
response.getWriter().println("ERROR: Exception connecting to remote server.");
this.printMessageAndCause(e, response);
this.handleServerResponseException(e, response);
this.printStackTrack(e, response);
logger.error(e.toString());
} catch (DataProviderException e) {
this.setAccessControlHeaders(response);
// This will be overwritten with the correct status code downstream if needed.
response.setStatus(500);
response.getWriter().println("ERROR: Exception in DataProvider.");
this.printMessageAndCause(e, response);
if (e.getCause() != null && (e.getCause() instanceof BaseServerResponseException)) {
this.handleServerResponseException((BaseServerResponseException) e.getCause(), response);
}
this.printStackTrack(e, response);
logger.error(e.toString());
} catch (CqlException e) {
this.setAccessControlHeaders(response);
// This will be overwritten with the correct status code downstream if needed.
response.setStatus(500);
response.getWriter().println("ERROR: Exception in CQL Execution.");
this.printMessageAndCause(e, response);
if (e.getCause() != null && (e.getCause() instanceof BaseServerResponseException)) {
this.handleServerResponseException((BaseServerResponseException) e.getCause(), response);
}
this.printStackTrack(e, response);
logger.error(e.toString());
} catch (Exception e) {
logger.error(e.toString());
throw new ServletException("ERROR: Exception in cds-hooks processing.", e);
}
}
Aggregations