-
Notifications
You must be signed in to change notification settings - Fork 18
CQL Execution Engine
The CQL Execution engine is used by the Prior Auth Rules to execute the rules against the Claim Bundle to determine a disposition automatically. The Implementation Guide does not require CQL but since it is an industry standard this Reference Implementation is using CQL as a proof of concept. For more information see the wiki page for the Rules Engine.
The Java CQL Engine can be a little finicky so any changes are documented here.
The rules engine is located in org.hl7.davinci.rules
. The PriorAuthRule
class is a static class responsible for executing a specific CQL file against the Claim Bundle. Before the CQL execution can take place the individual Claim Items are mapped to a CQL File. This mapping is done using the CDS-Library.
There are a few different dependencies for the CQL Execution engine. These are:
org.opencds.cqf:cql-engine
org.opencds.cqf:cql-engine-fhir
info.cqframework:cql-to-elm
Note: the two opencds libraries also import the same slf4j logging library so that should be excluded. Note: the execution engine requires hapi version 4.1.0 or newer
implementation('org.opencds.cqf:cql-engine:1.3.12.1') {
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
}
implementation ('org.opencds.cqf:cql-engine-fhir:1.3.12.1') {
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
}
implementation 'info.cqframework:cql-to-elm:1.4.6'
implementation 'ca.uhn.hapi.fhir:hapi-fhir-base:4.1.0'
implementation 'ca.uhn.hapi.fhir:hapi-fhir-structures-r4:4.1.0'
The rule execution requires a couple steps to build the context and include the Claim Bundle. The entire process can be broken up into a few steps
String cql; // The string contents of the CQL file
Bundle bundle; // The Claim Bundle
// Step 1: Create the library (convert the CQL into ELM)
ModelManager modelManager = new ModelManager();
LibraryManager libraryManager = new LibraryManager(modelManager);
libraryManager.getLibrarySourceLoader().registerProvider(new FhirLibrarySourceProvider());
CqlTranslator translator = CqlTranslator.fromText(cql, modelManager, libraryManager);
if (translator.getErrors().size() > 0) {
ArrayList<String> errors = new ArrayList<>();
for (CqlTranslatorException error : translator.getErrors()) {
TrackBack tb = error.getLocator();
String lines = tb == null ? "[n/a]"
: String.format("[%d:%d, %d:%d]", tb.getStartLine(), tb.getStartChar(), tb.getEndLine(),tb.getEndChar());
errors.add(lines + error.getMessage());
}
throw new IllegalArgumentException(errors.toString());
}
Library library = CqlLibraryReader.read(new StringReader(translator.toXml()));
// Step 2: Create the CQL Context and register the Bundle Retrieve Provider
BundleRetrieveProvider bundleRetrieveProvider = new BundleRetrieveProvider(FhirContext.forR4(), bundle);
ModelResolver modelResolver = new ModelResolver()
DataProvider dataProvider = new CompositeDataProvider(modelResolver, bundleRetrieveProvider);
Context context = new Context(library);
context.registerDataProvider("http://hl7.org/fhir", dataProvider);
// Step 3: Execute the rule
ExpressionDef expression = context.resolveExpressionRef("PRIORAUTH_GRANTED");
Object result = expression.evaluate(context);
Note: the BundleRetrieveProvider
and ModelResolver
are not from the opencds CQL engine but modified versions. They are included in the Rules package of this repository.