Compare commits

...

243 Commits

Author SHA1 Message Date
96c1b8ede5 chore: update datashield beam-connect mappings 2024-05-23 09:55:22 +02:00
eac9374815 feat: Add file-dispatcher to exporter compose 2024-05-23 09:38:37 +02:00
8b33912fee feat: Move to central rstudio 2024-04-17 14:25:59 +02:00
7d5f771181 Merge pull request #181 from samply/fix/secret-sync-args
fix: Generate public oidc client when there is no private client
2024-04-16 09:15:53 +02:00
f9a9baf13d fix: Generate public oidc client when there is no private client 2024-04-15 15:53:27 +02:00
d4259406a9 Merge pull request #180 from samply/fix/secret-sync
fix: Kill stale secret-sync instances
2024-04-15 13:18:38 +02:00
0745eab7b5 fix: Kill stale secret-sync instances 2024-04-15 13:14:46 +02:00
b404277083 Merge pull request #179 from samply/update/focus_0_4_4
update: dktk focus to 0.4.4
2024-04-15 11:02:31 +02:00
b767b3230f update: dktk focus to 0.4.4 2024-04-15 10:13:16 +02:00
dd653a7871 Merge pull request #178 from samply/PierreDelpy-patch-1
fix typo functions.sh
2024-04-15 09:09:47 +02:00
7418861e8c fix typo functions.sh 2024-04-15 09:08:56 +02:00
ac3ff314ff Merge pull request #176 from samply/fix/bash-math
fix: Make math work on bash 4.2
2024-04-03 12:59:52 +02:00
2831fb9a22 fix: Make math work on bash 4.2 2024-04-02 14:36:23 +02:00
7934d912b8 Merge pull request #175 from samply/update/focus_0_4_2
Update focus to 0.4.2
2024-03-22 14:11:09 +01:00
70ad318b28 Update focus to 0.4.2 2024-03-22 13:59:42 +01:00
6da143f348 Merge pull request #164 from samply/feature/datashield
Exporter, Teiler, QB, DataSHIELD
2024-03-19 09:55:56 +01:00
4fac079aec Merge branch 'main' into feature/datashield 2024-03-19 09:52:40 +01:00
ec6f9302a1 Fix spelling of log WARN 2024-03-19 08:47:57 +00:00
896b24be9b Use bridgehead log functions in datashield setup 2024-03-19 08:45:50 +00:00
adf8e35ba9 Remove empty file (teiler-ui-compose.yml) 2024-03-18 19:22:10 +01:00
480bbe04e7 Changed: TEILER_DEFAULT_LANGUAGE 2024-03-18 16:47:40 +01:00
d8b9498ef9 Update minimal/docker-compose.yml
Co-authored-by: Jan <59206115+Threated@users.noreply.github.com>
2024-03-18 12:45:46 +01:00
3180d0fd76 Replace | openssl rsautl -sign with | sha1sum | openssl pkeyutl -sign 2024-03-18 12:44:34 +01:00
3a8df378a6 Update lib/functions.sh
Co-authored-by: Tobias Kussel <TKussel@users.noreply.github.com>
2024-03-18 12:36:09 +01:00
8cb33c2ddc Add warning if ENABLE_EXPORTER is not set or set to true 2024-03-18 12:18:19 +01:00
591d95e8db Remove empty line 2024-03-18 12:13:09 +01:00
349027e969 Rename oauth2_proxy docker service to oauth2-proxy 2024-03-18 12:12:16 +01:00
ff06782234 Remove todo 2024-03-18 12:04:04 +01:00
6969a7a3bc Remove unnecessary comment 2024-03-18 12:02:53 +01:00
8ea7da64b7 Merge pull request #165 from samply/fix/useCommonLanguage
Use always English Output of free command
2024-03-15 11:51:37 +01:00
6217e28590 fix: use always english output of free command 2024-03-15 11:48:25 +01:00
a87e9b9284 Merge pull request #154 from samply/refactor/blazePerformanceTuning
Optimize memory usage of Blaze
2024-03-15 09:55:34 +01:00
1f17fad366 fix: Dont change ownership of all files under /tmp/bridgehead and /var/cache/bridgehead 2024-03-14 14:09:21 +00:00
5a6322fcaa refactor: Move oauth2 proxy related things to datashield setup 2024-03-14 11:50:08 +00:00
f88dfb5654 Merge pull request #145 from samply/feature/datashield-central-keycloak
Remove local Keycloak Installation
2024-03-13 10:34:13 +01:00
1a233b81a4 Merge pull request #163 from samply/refactor/datashield
refactor: Move vars to their setup files
2024-03-13 10:13:10 +01:00
e1e523f1ac refactor: tune configuration of blaze according to system memory 2024-03-13 08:56:48 +01:00
7478d804df refactor: Move vars to their setup files 2024-03-11 10:34:05 +00:00
06033c8ea0 Merge pull request #162 from samply/update/focus_0_4_1
Updated ccp focus to 0.4.1
2024-03-08 16:26:41 +01:00
eeb17e7bfe feat: added optional resource cache cap 2024-03-08 13:33:30 +01:00
3223c22ff5 Merge pull request #161 from samply/fix/minimal-checks
Don't test clock skew and private key existance for minimal bridgeheads
2024-03-08 09:20:05 +01:00
ea6441fbcb Updated ccp focus to 0.4.1 2024-03-08 08:33:15 +01:00
3777d4bf05 Add default value for BLAZE_MEMORY_CAP
Co-authored-by: Tobias Kussel <TKussel@users.noreply.github.com>
2024-03-05 10:35:16 +01:00
Jan
7245ddc720 Merge pull request #158 from samply/main
Fix focus version
2024-02-28 11:01:47 +01:00
db9692795a fix: Fix if syntrax 2024-02-27 12:47:33 +01:00
74eb86f8af fix: Update permissions on update 2024-02-27 12:47:33 +01:00
fb4da54297 chore: Add mannheim to datashield sites 2024-02-27 12:47:33 +01:00
3e44dab9f2 chore: Remame datashield mappings to datashield sites 2024-02-27 12:47:33 +01:00
f72e7c7799 Changed: replace keycloak with oidc 2024-02-27 12:47:33 +01:00
19d0fefe94 Changed: master realm 2024-02-27 12:47:33 +01:00
9a1860ccf9 Removed: / from groups 2024-02-27 12:47:33 +01:00
8a197ce5c7 Add oauth2_proxy 2024-02-27 12:47:33 +01:00
29d2bc0440 Add Keycloak to MTBA 2024-02-27 12:47:33 +01:00
2eb56e66c8 Integrate central Keycloak in Teiler 2024-02-27 12:47:33 +01:00
ef8866b943 fix: Start oauth proxy after forward_proxy is ready 2024-02-27 12:47:33 +01:00
cea577bde5 Removed: login-compose 2024-02-27 12:47:33 +01:00
97a558dd46 Removed:Login-compose 2024-02-27 12:47:33 +01:00
1995997ac2 fix: Wait for forward proxy to start 2024-02-27 12:47:33 +01:00
64250d9d21 refactor: Use beam proxy directly as proxy 2024-02-27 12:47:33 +01:00
f3fa1ce712 fix: secret sync account for minimal override 2024-02-27 12:47:33 +01:00
b241feecdb fix: Pull oauth2 proxy from harbor 2024-02-27 12:47:33 +01:00
4a9427a1bd fix: Use forward proxy for secret sync 2024-02-27 12:47:33 +01:00
af3e5231d8 Added: Proxy to R-Studio oauth2-proxy 2024-02-27 12:47:32 +01:00
51e8888fe1 Use latest jq 2024-02-27 12:47:32 +01:00
32ffb33ab1 fix: Only give writeable dirs the docker role 2024-02-27 12:47:32 +01:00
224c1472b2 fix: Correctly set file permissions 2024-02-27 12:47:32 +01:00
01d3a38e18 refactor: Use jq from docker 2024-02-27 12:47:32 +01:00
92a1f4bb59 Add dsCCPhos 2024-02-27 12:47:32 +01:00
4e3cd68922 Only sync secrets on startup 2024-02-27 12:47:32 +01:00
c60c9fc4b4 fix: Use strong pw for opal 2024-02-27 12:47:32 +01:00
f0a05b12ad fix: Generate stable passwords 2024-02-27 12:47:32 +01:00
935c45b74d Added: volume for opal metadata db (III) 2024-02-27 12:47:32 +01:00
01efc6f9b9 Added: volume for opal metadata db (II) 2024-02-27 12:47:32 +01:00
e54475f704 Added: volume for opal metadata db 2024-02-27 12:47:32 +01:00
2f04e51f96 Add test sites 2024-02-27 12:47:32 +01:00
d62f5a404b Add central token manager beam id 2024-02-27 12:47:32 +01:00
977ad139f8 Added: allowed-groups 2024-02-27 12:47:32 +01:00
643e9e67a6 Added: Enable MTBA and Enable DataSHIELD to Teiler Backend 2024-02-27 12:47:32 +01:00
37f100dc01 Default values for MTBA 2024-02-27 12:47:32 +01:00
0793ea9fc6 Use develop version of mtba 2024-02-27 12:47:32 +01:00
44d7b34834 Use last version of mtba 2024-02-27 12:47:32 +01:00
f6dac7038f Only users of group DataSHIELD can use R-Studio 2024-02-27 12:47:32 +01:00
8e5ddc493c teiler-orchestrator and teiler-dashboard latest 2024-02-27 12:47:32 +01:00
Jan
fa141f8e86 fix: undo permission changes on startup 2024-02-27 12:47:31 +01:00
Jan
2a024e751d fix: only change permissions on related files 2024-02-27 12:47:31 +01:00
d3da426610 fix: opal ssl cert 2024-02-27 12:47:31 +01:00
b34f4f2a0f fix: chown syntax 2024-02-27 12:47:31 +01:00
1edcdce5c6 fix: beam connect site renaming 2024-02-27 12:47:31 +01:00
b73ddc883c fix: Change permissions on new bridgehead dirs 2024-02-27 12:47:31 +01:00
9f31e950a5 fix: generate the right beam connect mappings 2024-02-27 12:47:31 +01:00
371097377a feat: Add token-manager to beam 2024-02-27 12:47:31 +01:00
0a2dbb4b2d fix: Restrict rstudio network access 2024-02-27 12:47:31 +01:00
148e87341f move OAUTH2_SECRET 2024-02-27 12:47:31 +01:00
28a612f218 add default template-ids of exporter and reporter 2024-02-27 12:47:31 +01:00
e411883d18 mtba develop 2024-02-27 12:47:31 +01:00
0b2e64a2d5 add /oauth2/callback and /mtba to Keycloak private client 2024-02-27 12:47:31 +01:00
25ac4d2590 mtba latest 2024-02-27 12:47:31 +01:00
f9b26b6958 Use develop branch for mtba 2024-02-27 12:47:27 +01:00
5d4d0405ab fix: public client generation 2024-02-27 12:47:14 +01:00
b44a208e08 Better redirect url handeling 2024-02-27 12:47:13 +01:00
0cd4ededc7 Add oauth2_proxy 2024-02-27 12:47:13 +01:00
f6965859fe Add comment about PASSWORD and DISABLE_AUTH in R-Studio 2024-02-27 12:47:13 +01:00
ae965fddb3 Add proxy to R-Studio for loading R packages 2024-02-27 12:47:13 +01:00
903ef0df9b Add Keycloak to MTBA 2024-02-27 12:47:13 +01:00
e32f484c31 Add keycloak configuration 2024-02-27 12:47:13 +01:00
8486abedd4 Add R-Studio Admin Password 2024-02-27 12:47:13 +01:00
163650f592 Add generate_password function 2024-02-27 12:47:13 +01:00
9ebbf2ed9b Bugfix: Export /var/cache/bridgehead/secrets as environment variables 2024-02-27 12:47:13 +01:00
131b52f57b Account for ip address host values 2024-02-27 12:47:13 +01:00
043e12b985 Remove port handeling when generating redirect url 2024-02-27 12:47:13 +01:00
bb076c5d5a Add function generate_redirect_urls 2024-02-27 12:47:13 +01:00
3c8ec73ac3 Update oidc provider to new url 2024-02-27 12:47:13 +01:00
0015365d1b Generate addtional redirect url 2024-02-27 12:47:13 +01:00
dc3d5496e1 Integrate central Keycloak in Teiler 2024-02-27 12:47:13 +01:00
93a91326a2 Make sure path exists 2024-02-27 12:47:13 +01:00
4115319956 Setup hostname earlier 2024-02-27 12:47:13 +01:00
f854ab58ce Update to new secret-sync semantics 2024-02-27 12:47:13 +01:00
cec3dfe4cd Add secret sync to the bridgehead 2024-02-27 12:47:13 +01:00
3d136959e7 Bugfix: Add version in every docker compose file 2024-02-27 12:47:13 +01:00
8e171b71de Remove unnecessary version of docker-compose.override files 2024-02-27 12:47:13 +01:00
d3edb5e143 Bugfix: Add version in every docker compose file 2024-02-27 12:47:13 +01:00
b87d746a20 Remove unnecessary version of docker-compose.override files 2024-02-27 12:47:09 +01:00
afb63306a8 Remove unnecessary version of docker-compose.override files 2024-02-27 12:46:36 +01:00
90ee8d63f7 Externalize postgres version 2024-02-27 12:44:33 +01:00
8d4f487806 MTBA 1.0.0 2024-02-27 12:44:33 +01:00
a2c242583e Remove nngmSetup in vars 2024-02-27 12:44:33 +01:00
178867cde7 Prevent creation of volumes 2024-02-27 12:44:33 +01:00
77240ff92f Use Bridgehead's internal http proxy 2024-02-27 12:44:33 +01:00
876c4efa41 Make Opal use proxy server 2024-02-27 12:44:33 +01:00
058d1c83e6 Use newest version of beam-connect 2024-02-27 12:44:33 +01:00
ec6407414b Update export template script: FHIR_QUERY to FHIR_PATH 2024-02-27 12:44:33 +01:00
89c90d3aa0 /var/cache for mtba 2024-02-27 12:44:32 +01:00
0039efa353 Add docu about login in teiler 2024-02-27 12:44:32 +01:00
c1020c569a Bugfix: datashield local.json as array 2024-02-27 12:44:32 +01:00
2237562e6e Prevent anonymous volume creation 2024-02-27 12:44:32 +01:00
c8fc35576e Bugfix: Exporter and Reporter /var/cache volumes 2024-02-27 12:44:32 +01:00
3dfc4cf57d Postgres 15.4 in datashield, exporter and login 2024-02-27 12:44:32 +01:00
3a6520a668 Update ccp/modules/mtba.md
Co-authored-by: Martin Lablans <6804500+lablans@users.noreply.github.com>
2024-02-27 12:44:32 +01:00
dcddbf2235 Bugfix: Add version of docker-compose 2024-02-27 12:44:26 +01:00
e2f31b6eeb Make sure copy works and the correct owner is set 2024-02-27 12:43:34 +01:00
452946aa04 Add all sites 2024-02-27 12:43:34 +01:00
5c7da0d40d Auto generate mappings 2024-02-27 12:43:34 +01:00
77145277de Add ccp to /var/cache/bridgehead/* volumes 2024-02-27 12:43:34 +01:00
9cdcf2afb8 Rewrite comments 2024-02-27 12:43:34 +01:00
13a74e5dab Move exporter db to /var/cache/bridgehead 2024-02-27 12:43:34 +01:00
c33726d385 Exporter cache 2024-02-27 12:43:34 +01:00
f38d9f8c19 Rework commented sections 2024-02-27 12:43:34 +01:00
b5ca5ea4a7 Autogenerate maps for Opal's beam-connect. To be completed by @Threated with a map-generator in the script. 2024-02-27 12:43:34 +01:00
862e452f3c Cache opal in /var/cache/bridgehead 2024-02-27 12:43:34 +01:00
4aa8f0f3ba Bugfix: Add version in every docker compose file 2024-02-27 12:43:33 +01:00
ccf0b91f17 #!/bin/bash -e 2024-02-27 12:43:33 +01:00
720783249d Bugfix: LDM_AUTH instead of LDM_PASSWORD 2024-02-27 12:43:33 +01:00
2b3eabe95c Rename Teiler Backend, Teiler Dashboard and Teiler Orchestrator 2024-02-27 12:43:33 +01:00
14aece46f7 Add site to exporter and reporter 2024-02-27 12:43:33 +01:00
ff1f7904ad Add forward proxy to teiler-core 2024-02-27 12:43:33 +01:00
8d38adc91e Bugfix: mtba labels 2024-02-27 12:43:33 +01:00
cfc3c7c90e Bugfix: exporter 2024-02-27 12:43:33 +01:00
963144cc31 Disable datashield 2024-02-27 12:43:33 +01:00
765613b87f Bugfix: MTBA path prefix 2024-02-27 12:43:32 +01:00
2b61775652 Enable datashield 2024-02-27 12:43:32 +01:00
4b0b17424f Comment Keycloak volume 2024-02-27 12:43:32 +01:00
f26a8f7a71 Fix comment in login-compose.yml 2024-02-27 12:43:32 +01:00
973b5828f6 Remove old comment of exporter-setup.sh 2024-02-27 12:43:32 +01:00
839e7a4518 Comment on datashield volume 2024-02-27 12:43:32 +01:00
6cfb42dc9b Comment on export and report volumes 2024-02-27 12:43:32 +01:00
5d8bec53c0 Bugfix: JAVA_OPTS for exporter 2024-02-27 12:43:32 +01:00
c52975f204 Add mtba module documentation 2024-02-27 12:43:32 +01:00
957fa64ce9 Add teiler-ui module documentation 2024-02-27 12:43:32 +01:00
b4805af0a1 Add some docs about beam-connect 2024-02-27 12:43:31 +01:00
e3b8a7369b Add login module documentation 2024-02-27 12:43:31 +01:00
adeaf433dc Add Exporter module documentation 2024-02-27 12:43:31 +01:00
846e9c23a7 Add DataSHIELD module documentation 2024-02-27 12:43:31 +01:00
bb7451d8c3 Add JAVA_OPTS to reporter and exporter 2024-02-27 12:43:31 +01:00
26165232f0 Enable Login, Teiler and Exporter 2024-02-27 12:43:31 +01:00
7ed24f667d Export and QB Curl templates 2024-02-27 12:43:31 +01:00
d97ac56126 Generate exporter api key automatically 2024-02-27 12:43:31 +01:00
e7f6c0b1a0 Add default language to ccp 2024-02-27 12:43:31 +01:00
c4c4f743d2 Remove updater cron of teiler-core 2024-02-27 12:43:31 +01:00
be9adcbfa2 Remove clean temp files configuration of exporter 2024-02-27 12:43:30 +01:00
10a362c237 Add explanation why is the volume of exporter-db currently so important for us. 2024-02-27 12:43:30 +01:00
75c86b79e8 Add Teiler Admin to Keycloak 2024-02-27 12:43:30 +01:00
a6443a6857 Remove IS_DKTK_SITE 2024-02-27 12:43:30 +01:00
f3745b973a User default user rstudio in rstudio 2024-02-27 12:43:30 +01:00
50d28d293f Generate DATASHIELD_CONNECT_SECRET automatically 2024-02-27 12:43:30 +01:00
44415369cc Update ccp/modules/datashield-compose.yml 2024-02-27 12:43:30 +01:00
9b8331ed28 Update ccp/modules/datashield-compose.yml 2024-02-27 12:43:30 +01:00
73d969e374 Use LDM_PASSWORD for all admin passwords 2024-02-27 12:43:30 +01:00
840096d1d5 Enable only if true 2024-02-27 12:43:29 +01:00
43c45f0628 Remove todo in rstudio 2024-02-27 12:43:29 +01:00
e182e2fbe6 Remove unnecessary version of docker-compose.override files 2024-02-27 12:43:23 +01:00
c8bafb2461 R-Server rock-base:6.3 2024-02-27 12:42:38 +01:00
0866cacc5a User postgres if docker.verbis.dkfz.de 2024-02-27 12:42:38 +01:00
a1e76a61b8 Remove ports of beam-connect in datashield-compose.yml 2024-02-27 12:42:38 +01:00
09aa33c912 Generate passwords only if modules are enabled 2024-02-27 12:42:38 +01:00
36ac8d41c8 Add http scheme to exporter 2024-02-27 12:42:37 +01:00
c003999721 Migrate to new app key syntax 2024-02-27 12:42:37 +01:00
50360d3f41 update new broker 2024-02-27 12:42:37 +01:00
5148e3382d Add parameter LOG_FHIR_VALIDATION to exporter 2024-02-27 12:42:37 +01:00
2d7d1d73b3 Add reporter 2024-02-27 12:42:37 +01:00
20c65336e6 Switch to no-auth branch of beam-connect 2024-02-27 12:42:37 +01:00
276f886546 secrets are readonly by default 2024-02-27 12:42:37 +01:00
bc239c0b02 change to dockerhub image 2024-02-27 12:42:37 +01:00
6438fc5f4e Change beam-connect version and load opal cert 2024-02-27 12:42:37 +01:00
f2f48869af Change cert permission and location 2024-02-27 12:42:36 +01:00
e9e1ce5a65 ccp.conf in teiler-core as secret 2024-02-27 12:42:36 +01:00
687dbba383 Add opal certificate 2024-02-27 12:42:36 +01:00
5e376b17ad Remove unnecessary volumes 2024-02-27 12:42:36 +01:00
04cf5128b0 Remove mongo db 2024-02-27 12:42:36 +01:00
43ab59563c Add Opal Password in Exporter 2024-02-27 12:42:36 +01:00
996f53a164 expose beam connect ports 2024-02-27 12:42:36 +01:00
b5ce188842 Fix beam connect app id 2024-02-27 12:42:36 +01:00
325ae1d574 beam connect and move beam-connect config 2024-02-27 12:42:36 +01:00
68782d1c32 Experiment 2024-02-27 12:42:35 +01:00
bedc2ca6d0 Add beam connect to docekr-compose 2024-02-27 12:42:35 +01:00
dfde7c18ff Experiment 2024-02-27 12:42:35 +01:00
0b1e0474d7 Add DataSHIELD 2024-02-27 12:42:35 +01:00
72255e6211 Bugfix: cross origins of exporter 2024-02-27 12:42:35 +01:00
32de51eefb Merge id-management-setup with main 2024-02-27 12:42:35 +01:00
0cfe1d3617 Change salt string for exporter and login 2024-02-27 12:42:35 +01:00
fe07c63f36 Adapt teiler-ui to traefik 2024-02-27 12:42:35 +01:00
3a91259a8a Add keycloak teiler app to teiler-ui 2024-02-27 12:42:35 +01:00
4bbd2a15fe Change volume names for teiler components 2024-02-27 12:42:35 +01:00
0a17bbc81f Add stripprefix to teiler-ui 2024-02-27 12:42:35 +01:00
c794508880 Add stripprefix to teiler-core 2024-02-27 12:42:34 +01:00
3e0bf38018 Add forward strategy to teiler-core 2024-02-27 12:42:34 +01:00
e2d109558d Add forward strategy to teiler-core 2024-02-27 12:42:34 +01:00
9299a201a6 Deactivate traffik for mtba 2024-02-27 12:42:34 +01:00
c9b1975c9e Tidy teiler and mtba volumes 2024-02-27 12:42:34 +01:00
17f52a7907 Add Teiler Core 2024-02-27 12:42:34 +01:00
4d1a9bb701 Add Endpoint for Teiler 2024-02-27 12:42:34 +01:00
efc04cea4f Update Teiler Core config 2024-02-27 12:42:34 +01:00
8fe03a6cd2 Add original Keycloak config 2024-02-27 12:42:34 +01:00
c66dac9881 update keykloak config 2024-02-27 12:42:33 +01:00
38c7f3c24a beautiful config 2024-02-27 12:42:33 +01:00
49be101165 Rename teiler to exporter (bugfix) 2024-02-27 12:42:33 +01:00
6626f860a2 Rename teiler to exporter 2024-02-27 12:42:33 +01:00
eb17d8c159 Configure login extern URLs 2024-02-27 12:42:33 +01:00
6340acdbe8 Bugfix: services in teiler-ui-compose.yml 2024-02-27 12:42:32 +01:00
c916a357dc Change images of dktk-teiler and dktk-keycloak 2024-02-27 12:42:32 +01:00
20e2b2a0ed Add nngm and exliquid modules 2024-02-27 12:42:32 +01:00
2e6edb6179 Add Teiler UI and Teiler module 2024-02-27 12:42:32 +01:00
b5ef856f12 refactor: calculate memory using free
Co-authored-by: Tobias Kussel <TKussel@users.noreply.github.com>
2024-02-23 08:27:06 +01:00
7d07c0623d refactor: optimize memory usage of blaze 2024-02-20 15:27:00 +01:00
28 changed files with 718 additions and 31 deletions

2
.gitignore vendored
View File

@ -1,7 +1,7 @@
##Ignore site configuration
.gitmodules
site-config/*
.idea
## Ignore site configuration
*/docker-compose.override.yml

View File

@ -8,8 +8,9 @@ services:
container_name: bridgehead-bbmri-blaze
environment:
BASE_URL: "http://bridgehead-bbmri-blaze:8080"
JAVA_TOOL_OPTIONS: "-Xmx4g"
LOG_LEVEL: "debug"
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
ENFORCE_REFERENTIAL_INTEGRITY: "false"
volumes:
- "blaze-data:/app/data"

View File

@ -1,3 +1,5 @@
version: "3.7"
services:
directory_sync_service:
image: "docker.verbis.dkfz.de/cache/samply/directory_sync_service"

View File

@ -50,6 +50,8 @@ loadVars() {
source /etc/bridgehead/$PROJECT.local.conf || fail_and_report 1 "Found /etc/bridgehead/$PROJECT.local.conf but failed to import"
fi
fetchVarsFromVaultByFile /etc/bridgehead/$PROJECT.conf || fail_and_report 1 "Unable to fetchVarsFromVaultByFile"
setHostname
optimizeBlazeMemoryUsage
[ -e ./$PROJECT/vars ] && source ./$PROJECT/vars
set +a
@ -64,7 +66,6 @@ loadVars() {
OVERRIDE+=" -f ./$PROJECT/docker-compose.override.yml"
fi
detectCompose
setHostname
setupProxy
# Set some project-independent default values
@ -89,11 +90,14 @@ case "$ACTION" in
loadVars
hc_send log "Bridgehead $PROJECT startup: Checking requirements ..."
checkRequirements
sync_secrets
hc_send log "Bridgehead $PROJECT startup: Requirements checked out. Now starting bridgehead ..."
exec $COMPOSE -p $PROJECT -f ./minimal/docker-compose.yml -f ./$PROJECT/docker-compose.yml $OVERRIDE up --abort-on-container-exit
;;
stop)
loadVars
# Kill stale secret-sync instances if present
docker kill $(docker ps -q --filter ancestor=docker.verbis.dkfz.de/cache/samply/secret-sync-local) 2>/dev/null || true
# HACK: This is temporarily to properly shut down false bridgehead instances (bridgehead-ccp instead ccp)
$COMPOSE -p bridgehead-$PROJECT -f ./minimal/docker-compose.yml -f ./$PROJECT/docker-compose.yml $OVERRIDE down
exec $COMPOSE -p $PROJECT -f ./minimal/docker-compose.yml -f ./$PROJECT/docker-compose.yml $OVERRIDE down

View File

@ -6,7 +6,9 @@ services:
container_name: bridgehead-ccp-blaze
environment:
BASE_URL: "http://bridgehead-ccp-blaze:8080"
JAVA_TOOL_OPTIONS: "-Xmx4g"
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
ENFORCE_REFERENTIAL_INTEGRITY: "false"
volumes:
- "blaze-data:/app/data"
@ -19,7 +21,7 @@ services:
- "traefik.http.routers.blaze_ccp.tls=true"
focus:
image: docker.verbis.dkfz.de/cache/samply/focus:0.4.0
image: docker.verbis.dkfz.de/cache/samply/focus:0.4.4
container_name: bridgehead-focus
environment:
API_KEY: ${FOCUS_BEAM_SECRET_SHORT}

View File

@ -0,0 +1,87 @@
version: "3.7"
services:
opal:
container_name: bridgehead-opal
image: docker.verbis.dkfz.de/ccp/dktk-opal:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.opal_ccp.rule=PathPrefix(`/opal`)"
- "traefik.http.services.opal_ccp.loadbalancer.server.port=8080"
- "traefik.http.routers.opal_ccp.tls=true"
links:
- opal-rserver
- opal-db
environment:
JAVA_OPTS: "-Xms1G -Xmx8G -XX:+UseG1GC -Dhttps.proxyHost=forward_proxy -Dhttps.proxyPort=3128"
# OPAL_ADMINISTRATOR_USER: "administrator" # This line is kept for informational purposes
OPAL_ADMINISTRATOR_PASSWORD: "${OPAL_ADMIN_PASSWORD}"
POSTGRESDATA_HOST: "opal-db"
POSTGRESDATA_DATABASE: "opal"
POSTGRESDATA_USER: "opal"
POSTGRESDATA_PASSWORD: "${OPAL_DB_PASSWORD}"
ROCK_HOSTS: "opal-rserver:8085"
APP_URL: "https://${HOST}/opal"
APP_CONTEXT_PATH: "/opal"
OPAL_PRIVATE_KEY: "/run/secrets/opal-key.pem"
OPAL_CERTIFICATE: "/run/secrets/opal-cert.pem"
OIDC_URL: "${OIDC_URL}"
OIDC_REALM: "${OIDC_REALM}"
OIDC_CLIENT_ID: "${OIDC_PRIVATE_CLIENT_ID}"
OIDC_CLIENT_SECRET: "${OIDC_CLIENT_SECRET}"
OIDC_ADMIN_GROUP: "${OIDC_ADMIN_GROUP}"
TOKEN_MANAGER_PASSWORD: "${TOKEN_MANAGER_OPAL_PASSWORD}"
EXPORTER_PASSWORD: "${EXPORTER_OPAL_PASSWORD}"
BEAM_APP_ID: token-manager.${PROXY_ID}
BEAM_SECRET: ${TOKEN_MANAGER_SECRET}
BEAM_DATASHIELD_PROXY: request-manager
volumes:
- "/var/cache/bridgehead/ccp/opal-metadata-db:/srv" # Opal metadata
secrets:
- opal-cert.pem
- opal-key.pem
opal-db:
container_name: bridgehead-opal-db
image: docker.verbis.dkfz.de/cache/postgres:${POSTGRES_TAG}
environment:
POSTGRES_PASSWORD: "${OPAL_DB_PASSWORD}" # Set in datashield-setup.sh
POSTGRES_USER: "opal"
POSTGRES_DB: "opal"
volumes:
- "/var/cache/bridgehead/ccp/opal-db:/var/lib/postgresql/data" # Opal project data (imported from exporter)
opal-rserver:
container_name: bridgehead-opal-rserver
image: docker.verbis.dkfz.de/ccp/dktk-rserver # datashield/rock-base + dsCCPhos
tmpfs:
- /srv
beam-connect:
image: docker.verbis.dkfz.de/cache/samply/beam-connect:develop
container_name: bridgehead-datashield-connect
environment:
PROXY_URL: "http://beam-proxy:8081"
TLS_CA_CERTIFICATES_DIR: /run/secrets
APP_ID: datashield-connect.${SITE_ID}.${BROKER_ID}
PROXY_APIKEY: ${DATASHIELD_CONNECT_SECRET}
DISCOVERY_URL: "./map/central.json"
LOCAL_TARGETS_FILE: "./map/local.json"
NO_AUTH: "true"
secrets:
- opal-cert.pem
depends_on:
- beam-proxy
volumes:
- /tmp/bridgehead/opal-map/:/map/:ro
beam-proxy:
environment:
APP_datashield-connect_KEY: ${DATASHIELD_CONNECT_SECRET}
APP_token-manager_KEY: ${TOKEN_MANAGER_SECRET}
secrets:
opal-cert.pem:
file: /tmp/bridgehead/opal-cert.pem
opal-key.pem:
file: /tmp/bridgehead/opal-key.pem

View File

@ -0,0 +1,157 @@
<template id="opal-ccp" source-id="blaze-store" opal-project="ccp-demo" target-id="opal" >
<container csv-filename="Patient-${TIMESTAMP}.csv" opal-table="patient" opal-entity-type="Patient">
<attribute csv-column="patient-id" opal-value-type="text" primary-key="true" val-fhir-path="Patient.id.value" anonym="Pat" op="EXTRACT_RELATIVE_ID"/>
<attribute csv-column="dktk-id-global" opal-value-type="text" val-fhir-path="Patient.identifier.where(type.coding.code = 'Global').value.value"/>
<attribute csv-column="dktk-id-lokal" opal-value-type="text" val-fhir-path="Patient.identifier.where(type.coding.code = 'Lokal').value.value" />
<attribute csv-column="geburtsdatum" opal-value-type="date" val-fhir-path="Patient.birthDate.value"/>
<attribute csv-column="geschlecht" opal-value-type="text" val-fhir-path="Patient.gender.value" />
<attribute csv-column="datum_des_letztbekannten_vitalstatus" opal-value-type="date" val-fhir-path="Observation.where(code.coding.code = '75186-7').effective.value" join-fhir-path="/Observation.where(code.coding.code = '75186-7').subject.reference.value"/>
<attribute csv-column="vitalstatus" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '75186-7').value.coding.code.value" join-fhir-path="/Observation.where(code.coding.code = '75186-7').subject.reference.value"/>
<!--fehlt in ADT2FHIR--><attribute csv-column="tod_tumorbedingt" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '68343-3').value.coding.where(system = 'http://fhir.de/CodeSystem/bfarm/icd-10-gm').code.value" join-fhir-path="/Observation.where(code.coding.code = '68343-3').subject.reference.value"/>
<!--fehlt in ADT2FHIR--><attribute csv-column="todesursachen" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '68343-3').value.coding.where(system = 'http://dktk.dkfz.de/fhir/onco/core/CodeSystem/JNUCS').code.value" join-fhir-path="/Observation.where(code.coding.code = '68343-3').subject.reference.value"/>
</container>
<container csv-filename="Diagnosis-${TIMESTAMP}.csv" opal-table="diagnosis" opal-entity-type="Diagnosis">
<attribute csv-column="diagnosis-id" primary-key="true" opal-value-type="text" val-fhir-path="Condition.id.value" anonym="Dia" op="EXTRACT_RELATIVE_ID"/>
<attribute csv-column="patient-id" opal-value-type="text" val-fhir-path="Condition.subject.reference.value" anonym="Pat"/>
<attribute csv-column="primaerdiagnose" opal-value-type="text" val-fhir-path="Condition.code.coding.code.value"/>
<attribute csv-column="tumor_diagnosedatum" opal-value-type="date" val-fhir-path="Condition.onset.value"/>
<attribute csv-column="primaertumor_diagnosetext" opal-value-type="text" val-fhir-path="Condition.code.text.value"/>
<attribute csv-column="version_des_icd-10_katalogs" opal-value-type="integer" val-fhir-path="Condition.code.coding.version.value"/>
<attribute csv-column="lokalisation" opal-value-type="text" val-fhir-path="Condition.bodySite.coding.where(system = 'urn:oid:2.16.840.1.113883.6.43.1').code.value"/>
<attribute csv-column="icd-o_katalog_topographie_version" opal-value-type="text" val-fhir-path="Condition.bodySite.coding.where(system = 'urn:oid:2.16.840.1.113883.6.43.1').version.value"/>
<attribute csv-column="seitenlokalisation_nach_adt-gekid" opal-value-type="text" val-fhir-path="Condition.bodySite.coding.where(system = 'http://dktk.dkfz.de/fhir/onco/core/CodeSystem/SeitenlokalisationCS').code.value"/>
</container>
<container csv-filename="Progress-${TIMESTAMP}.csv" opal-table="progress" opal-entity-type="Progress">
<!--it would be better to generate a an ID, instead of extracting the ClinicalImpression id-->
<attribute csv-column="progress-id" primary-key="true" opal-value-type="text" val-fhir-path="ClinicalImpression.id.value" anonym="Pro" op="EXTRACT_RELATIVE_ID"/>
<attribute csv-column="diagnosis-id" opal-value-type="text" val-fhir-path="ClinicalImpression.problem.reference.value" anonym="Dia"/>
<attribute csv-column="patient-id" opal-value-type="text" val-fhir-path="ClinicalImpression.subject.reference.value" anonym="Pat" />
<attribute csv-column="untersuchungs-_befunddatum_im_verlauf" opal-value-type="date" val-fhir-path="ClinicalImpression.effective.value" />
<!-- just for evaluation: redundant to Untersuchungs-, Befunddatum im Verlauf-->
<attribute csv-column="datum_lokales_oder_regionaeres_rezidiv" opal-value-type="date" val-fhir-path="Observation.where(code.coding.code = 'LA4583-6').effective.value" join-fhir-path="ClinicalImpression.finding.itemReference.reference.value" />
<attribute csv-column="gesamtbeurteilung_tumorstatus" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21976-6').value.coding.code.value" join-fhir-path="ClinicalImpression.finding.itemReference.reference.value"/>
<attribute csv-column="lokales_oder_regionaeres_rezidiv" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = 'LA4583-6').value.coding.code.value" join-fhir-path="ClinicalImpression.finding.itemReference.reference.value"/>
<attribute csv-column="lymphknoten-rezidiv" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = 'LA4370-8').value.coding.code.value" join-fhir-path="ClinicalImpression.finding.itemReference.reference.value" />
<attribute csv-column="fernmetastasen" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = 'LA4226-2').value.coding.code.value" join-fhir-path="ClinicalImpression.finding.itemReference.reference.value" />
</container>
<container csv-filename="Histology-${TIMESTAMP}.csv" opal-table="histology" opal-entity-type="Histology" >
<attribute csv-column="histology-id" primary-key="true" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '59847-4').id" anonym="His" op="EXTRACT_RELATIVE_ID"/>
<attribute csv-column="diagnosis-id" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '59847-4').focus.reference.value" anonym="Dia"/>
<attribute csv-column="patient-id" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '59847-4').subject.reference.value" anonym="Pat" />
<attribute csv-column="histologie_datum" opal-value-type="date" val-fhir-path="Observation.where(code.coding.code = '59847-4').effective.value"/>
<attribute csv-column="icd-o_katalog_morphologie_version" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '59847-4').value.coding.version.value" />
<attribute csv-column="morphologie" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '59847-4').value.coding.code.value"/>
<attribute csv-column="morphologie-freitext" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '59847-4').value.text.value"/>
<attribute csv-column="grading" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '59542-1').value.coding.code.value" join-fhir-path="Observation.where(code.coding.code = '59847-4').hasMember.reference.value"/>
</container>
<container csv-filename="Metastasis-${TIMESTAMP}.csv" opal-table="metastasis" opal-entity-type="Metastasis" >
<attribute csv-column="metastasis-id" primary-key="true" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21907-1').id" anonym="Met" op="EXTRACT_RELATIVE_ID"/>
<attribute csv-column="diagnosis-id" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21907-1').focus.reference.value" anonym="Dia"/>
<attribute csv-column="patient-id" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21907-1').subject.reference.value" anonym="Pat" />
<attribute csv-column="datum_fernmetastasen" opal-value-type="date" val-fhir-path="Observation.where(code.coding.code = '21907-1').effective.value"/>
<attribute csv-column="fernmetastasen_vorhanden" opal-value-type="boolean" val-fhir-path="Observation.where(code.coding.code = '21907-1').value.coding.code.value"/>
<attribute csv-column="lokalisation_fernmetastasen" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21907-1').bodySite.coding.code.value"/>
</container>
<container csv-filename="TNM-${TIMESTAMP}.csv" opal-table="tnm" opal-entity-type="TNM">
<attribute csv-column="tnm-id" primary-key="true" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').id" anonym="TNM" op="EXTRACT_RELATIVE_ID"/>
<attribute csv-column="diagnosis-id" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').focus.reference.value" anonym="Dia"/>
<attribute csv-column="patient-id" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').subject.reference.value" anonym="Pat" />
<attribute csv-column="datum_der_tnm_dokumentation_datum_befund" opal-value-type="date" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').effective.value"/>
<attribute csv-column="uicc_stadium" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').value.coding.code.value"/>
<attribute csv-column="tnm-t" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').component.where(code.coding.code = '21905-5' or code.coding.code = '21899-0').value.coding.code.value"/>
<attribute csv-column="tnm-n" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').component.where(code.coding.code = '21906-3' or code.coding.code = '21900-6').value.coding.code.value"/>
<attribute csv-column="tnm-m" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').component.where(code.coding.code = '21907-1' or code.coding.code = '21901-4').value.coding.code.value"/>
<attribute csv-column="c_p_u_preefix_t" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').component.where(code.coding.code = '21905-5' or code.coding.code = '21899-0').extension('http://dktk.dkfz.de/fhir/StructureDefinition/onco-core-Extension-TNMcpuPraefix').value.coding.code.value"/>
<attribute csv-column="c_p_u_preefix_n" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').component.where(code.coding.code = '21906-3' or code.coding.code = '21900-6').extension('http://dktk.dkfz.de/fhir/StructureDefinition/onco-core-Extension-TNMcpuPraefix').value.coding.code.value"/>
<attribute csv-column="c_p_u_preefix_m" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').component.where(code.coding.code = '21907-1' or code.coding.code = '21901-4').extension('http://dktk.dkfz.de/fhir/StructureDefinition/onco-core-Extension-TNMcpuPraefix').value.coding.code.value"/>
<attribute csv-column="tnm-y-symbol" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').component.where(code.coding.code = '59479-6' or code.coding.code = '59479-6').value.coding.code.value"/>
<attribute csv-column="tnm-r-symbol" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').component.where(code.coding.code = '21983-2' or code.coding.code = '21983-2').value.coding.code.value"/>
<attribute csv-column="tnm-m-symbol" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').component.where(code.coding.code = '42030-7' or code.coding.code = '42030-7').value.coding.code.value"/>
<!--nur bei UICC, nicht in ADT2FHIR--><attribute csv-column="tnm-version" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '21908-9' or code.coding.code = '21902-2').value.coding.version.value"/>
</container>
<container csv-filename="System-Therapy-${TIMESTAMP}.csv" opal-table="system-therapy" opal-entity-type="SystemTherapy">
<attribute csv-column="system-therapy-id" primary-key="true" opal-value-type="text" val-fhir-path="MedicationStatement.id" anonym="Sys" op="EXTRACT_RELATIVE_ID"/>
<attribute csv-column="diagnosis-id" opal-value-type="text" val-fhir-path="MedicationStatement.reasonReference.reference.value" anonym="Dia"/>
<attribute csv-column="patient-id" opal-value-type="text" val-fhir-path="MedicationStatement.subject.reference.value" anonym="Pat" />
<attribute csv-column="systemische_therapie_stellung_zu_operativer_therapie" opal-value-type="text" val-fhir-path="MedicationStatement.extension('http://dktk.dkfz.de/fhir/StructureDefinition/onco-core-Extension-StellungZurOp').value.coding.code.value"/>
<attribute csv-column="intention_chemotherapie" opal-value-type="text" val-fhir-path="MedicationStatement.extension('http://dktk.dkfz.de/fhir/StructureDefinition/onco-core-Extension-SYSTIntention').value.coding.code.value"/>
<attribute csv-column="therapieart" opal-value-type="text" val-fhir-path="MedicationStatement.category.coding.code.value"/>
<attribute csv-column="systemische_therapie_beginn" opal-value-type="date" val-fhir-path="MedicationStatement.effective.start.value"/>
<attribute csv-column="systemische_therapie_ende" opal-value-type="date" val-fhir-path="MedicationStatement.effective.end.value"/>
<attribute csv-column="systemische_therapie_protokoll" opal-value-type="text" val-fhir-path="MedicationStatement.extension('http://dktk.dkfz.de/fhir/StructureDefinition/onco-core-Extension-SystemischeTherapieProtokoll').value.text.value"/>
<attribute csv-column="systemische_therapie_substanzen" opal-value-type="text" val-fhir-path="MedicationStatement.medication.text.value"/>
<attribute csv-column="chemotherapie" opal-value-type="boolean" val-fhir-path="MedicationStatement.where(category.coding.code = 'CH').exists().value" />
<attribute csv-column="hormontherapie" opal-value-type="boolean" val-fhir-path="MedicationStatement.where(category.coding.code = 'HO').exists().value" />
<attribute csv-column="immuntherapie" opal-value-type="boolean" val-fhir-path="MedicationStatement.where(category.coding.code = 'IM').exists().value" />
<attribute csv-column="knochenmarktransplantation" opal-value-type="boolean" val-fhir-path="MedicationStatement.where(category.coding.code = 'KM').exists().value" />
<attribute csv-column="abwartende_strategie" opal-value-type="boolean" val-fhir-path="MedicationStatement.where(category.coding.code = 'WS').exists().value" />
</container>
<container csv-filename="Surgery-${TIMESTAMP}.csv" opal-table="surgery" opal-entity-type="Surgery">
<attribute csv-column="surgery-id" primary-key="true" opal-value-type="text" val-fhir-path="Procedure.where(category.coding.code = 'OP').id" anonym="Sur" op="EXTRACT_RELATIVE_ID"/>
<attribute csv-column="diagnosis-id" opal-value-type="text" val-fhir-path="Procedure.where(category.coding.code = 'OP').reasonReference.reference.value" anonym="Dia"/>
<attribute csv-column="patient-id" opal-value-type="text" val-fhir-path="Procedure.where(category.coding.code = 'OP').subject.reference.value" anonym="Pat" />
<attribute csv-column="ops-code" opal-value-type="text" val-fhir-path="Procedure.where(category.coding.code = 'OP').code.coding.code.value"/>
<attribute csv-column="datum_der_op" opal-value-type="date" val-fhir-path="Procedure.where(category.coding.code = 'OP').performed.value"/>
<attribute csv-column="intention_op" opal-value-type="text" val-fhir-path="Procedure.extension('http://dktk.dkfz.de/fhir/StructureDefinition/onco-core-Extension-OPIntention').value.coding.code.value"/>
<attribute csv-column="lokale_beurteilung_resttumor" opal-value-type="text" val-fhir-path="Procedure.where(category.coding.code = 'OP').outcome.coding.where(system = 'http://dktk.dkfz.de/fhir/onco/core/CodeSystem/LokaleBeurteilungResidualstatusCS').code.value" />
<attribute csv-column="gesamtbeurteilung_resttumor" opal-value-type="text" val-fhir-path="Procedure.where(category.coding.code = 'OP').outcome.coding.where(system = 'http://dktk.dkfz.de/fhir/onco/core/CodeSystem/GesamtbeurteilungResidualstatusCS').code.value" />
</container>
<container csv-filename="Radiation-Therapy-${TIMESTAMP}.csv" opal-table="radiation-therapy" opal-entity-type="RadiationTherapy">
<attribute csv-column="radiation-therapy-id" primary-key="true" opal-value-type="text" val-fhir-path="Procedure.where(category.coding.code = 'ST').id" anonym="Rad" op="EXTRACT_RELATIVE_ID"/>
<attribute csv-column="diagnosis-id" opal-value-type="text" val-fhir-path="Procedure.where(category.coding.code = 'ST').reasonReference.reference.value" anonym="Dia"/>
<attribute csv-column="patient-id" opal-value-type="text" val-fhir-path="Procedure.where(category.coding.code = 'ST').subject.reference.value" anonym="Pat" />
<attribute csv-column="strahlentherapie_stellung_zu_operativer_therapie" opal-value-type="text" val-fhir-path="Procedure.extension('http://dktk.dkfz.de/fhir/StructureDefinition/onco-core-Extension-StellungZurOp').value.coding.code.value"/>
<attribute csv-column="intention_strahlentherapie" opal-value-type="text" val-fhir-path="Procedure.extension('http://dktk.dkfz.de/fhir/StructureDefinition/onco-core-Extension-SYSTIntention').value.coding.code.value" />
<attribute csv-column="strahlentherapie_beginn" opal-value-type="date" val-fhir-path="Procedure.where(category.coding.code = 'ST').performed.start.value"/>
<attribute csv-column="strahlentherapie_ende" opal-value-type="date" val-fhir-path="Procedure.where(category.coding.code = 'ST').performed.end.value"/>
</container>
<container csv-filename="Molecular-Marker-${TIMESTAMP}.csv" opal-table="molecular-marker" opal-entity-type="MolecularMarker">
<attribute csv-column="mol-marker-id" primary-key="true" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '69548-6').id" anonym="Mol" op="EXTRACT_RELATIVE_ID"/>
<attribute csv-column="diagnosis-id" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '69548-6').focus.reference.value" anonym="Dia" />
<attribute csv-column="patient-id" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '69548-6').subject.reference.value" anonym="Pat" />
<attribute csv-column="datum_der_datenerhebung" opal-value-type="date" val-fhir-path="Observation.where(code.coding.code = '69548-6').effective.value"/>
<attribute csv-column="marker" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '69548-6').component.value.coding.code.value"/>
<attribute csv-column="status_des_molekularen_markers" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '69548-6').value.coding.code.value" />
<attribute csv-column="zusaetzliche_alternative_dokumentation" opal-value-type="text" val-fhir-path="Observation.where(code.coding.code = '69548-6').value.text.value"/>
</container>
<container csv-filename="Sample-${TIMESTAMP}.csv" opal-table="sample" opal-entity-type="Sample">
<attribute csv-column="sample-id" primary-key="true" opal-value-type="text" val-fhir-path="Specimen.id" anonym="Sam" op="EXTRACT_RELATIVE_ID"/>
<attribute csv-column="patient-id" opal-value-type="text" val-fhir-path="Specimen.subject.reference.value" anonym="Pat" />
<attribute csv-column="entnahmedatum" opal-value-type="date" val-fhir-path="Specimen.collection.collectedDateTime.value"/>
<attribute csv-column="probenart" opal-value-type="text" val-fhir-path="Specimen.type.coding.code.value"/>
<attribute csv-column="status" opal-value-type="text" val-fhir-path="Specimen.status.code.value"/>
<attribute csv-column="projekt" opal-value-type="text" val-fhir-path="Specimen.identifier.system.value"/>
<!-- @TODO: it is still necessary to clarify whether it would not be better to take the quantity of collection.quantity -->
<attribute csv-column="menge" opal-value-type="integer" val-fhir-path="Specimen.container.specimenQuantity.value.value"/>
<attribute csv-column="einheit" opal-value-type="text" val-fhir-path="Specimen.container.specimenQuantity.unit.value"/>
<attribute csv-column="aliquot" opal-value-type="text" val-fhir-path="Specimen.parent.reference.exists().value" />
</container>
<fhir-rev-include>Observation:patient</fhir-rev-include>
<fhir-rev-include>Condition:patient</fhir-rev-include>
<fhir-rev-include>ClinicalImpression:patient</fhir-rev-include>
<fhir-rev-include>MedicationStatement:patient</fhir-rev-include>
<fhir-rev-include>Procedure:patient</fhir-rev-include>
<fhir-rev-include>Specimen:patient</fhir-rev-include>
</template>

View File

@ -0,0 +1,33 @@
#!/bin/bash -e
if [ "$ENABLE_DATASHIELD" == true ]; then
# HACK: This only works because exporter-setup.sh and teiler-setup.sh are sourced after datashield-setup.sh
if [ -z "${ENABLE_EXPORTER}" ] || [ "${ENABLE_EXPORTER}" != "true" ]; then
log WARN "The ENABLE_EXPORTER variable is either not set or not set to 'true'."
fi
log INFO "DataSHIELD setup detected -- will start DataSHIELD services."
OVERRIDE+=" -f ./$PROJECT/modules/datashield-compose.yml"
EXPORTER_OPAL_PASSWORD="$(generate_password \"exporter in Opal\")"
TOKEN_MANAGER_OPAL_PASSWORD="$(generate_password \"Token Manager in Opal\")"
OPAL_DB_PASSWORD="$(echo \"Opal DB\" | generate_simple_password)"
OPAL_ADMIN_PASSWORD="$(generate_password \"admin password for Opal\")"
DATASHIELD_CONNECT_SECRET="$(echo \"DataShield Connect\" | generate_simple_password)"
TOKEN_MANAGER_SECRET="$(echo \"Token Manager\" | generate_simple_password)"
if [ ! -e /tmp/bridgehead/opal-cert.pem ]; then
mkdir -p /tmp/bridgehead/
openssl req -x509 -newkey rsa:4096 -nodes -keyout /tmp/bridgehead/opal-key.pem -out /tmp/bridgehead/opal-cert.pem -days 3650 -subj "/CN=opal/C=DE"
fi
mkdir -p /tmp/bridgehead/opal-map
echo '{"sites": []}' >/tmp/bridgehead/opal-map/central.json
echo '[{
"external": "'$SITE_ID':443",
"internal": "opal:8443",
"allowed": ["central-ds-orchestrator.'$BROKER_ID'"]
}]' > /tmp/bridgehead/opal-map/local.json
if [ "$USER" == "root" ]; then
chown -R bridgehead:docker /tmp/bridgehead
chmod g+wr /tmp/bridgehead/opal-map/*
chmod g+r /tmp/bridgehead/opal-key.pem
fi
add_private_oidc_redirect_url "/opal/*"
fi

28
ccp/modules/datashield.md Normal file
View File

@ -0,0 +1,28 @@
# DataSHIELD
This module constitutes the infrastructure to run DataSHIELD within the bridghead.
For more information about DataSHIELD, please visit https://www.datashield.org/
## R-Studio
To connect to the different bridgeheads of the CCP through DataSHIELD, you can use your own R-Studio environment.
However, this R-Studio has already installed the DataSHIELD libraries and is integrated within the bridgehead.
This can save you some time for extra configuration of your R-Studio environment.
## Opal
This is the core of DataSHIELD. It is made up of Opal, a Postgres database and an R-server.
For more information about Opal, please visit https://opaldoc.obiba.org
### Opal
Opal is OBiBas core database application for biobanks.
### Opal-DB
Opal requires a database to import the data for DataSHIELD. We use a Postgres instance as database.
The data is imported within the bridgehead through the exporter.
### Opal-R-Server
R-Server to execute R scripts in DataSHIELD.
## Beam
### Beam-Connect
Beam-Connect is used to route http(s) traffic through beam to enable R-Studio to access data from other bridgeheads that have datashield enabled.
### Beam-Proxy
The usual beam proxy used for communication.

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/bash -e
if [ -n "${ENABLE_DNPM}" ]; then
log INFO "DNPM setup detected (Beam.Connect) -- will start Beam.Connect for DNPM."

View File

@ -0,0 +1,6 @@
# 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

@ -0,0 +1,80 @@
version: "3.7"
services:
exporter:
image: docker.verbis.dkfz.de/ccp/dktk-exporter:latest
container_name: bridgehead-ccp-exporter
environment:
JAVA_OPTS: "-Xms1G -Xmx8G -XX:+UseG1GC"
LOG_LEVEL: "INFO"
EXPORTER_API_KEY: "${EXPORTER_API_KEY}" # Set in exporter-setup.sh
CROSS_ORIGINS: "https://${HOST}"
EXPORTER_DB_USER: "exporter"
EXPORTER_DB_PASSWORD: "${EXPORTER_DB_PASSWORD}" # Set in exporter-setup.sh
EXPORTER_DB_URL: "jdbc:postgresql://exporter-db:5432/exporter"
HTTP_RELATIVE_PATH: "/ccp-exporter"
SITE: "${SITE_ID}"
HTTP_SERVLET_REQUEST_SCHEME: "https"
OPAL_PASSWORD: "${EXPORTER_OPAL_PASSWORD}"
labels:
- "traefik.enable=true"
- "traefik.http.routers.exporter_ccp.rule=PathPrefix(`/ccp-exporter`)"
- "traefik.http.services.exporter_ccp.loadbalancer.server.port=8092"
- "traefik.http.routers.exporter_ccp.tls=true"
- "traefik.http.middlewares.exporter_ccp_strip.stripprefix.prefixes=/ccp-exporter"
- "traefik.http.routers.exporter_ccp.middlewares=exporter_ccp_strip"
volumes:
- "/var/cache/bridgehead/ccp/exporter-files:/app/exporter-files/output"
exporter-db:
image: docker.verbis.dkfz.de/cache/postgres:${POSTGRES_TAG}
container_name: bridgehead-ccp-exporter-db
environment:
POSTGRES_USER: "exporter"
POSTGRES_PASSWORD: "${EXPORTER_DB_PASSWORD}" # Set in exporter-setup.sh
POSTGRES_DB: "exporter"
volumes:
# Consider removing this volume once we find a solution to save Lens-queries to be executed in the explorer.
- "/var/cache/bridgehead/ccp/exporter-db:/var/lib/postgresql/data"
reporter:
image: docker.verbis.dkfz.de/ccp/dktk-reporter:latest
container_name: bridgehead-ccp-reporter
environment:
JAVA_OPTS: "-Xms1G -Xmx8G -XX:+UseG1GC"
LOG_LEVEL: "INFO"
CROSS_ORIGINS: "https://${HOST}"
HTTP_RELATIVE_PATH: "/ccp-reporter"
SITE: "${SITE_ID}"
EXPORTER_API_KEY: "${EXPORTER_API_KEY}" # Set in exporter-setup.sh
EXPORTER_URL: "http://exporter:8092"
LOG_FHIR_VALIDATION: "false"
HTTP_SERVLET_REQUEST_SCHEME: "https"
# In this initial development state of the bridgehead, we are trying to have so many volumes as possible.
# However, in the first executions in the CCP sites, this volume seems to be very important. A report is
# a process that can take several hours, because it depends on the exporter.
# There is a risk that the bridgehead restarts, losing the already created export.
volumes:
- "/var/cache/bridgehead/ccp/reporter-files:/app/reports"
labels:
- "traefik.enable=true"
- "traefik.http.routers.reporter_ccp.rule=PathPrefix(`/ccp-reporter`)"
- "traefik.http.services.reporter_ccp.loadbalancer.server.port=8095"
- "traefik.http.routers.reporter_ccp.tls=true"
- "traefik.http.middlewares.reporter_ccp_strip.stripprefix.prefixes=/ccp-reporter"
- "traefik.http.routers.reporter_ccp.middlewares=reporter_ccp_strip"
file-dispatcher:
image: docker.verbis.dkfz.de/cache/samply/file-dispatcher:latest
environment:
- BEAM_ID=file-dispatcher.${PROXY_ID}
- PROJECT_MANAGER_ID=project-manager.request-manager.${BROKER_ID}
- BEAM_SECRET=${FILE_DISPATCHER_BEAM_SECRET} # Generated in exporter-setup.sh
- BEAM_URL=http://beam-proxy:8081
- EXPORTER_URL=http://exporter:8092
beam-proxy:
environment:
- APP_file-dispatcher_KEY=${FILE_DISPATCHER_BEAM_SECRET}

View File

@ -0,0 +1,9 @@
#!/bin/bash -e
if [ "$ENABLE_EXPORTER" == true ]; then
log INFO "Exporter setup detected -- will start Exporter service."
OVERRIDE+=" -f ./$PROJECT/modules/exporter-compose.yml"
EXPORTER_DB_PASSWORD="$(echo \"This is a salt string to generate one consistent password for the exporter. It is not required to be secret.\" | sha1sum | openssl pkeyutl -sign -inkey /etc/bridgehead/pki/${SITE_ID}.priv.pem | base64 | head -c 30)"
EXPORTER_API_KEY="$(echo \"This is a salt string to generate one consistent API KEY for the exporter. It is not required to be secret.\" | sha1sum | openssl pkeyutl -sign -inkey /etc/bridgehead/pki/${SITE_ID}.priv.pem | base64 | head -c 64)"
FILE_DISPATCHER_BEAM_SECRET="$(cat /proc/sys/kernel/random/uuid | sed 's/[-]//g' | head -c 20)"
fi

15
ccp/modules/exporter.md Normal file
View File

@ -0,0 +1,15 @@
# Exporter and Reporter
## Exporter
The exporter is a REST API that exports the data of the different databases of the bridgehead in a set of tables.
It can accept different output formats as CSV, Excel, JSON or XML. It can also export data into Opal.
## Exporter-DB
It is a database to save queries for its execution in the exporter.
The exporter manages also the different executions of the same query in through the database.
## Reporter
This component is a plugin of the exporter that allows to create more complex Excel reports described in templates.
It is compatible with different template engines as Groovy, Thymeleaf,...
It is perfect to generate a document as our traditional CCP quality report.

View File

@ -1,4 +1,5 @@
version: "3.7"
services:
id-manager:
image: docker.verbis.dkfz.de/bridgehead/magicpl
@ -43,7 +44,7 @@ services:
- patientlist-db
patientlist-db:
image: docker.verbis.dkfz.de/cache/postgres:15.6-alpine
image: docker.verbis.dkfz.de/cache/postgres:${POSTGRES_TAG}
container_name: bridgehead-patientlist-db
environment:
POSTGRES_USER: "mainzelliste"

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/bash -e
function idManagementSetup() {
if [ -n "$IDMANAGER_UPLOAD_APIKEY" ]; then

View File

@ -2,7 +2,7 @@ version: "3.7"
services:
mtba:
image: docker.verbis.dkfz.de/cache/samply/mtba:1.0.0
image: docker.verbis.dkfz.de/cache/samply/mtba:develop
container_name: bridgehead-mtba
environment:
BLAZE_STORE_URL: http://blaze:8080
@ -11,22 +11,30 @@ services:
ID_MANAGER_API_KEY: ${IDMANAGER_UPLOAD_APIKEY}
ID_MANAGER_PSEUDONYM_ID_TYPE: BK_${IDMANAGEMENT_FRIENDLY_ID}_L-ID
ID_MANAGER_URL: http://id-manager:8080/id-manager
PATIENT_CSV_FIRST_NAME_HEADER: ${MTBA_PATIENT_CSV_FIRST_NAME_HEADER}
PATIENT_CSV_LAST_NAME_HEADER: ${MTBA_PATIENT_CSV_LAST_NAME_HEADER}
PATIENT_CSV_GENDER_HEADER: ${MTBA_PATIENT_CSV_GENDER_HEADER}
PATIENT_CSV_BIRTHDAY_HEADER: ${MTBA_PATIENT_CSV_BIRTHDAY_HEADER}
PATIENT_CSV_FIRST_NAME_HEADER: ${MTBA_PATIENT_CSV_FIRST_NAME_HEADER:-FIRST_NAME}
PATIENT_CSV_LAST_NAME_HEADER: ${MTBA_PATIENT_CSV_LAST_NAME_HEADER:-LAST_NAME}
PATIENT_CSV_GENDER_HEADER: ${MTBA_PATIENT_CSV_GENDER_HEADER:-GENDER}
PATIENT_CSV_BIRTHDAY_HEADER: ${MTBA_PATIENT_CSV_BIRTHDAY_HEADER:-BIRTHDAY}
CBIOPORTAL_URL: http://cbioportal:8080
FILE_CHARSET: ${MTBA_FILE_CHARSET}
FILE_END_OF_LINE: ${MTBA_FILE_END_OF_LINE}
CSV_DELIMITER: ${MTBA_CSV_DELIMITER}
FILE_CHARSET: ${MTBA_FILE_CHARSET:-UTF-8}
FILE_END_OF_LINE: ${MTBA_FILE_END_OF_LINE:-LF}
CSV_DELIMITER: ${MTBA_CSV_DELIMITER:-TAB}
HTTP_RELATIVE_PATH: "/mtba"
OIDC_ADMIN_GROUP: "${OIDC_ADMIN_GROUP}"
OIDC_CLIENT_ID: "${OIDC_PRIVATE_CLIENT_ID}"
OIDC_CLIENT_SECRET: "${OIDC_CLIENT_SECRET}"
OIDC_REALM: "${OIDC_REALM}"
OIDC_URL: "${OIDC_URL}"
labels:
- "traefik.enable=true"
- "traefik.http.routers.mtba.rule=PathPrefix(`/`)"
- "traefik.http.services.mtba.loadbalancer.server.port=80"
- "traefik.http.routers.mtba.tls=true"
- "traefik.http.routers.mtba_ccp.rule=PathPrefix(`/mtba`)"
- "traefik.http.services.mtba_ccp.loadbalancer.server.port=8480"
- "traefik.http.routers.mtba_ccp.tls=true"
volumes:
- /tmp/bridgehead/mtba/input:/app/input
- /tmp/bridgehead/mtba/persist:/app/persist
- /var/cache/bridgehead/ccp/mtba/input:/app/input
- /var/cache/bridgehead/ccp/mtba/persist:/app/persist
# TODO: Include CBioPortal in Deployment ...
# NOTE: CBioPortal can't load data while the system is running. So after import of data bridgehead needs to be restarted!

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/bash -e
function mtbaSetup() {
if [ -n "$ENABLE_MTBA" ];then
@ -8,5 +8,6 @@ function mtbaSetup() {
exit 1;
fi
OVERRIDE+=" -f ./$PROJECT/modules/mtba-compose.yml"
add_private_oidc_redirect_url "/mtba/*"
fi
}
}

6
ccp/modules/mtba.md Normal file
View File

@ -0,0 +1,6 @@
# Molecular Tumor Board Alliance (MTBA)
In this module, the genetic data to import is stored in a directory (/tmp/bridgehead/mtba/input). A process checks
regularly if there are files in the directory. The files are pseudonomized when the IDAT is provided. The files are
combined with clinical data of the blaze and imported in cBioPortal. On the other hand, this files are also imported in
Blaze.

View File

@ -1,4 +1,5 @@
version: "3.7"
volumes:
nngm-rest:
@ -21,9 +22,6 @@ services:
- "traefik.http.routers.connector.middlewares=connector_strip,auth-nngm"
volumes:
- nngm-rest:/var/log
traefik:
labels:
- "traefik.http.middlewares.auth-nngm.basicauth.users=${NNGM_AUTH}"

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/bash -e
if [ -n "$NNGM_CTS_APIKEY" ]; then
log INFO "nNGM setup detected -- will start nNGM Connector."

View File

@ -0,0 +1,81 @@
version: "3.7"
services:
teiler-orchestrator:
image: docker.verbis.dkfz.de/cache/samply/teiler-orchestrator:latest
container_name: bridgehead-teiler-orchestrator
labels:
- "traefik.enable=true"
- "traefik.http.routers.teiler_orchestrator_ccp.rule=PathPrefix(`/ccp-teiler`)"
- "traefik.http.services.teiler_orchestrator_ccp.loadbalancer.server.port=9000"
- "traefik.http.routers.teiler_orchestrator_ccp.tls=true"
- "traefik.http.middlewares.teiler_orchestrator_ccp_strip.stripprefix.prefixes=/ccp-teiler"
- "traefik.http.routers.teiler_orchestrator_ccp.middlewares=teiler_orchestrator_ccp_strip"
environment:
TEILER_BACKEND_URL: "https://${HOST}/ccp-teiler-backend"
TEILER_DASHBOARD_URL: "https://${HOST}/ccp-teiler-dashboard"
DEFAULT_LANGUAGE: "${TEILER_DEFAULT_LANGUAGE_LOWER_CASE}"
HTTP_RELATIVE_PATH: "/ccp-teiler"
teiler-dashboard:
image: docker.verbis.dkfz.de/cache/samply/teiler-dashboard:develop
container_name: bridgehead-teiler-dashboard
labels:
- "traefik.enable=true"
- "traefik.http.routers.teiler_dashboard_ccp.rule=PathPrefix(`/ccp-teiler-dashboard`)"
- "traefik.http.services.teiler_dashboard_ccp.loadbalancer.server.port=80"
- "traefik.http.routers.teiler_dashboard_ccp.tls=true"
- "traefik.http.middlewares.teiler_dashboard_ccp_strip.stripprefix.prefixes=/ccp-teiler-dashboard"
- "traefik.http.routers.teiler_dashboard_ccp.middlewares=teiler_dashboard_ccp_strip"
environment:
DEFAULT_LANGUAGE: "${TEILER_DEFAULT_LANGUAGE}"
TEILER_BACKEND_URL: "https://${HOST}/ccp-teiler-backend"
OIDC_URL: "${OIDC_URL}"
OIDC_REALM: "${OIDC_REALM}"
OIDC_CLIENT_ID: "${OIDC_PUBLIC_CLIENT_ID}"
OIDC_TOKEN_GROUP: "${OIDC_GROUP_CLAIM}"
TEILER_ADMIN_NAME: "${OPERATOR_FIRST_NAME} ${OPERATOR_LAST_NAME}"
TEILER_ADMIN_EMAIL: "${OPERATOR_EMAIL}"
TEILER_ADMIN_PHONE: "${OPERATOR_PHONE}"
TEILER_PROJECT: "${PROJECT}"
EXPORTER_API_KEY: "${EXPORTER_API_KEY}"
TEILER_ORCHESTRATOR_URL: "https://${HOST}/ccp-teiler"
TEILER_DASHBOARD_HTTP_RELATIVE_PATH: "/ccp-teiler-dashboard"
TEILER_ORCHESTRATOR_HTTP_RELATIVE_PATH: "/ccp-teiler"
TEILER_USER: "${OIDC_USER_GROUP}"
TEILER_ADMIN: "${OIDC_ADMIN_GROUP}"
REPORTER_DEFAULT_TEMPLATE_ID: "ccp-qb"
EXPORTER_DEFAULT_TEMPLATE_ID: "ccp"
teiler-backend:
image: docker.verbis.dkfz.de/ccp/dktk-teiler-backend:latest
container_name: bridgehead-teiler-backend
labels:
- "traefik.enable=true"
- "traefik.http.routers.teiler_backend_ccp.rule=PathPrefix(`/ccp-teiler-backend`)"
- "traefik.http.services.teiler_backend_ccp.loadbalancer.server.port=8085"
- "traefik.http.routers.teiler_backend_ccp.tls=true"
- "traefik.http.middlewares.teiler_backend_ccp_strip.stripprefix.prefixes=/ccp-teiler-backend"
- "traefik.http.routers.teiler_backend_ccp.middlewares=teiler_backend_ccp_strip"
environment:
LOG_LEVEL: "INFO"
APPLICATION_PORT: "8085"
APPLICATION_ADDRESS: "${HOST}"
DEFAULT_LANGUAGE: "${TEILER_DEFAULT_LANGUAGE}"
CONFIG_ENV_VAR_PATH: "/run/secrets/ccp.conf"
TEILER_ORCHESTRATOR_HTTP_RELATIVE_PATH: "/ccp-teiler"
TEILER_ORCHESTRATOR_URL: "https://${HOST}/ccp-teiler"
TEILER_DASHBOARD_DE_URL: "https://${HOST}/ccp-teiler-dashboard/de"
TEILER_DASHBOARD_EN_URL: "https://${HOST}/ccp-teiler-dashboard/en"
CENTRAX_URL: "${CENTRAXX_URL}"
HTTP_PROXY: "http://forward_proxy:3128"
ENABLE_MTBA: "${ENABLE_MTBA}"
ENABLE_DATASHIELD: "${ENABLE_DATASHIELD}"
secrets:
- ccp.conf
secrets:
ccp.conf:
file: /etc/bridgehead/ccp.conf

View File

@ -0,0 +1,9 @@
#!/bin/bash -e
if [ "$ENABLE_TEILER" == true ];then
log INFO "Teiler setup detected -- will start Teiler services."
OVERRIDE+=" -f ./$PROJECT/modules/teiler-compose.yml"
TEILER_DEFAULT_LANGUAGE=DE
TEILER_DEFAULT_LANGUAGE_LOWER_CASE=${TEILER_DEFAULT_LANGUAGE,,}
add_public_oidc_redirect_url "/ccp-teiler/*"
fi

19
ccp/modules/teiler.md Normal file
View File

@ -0,0 +1,19 @@
# Teiler
This module orchestrates the different microfrontends of the bridgehead as a single page application.
## Teiler Orchestrator
Single SPA component that consists on the root HTML site of the single page application and a javascript code that
gets the information about the microfrontend calling the teiler backend and is responsible for registering them. With the
resulting mapping, it can initialize, mount and unmount the required microfrontends on the fly.
The microfrontends run independently in different containers and can be based on different frameworks (Angular, Vue, React,...)
This microfrontends can run as single alone but need an extension with Single-SPA (https://single-spa.js.org/docs/ecosystem).
There are also available three templates (Angular, Vue, React) to be directly extended to be used directly in the teiler.
## Teiler Dashboard
It consists on the main dashboard and a set of embedded services.
### Login
user and password in ccp.local.conf
## Teiler Backend
In this component, the microfrontends are configured.

View File

@ -8,6 +8,17 @@ PRIVATEKEYFILENAME=/etc/bridgehead/pki/${SITE_ID}.priv.pem
BROKER_URL_FOR_PREREQ=$BROKER_URL
OIDC_USER_GROUP="DKTK_CCP_$(capitalize_first_letter ${SITE_ID})"
OIDC_ADMIN_GROUP="DKTK_CCP_$(capitalize_first_letter ${SITE_ID})_Verwalter"
OIDC_PRIVATE_CLIENT_ID=${SITE_ID}-private
OIDC_PUBLIC_CLIENT_ID=${SITE_ID}-public
# Use "test-realm-01" for testing
OIDC_REALM="${OIDC_REALM:-master}"
OIDC_URL="https://login.verbis.dkfz.de"
OIDC_ISSUER_URL="${OIDC_URL}/realms/${OIDC_REALM}"
OIDC_GROUP_CLAIM="groups"
POSTGRES_TAG=15.6-alpine
for module in $PROJECT/modules/*.sh
do
@ -17,4 +28,4 @@ done
idManagementSetup
mtbaSetup
adt2fhirRestSetup
adt2fhirRestSetup

View File

@ -155,6 +155,28 @@ setHostname() {
fi
}
# This function optimizes the usage of memory through blaze, according to the official performance tuning guide:
# https://github.com/samply/blaze/blob/master/docs/tuning-guide.md
# Short summary of the adjustments made:
# - set blaze memory cap to a quarter of the system memory
# - set db block cache size to a quarter of the system memory
# - limit resource count allowed in blaze to 1,25M per 4GB available system memory
optimizeBlazeMemoryUsage() {
if [ -z "$BLAZE_MEMORY_CAP" ]; then
system_memory_in_mb=$(LC_ALL=C free -m | grep 'Mem:' | awk '{print $2}');
export BLAZE_MEMORY_CAP=$(($system_memory_in_mb/4));
fi
if [ -z "$BLAZE_RESOURCE_CACHE_CAP" ]; then
available_system_memory_chunks=$((BLAZE_MEMORY_CAP / 1000))
if [ $available_system_memory_chunks -eq 0 ]; then
log WARN "Only ${BLAZE_MEMORY_CAP} system memory available for Blaze. If your Blaze stores more than 128000 fhir ressources it will run significally slower."
export BLAZE_RESOURCE_CACHE_CAP=128000;
else
export BLAZE_RESOURCE_CACHE_CAP=$((available_system_memory_chunks * 312500))
fi
fi
}
# Takes 1) The Backup Directory Path 2) The name of the Service to be backuped
# Creates 3 Backups: 1) For the past seven days 2) For the current month and 3) for each calendar week
createEncryptedPostgresBackup(){
@ -239,3 +261,109 @@ add_basic_auth_user() {
log DEBUG "Saving clear text credentials in $FILE. If wanted, delete them manually."
sed -i "/^$NAME/ s|$|\n# User: $USER\n# Password: $PASSWORD|" $FILE
}
OIDC_PUBLIC_REDIRECT_URLS=${OIDC_PUBLIC_REDIRECT_URLS:-""}
OIDC_PRIVATE_REDIRECT_URLS=${OIDC_PRIVATE_REDIRECT_URLS:-""}
# Add a redirect url to the public oidc client of the bridgehead
function add_public_oidc_redirect_url() {
if [[ $OIDC_PUBLIC_REDIRECT_URLS == "" ]]; then
OIDC_PUBLIC_REDIRECT_URLS+="$(generate_redirect_urls $1)"
else
OIDC_PUBLIC_REDIRECT_URLS+=",$(generate_redirect_urls $1)"
fi
}
# Add a redirect url to the private oidc client of the bridgehead
function add_private_oidc_redirect_url() {
if [[ $OIDC_PRIVATE_REDIRECT_URLS == "" ]]; then
OIDC_PRIVATE_REDIRECT_URLS+="$(generate_redirect_urls $1)"
else
OIDC_PRIVATE_REDIRECT_URLS+=",$(generate_redirect_urls $1)"
fi
}
function sync_secrets() {
local delimiter=$'\x1E'
local secret_sync_args=""
if [[ $OIDC_PRIVATE_REDIRECT_URLS != "" ]]; then
secret_sync_args="OIDC:OIDC_CLIENT_SECRET:private;$OIDC_PRIVATE_REDIRECT_URLS"
fi
if [[ $OIDC_PUBLIC_REDIRECT_URLS != "" ]]; then
if [[ $secret_sync_args == "" ]]; then
secret_sync_args="OIDC:OIDC_PUBLIC:public;$OIDC_PUBLIC_REDIRECT_URLS"
else
secret_sync_args+="${delimiter}OIDC:OIDC_PUBLIC:public;$OIDC_PUBLIC_REDIRECT_URLS"
fi
fi
if [[ $secret_sync_args == "" ]]; then
return
fi
mkdir -p /var/cache/bridgehead/secrets/ || fail_and_report 1 "Failed to create '/var/cache/bridgehead/secrets/'. Please run sudo './bridgehead install $PROJECT' again."
touch /var/cache/bridgehead/secrets/oidc
docker run --rm \
-v /var/cache/bridgehead/secrets/oidc:/usr/local/cache \
-v $PRIVATEKEYFILENAME:/run/secrets/privkey.pem:ro \
-v /srv/docker/bridgehead/$PROJECT/root.crt.pem:/run/secrets/root.crt.pem:ro \
-v /etc/bridgehead/trusted-ca-certs:/conf/trusted-ca-certs:ro \
-e TLS_CA_CERTIFICATES_DIR=/conf/trusted-ca-certs \
-e NO_PROXY=localhost,127.0.0.1 \
-e ALL_PROXY=$HTTPS_PROXY_FULL_URL \
-e PROXY_ID=$PROXY_ID \
-e BROKER_URL=$BROKER_URL \
-e OIDC_PROVIDER=secret-sync-central.oidc-client-enrollment.$BROKER_ID \
-e SECRET_DEFINITIONS=$secret_sync_args \
docker.verbis.dkfz.de/cache/samply/secret-sync-local:latest
set -a # Export variables as environment variables
source /var/cache/bridgehead/secrets/*
set +a # Export variables in the regular way
}
capitalize_first_letter() {
input="$1"
capitalized="$(tr '[:lower:]' '[:upper:]' <<< ${input:0:1})${input:1}"
echo "$capitalized"
}
# Generate a string of ',' separated string of redirect urls relative to $HOST.
# $1 will be appended to the url
# If the host looks like dev-jan.inet.dkfz-heidelberg.de it will generate urls with dev-jan and the original $HOST as url Authorities
function generate_redirect_urls(){
local redirect_urls="https://${HOST}$1"
local host_without_proxy="$(echo "$HOST" | cut -d '.' -f1)"
# Only append second url if its different and the host is not an ip address
if [[ "$HOST" != "$host_without_proxy" && ! "$HOST" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
redirect_urls+=",https://$host_without_proxy$1"
fi
echo "$redirect_urls"
}
# This password contains at least one special char, a random number and a random upper and lower case letter
generate_password(){
local seed_text="$1"
local seed_num=$(awk 'BEGIN{FS=""} NR==1{print $10}' /etc/bridgehead/pki/${SITE_ID}.priv.pem | od -An -tuC)
local nums="1234567890"
local n=$(echo "$seed_num" | awk '{print $1 % 10}')
local random_digit=${nums:$n:1}
local n=$(echo "$seed_num" | awk '{print $1 % 26}')
local upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local lower="abcdefghijklmnopqrstuvwxyz"
local random_upper=${upper:$n:1}
local random_lower=${lower:$n:1}
local n=$(echo "$seed_num" | awk '{print $1 % 8}')
local special='@#$%^&+='
local random_special=${special:$n:1}
local combined_text="This is a salt string to generate one consistent password for ${seed_text}. It is not required to be secret."
local main_password=$(echo "${combined_text}" | sha1sum | openssl pkeyutl -sign -inkey "/etc/bridgehead/pki/${SITE_ID}.priv.pem" 2> /dev/null | base64 | head -c 26 | sed 's/\//A/g')
echo "${main_password}${random_digit}${random_upper}${random_lower}${random_special}"
}
# This password only contains alphanumeric characters
generate_simple_password(){
local seed_text="$1"
local combined_text="This is a salt string to generate one consistent password for ${seed_text}. It is not required to be secret."
echo "${combined_text}" | sha1sum | openssl pkeyutl -sign -inkey "/etc/bridgehead/pki/${SITE_ID}.priv.pem" 2> /dev/null | base64 | head -c 26 | sed 's/[+\/]/A/g'
}

View File

@ -89,6 +89,9 @@ elif [[ "$DEV_MODE" == "DEV" ]]; then
fi
chown -R bridgehead /etc/bridgehead /srv/docker/bridgehead
mkdir -p /tmp/bridgehead /var/cache/bridgehead
chown -R bridgehead:docker /tmp/bridgehead /var/cache/bridgehead
chmod -R g+wr /var/cache/bridgehead /tmp/bridgehead
log INFO "System preparation is completed and configuration is present."

View File

@ -55,5 +55,3 @@ services:
HOST: ${HOST}
PROJECT: ${PROJECT}
SITE_NAME: ${SITE_NAME}