Compare commits

..

7 Commits

Author SHA1 Message Date
Jan
7a8664a636 fix project check in secret_sync_gitlab_token (#378) 2026-04-10 11:38:28 +02:00
Radovan Tomášik
71b25fe490 feat: add Data Quality Agent configuration and setup (#373)
* feat: add Data Quality Agent configuration and setup

* fix: correct environment variable name in Data Quality Agent configuration

* feat: update Data Quality Agent configuration and setup instructions

* feat: update Data Quality Agent setup and documentation

* feat: add volume configuration for agent data in Data Quality Agent compose file

* feat: update volume configuration for Data Quality Agent in compose file

* Update README.md

Co-authored-by: Tobias Kussel <TKussel@users.noreply.github.com>

---------

Co-authored-by: Tobias Kussel <TKussel@users.noreply.github.com>
2026-04-07 12:48:29 +02:00
Pierre Delpy
bbda99254f feature: add osiris2fhir in cce and minor fixes (#374) 2026-03-17 15:54:25 +01:00
Pierre Delpy
c1de9b8314 WIP: enable osiris2fhir in PSCC for GR (#372)
enable osiris2fhir in PSCC for GR
2026-02-24 12:09:39 +01:00
DavidCroftDKFZ
9d3ec957a2 Activate Directory token login (#371)
Right now, Directory sync will only be activated if a username has been
specified. It also needs to run if a login token has been specified,
hence the change in this commit.
2026-02-20 09:27:47 +01:00
Martin Jurk
7a9f80537b sites moved to etc itcc.comf (#369) 2026-02-10 16:04:33 +01:00
Pierre Delpy
bff06a6bb0 fix kr deployment (#370) 2026-02-10 11:21:36 +01:00
20 changed files with 123 additions and 103 deletions

View File

@@ -27,6 +27,7 @@ This repository is the starting point for any information and tools you will nee
- [Teiler (Frontend)](#teiler-frontend)
- [Data Exporter Service](#data-exporter-service)
- [Data Quality Report](#data-quality-report)
- [Data Quality Agent](#data-quality-agent)
4. [Things you should know](#things-you-should-know)
- [Auto-Updates](#auto-updates)
- [Auto-Backups](#auto-backups)
@@ -424,6 +425,32 @@ ENABLE_EXPORTER=true
```
[For further information](docs/exporter.md)
### Data Quality Agent
The Data Quality Agent is an optional module that periodically evaluates the quality of FHIR data stored in Blaze. It generates local data quality reports accessible via the Bridgehead web interface.
To enable the service, set the following variable in your `<PROJECT>.conf` file:
```bash
ENABLE_DATA_QUALITY_AGENT=true
```
#### Sharing Data Quality Reports (recommended)
We encourage sharing your data quality reports with the central BBMRI-ERIC quality dashboard. The reports contain only aggregated, non-patient-identifiable statistics and help the network to monitor and improve overall data quality. However, quality reporting is completely optional and opt-in.
To opt in, additionally set the following variables in your `<PROJECT>.conf` file:
```bash
DATA_QUALITY_SERVER_URL=https://quality-dashboard.bbmri-eric.eu
DATA_QUALITY_SERVER_NAME=Central Data Quality Server of BBMRI
```
If these variables are not set, the Data Quality Agent will still run and generate local reports, but no data will be shared externally.
Reports are accessible at `https://<your-host>/bbmri-data-quality-agent` (default credentials are admin:admin, please change it after first login!!).
[Official documentation](https://fdqf.bbmri-eric.eu/user/deployment.html)
## Things you should know
### Auto-Updates

View File

@@ -0,0 +1,23 @@
version: "3.7"
services:
data-quality-agent:
image: ghcr.io/bbmri-cz/data-quality-server:${DATA_QUALITY_AGENT_TAG}
container_name: bridgehead-bbmri-data-quality-agent
environment:
APP_SETTING_FHIR_URL: http://bridgehead-bbmri-blaze:8080/fhir
REPORTING_SERVER_URL: ${DATA_QUALITY_SERVER_URL}
REPORTING_SERVER_NAME: ${DATA_QUALITY_SERVER_NAME}
labels:
- "traefik.enable=true"
- "traefik.http.routers.data_quality_agent_bbmri.rule=PathPrefix(`/bbmri-data-quality-agent`)"
- "traefik.http.services.data_quality_agent_bbmri.loadbalancer.server.port=8082"
- "traefik.http.routers.data_quality_agent_bbmri.tls=true"
- "traefik.http.middlewares.data_quality_agent_bbmri_strip.stripprefix.prefixes=/bbmri-data-quality-agent"
- "traefik.http.routers.data_quality_agent_bbmri.middlewares=data_quality_agent_bbmri_strip,auth"
depends_on:
- "blaze"
volumes:
- /var/cache/bridgehead/bbmri/agent-db:/app/data
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro

View File

@@ -0,0 +1,7 @@
#!/bin/bash
if [ "$ENABLE_DATA_QUALITY_AGENT" == "true" ]; then
log INFO "Data Quality Agent setup detected -- will start data-quality-agent service."
OVERRIDE+=" -f ./$PROJECT/modules/data-quality-agent-compose.yml"
fi

View File

@@ -1,6 +1,6 @@
#!/bin/bash
if [ -n "${DS_DIRECTORY_USER_NAME}" ]; then
if [ -n "${DS_DIRECTORY_USER_NAME}" ] || [ -n "${DS_DIRECTORY_USER_TOKEN}" ]; then
log INFO "Directory sync setup detected -- will start directory sync service."
OVERRIDE+=" -f ./$PROJECT/modules/directory-sync-compose.yml"
fi

View File

@@ -0,0 +1,6 @@
#!/bin/bash
if [ -n "$ENABLE_OSIRIS2FHIR" ]; then
log INFO "OSIRIS2FHIR-REST setup detected -- will start osiris2fhir module."
OVERRIDE+=" -f ./pscc/modules/osiris2fhir-compose.yml"
LOCAL_SALT="$(echo \"local-random-salt\" | openssl pkeyutl -sign -inkey /etc/bridgehead/pki/${SITE_ID}.priv.pem | base64 | head -c 30)"
fi

View File

@@ -32,7 +32,7 @@ services:
BEAM_PROXY_URL: http://beam-proxy:8081
RETRY_COUNT: ${FOCUS_RETRY_COUNT}
EPSILON: 0.28
QUERIES_TO_CACHE: "/queries_to_cache.conf"
QUERIES_TO_CACHE: '/queries_to_cache.conf'
ENDPOINT_TYPE: ${FOCUS_ENDPOINT_TYPE:-blaze}
volumes:
- /srv/docker/bridgehead/itcc/queries_to_cache.conf:/queries_to_cache.conf:ro
@@ -41,13 +41,12 @@ services:
- "blaze"
beam-proxy:
image: docker.verbis.dkfz.de/cache/samply/beam-proxy:develop-sockets
image: docker.verbis.dkfz.de/cache/samply/beam-proxy:${BEAM_TAG}
container_name: bridgehead-beam-proxy
environment:
BROKER_URL: ${BROKER_URL}
PROXY_ID: ${PROXY_ID}
APP_focus_KEY: ${FOCUS_BEAM_SECRET_SHORT}
APP_omics-endpoint_KEY: ${FOCUS_BEAM_SECRET_SHORT}
PRIVKEY_FILE: /run/secrets/proxy.pem
ALL_PROXY: http://forward_proxy:3128
TLS_CA_CERTIFICATES_DIR: /conf/trusted-ca-certs
@@ -60,6 +59,7 @@ services:
- /etc/bridgehead/trusted-ca-certs:/conf/trusted-ca-certs:ro
- /srv/docker/bridgehead/itcc/root.crt.pem:/conf/root.crt.pem:ro
volumes:
blaze-data:

View File

@@ -3,5 +3,4 @@
if [ -n "$ENABLE_OMICS" ];then
OVERRIDE+=" -f ./$PROJECT/modules/itcc-omics-ingest.yaml"
GENERATE_API_KEY="$(generate_simple_password 'omics')"
PATIENTLIST_POSTGRES_PASSWORD=="$(generate_simple_password 'mainzelliste')"
fi

View File

@@ -1,20 +1,8 @@
services:
omics-endpoint:
image: ghcr.io/samply/itcc-omics-ingest:fix-task
image: ghcr.io/samply/itcc-omics-ingest:main
environment:
API_KEY: ${GENERATE_API_KEY}
RUST_LOG: debug
BEAM_ID: "omics-endpoint.${PROXY_ID}"
BEAM_SECRET: "${FOCUS_BEAM_SECRET_SHORT}"
BEAM_URL: http://beam-proxy:8081
ML_URL: http://mainzelliste:8080
BLAZE_URL: http://bridgehead-itcc-blaze:8080/fhir/
DWH_SOCKET_ID: "${DWH_SOCKET_ID}"
DWH_TASK_ID: "${DWH_TASK_ID}"
ENABLE_SOCKETS: true
PARTNER_ID: itcc-inform
ML_API_KEY: ${GENERATE_API_KEY}
- API_KEY=${GENERATE_API_KEY}
volumes:
- /var/cache/bridgehead/omics/data:/data/uploads
labels:
@@ -24,58 +12,3 @@ services:
- "traefik.http.routers.omics.tls=true"
- "traefik.http.middlewares.omics-stripprefix.stripprefix.prefixes=/api"
- "traefik.http.routers.omics.middlewares=omics-stripprefix"
db:
image: postgres:15
container_name: db
restart: unless-stopped
environment:
POSTGRES_DB: mainzelliste
POSTGRES_USER: ${ML_DB_USER}
POSTGRES_PASSWORD: ${PATIENTLIST_POSTGRES_PASSWORD}
ports:
- "5432:5432"
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${ML_DB_USER} -d mainzelliste"]
interval: 5s
timeout: 5s
retries: 10
start_period: 10s
mainzelliste:
image: medicalinformatics/mainzelliste:latest
container_name: mainzelliste
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- 7887:8080
environment:
ML_API_KEY: ${GENERATE_API_KEY}
ML_DB_HOST: db
ML_DB_PORT: "5432"
ML_DB_NAME: mainzelliste
ML_DB_USER: ${ML_DB_USER}
ML_DB_PASS: ${PATIENTLIST_POSTGRES_PASSWORD}
ML_DB_DRIVER: org.postgresql.Driver
ML_DB_TYPE: postgresql
ML_LOG_LEVEL: INFO
ML_ALLOWEDREMOTEADDRESSES: "127.0.0.1,::1,172.16.0.0/12"
secrets:
- mainzelliste.docker.conf
- source: symmetric_key
target: /etc/resources/keys/symmetric_key.der
volumes:
db_data:
secrets:
mainzelliste.docker.conf:
file: /etc/bridgehead/mainzelliste/mainzelliste.docker.conf
symmetric_key:
file: /etc/bridgehead/mainzelliste/keyset_siv.json

View File

@@ -7,9 +7,6 @@ SUPPORT_EMAIL=arturo.macias@dkfz-heidelberg.de
PRIVATEKEYFILENAME=/etc/bridgehead/pki/${SITE_ID}.priv.pem
BROKER_URL_FOR_PREREQ=$BROKER_URL
PUBLIC_ENVIRONMENT=prod
DWH_SOCKET_ID=socket.itcc-datalake.${BROKER_ID}
DWH_TASK_ID=task.itcc-datalake.${BROKER_ID}
ML_DB_USER=mainzelliste
for module in $PROJECT/modules/*.sh
do

View File

@@ -12,7 +12,8 @@ services:
BASE_URL: "http://bridgehead-kr-blaze:8080"
JAVA_TOOL_OPTIONS: "-Xmx${BLAZE_MEMORY_CAP:-4096}m"
DB_RESOURCE_CACHE_SIZE: ${BLAZE_RESOURCE_CACHE_CAP:-2500000}
DB_BLOCK_CACHE_SIZE: $BLAZE_MEMORY_CAP
DB_BLOCK_CACHE_SIZE: ${BLAZE_MEMORY_CAP}
CQL_EXPR_CACHE_SIZE: ${BLAZE_CQL_CACHE_CAP:-32}
ENFORCE_REFERENTIAL_INTEGRITY: "false"
volumes:
- "blaze-data:/app/data"

View File

@@ -1,6 +0,0 @@
# Full Excel Export
curl --location --request POST 'https://${HOST}/ccp-exporter/request?query=Patient&query-format=FHIR_PATH&template-id=ccp&output-format=EXCEL' \
--header 'x-api-key: ${EXPORT_API_KEY}'
# QB
curl --location --request POST 'https://${HOST}/ccp-reporter/generate?template-id=ccp'

View File

@@ -4,32 +4,41 @@ services:
deploy:
replicas: 1 #reactivate if lens is in use
container_name: lens_federated-search
image: docker.verbis.dkfz.de/ccp/lens:${SITE_ID}
image: docker.verbis.dkfz.de/ccp/kr-explorer:main
environment:
PUBLIC_SPOT_URL: https://${HOST}/prod
labels:
- "traefik.http.services.lens.loadbalancer.server.port=3000"
- "traefik.enable=true"
- "traefik.http.routers.landing.rule=PathPrefix(`/`)"
- "traefik.http.services.landing.loadbalancer.server.port=80"
- "traefik.http.routers.landing.tls=true"
- "traefik.http.routers.lens.rule=Host(`${HOST}`)"
- "traefik.http.routers.lens.tls=true"
spot:
image: docker.verbis.dkfz.de/ccp-private/central-spot
image: samply/rustyspot:latest
environment:
BEAM_SECRET: "${FOCUS_BEAM_SECRET_SHORT}"
BEAM_URL: http://beam-proxy:8081
BEAM_PROXY_ID: ${SITE_ID}
BEAM_BROKER_ID: ${BROKER_ID}
BEAM_APP_ID: "focus"
PROJECT_METADATA: "kr_supervisors"
BEAM_PROXY_URL: http://beam-proxy:8081
BEAM_APP_ID: "spot.${SITE_ID}.${BROKER_ID}"
CORS_ORIGIN: "https://${HOST}"
SITES: ${SITES}
TRANSFORM: LENS
PROJECT: kr
BIND_ADDR: 0.0.0.0:8055
depends_on:
- "beam-proxy"
labels:
- "traefik.enable=true"
- "traefik.http.services.spot.loadbalancer.server.port=8080"
- "traefik.http.services.spot.loadbalancer.server.port=8055"
- "traefik.http.middlewares.corsheaders2.headers.accesscontrolallowmethods=GET,OPTIONS,POST"
- "traefik.http.middlewares.corsheaders2.headers.accesscontrolallowheaders=content-type"
- "traefik.http.middlewares.corsheaders2.headers.accesscontrolalloworiginlist=https://${HOST}"
- "traefik.http.middlewares.corsheaders2.headers.accesscontrolallowcredentials=true"
- "traefik.http.middlewares.corsheaders2.headers.accesscontrolmaxage=-1"
- "traefik.http.routers.spot.rule=Host(`${HOST}`) && PathPrefix(`/backend`)"
- "traefik.http.middlewares.stripprefix_spot.stripprefix.prefixes=/backend"
- "traefik.http.routers.spot.rule=Host(`${HOST}`) && PathPrefix(`/prod`)"
- "traefik.http.middlewares.stripprefix_spot.stripprefix.prefixes=/prod"
- "traefik.http.routers.spot.tls=true"
- "traefik.http.routers.spot.middlewares=corsheaders2,stripprefix_spot"
- "traefik.http.routers.spot.middlewares=corsheaders2,stripprefix_spot,auth"
beam-proxy:
environment:
APP_spot_KEY: ${FOCUS_BEAM_SECRET_SHORT}

View File

@@ -3,7 +3,7 @@ version: "3.7"
services:
obds2fhir-rest:
container_name: bridgehead-obds2fhir-rest
image: docker.verbis.dkfz.de/ccp/obds2fhir-rest:main
image: docker.verbis.dkfz.de/samply/obds2fhir-rest:main
environment:
IDTYPE: BK_${IDMANAGEMENT_FRIENDLY_ID}_L-ID
MAINZELLISTE_APIKEY: ${IDMANAGER_LOCAL_PATIENTLIST_APIKEY}

View File

@@ -3,7 +3,7 @@ BROKER_URL=https://${BROKER_ID}
PROXY_ID=${SITE_ID}.${BROKER_ID}
FOCUS_BEAM_SECRET_SHORT="$(cat /proc/sys/kernel/random/uuid | sed 's/[-]//g' | head -c 20)"
FOCUS_RETRY_COUNT=${FOCUS_RETRY_COUNT:-64}
SUPPORT_EMAIL=arturo.macias@dkfz-heidelberg.de
SUPPORT_EMAIL=p.delpy@dkfz-heidelberg.de
PRIVATEKEYFILENAME=/etc/bridgehead/pki/${SITE_ID}.priv.pem
BROKER_URL_FOR_PREREQ=$BROKER_URL

View File

@@ -337,7 +337,7 @@ function sync_secrets() {
}
function secret_sync_gitlab_token() {
if [[ "$PROJECT" != "dktk" && "$PROJECT" != "bbmri" ]]; then
if [[ "$PROJECT" != "ccp" && "$PROJECT" != "bbmri" ]]; then
log "INFO" "Not running Secret Sync for project minimal"
return
fi

View File

@@ -0,0 +1,15 @@
services:
osiris2fhir:
container_name: bridgehead-osiris2fhir
image: docker.verbis.dkfz.de/ccp/osiris2fhir
environment:
FHIR_PROFILE: ${PROJECT:-pscc}
LOG_LEVEL: ${LOG_LEVEL:-INFO}
SALT: ${LOCAL_SALT}
labels:
- "traefik.enable=true"
- "traefik.http.routers.osiris2fhir.rule=PathPrefix(`/osiris2fhir`)"
- "traefik.http.middlewares.osiris2fhir_strip.stripprefix.prefixes=/osiris2fhir"
- "traefik.http.services.osiris2fhir.loadbalancer.server.port=8080"
- "traefik.http.routers.osiris2fhir.tls=true"
- "traefik.http.routers.osiris2fhir.middlewares=osiris2fhir_strip,auth"

View File

@@ -0,0 +1,6 @@
#!/bin/bash
if [ -n "$ENABLE_OSIRIS2FHIR" ]; then
log INFO "OSIRIS2FHIR-REST setup detected -- will start osiris2fhir module."
OVERRIDE+=" -f ./pscc/modules/osiris2fhir-compose.yml"
LOCAL_SALT="$(echo \"local-random-salt\" | openssl pkeyutl -sign -inkey /etc/bridgehead/pki/${SITE_ID}.priv.pem | base64 | head -c 30)"
fi

View File

@@ -3,4 +3,5 @@ BEAM_TAG=develop
BLAZE_TAG=0.32
POSTGRES_TAG=15.13-alpine
TEILER_DASHBOARD_TAG=develop
MTBA_TAG=develop
MTBA_TAG=develop
DATA_QUALITY_AGENT_TAG=latest

View File

@@ -3,4 +3,5 @@ BEAM_TAG=main
BLAZE_TAG=0.32
POSTGRES_TAG=15.13-alpine
TEILER_DASHBOARD_TAG=main
MTBA_TAG=main
MTBA_TAG=main
DATA_QUALITY_AGENT_TAG=0.1

View File

@@ -4,3 +4,4 @@ BLAZE_TAG=0.32
POSTGRES_TAG=15.13-alpine
TEILER_DASHBOARD_TAG=develop
MTBA_TAG=develop
DATA_QUALITY_AGENT_TAG=latest