Skip to content

Commit 6b034e8

Browse files
Merge branch 'main' into feature/fix_infinite_scroll_page
2 parents 552be3f + 53ca669 commit 6b034e8

File tree

46 files changed

+583
-523
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+583
-523
lines changed

.github/workflows/ci.yml

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ on:
1010
merge_group:
1111
branches: [ main ]
1212

13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.ref }}
15+
cancel-in-progress: true
16+
1317
env:
1418
FHIRCORE_USERNAME: ${{ secrets.FHIRCORE_USERNAME }}
1519
FHIRCORE_ACCESS_TOKEN: ${{ secrets.FHIRCORE_ACCESS_TOKEN }}
@@ -21,13 +25,9 @@ jobs:
2125
runs-on: ubuntu-latest
2226
strategy:
2327
matrix:
24-
api-level: [30]
28+
api-level: [34]
29+
2530
steps:
26-
- name: Cancel Previous workflow runs
27-
uses: styfle/[email protected]
28-
with:
29-
access_token: ${{ github.token }}
30-
3131
- name: Checkout 🛎️
3232
uses: actions/checkout@v4
3333

@@ -106,21 +106,17 @@ jobs:
106106

107107

108108
- name: Upload Engine module test coverage report to Codecov
109-
if: matrix.api-level == 30 # Only upload coverage on API level 30
109+
if: matrix.api-level == 34 # Only upload coverage on API level 34
110110
working-directory: android
111111
run: bash <(curl -s https://codecov.io/bash) -F engine -f "engine/build/reports/jacoco/fhircoreJacocoReport/fhircoreJacocoReport.xml"
112112

113113
geowidget-tests:
114114
runs-on: ubuntu-latest
115115
strategy:
116116
matrix:
117-
api-level: [30]
117+
api-level: [34]
118+
118119
steps:
119-
- name: Cancel Previous workflow runs
120-
uses: styfle/[email protected]
121-
with:
122-
access_token: ${{ github.token }}
123-
124120
- name: Checkout 🛎️
125121
uses: actions/checkout@v4
126122

@@ -198,20 +194,17 @@ jobs:
198194
path: android/geowidget/build/reports
199195

200196
- name: Upload Geowidget module test coverage report to Codecov
201-
if: matrix.api-level == 30 # Only upload coverage on API level 30
197+
if: matrix.api-level == 34 # Only upload coverage on API level 34
202198
working-directory: android
203199
run: bash <(curl -s https://codecov.io/bash) -F geowidget -f "geowidget/build/reports/jacoco/fhircoreJacocoReport/fhircoreJacocoReport.xml"
204200

205201
quest-tests:
206202
runs-on: ubuntu-latest
207203
strategy:
208204
matrix:
209-
api-level: [30]
210-
steps:
211-
- name: Cancel Previous workflow runs
212-
uses: styfle/[email protected]
213-
with:
214-
access_token: ${{ github.token }}
205+
api-level: [34]
206+
207+
steps:
215208
- name: Checkout 🛎️
216209
uses: actions/checkout@v4
217210

@@ -315,6 +308,6 @@ jobs:
315308
path: android/quest/build/reports
316309

317310
- name: Upload Quest module test coverage report to Codecov
318-
if: matrix.api-level == 30 # Only upload coverage on API level 30
311+
if: matrix.api-level == 34 # Only upload coverage on API level 34
319312
working-directory: android
320-
run: bash <(curl -s https://codecov.io/bash) -F quest -f "quest/build/reports/jacoco/fhircoreJacocoReport/fhircoreJacocoReport.xml"
313+
run: bash <(curl -s https://codecov.io/bash) -F quest -f "quest/build/reports/jacoco/fhircoreJacocoReport/fhircoreJacocoReport.xml"

android/engine/build.gradle.kts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent
33

44
plugins {
55
`jacoco-report`
6-
`ktlint`
6+
ktlint
77
id("com.android.library")
88
id("kotlin-android")
99
id("kotlin-kapt")
@@ -162,7 +162,7 @@ dependencies {
162162
api(libs.glide)
163163
api(libs.knowledge) { exclude(group = "org.slf4j", module = "jcl-over-slf4j") }
164164
api(libs.p2p.lib)
165-
api(libs.jjwt)
165+
api(libs.java.jwt)
166166
api(libs.fhir.common.utils) { exclude(group = "org.slf4j", module = "jcl-over-slf4j") }
167167
api(libs.runtime.livedata)
168168
api(libs.foundation)
@@ -180,8 +180,8 @@ dependencies {
180180
api(libs.data.capture) {
181181
isTransitive = true
182182
exclude(group = "ca.uhn.hapi.fhir")
183-
exclude(group = "com.google.android.fhir", module = "engine")
184183
exclude(group = "com.google.android.fhir", module = "common")
184+
exclude(group = "org.smartregister", module = "common")
185185
exclude(group = "org.slf4j", module = "jcl-over-slf4j")
186186
}
187187
api(libs.cqf.fhir.cr) {
@@ -194,23 +194,19 @@ dependencies {
194194
exclude(group = "xerces")
195195
exclude(group = "com.github.java-json-tools")
196196
exclude(group = "org.codehaus.woodstox")
197-
exclude(group = "com.google.android.fhir", module = "common")
198197
exclude(group = "com.google.android.fhir", module = "engine")
198+
exclude(group = "org.smartregister", module = "engine")
199199
exclude(group = "com.github.ben-manes.caffeine")
200200
}
201201
api(libs.contrib.barcode) {
202202
isTransitive = true
203203
exclude(group = "org.smartregister", module = "data-capture")
204204
exclude(group = "ca.uhn.hapi.fhir")
205-
exclude(group = "com.google.android.fhir", module = "common")
206-
exclude(group = "com.google.android.fhir", module = "engine")
207205
}
208206
api(libs.contrib.locationwidget) {
209207
isTransitive = true
210208
exclude(group = "org.smartregister", module = "data-capture")
211209
exclude(group = "ca.uhn.hapi.fhir")
212-
exclude(group = "com.google.android.fhir", module = "common")
213-
exclude(group = "com.google.android.fhir", module = "engine")
214210
}
215211
api(libs.fhir.engine) {
216212
isTransitive = true

android/engine/src/androidTest/java/org/smartregister/fhircore/engine/util/extension/FhirEngineExtensionKtTest.kt

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import com.google.android.fhir.FhirEngineProvider
2525
import com.google.android.fhir.search.search
2626
import kotlinx.coroutines.launch
2727
import kotlinx.coroutines.runBlocking
28+
import kotlinx.coroutines.test.runTest
2829
import org.hl7.fhir.r4.model.Patient
2930
import org.hl7.fhir.r4.model.Questionnaire
3031
import org.hl7.fhir.r4.model.Resource
@@ -57,19 +58,15 @@ class FhirEngineExtensionKtTest {
5758
}
5859

5960
@Test
60-
fun test_search_time_searches_sequentially_and_short_running_query_waits() {
61+
fun test_search_time_searches_sequentially_and_short_running_query_waits() = runTest {
6162
val fetchedResources = mutableListOf<Resource>()
62-
runBlocking {
63-
launch {
64-
val patients = fhirEngine.search<Patient> {}.map { it.resource }
65-
fetchedResources += patients
66-
}
6763

68-
launch {
69-
val questionnaires = fhirEngine.search<Questionnaire> {}.map { it.resource }
70-
fetchedResources += questionnaires
71-
}
72-
}
64+
val patients = fhirEngine.search<Patient> {}.map { it.resource }
65+
fetchedResources += patients
66+
67+
val questionnaires = fhirEngine.search<Questionnaire> {}.map { it.resource }
68+
fetchedResources += questionnaires
69+
7370
val indexOfResultOfShortQuery =
7471
fetchedResources.indexOfFirst { it.resourceType == ResourceType.Questionnaire }
7572
val indexOfResultOfLongQuery =

android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/ConfigurationRegistry.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ constructor(
104104
private var _isNonProxy = BuildConfig.IS_NON_PROXY_APK
105105
private val fhirContext = FhirContext.forR4Cached()
106106
private val authConfiguration = configService.provideAuthConfiguration()
107-
private val jsonParser = fhirContext.newJsonParser()
108107

109108
/**
110109
* Retrieve configuration for the provided [ConfigType]. The JSON retrieved from [configsJsonMap]
@@ -629,9 +628,14 @@ constructor(
629628
resource.idElement.idPart
630629
}
631630

632-
return File(context.filesDir, "$fileName.json").apply {
633-
writeText(jsonParser.encodeResourceToString(resource))
634-
}
631+
return File(
632+
context.filesDir,
633+
"$KNOWLEDGE_MANAGER_ASSETS_SUBFOLDER/${resource.resourceType}/$fileName.json",
634+
)
635+
.apply {
636+
this.parentFile?.mkdirs()
637+
writeText(fhirContext.newJsonParser().encodeResourceToString(resource))
638+
}
635639
}
636640

637641
/**
@@ -813,6 +817,7 @@ constructor(
813817
const val PAGINATION_NEXT = "next"
814818
const val RESOURCES_PATH = "resources/"
815819
const val SYNC_LOCATION_IDS = "_syncLocations"
820+
const val KNOWLEDGE_MANAGER_ASSETS_SUBFOLDER = "km"
816821

817822
/**
818823
* The list of resources whose types can be synced down as part of the Composition configs.

android/engine/src/main/java/org/smartregister/fhircore/engine/data/local/DefaultRepository.kt

Lines changed: 39 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,15 @@ constructor(
114114
@ApplicationContext open val context: Context,
115115
) {
116116

117-
suspend inline fun <reified T : Resource> loadResource(resourceId: String): T? {
118-
return withContext(dispatcherProvider.io()) { fhirEngine.loadResource(resourceId) }
119-
}
117+
suspend inline fun <reified T : Resource> loadResource(resourceId: String): T? =
118+
fhirEngine.loadResource(resourceId)
120119

121120
suspend fun loadResource(resourceId: String, resourceType: ResourceType): Resource =
122-
withContext(dispatcherProvider.io()) { fhirEngine.get(resourceType, resourceId) }
121+
fhirEngine.get(resourceType, resourceId)
123122

124123
suspend fun loadResource(reference: Reference) =
125-
withContext(dispatcherProvider.io()) {
126-
IdType(reference.reference).let {
127-
fhirEngine.get(ResourceType.fromCode(it.resourceType), it.idPart)
128-
}
124+
IdType(reference.reference).let {
125+
fhirEngine.get(ResourceType.fromCode(it.resourceType), it.idPart)
129126
}
130127

131128
suspend inline fun <reified T : Resource> searchResourceFor(
@@ -135,19 +132,17 @@ constructor(
135132
dataQueries: List<DataQuery> = listOf(),
136133
configComputedRuleValues: Map<String, Any>,
137134
): List<T> =
138-
withContext(dispatcherProvider.io()) {
139-
fhirEngine
140-
.batchedSearch<T> {
141-
filterByResourceTypeId(token, subjectType, subjectId)
142-
dataQueries.forEach {
143-
filterBy(
144-
dataQuery = it,
145-
configComputedRuleValues = configComputedRuleValues,
146-
)
147-
}
135+
fhirEngine
136+
.batchedSearch<T> {
137+
filterByResourceTypeId(token, subjectType, subjectId)
138+
dataQueries.forEach {
139+
filterBy(
140+
dataQuery = it,
141+
configComputedRuleValues = configComputedRuleValues,
142+
)
148143
}
149-
.map { it.resource }
150-
}
144+
}
145+
.map { it.resource }
151146

152147
suspend inline fun <reified R : Resource> search(search: Search) =
153148
fhirEngine.batchedSearch<R>(search).map { it.resource }
@@ -162,17 +157,13 @@ constructor(
162157
* param [addResourceTags]
163158
*/
164159
suspend fun create(addResourceTags: Boolean = true, vararg resource: Resource): List<String> {
165-
return withContext(dispatcherProvider.io()) {
166-
preProcessResources(addResourceTags, *resource)
167-
fhirEngine.create(*resource)
168-
}
160+
preProcessResources(addResourceTags, *resource)
161+
return fhirEngine.create(*resource)
169162
}
170163

171164
suspend fun createRemote(addResourceTags: Boolean = true, vararg resource: Resource) {
172-
return withContext(dispatcherProvider.io()) {
173-
preProcessResources(addResourceTags, *resource)
174-
fhirEngine.create(*resource, isLocalOnly = true)
175-
}
165+
preProcessResources(addResourceTags, *resource)
166+
fhirEngine.create(*resource, isLocalOnly = true)
176167
}
177168

178169
private fun preProcessResources(addResourceTags: Boolean, vararg resource: Resource) {
@@ -198,23 +189,19 @@ constructor(
198189
resourceId: String,
199190
softDelete: Boolean = false,
200191
) {
201-
withContext(dispatcherProvider.io()) {
202-
if (softDelete) {
203-
val resource = fhirEngine.get(resourceType, resourceId)
204-
softDelete(resource)
205-
} else {
206-
fhirEngine.delete(resourceType, resourceId)
207-
}
192+
if (softDelete) {
193+
val resource = fhirEngine.get(resourceType, resourceId)
194+
softDelete(resource)
195+
} else {
196+
fhirEngine.delete(resourceType, resourceId)
208197
}
209198
}
210199

211200
suspend fun delete(resource: Resource, softDelete: Boolean = false) {
212-
withContext(dispatcherProvider.io()) {
213-
if (softDelete) {
214-
softDelete(resource)
215-
} else {
216-
fhirEngine.delete(resource.resourceType, resource.logicalId)
217-
}
201+
if (softDelete) {
202+
softDelete(resource)
203+
} else {
204+
fhirEngine.delete(resource.resourceType, resource.logicalId)
218205
}
219206
}
220207

@@ -243,24 +230,20 @@ constructor(
243230
* param [addMandatoryTags]
244231
*/
245232
suspend fun <R : Resource> addOrUpdate(addMandatoryTags: Boolean = true, resource: R) {
246-
return withContext(dispatcherProvider.io()) {
247-
resource.updateLastUpdated()
248-
try {
249-
fhirEngine.get(resource.resourceType, resource.logicalId).run {
250-
val updateFrom = updateFrom(resource)
251-
fhirEngine.update(updateFrom)
252-
}
253-
} catch (resourceNotFoundException: ResourceNotFoundException) {
254-
create(addMandatoryTags, resource)
233+
resource.updateLastUpdated()
234+
try {
235+
fhirEngine.get(resource.resourceType, resource.logicalId).run {
236+
val updateFrom = updateFrom(resource)
237+
fhirEngine.update(updateFrom)
255238
}
239+
} catch (resourceNotFoundException: ResourceNotFoundException) {
240+
create(addMandatoryTags, resource)
256241
}
257242
}
258243

259244
suspend fun <R : Resource> update(resource: R) {
260-
return withContext(dispatcherProvider.io()) {
261-
resource.updateLastUpdated()
262-
fhirEngine.update(resource)
263-
}
245+
resource.updateLastUpdated()
246+
fhirEngine.update(resource)
264247
}
265248

266249
suspend fun loadManagingEntity(group: Group) =
@@ -904,7 +887,7 @@ constructor(
904887
val updatedResource =
905888
parser.parseResource(resourceDefinition, updatedResourceDocument.jsonString())
906889
updatedResource.setId(updatedResource.idElement.idPart)
907-
withContext(dispatcherProvider.io()) { fhirEngine.update(updatedResource as Resource) }
890+
fhirEngine.update(updatedResource as Resource)
908891
}
909892

910893
private fun getJsonContent(jsonElement: JsonElement): Any? {
@@ -935,9 +918,7 @@ constructor(
935918

936919
suspend fun purge(resource: Resource, forcePurge: Boolean) {
937920
try {
938-
withContext(dispatcherProvider.io()) {
939-
fhirEngine.purge(resource.resourceType, resource.logicalId, forcePurge)
940-
}
921+
fhirEngine.purge(resource.resourceType, resource.logicalId, forcePurge)
941922
} catch (resourceNotFoundException: ResourceNotFoundException) {
942923
Timber.e(
943924
"Purge failed -> Resource with ID ${resource.logicalId} does not exist",

0 commit comments

Comments
 (0)