Skip to content

CQL Execution Engine

blangley28 edited this page Jun 30, 2020 · 6 revisions

Motivation

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.

Overview

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.

Dependencies

There are a few different dependencies for the CQL Execution engine. These are:

  1. org.opencds.cqf:cql-engine
  2. org.opencds.cqf:cql-engine-fhir
  3. 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'

Execution

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.

Clone this wiki locally