1
0
mirror of https://github.com/pcvolkmer/etl-processor.git synced 2025-04-19 17:26:51 +00:00

Issue #12: Basic implementation of transformation service

This commit is contained in:
Paul-Christian Volkmer 2023-10-05 10:51:49 +02:00
parent 3f5c5e28fa
commit 7440fe1e23
3 changed files with 146 additions and 0 deletions

View File

@ -69,6 +69,7 @@ dependencies {
implementation("ca.uhn.hapi.fhir:hapi-fhir-base:${versions["hapi-fhir"]}")
implementation("ca.uhn.hapi.fhir:hapi-fhir-structures-r4:${versions["hapi-fhir"]}")
implementation("org.apache.httpcomponents.client5:httpclient5:${versions["httpclient5"]}")
implementation("com.jayway.jsonpath:json-path")
runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
runtimeOnly("org.postgresql:postgresql")
developmentOnly("org.springframework.boot:spring-boot-devtools")

View File

@ -0,0 +1,62 @@
package dev.dnpm.etl.processor.services
import com.fasterxml.jackson.databind.ObjectMapper
import com.jayway.jsonpath.JsonPath
import com.jayway.jsonpath.PathNotFoundException
import de.ukw.ccc.bwhc.dto.MtbFile
class TransformationService(private val objectMapper: ObjectMapper) {
fun transform(mtbFile: MtbFile, vararg transformations: Transformation): MtbFile {
var json = objectMapper.writeValueAsString(mtbFile)
transformations.forEach { transformation ->
val jsonPath = JsonPath.parse(json)
try {
val before = transformation.path.substringBeforeLast(".")
val last = transformation.path.substringAfterLast(".")
val existingValue = if (transformation.existingValue is Number) transformation.existingValue else transformation.existingValue.toString()
val newValue = if (transformation.newValue is Number) transformation.newValue else transformation.newValue.toString()
jsonPath.set("$.$before.[?]$last", newValue, {
it.item(HashMap::class.java)[last] == existingValue
})
} catch (e: PathNotFoundException) {
// Ignore
}
json = jsonPath.jsonString()
}
return objectMapper.readValue(json, MtbFile::class.java)
}
}
class Transformation private constructor(internal val path: String) {
lateinit var existingValue: Any
private set
lateinit var newValue: Any
private set
infix fun from(value: Any): Transformation {
this.existingValue = value
return this
}
infix fun to(value: Any): Transformation {
this.newValue = value
return this
}
companion object {
fun of(path: String): Transformation {
return Transformation(path)
}
}
}

View File

@ -0,0 +1,83 @@
package dev.dnpm.etl.processor.services
import com.fasterxml.jackson.databind.ObjectMapper
import de.ukw.ccc.bwhc.dto.Consent
import de.ukw.ccc.bwhc.dto.Diagnosis
import de.ukw.ccc.bwhc.dto.Icd10
import de.ukw.ccc.bwhc.dto.MtbFile
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
class TransformationServiceTest {
private lateinit var service: TransformationService
@BeforeEach
fun setup() {
this.service = TransformationService(ObjectMapper())
}
@Test
fun shouldTransformMtbFile() {
val transformations = arrayOf(
Transformation.of("diagnoses[*].icd10.version") from "2013" to "2014",
)
val mtbFile = MtbFile.builder().withDiagnoses(
listOf(
Diagnosis.builder().withId("1234").withIcd10(Icd10("F79.9").also {
it.version = "2013"
}).build()
)
).build()
val actual = this.service.transform(mtbFile, *transformations)
assertThat(actual).isNotNull
assertThat(actual.diagnoses[0].icd10.version).isEqualTo("2014")
}
@Test
fun shouldOnlyTransformGivenValues() {
val transformations = arrayOf(
Transformation.of("diagnoses[*].icd10.version") from "2013" to "2014",
)
val mtbFile = MtbFile.builder().withDiagnoses(
listOf(
Diagnosis.builder().withId("1234").withIcd10(Icd10("F79.9").also {
it.version = "2013"
}).build(),
Diagnosis.builder().withId("5678").withIcd10(Icd10("F79.8").also {
it.version = "2019"
}).build()
)
).build()
val actual = this.service.transform(mtbFile, *transformations)
assertThat(actual).isNotNull
assertThat(actual.diagnoses[0].icd10.code).isEqualTo("F79.9")
assertThat(actual.diagnoses[0].icd10.version).isEqualTo("2014")
assertThat(actual.diagnoses[1].icd10.code).isEqualTo("F79.8")
assertThat(actual.diagnoses[1].icd10.version).isEqualTo("2019")
}
@Test
fun shouldTransformMtbFileWithConsentEnum() {
val transformations = arrayOf(
Transformation.of("consent.status") from Consent.Status.ACTIVE to Consent.Status.REJECTED,
)
val mtbFile = MtbFile.builder().withConsent(
Consent("123", "456", Consent.Status.ACTIVE)
).build()
val actual = this.service.transform(mtbFile, *transformations)
assertThat(actual.consent).isNotNull
assertThat(actual.consent.status).isEqualTo(Consent.Status.REJECTED)
}
}