Skip to content

Commit b9e3fed

Browse files
committed
rebrand to medic etl toolkit and byte compile groovy just once
1 parent 54ae9a1 commit b9e3fed

8 files changed

Lines changed: 77 additions & 41 deletions

File tree

.github/workflows/docker-image.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,5 @@ jobs:
2828
uses: docker/build-push-action@v7
2929
with:
3030
push: true
31-
tags: ghcr.io/itcr-uni-luebeck/obds2openehr:latest
31+
tags: ghcr.io/skfit-uni-luebeck/medic-etl-toolkit:latest
3232
platforms: linux/amd64,linux/arm64/v8

Dockerfile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
FROM busybox:uclibc AS wget
22
FROM docker.io/maven:3-eclipse-temurin-25 as build
3-
COPY $PWD /openehr-obds
4-
WORKDIR /openehr-obds
3+
COPY $PWD /medic-etl-toolkit
4+
WORKDIR /medic-etl-toolkit
55
RUN mvn -DskipTests clean package
66

77
FROM gcr.io/distroless/java25-debian13
88
COPY --from=wget /bin/wget /bin/wget
99
COPY --from=wget /bin/sh /bin/sh
10-
COPY --from=build /openehr-obds/target/openehr-obds-*-jar-with-dependencies.jar /app/openehr-obds.jar
11-
ENTRYPOINT ["java", "-jar", "/app/openehr-obds.jar"]
10+
COPY --from=build /medic-etl-toolkit/target/medic-etl-toolkit-*-jar-with-dependencies.jar /app/medic-etl-toolkit.jar
11+
ENTRYPOINT ["java", "-jar", "/app/medic-etl-toolkit.jar"]
1212
HEALTHCHECK CMD /bin/wget -q -O - http://localhost:4567/health || exit 1

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
# oBDS 2 openEHR
1+
# MeDIC-ETL-Toolkit
22

3-
This project is used to map [oBDS](https://www.basisdatensatz.de/basisdatensatz) (German oncological basis data set) data to openEHR using a FHIR Terminology Server and CentraXX MDR. The target openEHR templates are available [here](https://ckm.highmed.org/ckm/projects/1246.152.61).
3+
A toolkit for mapping various data formats to openEHR. It reads json/xml files from kafka, transforms them using groovy scripts to openEHR compositions, which then will be uploaded to the openEHR repository.
4+
5+
This project was initially created to map [oBDS](https://www.basisdatensatz.de/basisdatensatz) (German oncological basis data set) data to openEHR using a FHIR Terminology Server and CentraXX MDR. The target openEHR templates are available [here](https://ckm.highmed.org/ckm/projects/1246.152.61).
46

57
## Get started
68

79
To get started, copy the `settings.yaml.example` file to `settings.yaml`. This avoids future conflicts within the git tree. The parameters need to be tailored to your environment.
810

911
### Running in container
1012

11-
oBDS 2 openEHR is also available as a container. The image is available at `ghcr.io/skfit-uni-luebeck/obds2openehr:latest`. There are native builds available for `linux/amd64` and `linux/arm64/v8`.
13+
MeDIC-ETL-Toolkit is also available as a container. The image is available at `ghcr.io/skfit-uni-luebeck/medic-etl-toolkit:latest`. There are native builds available for `linux/amd64` and `linux/arm64/v8`.
1214
There is also a compose file available.
1315

1416
## Citation

compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
version: "3"
22
services:
3-
openehr-obds:
3+
medic-etl-toolkit:
44
restart: unless-stopped
55
build: ./
66
command: "/app/settings.yml"

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<modelVersion>4.0.0</modelVersion>
66

77
<groupId>de.uksh.medic.etl</groupId>
8-
<artifactId>openehr-obds</artifactId>
8+
<artifactId>medic-etl-toolkit</artifactId>
99
<version>0.1-SNAPSHOT</version>
1010

1111
<properties>
@@ -18,7 +18,7 @@
1818
<maven-surefire-plugin.version>3.5.5</maven-surefire-plugin.version>
1919
<coveralls-maven-plugin.version>4.3.0</coveralls-maven-plugin.version>
2020
<maven-source-plugin.version>3.4.0</maven-source-plugin.version>
21-
<exec.mainClass>de.uksh.medic.etl.OpenEhrObds</exec.mainClass>
21+
<exec.mainClass>de.uksh.medic.etl.MedicEtlToolkit</exec.mainClass>
2222
</properties>
2323

2424
<dependencies>
@@ -197,7 +197,7 @@
197197
</descriptorRefs>
198198
<archive>
199199
<manifest>
200-
<mainClass>de.uksh.medic.etl.OpenEhrObds</mainClass>
200+
<mainClass>de.uksh.medic.etl.MedicEtlToolkit</mainClass>
201201
</manifest>
202202
</archive>
203203
</configuration>

src/main/java/de/uksh/medic/etl/OpenEhrObds.java renamed to src/main/java/de/uksh/medic/etl/MedicEtlToolkit.java

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
import de.uksh.medic.etl.settings.ServerCheckSettings;
3535
import de.uksh.medic.etl.settings.Settings;
3636
import groovy.lang.Binding;
37-
import groovy.lang.GroovyShell;
37+
import groovy.lang.GroovyClassLoader;
38+
import groovy.lang.Script;
3839
import java.io.BufferedWriter;
3940
import java.io.File;
4041
import java.io.FileInputStream;
@@ -83,14 +84,16 @@
8384
import org.openehr.schemas.v1.OPERATIONALTEMPLATE;
8485
import org.tinylog.Logger;
8586

86-
public final class OpenEhrObds {
87+
public final class MedicEtlToolkit {
8788

8889
private static final Cache<String, Object> SPEED = Caffeine.newBuilder()
8990
.expireAfterWrite(60, TimeUnit.SECONDS).build();
9091
private static final Map<String, Map<String, MappingAttributes>> FHIR_ATTRIBUTES = new HashMap<>();
9192
private static final Map<String, Object> OPENEHR_ATTRIBUTES = new HashMap<>();
9293
private static final Map<String, MappingAttributes> AQLS = new HashMap<>();
9394
private static final Map<String, EHRParser> PARSERS = new HashMap<>();
95+
private static final Map<String, Class<? extends Script>> GROOVY_SCRIPTS = new HashMap<>();
96+
private static GroovyClassLoader groovyClassLoader;
9497
private static Integer i = 0;
9598
private static final int DEFAULT_RECONNECT_DELAY_MS = 1000;
9699
private static final int MAX_RECONNECT_DELAY_MS = 30000;
@@ -101,7 +104,7 @@ public final class OpenEhrObds {
101104
private static IGenericClient fc;
102105
private static IGenericClient fhirTsClient;
103106

104-
private OpenEhrObds() {
107+
private MedicEtlToolkit() {
105108
}
106109

107110
@SuppressWarnings({ "IllegalCatch", "MethodLength" })
@@ -194,7 +197,7 @@ public static void main(String[] args) throws IOException, KeyStoreException, Ge
194197
return "{\"msgsPerMinute\": " + SPEED.estimatedSize() + ", \"cacheSize\": " + fr.getCacheSize() + "}";
195198
});
196199

197-
Logger.info("OpenEhrObds started!");
200+
Logger.info("MedicEtlToolkit started!");
198201

199202
if (Settings.getKafka().getUrl() == null || Settings.getKafka().getUrl().isEmpty()) {
200203
Logger.debug("Kafka URL not set, loading local file");
@@ -352,6 +355,25 @@ private static void initializeAttribute(Mapping m, ObjectMapper mapper) {
352355
XmlOptions opts = new XmlOptions();
353356
opts.setSaveSyntheticDocumentElement(new QName("http://schemas.openehr.org/v1", "template"));
354357
PARSERS.put(m.getTemplateId(), new EHRParser(template.xmlText(opts)));
358+
359+
// Pre-compile Groovy script for this template
360+
if (Settings.getDev()) {
361+
return;
362+
}
363+
File groovyFile = new File("scripts", m.getTemplateId() + ".groovy");
364+
if (!groovyFile.exists()) {
365+
return;
366+
}
367+
if (groovyClassLoader == null) {
368+
groovyClassLoader = new GroovyClassLoader();
369+
}
370+
try {
371+
Class<? extends Script> scriptClass = groovyClassLoader.parseClass(groovyFile);
372+
GROOVY_SCRIPTS.put(m.getTemplateId(), scriptClass);
373+
Logger.info("Pre-compiled Groovy script for template: {}", m.getTemplateId());
374+
} catch (IOException e) {
375+
Logger.error("Failed to pre-compile Groovy script for template {}: {}", m.getTemplateId(), e);
376+
}
355377
}
356378

357379
if (m.getSource() == null) {
@@ -407,26 +429,35 @@ private static void initializeAttribute(Mapping m, ObjectMapper mapper) {
407429
@SuppressWarnings({ "IllegalCatch" })
408430
public static Object localMap(Set<Entry<String, Object>> xmlSet, String templateId, String path,
409431
Map<String, Object> cache) {
410-
Binding b = new Binding();
411-
GroovyShell s = new GroovyShell(b);
412-
b.setVariable("xmlSet", xmlSet);
413-
b.setVariable("path", path);
414-
b.setVariable("fhirClient", fc);
415-
b.setVariable("fhirResolver", fr);
416-
b.setVariable("openEhrClient", openEhrClient);
417-
b.setVariable("utils", um);
418-
b.setVariable("cache", cache);
419-
420432
if (Settings.getDev()) {
433+
Binding b = new Binding();
434+
b.setVariable("xmlSet", xmlSet);
435+
b.setVariable("path", path);
436+
b.setVariable("fhirClient", fc);
437+
b.setVariable("fhirResolver", fr);
438+
b.setVariable("openEhrClient", openEhrClient);
439+
b.setVariable("utils", um);
440+
b.setVariable("cache", cache);
421441
return Mapper.javaMap(xmlSet, path, fc, fr, openEhrClient, um, cache);
422442
} else {
423-
try {
424-
File groovyFile = new File("scripts", templateId + ".groovy");
425-
if (groovyFile.exists()) {
426-
return s.evaluate(groovyFile);
443+
// Use pre-compiled script instance
444+
Class<? extends Script> scriptClass = GROOVY_SCRIPTS.get(templateId);
445+
if (scriptClass != null) {
446+
try {
447+
Script script = scriptClass.getDeclaredConstructor().newInstance();
448+
Binding b = new Binding();
449+
b.setVariable("xmlSet", xmlSet);
450+
b.setVariable("path", path);
451+
b.setVariable("fhirClient", fc);
452+
b.setVariable("fhirResolver", fr);
453+
b.setVariable("openEhrClient", openEhrClient);
454+
b.setVariable("utils", um);
455+
b.setVariable("cache", cache);
456+
script.setBinding(b);
457+
return script.run();
458+
} catch (Exception e) {
459+
throw new ProcessingException(e);
427460
}
428-
} catch (Exception e) {
429-
throw new ProcessingException(e);
430461
}
431462
}
432463

src/main/java/de/uksh/medic/etl/settings/Settings.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import java.util.Map;
1010

1111
/**
12-
* Settings for OpenEhrObds.
12+
* Settings for MedicEtlToolkit.
1313
*/
1414
@JsonInclude(JsonInclude.Include.NON_NULL)
1515
public final class Settings {
Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
locale = de_DE
2-
level = info
3-
writer1 = console
4-
writer2 = rolling file
5-
writer2.file = log_{date}.txt
6-
writer2.charset = UTF-8
7-
writer2.policies = daily: 00:00
8-
writer.backups = 100
1+
writer1 = console
2+
writer1.format = {date: yyyy-MM-dd HH:mm:ss.SSS} {level}: {message}{exception}
3+
4+
writer2 = rolling file
5+
writer2.level = info
6+
writer2.format = {date: yyyy-MM-dd HH:mm:ss.SSS} {level}: {message}{exception}
7+
writer2.file = /log/log_{pid}_{count}.txt
8+
writer2.charset = UTF-8
9+
writer2.policies = startup, daily: 03:00
10+
writer2.backups = 30
11+
writer2.convert = gzip

0 commit comments

Comments
 (0)