From 7a87ccc2438c95bf33dac6e3e6a5b27e2814d6cd Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 10 Oct 2023 14:04:20 -0400 Subject: [PATCH] Migrates engine to HAPI 6.8 while forcing Workflow to stay on 6.0 (#2245) * Migrates engine to HAPI 6.8 while forcing Workflow to stay on 6.0 * comment --- buildSrc/build.gradle.kts | 2 +- buildSrc/src/main/kotlin/Dependencies.kt | 36 +++++++++------ .../src/main/kotlin/FirebaseTestLabConfig.kt | 9 ++-- buildSrc/src/main/kotlin/LicenseeConfig.kt | 4 ++ catalog/build.gradle.kts | 4 ++ contrib/barcode/build.gradle.kts | 9 +++- datacapture/build.gradle.kts | 15 +++++- .../fhirpath/FHIRPathEngineHostServices.kt | 12 +++-- .../datacapture/mapping/ResourceMapper.kt | 12 ++++- .../datacapture/QuestionnaireViewModelTest.kt | 2 +- .../FHIRPathEngineHostServicesTest.kt | 10 ++-- .../datacapture/mapping/ResourceMapperTest.kt | 2 +- demo/build.gradle.kts | 4 ++ engine/benchmark/build.gradle.kts | 2 + engine/build.gradle.kts | 18 ++++++++ .../fhir/index/DualHapiWorkerContext.kt | 46 +++++++++++++++++++ .../android/fhir/index/ResourceIndexer.kt | 5 +- .../android/fhir/impl/FhirEngineImplTest.kt | 2 +- knowledge/build.gradle.kts | 32 ++++++++++++- settings.gradle.kts | 13 ++++++ workflow-testing/build.gradle.kts | 31 +++++++++++-- workflow/benchmark/build.gradle.kts | 31 +++++++++++-- workflow/build.gradle.kts | 32 +++++++++++-- 23 files changed, 279 insertions(+), 54 deletions(-) create mode 100644 engine/src/main/java/com/google/android/fhir/index/DualHapiWorkerContext.kt diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 01550c144c..b515c1f35d 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -18,6 +18,6 @@ dependencies { implementation("com.spotify.ruler:ruler-gradle-plugin:1.2.1") - implementation("ca.uhn.hapi.fhir:hapi-fhir-structures-r4:6.0.1") + implementation("ca.uhn.hapi.fhir:hapi-fhir-structures-r4:6.8.0") implementation("com.squareup:kotlinpoet:1.12.0") } diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 67fbcd8903..baefd25852 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -88,6 +88,7 @@ object Dependencies { // Version 3.0 uses java.lang.System.Logger, which is not available on Android // Replace for Guava when this PR gets merged: https://github.com/hapifhir/hapi-fhir/pull/3977 const val caffeine = "com.github.ben-manes.caffeine:caffeine:${Versions.caffeine}" + const val guavaCaching = "ca.uhn.hapi.fhir:hapi-fhir-caching-guava:${Versions.hapiFhir}" } object Jackson { @@ -99,7 +100,7 @@ object Dependencies { const val annotations = "$coreGroup:jackson-annotations:${Versions.jackson}" const val bom = "$mainGroup:jackson-bom:${Versions.jackson}" - const val core = "$coreGroup:jackson-core:${Versions.jackson}" + const val core = "$coreGroup:jackson-core:${Versions.jacksonCore}" const val databind = "$coreGroup:jackson-databind:${Versions.jackson}" const val dataformatXml = "$dataformatGroup:jackson-dataformat-xml:${Versions.jackson}" const val jaxbAnnotations = "$moduleGroup:jackson-module-jaxb-annotations:${Versions.jackson}" @@ -243,7 +244,7 @@ object Dependencies { const val stdlib = "1.8.20" } - const val androidFhirCommon = "0.1.0-alpha04" + const val androidFhirCommon = "0.1.0-alpha05" const val androidFhirEngine = "0.1.0-beta03" const val androidFhirKnowledge = "0.1.0-alpha01" const val apacheCommonsCompress = "1.21" @@ -251,22 +252,20 @@ object Dependencies { const val caffeine = "2.9.1" const val fhirUcum = "1.0.3" const val gson = "2.9.1" - const val guava = "28.2-android" + const val guava = "32.1.2-android" - // Hapi FHIR and HL7 Core Components are interlinked. - // Newer versions of HapiFhir don't work on Android due to the use of Caffeine 3+ - // Wait for this to release (6.3): https://github.com/hapifhir/hapi-fhir/pull/4196 - const val hapiFhir = "6.0.1" - - // Newer versions don't work on Android due to Apache Commons Codec: - // Wait for this fix: https://github.com/hapifhir/org.hl7.fhir.core/issues/1046 - const val hapiFhirCore = "5.6.36" + const val hapiFhir = "6.8.0" + const val hapiFhirCore = "6.0.22" const val http = "4.11.0" - // Maximum version that supports Android API Level 24: + // Maximum Jackson libraries (excluding core) version that supports Android API Level 24: // https://github.com/FasterXML/jackson-databind/issues/3658 const val jackson = "2.13.5" + + // Maximum Jackson Core library version that supports Android API Level 24: + const val jacksonCore = "2.15.2" + const val jsonToolsPatch = "1.13" const val jsonAssert = "1.5.1" const val material = "1.9.0" @@ -312,13 +311,22 @@ object Dependencies { exclude(group = "org.apache.httpcomponents") } + fun Configuration.forceGuava() { + // Removes caffeine + exclude(module = "hapi-fhir-caching-caffeine") + exclude(group = "com.github.ben-manes.caffeine", module = "caffeine") + + resolutionStrategy { + force(guava) + force(HapiFhir.guavaCaching) + } + } + fun Configuration.forceHapiVersion() { // Removes newer versions of caffeine and manually imports 2.9 // Removes newer versions of hapi and keeps on 6.0.1 // (newer versions don't work on Android) resolutionStrategy { - force(HapiFhir.caffeine) - force(HapiFhir.fhirBase) force(HapiFhir.fhirClient) force(HapiFhir.fhirCoreConvertors) diff --git a/buildSrc/src/main/kotlin/FirebaseTestLabConfig.kt b/buildSrc/src/main/kotlin/FirebaseTestLabConfig.kt index 8b65773845..14e43a11c6 100644 --- a/buildSrc/src/main/kotlin/FirebaseTestLabConfig.kt +++ b/buildSrc/src/main/kotlin/FirebaseTestLabConfig.kt @@ -33,7 +33,6 @@ fun Project.configureFirebaseTestLabForLibraries() { "clearPackageData" to "true", ), ) - flakyTestAttempts.set(3) devices.set( listOf( mapOf( @@ -43,7 +42,7 @@ fun Project.configureFirebaseTestLabForLibraries() { "locale" to "en_US", ), mapOf( - "model" to "panther", + "model" to "MediumPhone.arm", "version" to "${project.extensions.getByType(LibraryExtension::class.java).compileSdk}", "locale" to "en_US", ), @@ -64,8 +63,6 @@ fun Project.configureFirebaseTestLabForMicroBenchmark() { "clearPackageData" to "true", ), ) - // some of the benchmark tests get timed-out in the default 15m - testTimeout.set("45m") devices.set( listOf( mapOf( @@ -86,7 +83,9 @@ private fun FlankGradleExtension.commonConfigurationForFirebaseTestLab(project: }, ) useOrchestrator.set(true) - maxTestShards.set(20) + flakyTestAttempts.set(1) + maxTestShards.set(10) + testTimeout.set("45m") directoriesToPull.set(listOf("/sdcard/Download")) resultsBucket.set("android-fhir-build-artifacts") resultsDir.set( diff --git a/buildSrc/src/main/kotlin/LicenseeConfig.kt b/buildSrc/src/main/kotlin/LicenseeConfig.kt index b0057e983b..8a09e43b8f 100644 --- a/buildSrc/src/main/kotlin/LicenseeConfig.kt +++ b/buildSrc/src/main/kotlin/LicenseeConfig.kt @@ -39,6 +39,10 @@ fun Project.configureLicensee() { ignoreDependencies("org.jacoco", "org.jacoco.agent") { because("JaCoCo is used in tests only, so it is not distributed with our library") } + allowDependency("org.javassist", "javassist", "3.29.0-GA") { + because("Multi-licensed under Apache. https://github.com/jboss-javassist/javassist") + } + // Remove once Evaluator 3 migration is over allowDependency("org.javassist", "javassist", "3.20.0-GA") { because("Multi-licensed under Apache. https://github.com/jboss-javassist/javassist") } diff --git a/catalog/build.gradle.kts b/catalog/build.gradle.kts index e4bb7a4373..d137d0a320 100644 --- a/catalog/build.gradle.kts +++ b/catalog/build.gradle.kts @@ -1,3 +1,5 @@ +import Dependencies.forceGuava + plugins { id(Plugins.BuildPlugins.application) id(Plugins.BuildPlugins.kotlinAndroid) @@ -40,6 +42,8 @@ android { kotlin { jvmToolchain(11) } } +configurations { all { forceGuava() } } + dependencies { androidTestImplementation(Dependencies.AndroidxTest.extJunit) androidTestImplementation(Dependencies.Espresso.espressoCore) diff --git a/contrib/barcode/build.gradle.kts b/contrib/barcode/build.gradle.kts index 25fa799395..2f847d9456 100644 --- a/contrib/barcode/build.gradle.kts +++ b/contrib/barcode/build.gradle.kts @@ -1,3 +1,5 @@ +import Dependencies.forceGuava + plugins { id(Plugins.BuildPlugins.androidLib) id(Plugins.BuildPlugins.kotlinAndroid) @@ -44,7 +46,12 @@ android { kotlin { jvmToolchain(11) } } -configurations { all { exclude(module = "xpp3") } } +configurations { + all { + exclude(module = "xpp3") + forceGuava() + } +} dependencies { androidTestImplementation(Dependencies.AndroidxTest.core) diff --git a/datacapture/build.gradle.kts b/datacapture/build.gradle.kts index 0b16178798..6e8dbee0a8 100644 --- a/datacapture/build.gradle.kts +++ b/datacapture/build.gradle.kts @@ -1,3 +1,6 @@ +import Dependencies.forceGuava +import Dependencies.forceHapiVersion +import Dependencies.forceJacksonVersion import java.net.URL plugins { @@ -52,7 +55,15 @@ android { afterEvaluate { configureFirebaseTestLabForLibraries() } -configurations { all { exclude(module = "xpp3") } } +configurations { + all { + exclude(module = "xpp3") + exclude(group = "net.sf.saxon", module = "Saxon-HE") + forceGuava() + forceHapiVersion() + forceJacksonVersion() + } +} dependencies { androidTestImplementation(Dependencies.AndroidxTest.core) @@ -77,10 +88,10 @@ dependencies { implementation(Dependencies.Androidx.coreKtx) implementation(Dependencies.Androidx.fragmentKtx) implementation(Dependencies.Glide.glide) + implementation(Dependencies.HapiFhir.guavaCaching) implementation(Dependencies.HapiFhir.validation) { exclude(module = "commons-logging") exclude(module = "httpclient") - exclude(group = "net.sf.saxon", module = "Saxon-HE") } implementation(Dependencies.Kotlin.kotlinCoroutinesCore) implementation(Dependencies.Kotlin.stdlib) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/fhirpath/FHIRPathEngineHostServices.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/fhirpath/FHIRPathEngineHostServices.kt index b4b6c786cd..ee33bfa77e 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/fhirpath/FHIRPathEngineHostServices.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/fhirpath/FHIRPathEngineHostServices.kt @@ -25,8 +25,12 @@ import org.hl7.fhir.r4.utils.FHIRPathEngine * Resolves constants defined in the fhir path expressions beyond those defined in the specification */ internal object FHIRPathEngineHostServices : FHIRPathEngine.IEvaluationContext { - override fun resolveConstant(appContext: Any?, name: String?, beforeContext: Boolean): Base? = - (appContext as? Map<*, *>)?.get(name) as? Base + override fun resolveConstant( + appContext: Any?, + name: String?, + beforeContext: Boolean, + ): List? = + ((appContext as? Map<*, *>)?.get(name) as? Base)?.let { listOf(it) } ?: emptyList() override fun resolveConstantType(appContext: Any?, name: String?): TypeDetails { throw UnsupportedOperationException() @@ -59,7 +63,7 @@ internal object FHIRPathEngineHostServices : FHIRPathEngine.IEvaluationContext { throw UnsupportedOperationException() } - override fun resolveReference(appContext: Any?, url: String?): Base { + override fun resolveReference(appContext: Any?, url: String?, refContext: Base?): Base? { throw UnsupportedOperationException() } @@ -67,7 +71,7 @@ internal object FHIRPathEngineHostServices : FHIRPathEngine.IEvaluationContext { throw UnsupportedOperationException() } - override fun resolveValueSet(appContext: Any?, url: String?): ValueSet { + override fun resolveValueSet(appContext: Any?, url: String?): ValueSet? { throw UnsupportedOperationException() } } diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/mapping/ResourceMapper.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/mapping/ResourceMapper.kt index 28cf09290b..aaf60345d7 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/mapping/ResourceMapper.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/mapping/ResourceMapper.kt @@ -775,13 +775,21 @@ private fun Base.asExpectedReferenceType(): Type { this@asExpectedReferenceType as Resource Reference().apply { reference = - "${this@asExpectedReferenceType.resourceType}/${this@asExpectedReferenceType.logicalId}" + if (this@asExpectedReferenceType.resourceType != null) { + "${this@asExpectedReferenceType.resourceType}/${this@asExpectedReferenceType.logicalId}" + } else { + this@asExpectedReferenceType.logicalId + } } } this is IdType -> Reference().apply { reference = - "${this@asExpectedReferenceType.resourceType}/${this@asExpectedReferenceType.idPart}" + if (this@asExpectedReferenceType.resourceType != null) { + "${this@asExpectedReferenceType.resourceType}/${this@asExpectedReferenceType.idPart}" + } else { + this@asExpectedReferenceType.idPart + } } else -> throw FHIRException("Expression supplied does not evaluate to IdType.") } diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/QuestionnaireViewModelTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/QuestionnaireViewModelTest.kt index 48e44cd743..a9b2736ca1 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/QuestionnaireViewModelTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/QuestionnaireViewModelTest.kt @@ -4400,7 +4400,7 @@ class QuestionnaireViewModelTest { Extension( "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-answerExpression", Expression().apply { - this.expression = "Observation?subject={{%patient.id}}" + this.expression = "Observation?subject=Patient/{{%patient.id}}" this.language = Expression.ExpressionLanguage.APPLICATION_XFHIRQUERY.toCode() }, ), diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/fhirpath/FHIRPathEngineHostServicesTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/fhirpath/FHIRPathEngineHostServicesTest.kt index bcadcad0e6..936493527d 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/fhirpath/FHIRPathEngineHostServicesTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/fhirpath/FHIRPathEngineHostServicesTest.kt @@ -30,28 +30,28 @@ class FHIRPathEngineHostServicesTest { fun testFHIRPathHostServices_resolveConstantKeyNotPresent_returnsNull() { val answer = FHIRPathEngineHostServices.resolveConstant(mapOf("A" to IntegerType(1)), "B", true) - assertThat(answer).isNull() + assertThat(answer).isEmpty() } @Test fun testFHIRPathHostServices_resolveConstantKeyAndValuePresent_returnsNotNull() { val answer = FHIRPathEngineHostServices.resolveConstant(mapOf("A" to IntegerType(1)), "A", true) - assertThat((answer as Type).asStringValue()).isEqualTo("1") + assertThat((answer?.first() as Type).asStringValue()).isEqualTo("1") } @Test fun testFHIRPathHostServices_resolveConstantKeyPresentAndValueNotPresent_returnsNull() { val answer = FHIRPathEngineHostServices.resolveConstant(mapOf("A" to null), "A", true) - assertThat(answer).isNull() + assertThat(answer).isEmpty() } @Test fun testFHIRPathHostServices_resolveConstantNullAppContext_returnsNull() { val answer = FHIRPathEngineHostServices.resolveConstant(null, "A", true) - assertThat(answer).isNull() + assertThat(answer).isEmpty() } @Test @@ -97,7 +97,7 @@ class FHIRPathEngineHostServicesTest { @Test fun testFHIRPathHostServices_resolveReference_throwsUnsupportedOperationException() { assertThrows(UnsupportedOperationException::class.java) { - FHIRPathEngineHostServices.resolveReference(mapOf(), "") + FHIRPathEngineHostServices.resolveReference(mapOf(), "", null) } } diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/mapping/ResourceMapperTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/mapping/ResourceMapperTest.kt index 55ce7f3bd0..fefc484dde 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/mapping/ResourceMapperTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/mapping/ResourceMapperTest.kt @@ -1564,7 +1564,7 @@ class ResourceMapperTest { val questionnaireResponse = ResourceMapper.populate(questionnaire, patient) assertThat((questionnaireResponse.item[0].answer[0].value as Reference).reference) - .isEqualTo(patient.id) + .isEqualTo(patient.idPart) } @Test diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts index 0e53d5f6ba..9e8718df2f 100644 --- a/demo/build.gradle.kts +++ b/demo/build.gradle.kts @@ -1,3 +1,5 @@ +import Dependencies.forceGuava + plugins { id(Plugins.BuildPlugins.application) id(Plugins.BuildPlugins.kotlinAndroid) @@ -38,6 +40,8 @@ android { kotlin { jvmToolchain(11) } } +configurations { all { forceGuava() } } + dependencies { androidTestImplementation(Dependencies.AndroidxTest.extJunit) androidTestImplementation(Dependencies.Espresso.espressoCore) diff --git a/engine/benchmark/build.gradle.kts b/engine/benchmark/build.gradle.kts index 2343b4548d..42c50096c1 100644 --- a/engine/benchmark/build.gradle.kts +++ b/engine/benchmark/build.gradle.kts @@ -1,3 +1,4 @@ +import Dependencies.forceGuava import Dependencies.forceHapiVersion import Dependencies.forceJacksonVersion import Dependencies.removeIncompatibleDependencies @@ -50,6 +51,7 @@ afterEvaluate { configureFirebaseTestLabForMicroBenchmark() } configurations { all { removeIncompatibleDependencies() + forceGuava() forceHapiVersion() forceJacksonVersion() } diff --git a/engine/build.gradle.kts b/engine/build.gradle.kts index f1f556fd2c..155f481ddc 100644 --- a/engine/build.gradle.kts +++ b/engine/build.gradle.kts @@ -1,3 +1,6 @@ +import Dependencies.forceGuava +import Dependencies.forceHapiVersion +import Dependencies.forceJacksonVersion import codegen.GenerateSearchParamsTask import java.net.URL @@ -84,6 +87,10 @@ configurations { exclude(module = "jakarta.activation-api") exclude(module = "javax.activation") exclude(module = "jakarta.xml.bind-api") + + forceGuava() + forceHapiVersion() + forceJacksonVersion() } } @@ -98,6 +105,17 @@ dependencies { api(Dependencies.HapiFhir.structuresR4) { exclude(module = "junit") } + // We have removed the dependency on Caffeine from HAPI due to conflicts with android + // Guave Caching must be individually loaded instead. + implementation(Dependencies.HapiFhir.guavaCaching) + + // Validation to load system types into FhirPath's Context + // The loading happens via a ResourceStream in XML and thus + // XML parsers are also necessary. + implementation(Dependencies.HapiFhir.validationR4) + implementation(Dependencies.woodstox) + implementation(Dependencies.xerces) + coreLibraryDesugaring(Dependencies.desugarJdkLibs) implementation(Dependencies.Androidx.datastorePref) diff --git a/engine/src/main/java/com/google/android/fhir/index/DualHapiWorkerContext.kt b/engine/src/main/java/com/google/android/fhir/index/DualHapiWorkerContext.kt new file mode 100644 index 0000000000..bfd12c5422 --- /dev/null +++ b/engine/src/main/java/com/google/android/fhir/index/DualHapiWorkerContext.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.fhir.index + +import ca.uhn.fhir.context.FhirContext +import org.fhir.ucum.UcumEssenceService +import org.hl7.fhir.r4.context.SimpleWorkerContext +import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext +import org.hl7.fhir.r4.model.Resource + +/** + * Merges the caching system in the HAPIWorker with the Ucum Support in the SimpleWorker + * + * TODO: Ideally we update the upstream's HapiWorkerContext to support ucumServices. + */ +class DualHapiWorkerContext : SimpleWorkerContext() { + val hapi = + HapiWorkerContext( + FhirContext.forR4Cached(), + FhirContext.forR4Cached().validationSupport, + ) + + init { + // TODO: get this service from Common: UnitConverter.ucumService + this.ucumService = UcumEssenceService(this::class.java.getResourceAsStream("/ucum-essence.xml")) + } + + override fun fetchResourceWithException(class_: Class?, uri: String?): T { + return hapi.fetchResourceWithException(class_, uri) + ?: super.fetchResourceWithException(class_, uri) + } +} diff --git a/engine/src/main/java/com/google/android/fhir/index/ResourceIndexer.kt b/engine/src/main/java/com/google/android/fhir/index/ResourceIndexer.kt index 3d553a7fc7..b1c3f81468 100644 --- a/engine/src/main/java/com/google/android/fhir/index/ResourceIndexer.kt +++ b/engine/src/main/java/com/google/android/fhir/index/ResourceIndexer.kt @@ -34,7 +34,6 @@ import com.google.android.fhir.search.LAST_UPDATED import com.google.android.fhir.search.LOCAL_LAST_UPDATED import com.google.android.fhir.ucumUrl import java.math.BigDecimal -import org.hl7.fhir.r4.context.SimpleWorkerContext import org.hl7.fhir.r4.model.Address import org.hl7.fhir.r4.model.Base import org.hl7.fhir.r4.model.CanonicalType @@ -68,9 +67,7 @@ import org.hl7.fhir.r4.utils.FHIRPathEngine internal class ResourceIndexer( private val searchParamDefinitionsProvider: SearchParamDefinitionsProvider, ) { - // Switched HapiWorkerContext to SimpleWorkerContext as a fix for - // https://github.com/google/android-fhir/issues/768 - private val fhirPathEngine = FHIRPathEngine(SimpleWorkerContext()) + private val fhirPathEngine = FHIRPathEngine(DualHapiWorkerContext()) fun index(resource: R) = extractIndexValues(resource) diff --git a/engine/src/test/java/com/google/android/fhir/impl/FhirEngineImplTest.kt b/engine/src/test/java/com/google/android/fhir/impl/FhirEngineImplTest.kt index 2229cb0f9d..a77a6b76f4 100644 --- a/engine/src/test/java/com/google/android/fhir/impl/FhirEngineImplTest.kt +++ b/engine/src/test/java/com/google/android/fhir/impl/FhirEngineImplTest.kt @@ -241,7 +241,7 @@ class FhirEngineImplTest { fhirEngine.search("CustomResource?active=true&gender=male&_sort=name&_count=2") } } - assertThat(exception.message).isEqualTo("Unknown resource typeCustomResource") + assertThat(exception.message).isEqualTo("Unknown resource type CustomResource") } @Test diff --git a/knowledge/build.gradle.kts b/knowledge/build.gradle.kts index 7003e1009a..22c4f09d96 100644 --- a/knowledge/build.gradle.kts +++ b/knowledge/build.gradle.kts @@ -1,3 +1,4 @@ +import Dependencies.guava import java.net.URL plugins { @@ -70,6 +71,33 @@ configurations { all { exclude(module = "xpp3") exclude(module = "xpp3_min") + exclude( + module = "hapi-fhir-structures-r4b", + ) + resolutionStrategy { + force(Dependencies.guava) + force("ca.uhn.hapi.fhir:hapi-fhir-base:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-client:6.0.1") + force("ca.uhn.hapi.fhir:org.hl7.fhir.convertors:6.0.22") + + force("ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2:6.0.1") + force("ca.uhn.hapi.fhir:org.hl7.fhir.dstu2016may:6.0.22") + force("ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-structures-r4:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-structures-r5:6.0.1") + force("ca.uhn.hapi.fhir:org.hl7.fhir.utilities:6.0.22") + + force("ca.uhn.hapi.fhir:org.hl7.fhir.dstu2:6.0.22") + force("ca.uhn.hapi.fhir:org.hl7.fhir.dstu3:6.0.22") + force("ca.uhn.hapi.fhir:org.hl7.fhir.r4:6.0.22") + force("ca.uhn.hapi.fhir:org.hl7.fhir.r4b:6.0.22") + force("ca.uhn.hapi.fhir:org.hl7.fhir.r5:6.0.22") + + force("ca.uhn.hapi.fhir:hapi-fhir-validation:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-validation-resources-dstu3:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-validation-resources-r4:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-validation-resources-r5:6.0.1") + } } } @@ -81,7 +109,7 @@ dependencies { androidTestImplementation(Dependencies.junit) androidTestImplementation(Dependencies.truth) - api(Dependencies.HapiFhir.structuresR4) { exclude(module = "junit") } + api("ca.uhn.hapi.fhir:hapi-fhir-structures-r4:6.0.1") { exclude(module = "junit") } coreLibraryDesugaring(Dependencies.desugarJdkLibs) @@ -92,7 +120,7 @@ dependencies { implementation(Dependencies.Room.runtime) implementation(Dependencies.timber) implementation(Dependencies.http) - implementation(Dependencies.HapiFhir.fhirCoreConvertors) + implementation("ca.uhn.hapi.fhir:org.hl7.fhir.convertors:6.0.22") implementation(Dependencies.apacheCommonsCompress) kapt(Dependencies.Room.compiler) diff --git a/settings.gradle.kts b/settings.gradle.kts index 7cc39b2243..a3fb255a35 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -28,6 +28,19 @@ if (kokoroRun == true) { } } +// NECESSARY force of the Jackson to run generateSearchParams in the new version of HAPI (6.8) +buildscript { + dependencies { + classpath("com.fasterxml.jackson.core:jackson-core:2.15.2") + classpath("com.fasterxml.jackson.core:jackson-annotations:2.15.2") + classpath("com.fasterxml.jackson.core:jackson-databind:2.15.2") + classpath("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.15.2") + classpath("com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.15.2") + classpath("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2") + classpath("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2") + } +} + include(":catalog") include(":common") diff --git a/workflow-testing/build.gradle.kts b/workflow-testing/build.gradle.kts index b9ee8a4ffb..55fcd55932 100644 --- a/workflow-testing/build.gradle.kts +++ b/workflow-testing/build.gradle.kts @@ -1,5 +1,3 @@ -import Dependencies.forceHapiVersion -import Dependencies.forceJacksonVersion import Dependencies.removeIncompatibleDependencies plugins { @@ -17,8 +15,33 @@ android { configurations { all { removeIncompatibleDependencies() - forceHapiVersion() - forceJacksonVersion() + exclude( + module = "hapi-fhir-structures-r4b", + ) + resolutionStrategy { + force(Dependencies.guava) + force("ca.uhn.hapi.fhir:hapi-fhir-base:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-client:6.0.1") + force("ca.uhn.hapi.fhir:org.hl7.fhir.convertors:5.6.36") + + force("ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2:6.0.1") + force("ca.uhn.hapi.fhir:org.hl7.fhir.dstu2016may:5.6.36") + force("ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-structures-r4:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-structures-r5:6.0.1") + force("ca.uhn.hapi.fhir:org.hl7.fhir.utilities:5.6.36") + + force("ca.uhn.hapi.fhir:org.hl7.fhir.dstu2:5.6.36") + force("ca.uhn.hapi.fhir:org.hl7.fhir.dstu3:5.6.36") + force("ca.uhn.hapi.fhir:org.hl7.fhir.r4:5.6.36") + force("ca.uhn.hapi.fhir:org.hl7.fhir.r4b:5.6.36") + force("ca.uhn.hapi.fhir:org.hl7.fhir.r5:5.6.36") + + force("ca.uhn.hapi.fhir:hapi-fhir-validation:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-validation-resources-dstu3:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-validation-resources-r4:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-validation-resources-r5:6.0.1") + } } } diff --git a/workflow/benchmark/build.gradle.kts b/workflow/benchmark/build.gradle.kts index c7bee7157d..cc7f5f84ac 100644 --- a/workflow/benchmark/build.gradle.kts +++ b/workflow/benchmark/build.gradle.kts @@ -1,5 +1,3 @@ -import Dependencies.forceHapiVersion -import Dependencies.forceJacksonVersion import Dependencies.removeIncompatibleDependencies plugins { @@ -50,8 +48,33 @@ afterEvaluate { configureFirebaseTestLabForMicroBenchmark() } configurations { all { removeIncompatibleDependencies() - forceHapiVersion() - forceJacksonVersion() + exclude( + module = "hapi-fhir-structures-r4b", + ) + resolutionStrategy { + force(Dependencies.guava) + force("ca.uhn.hapi.fhir:hapi-fhir-base:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-client:6.0.1") + force("ca.uhn.hapi.fhir:org.hl7.fhir.convertors:5.6.36") + + force("ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2:6.0.1") + force("ca.uhn.hapi.fhir:org.hl7.fhir.dstu2016may:5.6.36") + force("ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-structures-r4:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-structures-r5:6.0.1") + force("ca.uhn.hapi.fhir:org.hl7.fhir.utilities:5.6.36") + + force("ca.uhn.hapi.fhir:org.hl7.fhir.dstu2:5.6.36") + force("ca.uhn.hapi.fhir:org.hl7.fhir.dstu3:5.6.36") + force("ca.uhn.hapi.fhir:org.hl7.fhir.r4:5.6.36") + force("ca.uhn.hapi.fhir:org.hl7.fhir.r4b:5.6.36") + force("ca.uhn.hapi.fhir:org.hl7.fhir.r5:5.6.36") + + force("ca.uhn.hapi.fhir:hapi-fhir-validation:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-validation-resources-dstu3:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-validation-resources-r4:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-validation-resources-r5:6.0.1") + } } } diff --git a/workflow/build.gradle.kts b/workflow/build.gradle.kts index 85fb74cc8c..983e2c7534 100644 --- a/workflow/build.gradle.kts +++ b/workflow/build.gradle.kts @@ -1,5 +1,5 @@ -import Dependencies.forceHapiVersion import Dependencies.forceJacksonVersion +import Dependencies.guava import Dependencies.removeIncompatibleDependencies import java.net.URL @@ -78,7 +78,33 @@ afterEvaluate { configureFirebaseTestLabForLibraries() } configurations { all { removeIncompatibleDependencies() - forceHapiVersion() + exclude( + module = "hapi-fhir-structures-r4b", + ) + resolutionStrategy { + force(Dependencies.guava) + force("ca.uhn.hapi.fhir:hapi-fhir-base:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-client:6.0.1") + force("ca.uhn.hapi.fhir:org.hl7.fhir.convertors:5.6.36") + + force("ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2:6.0.1") + force("ca.uhn.hapi.fhir:org.hl7.fhir.dstu2016may:5.6.36") + force("ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-structures-r4:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-structures-r5:6.0.1") + force("ca.uhn.hapi.fhir:org.hl7.fhir.utilities:5.6.36") + + force("ca.uhn.hapi.fhir:org.hl7.fhir.dstu2:5.6.36") + force("ca.uhn.hapi.fhir:org.hl7.fhir.dstu3:5.6.36") + force("ca.uhn.hapi.fhir:org.hl7.fhir.r4:5.6.36") + force("ca.uhn.hapi.fhir:org.hl7.fhir.r4b:5.6.36") + force("ca.uhn.hapi.fhir:org.hl7.fhir.r5:5.6.36") + + force("ca.uhn.hapi.fhir:hapi-fhir-validation:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-validation-resources-dstu3:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-validation-resources-r4:6.0.1") + force("ca.uhn.hapi.fhir:hapi-fhir-validation-resources-r5:6.0.1") + } forceJacksonVersion() } } @@ -98,7 +124,7 @@ dependencies { androidTestImplementation(Dependencies.xmlUnit) androidTestImplementation(project(":workflow-testing")) - api(Dependencies.HapiFhir.structuresR4) { exclude(module = "junit") } + api("ca.uhn.hapi.fhir:hapi-fhir-structures-r4:6.0.1") { exclude(module = "junit") } implementation(Dependencies.Androidx.coreKtx)