mirror of
https://github.com/pcvolkmer/etl-processor.git
synced 2025-04-20 01:36:50 +00:00
Issue #12: Basic implementation of transformation service
This commit is contained in:
parent
3f5c5e28fa
commit
7440fe1e23
@ -69,6 +69,7 @@ dependencies {
|
|||||||
implementation("ca.uhn.hapi.fhir:hapi-fhir-base:${versions["hapi-fhir"]}")
|
implementation("ca.uhn.hapi.fhir:hapi-fhir-base:${versions["hapi-fhir"]}")
|
||||||
implementation("ca.uhn.hapi.fhir:hapi-fhir-structures-r4:${versions["hapi-fhir"]}")
|
implementation("ca.uhn.hapi.fhir:hapi-fhir-structures-r4:${versions["hapi-fhir"]}")
|
||||||
implementation("org.apache.httpcomponents.client5:httpclient5:${versions["httpclient5"]}")
|
implementation("org.apache.httpcomponents.client5:httpclient5:${versions["httpclient5"]}")
|
||||||
|
implementation("com.jayway.jsonpath:json-path")
|
||||||
runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
|
runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
|
||||||
runtimeOnly("org.postgresql:postgresql")
|
runtimeOnly("org.postgresql:postgresql")
|
||||||
developmentOnly("org.springframework.boot:spring-boot-devtools")
|
developmentOnly("org.springframework.boot:spring-boot-devtools")
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user