Skip to content

Commit

Permalink
pin ca.uhn.hapi.fhir:org.hl7.fhir.utilities:6.3.24 and ca.uhn.hapi.fh…
Browse files Browse the repository at this point in the history
…ir:org.hl7.fhir.r4:6.3.24 (#15863)

* Remediate Snyk finding

* Code updates for updated FHIR library

---------

Co-authored-by: Michael Kalish <[email protected]>
  • Loading branch information
snesm and mkalish authored Sep 17, 2024
1 parent b563b3e commit 0281602
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 35 deletions.
3 changes: 3 additions & 0 deletions prime-router/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,9 @@ dependencies {
// https://mvnrepository.com/artifact/ca.uhn.hapi.fhir/hapi-fhir-caching-caffeine
implementation("ca.uhn.hapi.fhir:hapi-fhir-caching-caffeine:7.2.2")
implementation("ca.uhn.hapi.fhir:hapi-fhir-client:7.2.2")
// pin
implementation("ca.uhn.hapi.fhir:org.hl7.fhir.utilities:6.3.24")
implementation("ca.uhn.hapi.fhir:org.hl7.fhir.r4:6.3.24")
implementation("ca.uhn.hapi:hapi-base:2.5.1")
implementation("ca.uhn.hapi:hapi-structures-v251:2.5.1")
implementation("ca.uhn.hapi:hapi-structures-v27:2.5.1")
Expand Down
2 changes: 1 addition & 1 deletion prime-router/src/main/kotlin/cli/ProcessFhirCommands.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ import gov.cdc.prime.router.fhirengine.translation.hl7.utils.FhirPathUtils
import gov.cdc.prime.router.fhirengine.utils.FhirTranscoder
import gov.cdc.prime.router.fhirengine.utils.HL7Reader
import gov.cdc.prime.router.fhirengine.utils.getObservations
import org.hl7.fhir.r4.fhirpath.FHIRLexer.FHIRLexerException
import org.hl7.fhir.r4.model.Base
import org.hl7.fhir.r4.model.Bundle
import org.hl7.fhir.r4.model.Extension
import org.hl7.fhir.r4.model.Reference
import org.hl7.fhir.r4.utils.FHIRLexer.FHIRLexerException

/**
* Process data into/from FHIR.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import gov.cdc.prime.router.common.NPIUtilities
import gov.cdc.prime.router.fhirengine.translation.hl7.SchemaException
import gov.cdc.prime.router.metadata.GeoData
import gov.cdc.prime.router.metadata.LivdLookup
import org.hl7.fhir.r4.fhirpath.FHIRPathUtilityClasses.FunctionDetails
import org.hl7.fhir.r4.model.Base
import org.hl7.fhir.r4.model.Device
import org.hl7.fhir.r4.model.Observation
import org.hl7.fhir.r4.model.StringType
import org.hl7.fhir.r4.utils.FHIRPathUtilityClasses.FunctionDetails
import java.time.LocalDate
import java.util.Date
import java.util.UUID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import org.apache.commons.text.StringSubstitutor
import org.apache.commons.text.lookup.StringLookup
import org.apache.logging.log4j.kotlin.Logging
import org.hl7.fhir.exceptions.PathEngineException
import org.hl7.fhir.r4.fhirpath.FHIRPathEngine
import org.hl7.fhir.r4.fhirpath.FHIRPathUtilityClasses
import org.hl7.fhir.r4.fhirpath.TypeDetails
import org.hl7.fhir.r4.model.Base
import org.hl7.fhir.r4.model.Bundle
import org.hl7.fhir.r4.model.IntegerType
import org.hl7.fhir.r4.model.StringType
import org.hl7.fhir.r4.model.TypeDetails
import org.hl7.fhir.r4.model.ValueSet
import org.hl7.fhir.r4.utils.FHIRPathEngine
import org.hl7.fhir.r4.utils.FHIRPathUtilityClasses.FunctionDetails
import java.lang.IllegalArgumentException
import java.lang.NumberFormatException

Expand Down Expand Up @@ -145,7 +145,13 @@ class ConstantSubstitutor {
*/
class FhirPathCustomResolver(private val customFhirFunctions: FhirPathFunctions? = null) :
FHIRPathEngine.IEvaluationContext, Logging {
override fun resolveConstant(appContext: Any?, name: String?, beforeContext: Boolean): List<Base> {
override fun resolveConstant(
engine: FHIRPathEngine?,
appContext: Any?,
name: String?,
beforeContext: Boolean,
explicitConstant: Boolean,
): List<Base> {
// Name is always passed in from the FHIR path engine
require(!name.isNullOrBlank())

Expand Down Expand Up @@ -210,27 +216,38 @@ class FhirPathCustomResolver(private val customFhirFunctions: FhirPathFunctions?
}
}

override fun resolveConstantType(appContext: Any?, name: String?): TypeDetails {
override fun resolveConstantType(
engine: FHIRPathEngine?,
appContext: Any?,
name: String?,
explicitConstant: Boolean,
): TypeDetails {
throw NotImplementedError("Not implemented")
}

override fun log(argument: String?, focus: MutableList<Base>?): Boolean {
throw NotImplementedError("Not implemented")
}

override fun resolveFunction(functionName: String?): FunctionDetails? {
override fun resolveFunction(
engine: FHIRPathEngine?,
functionName: String?,
): FHIRPathUtilityClasses.FunctionDetails? {
return CustomFHIRFunctions.resolveFunction(functionName, customFhirFunctions)
}

override fun checkFunction(
engine: FHIRPathEngine?,
appContext: Any?,
functionName: String?,
focus: TypeDetails?,
parameters: MutableList<TypeDetails>?,
): TypeDetails {
throw NotImplementedError("Not implemented")
}

override fun executeFunction(
engine: FHIRPathEngine?,
appContext: Any?,
focus: MutableList<Base>?,
functionName: String?,
Expand All @@ -246,7 +263,7 @@ class FhirPathCustomResolver(private val customFhirFunctions: FhirPathFunctions?
}
}

override fun resolveReference(appContext: Any?, url: String?, refContext: Base?): Base? {
override fun resolveReference(engine: FHIRPathEngine?, appContext: Any?, url: String?, refContext: Base?): Base? {
// Name is always passed in from the FHIR path engine
require(!url.isNullOrBlank())

Expand All @@ -256,11 +273,11 @@ class FhirPathCustomResolver(private val customFhirFunctions: FhirPathFunctions?
}
}

override fun conformsToProfile(appContext: Any?, item: Base?, url: String?): Boolean {
override fun conformsToProfile(engine: FHIRPathEngine?, appContext: Any?, item: Base?, url: String?): Boolean {
throw NotImplementedError("Not implemented")
}

override fun resolveValueSet(appContext: Any?, url: String?): ValueSet {
override fun resolveValueSet(engine: FHIRPathEngine?, appContext: Any?, url: String?): ValueSet {
throw NotImplementedError("Not implemented")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import ca.uhn.fhir.model.api.TemporalPrecisionEnum
import fhirengine.translation.hl7.utils.FhirPathFunctions
import fhirengine.translation.hl7.utils.helpers.convertDateToAge
import gov.cdc.prime.router.fhirengine.translation.hl7.SchemaException
import org.hl7.fhir.r4.fhirpath.FHIRPathUtilityClasses.FunctionDetails
import org.hl7.fhir.r4.model.Base
import org.hl7.fhir.r4.model.BaseDateTimeType
import org.hl7.fhir.r4.model.BooleanType
import org.hl7.fhir.r4.model.DateTimeType
import org.hl7.fhir.r4.model.IntegerType
import org.hl7.fhir.r4.model.StringType
import org.hl7.fhir.r4.utils.FHIRPathUtilityClasses.FunctionDetails
import java.time.DateTimeException
import java.time.ZoneId
import java.util.TimeZone
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package fhirengine.translation.hl7.utils

import org.hl7.fhir.r4.fhirpath.FHIRPathUtilityClasses.FunctionDetails
import org.hl7.fhir.r4.model.Base
import org.hl7.fhir.r4.utils.FHIRPathUtilityClasses.FunctionDetails

/**
* This interface contains the required method signatures required to implement custom FHIR functions
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ import gov.cdc.prime.router.fhirengine.translation.hl7.HL7ConversionException
import gov.cdc.prime.router.fhirengine.translation.hl7.SchemaException
import gov.cdc.prime.router.fhirengine.translation.hl7.schema.converter.ConverterSchemaElement
import org.apache.logging.log4j.kotlin.Logging
import org.hl7.fhir.r4.fhirpath.ExpressionNode
import org.hl7.fhir.r4.fhirpath.FHIRLexer
import org.hl7.fhir.r4.fhirpath.FHIRPathEngine
import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext
import org.hl7.fhir.r4.model.Base
import org.hl7.fhir.r4.model.BaseDateTimeType
import org.hl7.fhir.r4.model.BooleanType
import org.hl7.fhir.r4.model.Bundle
import org.hl7.fhir.r4.model.DateTimeType
import org.hl7.fhir.r4.model.DateType
import org.hl7.fhir.r4.model.ExpressionNode
import org.hl7.fhir.r4.model.InstantType
import org.hl7.fhir.r4.model.TimeType
import org.hl7.fhir.r4.utils.FHIRLexer.FHIRLexerException
import org.hl7.fhir.r4.utils.FHIRPathEngine
import java.time.DateTimeException
import java.time.LocalTime
import java.time.format.DateTimeFormatter
Expand Down Expand Up @@ -97,7 +97,7 @@ object FhirPathUtils : Logging {
} else {
pathEngine.evaluate(appContext, focusResource, bundle, bundle, expressionNode)
}
} catch (e: FHIRLexerException) {
} catch (e: FHIRLexer.FHIRLexerException) {
logger.error("${e.javaClass.name}: Syntax error in FHIR Path $expression.")
emptyList()
} catch (e: IndexOutOfBoundsException) {
Expand Down Expand Up @@ -145,7 +145,7 @@ object FhirPathUtils : Logging {
}
} catch (e: Exception) {
val msg = when (e) {
is FHIRLexerException -> "Syntax error in FHIR Path expression $expression"
is FHIRLexer.FHIRLexerException -> "Syntax error in FHIR Path expression $expression"
is SchemaException -> e.message.toString()
else ->
"Unknown error while evaluating FHIR Path expression $expression for condition. " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,24 +86,24 @@ class ConstantResolverTests {
@Test
fun `test fhir path resolver`() {
mockkObject(FhirPathUtils)
assertFailure { FhirPathCustomResolver().resolveConstant(null, null, false) }
assertFailure { FhirPathCustomResolver().resolveConstant(null, "const1", false) }
assertFailure { FhirPathCustomResolver().resolveConstant(null, null, null, false, false) }
assertFailure { FhirPathCustomResolver().resolveConstant(null, null, "const1", false, false) }
.hasClass(PathEngineException::class.java)

val integerValue = 99
val urlPrefix = "https://reportstream.cdc.gov/fhir/StructureDefinition/"
val constants = sortedMapOf("const1" to "'value1'", "int1" to "'$integerValue'", "rsext" to "'$urlPrefix'")
val context = CustomContext.addConstants(constants, CustomContext(Bundle(), Bundle()))
assertThat(FhirPathCustomResolver().resolveConstant(context, "const2", false)).isEmpty()
assertThat(FhirPathCustomResolver().resolveConstant(context, "const1", false)).isNotNull()
var result = FhirPathCustomResolver().resolveConstant(context, "int1", false)
assertThat(FhirPathCustomResolver().resolveConstant(null, context, "const2", false, false)).isEmpty()
assertThat(FhirPathCustomResolver().resolveConstant(null, context, "const1", false, false)).isNotNull()
var result = FhirPathCustomResolver().resolveConstant(null, context, "int1", false, false)
assertThat(result).isNotNull()
assertThat(result).isNotEmpty()
assertThat(result[0] is IntegerType).isTrue()
assertThat((result[0] as IntegerType).value).isEqualTo(integerValue)

// Now lets resolve a constant
result = FhirPathCustomResolver().resolveConstant(context, "const1", false)
result = FhirPathCustomResolver().resolveConstant(null, context, "const1", false, false)
assertThat(result).isNotNull()
assertThat(result.isNotEmpty())
assertThat(result[0].isPrimitive).isTrue()
Expand All @@ -114,21 +114,21 @@ class ConstantResolverTests {

// Test the ability to resolve constants with suffix
val urlSuffix = "SomeSuffix"
result = FhirPathCustomResolver().resolveConstant(context, "`rsext-$urlSuffix`", false)
result = FhirPathCustomResolver().resolveConstant(null, context, "`rsext-$urlSuffix`", false, false)
assertThat(result).isNotNull()
assertThat(result.isNotEmpty())
assertThat(result[0].isPrimitive).isTrue()
assertThat(result[0]).isInstanceOf(StringType::class.java)
assertThat((result[0] as StringType).value).isEqualTo("$urlPrefix$urlSuffix")

result = FhirPathCustomResolver().resolveConstant(context, "`rsext`", false)
result = FhirPathCustomResolver().resolveConstant(null, context, "`rsext`", false, false)
assertThat(result).isNotNull()
assertThat(result.isNotEmpty())
assertThat(result[0].isPrimitive).isTrue()
assertThat(result[0]).isInstanceOf(StringType::class.java)
assertThat((result[0] as StringType).value).isEqualTo(urlPrefix)

result = FhirPathCustomResolver().resolveConstant(context, "unknownconst", false)
result = FhirPathCustomResolver().resolveConstant(null, context, "unknownconst", false, false)
assertThat(result).isEmpty()
}

Expand All @@ -144,7 +144,7 @@ class ConstantResolverTests {

val constants = sortedMapOf("const1" to "'value1'") // this does not matter but context wants something
val context = CustomContext.addConstants(constants, CustomContext(Bundle(), Bundle()))
val result = FhirPathCustomResolver().resolveConstant(context, "const1", false)
val result = FhirPathCustomResolver().resolveConstant(null, context, "const1", false, false)
assertThat(result).isNotNull()
assertThat(result.isNotEmpty())
assertThat(result.size == 3)
Expand All @@ -167,6 +167,7 @@ class ConstantResolverTests {
val context = CustomContext(Bundle(), Bundle())
assertThat(
FhirPathCustomResolver(CustomFhirPathFunctions()).executeFunction(
null,
context,
mutableListOf(Observation()),
"livdTableLookup",
Expand All @@ -180,6 +181,7 @@ class ConstantResolverTests {
val context = CustomContext(Bundle(), Bundle())
assertFailure {
FhirPathCustomResolver(CustomFhirPathFunctions()).executeFunction(
null,
context,
mutableListOf(Observation()),
"unknown",
Expand All @@ -198,15 +200,15 @@ class ConstantResolverTests {

val bundle = Bundle()
val customContext = CustomContext(bundle, bundle)
assertThat(FhirPathCustomResolver().resolveReference(customContext, org2Url, null)).isNull()
assertThat(FhirPathCustomResolver().resolveReference(null, customContext, org2Url, null)).isNull()

bundle.addEntry().resource = org1
bundle.entry[0].fullUrl = "Organization/${org1.id}"
assertThat(FhirPathCustomResolver().resolveReference(customContext, org2Url, null)).isNull()
assertThat(FhirPathCustomResolver().resolveReference(null, customContext, org2Url, null)).isNull()

bundle.addEntry().resource = org2
bundle.entry[1].fullUrl = org2Url
val reference = FhirPathCustomResolver().resolveReference(customContext, org2Url, null)
val reference = FhirPathCustomResolver().resolveReference(null, customContext, org2Url, null)
assertThat(reference).isNotNull()
assertThat(reference).isEqualTo(org2)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import io.mockk.spyk
import io.mockk.verify
import org.apache.logging.log4j.kotlin.KotlinLogger
import org.hl7.fhir.exceptions.PathEngineException
import org.hl7.fhir.r4.fhirpath.FHIRLexer
import org.hl7.fhir.r4.model.Bundle
import org.hl7.fhir.r4.model.DateTimeType
import org.hl7.fhir.r4.model.DateType
Expand All @@ -37,7 +38,6 @@ import org.hl7.fhir.r4.model.InstantType
import org.hl7.fhir.r4.model.Observation
import org.hl7.fhir.r4.model.ServiceRequest
import org.hl7.fhir.r4.model.TimeType
import org.hl7.fhir.r4.utils.FHIRLexer.FHIRLexerException
import org.junit.jupiter.api.BeforeEach
import java.util.Date
import kotlin.test.Test
Expand Down Expand Up @@ -69,7 +69,7 @@ class FhirPathUtilsTests {
assertThat(FhirPathUtils.parsePath("")).isNull()

// Invalid fhir path syntax
assertFailsWith<FHIRLexerException> { FhirPathUtils.parsePath("Bundle.#*($&id.exists()") }
assertFailsWith<FHIRLexer.FHIRLexerException> { FhirPathUtils.parsePath("Bundle.#*($&id.exists()") }
}

@Test
Expand Down Expand Up @@ -101,7 +101,7 @@ class FhirPathUtilsTests {
FhirPathUtils.evaluateCondition(null, bundle, bundle, bundle, path)
} catch (e: Exception) {
assertThat(e).isInstanceOf<SchemaException>()
assertThat(e.cause).isNotNull().isInstanceOf<FHIRLexerException>()
assertThat(e.cause).isNotNull().isInstanceOf<FHIRLexer.FHIRLexerException>()
}
}

Expand Down Expand Up @@ -193,7 +193,7 @@ class FhirPathUtilsTests {

verify {
mockedLogger.error(
"org.hl7.fhir.r4.utils.FHIRLexer\$FHIRLexerException: " +
"org.hl7.fhir.r4.fhirpath.FHIRLexer\$FHIRLexerException: " +
"Syntax error in FHIR Path Bundle.#*(\$&id.exists()."
)
}
Expand Down

0 comments on commit 0281602

Please sign in to comment.