Skip to content
This repository was archived by the owner on Oct 6, 2025. It is now read-only.

Commit d36002d

Browse files
committed
Merge remote-tracking branch 'origin/hotfix/4_conditional-update-urls'
into main
2 parents 5e8e548 + e066dfa commit d36002d

File tree

5 files changed

+119
-63
lines changed

5 files changed

+119
-63
lines changed

codex-process-data-transfer/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<parent>
99
<groupId>de.netzwerk-universitaetsmedizin.codex</groupId>
1010
<artifactId>codex-processes-ap1</artifactId>
11-
<version>0.4.1</version>
11+
<version>0.4.1.1</version>
1212
</parent>
1313

1414
<properties>

codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/service/ReadData.java

Lines changed: 98 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.hl7.fhir.r4.model.Procedure;
4545
import org.hl7.fhir.r4.model.Reference;
4646
import org.hl7.fhir.r4.model.Resource;
47+
import org.hl7.fhir.r4.model.ResourceType;
4748
import org.hl7.fhir.r4.model.Task;
4849
import org.hl7.fhir.r4.model.Type;
4950
import org.slf4j.Logger;
@@ -237,19 +238,33 @@ else if (resource instanceof Procedure)
237238

238239
protected String getConditionalUpdateUrl(String pseudonym, DomainResource resource)
239240
{
241+
String patientIdentifier = ConstantsDataTransfer.NAMING_SYSTEM_NUM_CODEX_DIC_PSEUDONYM + "|" + pseudonym;
242+
240243
if (resource instanceof Patient)
241244
{
242-
return "Patient?identifier=" + ConstantsDataTransfer.NAMING_SYSTEM_NUM_CODEX_DIC_PSEUDONYM + "|"
243-
+ pseudonym;
245+
return "Patient?identifier=" + patientIdentifier;
244246
}
245247
else if (resource instanceof Condition)
246248
{
247249
Condition c = (Condition) resource;
248250
String profileUrl = getProfileUrl(resource, v -> v.startsWith(NUM_CODEX_STRUCTURE_DEFINITION_PREFIX));
249251

250-
return "Condition?_profile=" + profileUrl + "&recorded-date="
251-
+ c.getRecordedDateElement().getValueAsString() + "&patient:identifier="
252-
+ ConstantsDataTransfer.NAMING_SYSTEM_NUM_CODEX_DIC_PSEUDONYM + "|" + pseudonym;
252+
String updateUrl = getBaseConditionalUpdateUrl(ResourceType.Condition.name(), profileUrl,
253+
patientIdentifier);
254+
255+
if (c.hasRecordedDateElement() && c.getRecordedDateElement().getValueAsString() != null)
256+
updateUrl = updateUrl + "&recorded-date=" + c.getRecordedDateElement().getValueAsString();
257+
258+
if (c.hasCategory() && c.getCategoryFirstRep().hasCoding())
259+
updateUrl = updateUrl + "&category=" + getCodingUpdateUrl(c.getCategoryFirstRep().getCodingFirstRep());
260+
261+
if (c.hasCode() && c.getCode().hasCoding())
262+
updateUrl = updateUrl + "&code=" + getCodingUpdateUrl(c.getCode().getCodingFirstRep());
263+
264+
if (c.hasBodySite() && c.getBodySiteFirstRep().hasCoding())
265+
updateUrl = updateUrl + "&body-site=" + getCodingUpdateUrl(c.getBodySiteFirstRep().getCodingFirstRep());
266+
267+
return updateUrl;
253268
}
254269
else if (resource instanceof Consent)
255270
{
@@ -258,21 +273,20 @@ else if (resource instanceof Consent)
258273

259274
if (NUM_CODEX_DO_NOT_RESUSCITAT_ORDER.equals(profileUrl))
260275
{
261-
boolean scopePresent = c.getScope().getCoding().stream().filter(co -> co.hasSystem())
276+
boolean scopePresent = c.getScope().getCoding().stream().filter(Coding::hasSystem)
262277
.filter(co -> "http://terminology.hl7.org/CodeSystem/consentscope".equals(co.getSystem()))
263-
.filter(co -> co.hasCode()).filter(co -> "adr".equals(co.getCode())).findAny().isPresent();
278+
.filter(Coding::hasCode).anyMatch(co -> "adr".equals(co.getCode()));
264279
boolean categoryPresent = c.getCategory().stream().flatMap(coc -> coc.getCoding().stream())
265-
.filter(co -> co.hasSystem())
280+
.filter(Coding::hasSystem)
266281
.filter(co -> "http://terminology.hl7.org/CodeSystem/consentcategorycodes"
267282
.equals(co.getSystem()))
268-
.filter(co -> co.hasCode()).filter(co -> "dnr".equals(co.getCode())).findAny().isPresent();
283+
.filter(Coding::hasCode).anyMatch(co -> "dnr".equals(co.getCode()));
269284

270285
if (scopePresent && categoryPresent)
271-
return "Consent?_profile=" + profileUrl
286+
return getBaseConditionalUpdateUrl(ResourceType.Consent.name(), profileUrl, patientIdentifier)
272287
+ "&scope=http://terminology.hl7.org/CodeSystem/consentscope|adr"
273-
+ "&category=http://terminology.hl7.org/CodeSystem/consentcategorycodes|dnr"
274-
+ "&patient:identifier=" + ConstantsDataTransfer.NAMING_SYSTEM_NUM_CODEX_DIC_PSEUDONYM + "|"
275-
+ pseudonym;
288+
+ "&category=http://terminology.hl7.org/CodeSystem/consentcategorycodes|dnr";
289+
276290
else
277291
throw new RuntimeException("Resource of type Consent with profile " + profileUrl
278292
+ " is missing scope: http://terminology.hl7.org/CodeSystem/consentscope|adr and/or category: http://terminology.hl7.org/CodeSystem/consentcategorycodes|dnr");
@@ -285,61 +299,92 @@ else if (resource instanceof DiagnosticReport)
285299
DiagnosticReport dr = (DiagnosticReport) resource;
286300
String profileUrl = getProfileUrl(resource, v -> v.startsWith(NUM_CODEX_STRUCTURE_DEFINITION_PREFIX));
287301

288-
return "DiagnosticReport?_profile=" + profileUrl + "&date="
289-
+ dr.getEffectiveDateTimeType().getValueAsString() + "&patient:identifier="
290-
+ ConstantsDataTransfer.NAMING_SYSTEM_NUM_CODEX_DIC_PSEUDONYM + "|" + pseudonym;
302+
String updateUrl = getBaseConditionalUpdateUrl(ResourceType.DiagnosticReport.name(), profileUrl,
303+
patientIdentifier);
304+
305+
if (dr.hasEffectiveDateTimeType() && dr.getEffectiveDateTimeType().getValueAsString() != null)
306+
updateUrl = updateUrl + "&date=" + dr.getEffectiveDateTimeType().getValueAsString();
307+
308+
if (dr.hasCategory() && dr.getCategoryFirstRep().hasCoding())
309+
updateUrl = updateUrl + "&category=" + getCodingUpdateUrl(dr.getCategoryFirstRep().getCodingFirstRep());
310+
311+
if (dr.hasCode() && dr.getCode().hasCoding())
312+
updateUrl = updateUrl + "&code=" + getCodingUpdateUrl(dr.getCode().getCodingFirstRep());
313+
314+
return updateUrl;
291315
}
292316
else if (resource instanceof Immunization)
293317
{
294318
Immunization i = (Immunization) resource;
295319
String profileUrl = getProfileUrl(resource, v -> v.startsWith(NUM_CODEX_STRUCTURE_DEFINITION_PREFIX));
296320

297-
return "Immunization?_profile=" + profileUrl + "&date=" + i.getOccurrenceDateTimeType().getValueAsString()
298-
+ "&patient:identifier=" + ConstantsDataTransfer.NAMING_SYSTEM_NUM_CODEX_DIC_PSEUDONYM + "|"
299-
+ pseudonym;
321+
String updateUrl = getBaseConditionalUpdateUrl(ResourceType.Immunization.name(), profileUrl,
322+
patientIdentifier);
323+
324+
if (i.hasOccurrenceDateTimeType() && i.getOccurrenceDateTimeType().getValueAsString() != null)
325+
updateUrl = updateUrl + "&date=" + i.getOccurrenceDateTimeType().getValueAsString();
326+
327+
if (i.hasVaccineCode() && i.getVaccineCode().hasCoding())
328+
updateUrl = updateUrl + "&vaccine-code=" + i.getVaccineCode().getCodingFirstRep();
329+
330+
return updateUrl;
300331
}
301332
else if (resource instanceof MedicationStatement)
302333
{
303334
MedicationStatement ms = (MedicationStatement) resource;
304335
String profileUrl = getProfileUrl(resource, v -> v.startsWith(NUM_CODEX_STRUCTURE_DEFINITION_PREFIX));
305336

306-
return "MedicationStatement?_profile=" + profileUrl + "&effective="
307-
+ ms.getEffectiveDateTimeType().getValueAsString() + "&patient:identifier="
308-
+ ConstantsDataTransfer.NAMING_SYSTEM_NUM_CODEX_DIC_PSEUDONYM + "|" + pseudonym;
309-
}
337+
String updateUrl = getBaseConditionalUpdateUrl(ResourceType.MedicationStatement.name(), profileUrl,
338+
patientIdentifier);
310339

340+
if (ms.hasEffectiveDateTimeType() && ms.getEffectiveDateTimeType().getValueAsString() != null)
341+
updateUrl = updateUrl + "&effective=" + ms.getEffectiveDateTimeType();
342+
343+
if (ms.hasMedicationCodeableConcept() && ms.getMedicationCodeableConcept().hasCoding())
344+
updateUrl = updateUrl + "&code="
345+
+ getCodingUpdateUrl(ms.getMedicationCodeableConcept().getCodingFirstRep());
346+
347+
return updateUrl;
348+
}
311349
else if (resource instanceof Observation)
312350
{
313351
Observation o = (Observation) resource;
314352
String profileUrl = getProfileUrl(resource, v -> v.startsWith(NUM_CODEX_STRUCTURE_DEFINITION_PREFIX)
315353
|| MII_LAB_STRUCTURED_DEFINITION.equals(v));
316354

317-
if (MII_LAB_STRUCTURED_DEFINITION.equals(profileUrl))
318-
{
319-
Coding loincCode = o.getCode().getCoding().stream()
320-
.filter(c -> "http://loinc.org".equals(c.getSystem())).findFirst()
321-
.orElseThrow(() -> new RuntimeException("Observation (" + MII_LAB_STRUCTURED_DEFINITION
322-
+ ") not supported, missing LOINC code"));
323-
324-
return "Observation?_profile=" + profileUrl + "&date=" + o.getEffectiveDateTimeType().getValueAsString()
325-
+ "&code=" + loincCode.getSystem() + "|" + loincCode.getCode() + "&patient:identifier="
326-
+ ConstantsDataTransfer.NAMING_SYSTEM_NUM_CODEX_DIC_PSEUDONYM + "|" + pseudonym;
327-
}
328-
else
329-
{
330-
return "Observation?_profile=" + profileUrl + "&date=" + o.getEffectiveDateTimeType().getValueAsString()
331-
+ "&patient:identifier=" + ConstantsDataTransfer.NAMING_SYSTEM_NUM_CODEX_DIC_PSEUDONYM + "|"
332-
+ pseudonym;
333-
}
355+
String updateUrl = getBaseConditionalUpdateUrl(ResourceType.Observation.name(), profileUrl,
356+
patientIdentifier);
357+
358+
if (o.hasEffectiveDateTimeType() && o.getEffectiveDateTimeType().getValueAsString() != null)
359+
updateUrl = updateUrl + "&date=" + o.getEffectiveDateTimeType().getValueAsString();
360+
361+
if (o.hasCategory() && o.getCategoryFirstRep().hasCoding())
362+
updateUrl = updateUrl + "&category=" + getCodingUpdateUrl(o.getCategoryFirstRep().getCodingFirstRep());
363+
364+
if (o.hasCode() && o.getCode().hasCoding())
365+
updateUrl = updateUrl + "&code=" + getCodingUpdateUrl(o.getCode().getCodingFirstRep());
366+
367+
return updateUrl;
334368
}
335369
else if (resource instanceof Procedure)
336370
{
337371
Procedure p = (Procedure) resource;
338372
String profileUrl = getProfileUrl(resource, v -> v.startsWith(NUM_CODEX_STRUCTURE_DEFINITION_PREFIX));
339373

340-
return "Procedure?_profile=" + profileUrl + "&date=" + p.getPerformedDateTimeType().getValueAsString()
341-
+ "&patient:identifier=" + ConstantsDataTransfer.NAMING_SYSTEM_NUM_CODEX_DIC_PSEUDONYM + "|"
342-
+ pseudonym;
374+
String updateUrl = getBaseConditionalUpdateUrl(ResourceType.Procedure.name(), profileUrl,
375+
patientIdentifier);
376+
377+
if (p.hasPerformedDateTimeType() && p.getPerformedDateTimeType().getValueAsString() != null)
378+
updateUrl = updateUrl + "&date=" + p.getPerformedDateTimeType().getValueAsString();
379+
380+
if (p.hasCategory() && p.getCategory().hasCoding())
381+
updateUrl = updateUrl + "&category=" + getCodingUpdateUrl(p.getCategory().getCodingFirstRep());
382+
383+
if (p.hasCode() && p.getCode().hasCoding())
384+
updateUrl = updateUrl + "&code=" + getCodingUpdateUrl(p.getCode().getCodingFirstRep());
385+
386+
return updateUrl;
387+
343388
}
344389
else
345390
throw new RuntimeException("Resource of type " + resource.getResourceType().name() + " not supported");
@@ -351,4 +396,14 @@ private String getProfileUrl(DomainResource resource, Predicate<String> filter)
351396
.orElseThrow(() -> new RuntimeException("Resource of type " + resource.getResourceType().name()
352397
+ " not supported, missing NUM or MII profile"));
353398
}
399+
400+
private String getBaseConditionalUpdateUrl(String resourceName, String profileUrl, String patientIdentifier)
401+
{
402+
return resourceName + "?_profile=" + profileUrl + "&patient:identifier=" + patientIdentifier;
403+
}
404+
405+
private String getCodingUpdateUrl(Coding coding)
406+
{
407+
return coding.getSystem() + "|" + coding.getCode();
408+
}
354409
}

codex-processes-ap1-docker-test-setup/docker-compose.yml

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ services:
3737
image: postgres:13
3838
restart: on-failure
3939
healthcheck:
40-
test: [ "CMD-SHELL", "pg_isready -U postgres -d postgres" ]
40+
test: [ "CMD-SHELL", "pg_isready -U liquibase_user -d postgres" ]
4141
interval: 10s
4242
timeout: 5s
4343
retries: 5
@@ -66,7 +66,7 @@ services:
6666

6767

6868
dic-fhir:
69-
image: ghcr.io/highmed/fhir:0.5.1
69+
image: ghcr.io/highmed/fhir:0.6.0
7070
restart: on-failure
7171
ports:
7272
- 127.0.0.1:5000:5000
@@ -113,7 +113,7 @@ services:
113113
- db
114114
- proxy
115115
dic-bpe:
116-
image: ghcr.io/highmed/bpe:0.5.1
116+
image: ghcr.io/highmed/bpe:0.6.0
117117
restart: on-failure
118118
ports:
119119
- 127.0.0.1:5003:5003
@@ -194,7 +194,7 @@ services:
194194

195195

196196
gth-fhir:
197-
image: ghcr.io/highmed/fhir:0.5.1
197+
image: ghcr.io/highmed/fhir:0.6.0
198198
restart: on-failure
199199
ports:
200200
- 127.0.0.1:5001:5001
@@ -241,7 +241,7 @@ services:
241241
- db
242242
- proxy
243243
gth-bpe:
244-
image: ghcr.io/highmed/bpe:0.5.1
244+
image: ghcr.io/highmed/bpe:0.6.0
245245
restart: on-failure
246246
ports:
247247
- 127.0.0.1:5004:5004
@@ -298,7 +298,7 @@ services:
298298

299299

300300
crr-fhir:
301-
image: ghcr.io/highmed/fhir:0.5.1
301+
image: ghcr.io/highmed/fhir:0.6.0
302302
restart: on-failure
303303
ports:
304304
- 127.0.0.1:5002:5002
@@ -345,7 +345,7 @@ services:
345345
- db
346346
- proxy
347347
crr-bpe:
348-
image: ghcr.io/highmed/bpe:0.5.1
348+
image: ghcr.io/highmed/bpe:0.6.0
349349
restart: on-failure
350350
ports:
351351
- 127.0.0.1:5005:5005
@@ -404,7 +404,7 @@ services:
404404
- crr-fhir
405405
# - crr-fhir-bridge not defining a dependency here, crr-fhir-bridge* needs to be started manually
406406
crr-ehrbase-db:
407-
image: ehrbase/ehrbase-postgres:latest
407+
image: ehrbase/ehrbase-postgres
408408
networks:
409409
- crr-ehrbase-network
410410
environment:
@@ -414,7 +414,7 @@ services:
414414
EHRBASE_PASSWORD: ehrbase
415415
TZ: Europe/Berlin
416416
crr-ehrbase:
417-
image: ehrbase/ehrbase:next
417+
image: ehrbase/ehrbase
418418
networks:
419419
- crr-ehrbase-network
420420
environment:
@@ -428,22 +428,23 @@ services:
428428
SECURITY_AUTHADMINPASSWORD: mySuperAwesomePassword123
429429
SYSTEM_NAME: local.ehrbase.org
430430
ADMIN_API_ACTIVE: 'true'
431+
# SERVER_DISABLESTRICTVALIDATION: 'true'
431432
TZ: Europe/Berlin
432433
depends_on:
433434
- crr-ehrbase-db
434435
crr-fhir-bridge:
435-
image: ehrbase/fhir-bridge:1.2.1
436+
image: ehrbase/fhir-bridge
436437
ports:
437438
- 127.0.0.1:8888:8888
438439
- 127.0.0.1:5006:5006
439440
networks:
440441
- crr-ehrbase-network
441442
- crr-bpe-backend
442443
environment:
443-
FHIR_BRIDGE_EHRBASE_BASE_URL: http://crr-ehrbase:8080/ehrbase/rest/openehr/v1/
444+
FHIR_BRIDGE_EHRBASE_BASE_URL: http://crr-ehrbase:8080/ehrbase/
444445
FHIR_BRIDGE_FHIR_VALIDATION_OPTIONAL_IDENTIFIER: 'true'
445446
TZ: Europe/Berlin
446-
# SPRING_PROFILES_ACTIVE: dev
447+
# SPRING_PROFILES_ACTIVE: dev
447448
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5006
448449
depends_on:
449450
- crr-ehrbase
@@ -459,7 +460,7 @@ secrets:
459460

460461
db_liquibase.password:
461462
file: ./secrets/db_liquibase.password
462-
463+
463464
db_dic_fhir_user.password:
464465
file: ./secrets/db_dic_fhir_user.password
465466
db_dic_fhir_user_permanent_delete.password:
@@ -519,7 +520,7 @@ networks:
519520
ipam:
520521
driver: default
521522
config:
522-
- subnet: 172.20.0.64/28
523+
- subnet: 172.20.0.64/28
523524
dic-fhir-backend:
524525
dic-bpe-frontend:
525526
dic-bpe-backend:
@@ -528,7 +529,7 @@ networks:
528529
ipam:
529530
driver: default
530531
config:
531-
- subnet: 172.20.0.80/28
532+
- subnet: 172.20.0.80/28
532533
gth-fhir-backend:
533534
gth-bpe-frontend:
534535
gth-bpe-backend:
@@ -537,7 +538,7 @@ networks:
537538
ipam:
538539
driver: default
539540
config:
540-
- subnet: 172.20.0.96/28
541+
- subnet: 172.20.0.96/28
541542
crr-fhir-backend:
542543
crr-bpe-frontend:
543544
crr-bpe-backend:
@@ -546,4 +547,4 @@ networks:
546547

547548
volumes:
548549
db-data:
549-
name: db-data
550+
name: db-data-codex-dsf-processes

codex-processes-ap1-test-data-generator/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<parent>
99
<groupId>de.netzwerk-universitaetsmedizin.codex</groupId>
1010
<artifactId>codex-processes-ap1</artifactId>
11-
<version>0.4.1</version>
11+
<version>0.4.1.1</version>
1212
</parent>
1313

1414
<properties>

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>de.netzwerk-universitaetsmedizin.codex</groupId>
88
<artifactId>codex-processes-ap1</artifactId>
9-
<version>0.4.1</version>
9+
<version>0.4.1.1</version>
1010
<packaging>pom</packaging>
1111

1212
<modules>

0 commit comments

Comments
 (0)