diff --git a/android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/ConfigurationRegistry.kt b/android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/ConfigurationRegistry.kt index 99d2e31039..50579cce38 100644 --- a/android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/ConfigurationRegistry.kt +++ b/android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/ConfigurationRegistry.kt @@ -611,7 +611,7 @@ constructor( context = context, configService = configService, metadataResource = resource, - filePath = + subFilePath = "${KnowledgeManagerUtil.KNOWLEDGE_MANAGER_ASSETS_SUBFOLDER}/${resource.resourceType}/${resource.idElement.idPart}.json", ), ) diff --git a/android/engine/src/main/java/org/smartregister/fhircore/engine/util/KnowledgeManagerUtil.kt b/android/engine/src/main/java/org/smartregister/fhircore/engine/util/KnowledgeManagerUtil.kt index e1cf11ad0f..95697941d3 100644 --- a/android/engine/src/main/java/org/smartregister/fhircore/engine/util/KnowledgeManagerUtil.kt +++ b/android/engine/src/main/java/org/smartregister/fhircore/engine/util/KnowledgeManagerUtil.kt @@ -28,14 +28,26 @@ object KnowledgeManagerUtil { const val KNOWLEDGE_MANAGER_ASSETS_SUBFOLDER = "km" private val fhirContext = FhirContext.forR4Cached() + /** + * Util method that creates a physical file and writes the Metadata FHIR resource content to it. + * Note the filepath provided is appended to the apps private directory as returned by + * Context.filesDir + * + * @param subFilePath the path of the file but within the apps private directory + * {Context.filesDir} + * @param metadataResource the actual FHIR Resource of type MetadataResource + * @param configService the configuration service + * @param context the application context + * @return File the file object after creating and writing + */ fun writeToFile( - filePath: String, + subFilePath: String, metadataResource: MetadataResource, configService: ConfigService, context: Context, ): File = context - .createFileInPrivateDirectory(filePath) + .createFileInPrivateDirectory(subFilePath) .also { it.parentFile?.mkdirs() } .apply { writeText( diff --git a/android/engine/src/main/java/org/smartregister/fhircore/engine/util/ParallelUtil.kt b/android/engine/src/main/java/org/smartregister/fhircore/engine/util/ParallelUtil.kt index 895f4be679..78b46a65bb 100644 --- a/android/engine/src/main/java/org/smartregister/fhircore/engine/util/ParallelUtil.kt +++ b/android/engine/src/main/java/org/smartregister/fhircore/engine/util/ParallelUtil.kt @@ -16,12 +16,9 @@ package org.smartregister.fhircore.engine.util -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch /** * Launch a new coroutine for each map iteration using async. From @@ -37,16 +34,10 @@ suspend fun Iterable.pmap(f: suspend (A) -> B): Iterable = coroutin } /** - * Launch a new coroutine for each loop iteration using launch and the Default Dispatcher for - * computationaly intensive tasks. + * Launch a new coroutine for each loop iteration using async. * * @param T the type of elements in the iterable */ suspend fun Iterable.forEachAsync(action: suspend (T) -> Unit): Unit = coroutineScope { - forEach { launch(Dispatchers.Default) { action(it) } } + forEach { async { action(it) } } } - -suspend fun Iterable.forEachAsync( - dispatcher: CoroutineDispatcher, - action: suspend (T) -> Unit, -): Unit = coroutineScope { forEach { launch(dispatcher) { action(it) } } } diff --git a/android/engine/src/test/java/org/smartregister/fhircore/engine/configuration/ConfigurationRegistryTest.kt b/android/engine/src/test/java/org/smartregister/fhircore/engine/configuration/ConfigurationRegistryTest.kt index 31e2665ea1..7ea15619cc 100644 --- a/android/engine/src/test/java/org/smartregister/fhircore/engine/configuration/ConfigurationRegistryTest.kt +++ b/android/engine/src/test/java/org/smartregister/fhircore/engine/configuration/ConfigurationRegistryTest.kt @@ -1028,7 +1028,7 @@ class ConfigurationRegistryTest : RobolectricTest() { configService = configService, metadataResource = resource, context = context, - filePath = + subFilePath = "${KnowledgeManagerUtil.KNOWLEDGE_MANAGER_ASSETS_SUBFOLDER}/${resource.resourceType}/${resource.idElement.idPart}.json", ) assertNotNull(resultFile) diff --git a/android/engine/src/test/java/org/smartregister/fhircore/engine/util/KnowledgeManagerUtilTest.kt b/android/engine/src/test/java/org/smartregister/fhircore/engine/util/KnowledgeManagerUtilTest.kt new file mode 100644 index 0000000000..2cd1c0dbf7 --- /dev/null +++ b/android/engine/src/test/java/org/smartregister/fhircore/engine/util/KnowledgeManagerUtilTest.kt @@ -0,0 +1,75 @@ +/* + * Copyright 2021-2024 Ona Systems, Inc + * + * 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 org.smartregister.fhircore.engine.util + +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import ca.uhn.fhir.context.FhirContext +import java.io.File +import org.hl7.fhir.r4.model.StructureMap +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.smartregister.fhircore.engine.app.AppConfigService +import org.smartregister.fhircore.engine.robolectric.RobolectricTest + +class KnowledgeManagerUtilTest : RobolectricTest() { + + private lateinit var configService: AppConfigService + private val context = ApplicationProvider.getApplicationContext()!! + + @Before + fun setUp() { + configService = AppConfigService(context) + } + + @Test + fun testWriteToFile() { + val structureMap = StructureMap().apply { id = "structure-map-id" } + + val filePath = + "${KnowledgeManagerUtil.KNOWLEDGE_MANAGER_ASSETS_SUBFOLDER}/StructureMap/structure-map-id.json" + val absoluteFilePath = "${context.filesDir}/$filePath" + + val file = File(absoluteFilePath) + Assert.assertFalse(file.exists()) + + KnowledgeManagerUtil.writeToFile(filePath, structureMap, configService, context) + + Assert.assertTrue(file.exists()) + + val savedStructureMap = + FhirContext.forR4Cached().newJsonParser().parseResource(file.readText()) as StructureMap + Assert.assertNotNull(savedStructureMap.url) + Assert.assertEquals( + "http://fake.base.url.com/StructureMap/structure-map-id", + savedStructureMap.url, + ) + } + + @After + fun tearDown() { + val testFile = + File( + "${context.filesDir}/${KnowledgeManagerUtil.KNOWLEDGE_MANAGER_ASSETS_SUBFOLDER}/StructureMap/structure-map-id.json", + ) + if (testFile.exists()) { + testFile.delete() + } + } +} diff --git a/android/gradle/libs.versions.toml b/android/gradle/libs.versions.toml index 91b92d4287..73f98b8d69 100644 --- a/android/gradle/libs.versions.toml +++ b/android/gradle/libs.versions.toml @@ -27,7 +27,7 @@ espresso-core = "3.6.1" fhir-sdk-contrib-barcode = "0.1.0-beta3-preview7-rc1-SNAPSHOT" fhir-sdk-contrib-locationwidget = "0.1.0-alpha01-preview2-rc1-SNAPSHOT" fhir-sdk-data-capture = "1.2.0-preview4-SNAPSHOT" -fhir-sdk-engine = "1.0.0-preview15-SNAPSHOT" +fhir-sdk-engine = "1.0.0-preview16-SNAPSHOT" fhir-sdk-knowledge = "0.1.0-alpha03-preview5-rc1-SNAPSHOT" fhir-sdk-workflow = "0.1.0-alpha04-preview10-rc1-SNAPSHOT" fragment-ktx = "1.8.3"