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

Commit cf4cca4

Browse files
authored
Merge pull request #136 from NUM-Forschungsdatenplattform/feature/multiple_mandates
Feature/multiple mandates
2 parents 9ce44ec + 39d54a4 commit cf4cca4

File tree

21 files changed

+502
-118
lines changed

21 files changed

+502
-118
lines changed

codex-process-data-transfer/pom.xml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@
6565
<artifactId>mockito-core</artifactId>
6666
<scope>test</scope>
6767
</dependency>
68+
<dependency>
69+
<groupId>org.mockito</groupId>
70+
<artifactId>mockito-junit-jupiter</artifactId>
71+
<scope>test</scope>
72+
</dependency>
73+
<dependency>
74+
<groupId>org.springframework</groupId>
75+
<artifactId>spring-test</artifactId>
76+
<version>6.0.11</version>
77+
<scope>test</scope>
78+
</dependency>
6879
<dependency>
6980
<groupId>org.apache.logging.log4j</groupId>
7081
<artifactId>log4j-slf4j2-impl</artifactId>
@@ -102,7 +113,7 @@
102113
<createDependencyReducedPom>false</createDependencyReducedPom>
103114
<artifactSet>
104115
<excludes>
105-
116+
106117
</excludes>
107118
</artifactSet>
108119
</configuration>
@@ -263,4 +274,4 @@
263274
</plugin>
264275
</plugins>
265276
</build>
266-
</project>
277+
</project>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public interface ConstantsDataTransfer
4343
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_EXPORT_TO = "export-to";
4444
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_DATA_REFERENCE = "data-reference";
4545
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_DRY_RUN = "dry-run";
46+
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_STUDY_ID = "study-id";
4647
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_ENCRYPTED_BUNDLE_SIZE = "encrypted-bundle-size";
4748
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_LOCAL_VALIDATION_SUCCESSFUL = "local-validation-successful";
4849
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_ENCRYPTED_BUNDLE_RESOURCES_COUNT = "encrypted-bundle-resources-count";

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

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,7 @@
55
import java.util.List;
66
import java.util.Map;
77

8-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.ProcessPluginDeploymentConfig;
9-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.ReceiveConfig;
10-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.SendConfig;
11-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.TransferDataConfig;
12-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.TransferDataSerializerConfig;
13-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.TranslateConfig;
14-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.TriggerConfig;
15-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.ValidationConfig;
8+
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.*;
169
import dev.dsf.bpe.v1.ProcessPluginDefinition;
1710

1811
public class DataTransferProcessPluginDefinition implements ProcessPluginDefinition
@@ -49,7 +42,7 @@ public List<Class<?>> getSpringConfigurations()
4942
{
5043
return List.of(TransferDataConfig.class, TransferDataSerializerConfig.class, ValidationConfig.class,
5144
TriggerConfig.class, SendConfig.class, TranslateConfig.class, ReceiveConfig.class,
52-
ProcessPluginDeploymentConfig.class);
45+
ReceiveDataStoreConfig.class, ProcessPluginDeploymentConfig.class);
5346
}
5447

5548
@Override

codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/client/DataStoreClientFactory.java

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.security.cert.Certificate;
1010
import java.security.cert.CertificateException;
1111
import java.security.cert.X509Certificate;
12+
import java.util.Map;
1213
import java.util.UUID;
1314

1415
import org.bouncycastle.pkcs.PKCSException;
@@ -20,13 +21,15 @@
2021
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.client.fhir.DataStoreFhirClient;
2122
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.client.fhir.DataStoreFhirClientStub;
2223
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.logging.DataLogger;
24+
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.ReceiveDataStoreConfig;
2325
import de.rwh.utils.crypto.CertificateHelper;
2426
import de.rwh.utils.crypto.io.CertificateReader;
2527
import de.rwh.utils.crypto.io.PemIo;
2628

2729
public class DataStoreClientFactory
2830
{
2931
private static final Logger logger = LoggerFactory.getLogger(DataStoreClientFactory.class);
32+
private static final String DEFAULT_DATA_STORE = "default";
3033

3134
private static final class DataStoreClientStub implements DataStoreClient
3235
{
@@ -91,10 +94,7 @@ public boolean shouldUseChainedParameterNotLogicalReference()
9194
private final int socketTimeout;
9295
private final int connectionRequestTimeout;
9396

94-
private final String dataStoreServerBase;
95-
private final String dataStoreServerBasicAuthUsername;
96-
private final String dataStoreServerBasicAuthPassword;
97-
private final String dataStoreServerBearerToken;
97+
private final Map<String, ReceiveDataStoreConfig.DataStoreConnectionValues> dataStoreConnectionMap;
9898

9999
private final String proxyUrl;
100100
private final String proxyUsername;
@@ -112,7 +112,8 @@ public boolean shouldUseChainedParameterNotLogicalReference()
112112
public DataStoreClientFactory(Path trustStorePath, Path certificatePath, Path privateKeyPath,
113113
char[] privateKeyPassword, int connectTimeout, int socketTimeout, int connectionRequestTimeout,
114114
String dataStoreServerBase, String dataStoreServerBasicAuthUsername,
115-
String dataStoreServerBasicAuthPassword, String dataStoreServerBearerToken, String proxyUrl,
115+
String dataStoreServerBasicAuthPassword, String dataStoreServerBearerToken,
116+
Map<String, ReceiveDataStoreConfig.DataStoreConnectionValues> dataStoreConnectionMap, String proxyUrl,
116117
String proxyUsername, String proxyPassword, boolean hapiClientVerbose, FhirContext fhirContext,
117118
Path searchBundleOverride, Class<DataStoreFhirClient> dataStoreFhirClientClass,
118119
boolean useChainedParameterNotLogicalReference, DataLogger dataLogger)
@@ -126,10 +127,11 @@ public DataStoreClientFactory(Path trustStorePath, Path certificatePath, Path pr
126127
this.socketTimeout = socketTimeout;
127128
this.connectionRequestTimeout = connectionRequestTimeout;
128129

129-
this.dataStoreServerBase = dataStoreServerBase;
130-
this.dataStoreServerBasicAuthUsername = dataStoreServerBasicAuthUsername;
131-
this.dataStoreServerBasicAuthPassword = dataStoreServerBasicAuthPassword;
132-
this.dataStoreServerBearerToken = dataStoreServerBearerToken;
130+
this.dataStoreConnectionMap = dataStoreConnectionMap;
131+
this.dataStoreConnectionMap.put(DEFAULT_DATA_STORE,
132+
new ReceiveDataStoreConfig.DataStoreConnectionValues(dataStoreServerBase,
133+
dataStoreServerBasicAuthUsername, dataStoreServerBasicAuthPassword,
134+
dataStoreServerBearerToken));
133135

134136
this.proxyUrl = proxyUrl;
135137
this.proxyUsername = proxyUsername;
@@ -146,21 +148,25 @@ public DataStoreClientFactory(Path trustStorePath, Path certificatePath, Path pr
146148

147149
public String getServerBase()
148150
{
149-
return dataStoreServerBase;
151+
return dataStoreConnectionMap.get(DEFAULT_DATA_STORE).getBaseUrl();
150152
}
151153

152154
public void testConnection()
153155
{
154156
try
155157
{
156-
logger.info(
157-
"Testing connection to Data Store FHIR server with {trustStorePath: {}, certificatePath: {}, privateKeyPath: {}, privateKeyPassword: {},"
158-
+ " basicAuthUsername: {}, basicAuthPassword: {}, bearerToken: {}, serverBase: {}, proxy: values from 'DEV_DSF_PROXY'... config}",
159-
trustStorePath, certificatePath, privateKeyPath, privateKeyPassword != null ? "***" : "null",
160-
dataStoreServerBasicAuthUsername, dataStoreServerBasicAuthPassword != null ? "***" : "null",
161-
dataStoreServerBearerToken != null ? "***" : "null", dataStoreServerBase);
162-
163-
getDataStoreClient().testConnection();
158+
for (String client : dataStoreConnectionMap.keySet())
159+
{
160+
final ReceiveDataStoreConfig.DataStoreConnectionValues value = dataStoreConnectionMap.get(client);
161+
logger.info(
162+
"Testing connection to Data Store FHIR server with {trustStorePath: {}, certificatePath: {}, privateKeyPath: {}, privateKeyPassword: {},"
163+
+ " basicAuthUsername: {}, basicAuthPassword: {}, bearerToken: {}, serverBase: {}, proxy: values from 'DEV_DSF_PROXY'... config}",
164+
trustStorePath, certificatePath, privateKeyPath, privateKeyPassword != null ? "***" : "null",
165+
value.getBaseUrl(), value.getPassword() != null ? "***" : "null",
166+
value.getBearerToken() != null ? "***" : "null", value.getUsername());
167+
168+
getDataStoreClient(client).testConnection();
169+
}
164170
}
165171
catch (Exception e)
166172
{
@@ -170,18 +176,29 @@ public void testConnection()
170176

171177
public DataStoreClient getDataStoreClient()
172178
{
173-
if (configured())
174-
return createDataStoreClient();
179+
return getDataStoreClient(DEFAULT_DATA_STORE);
180+
}
181+
182+
public DataStoreClient getDataStoreClient(String client)
183+
{
184+
if (configured(client))
185+
return createDataStoreClient(client);
175186
else
176187
return new DataStoreClientStub(fhirContext, dataLogger);
177188
}
178189

179-
private boolean configured()
190+
private boolean configured(String client)
180191
{
181-
return dataStoreServerBase != null && !dataStoreServerBase.isBlank();
192+
return dataStoreConnectionMap.get(client).getBaseUrl() != null
193+
&& !dataStoreConnectionMap.get(client).getBaseUrl().isBlank();
182194
}
183195

184196
protected DataStoreClient createDataStoreClient()
197+
{
198+
return createDataStoreClient(DEFAULT_DATA_STORE);
199+
}
200+
201+
protected DataStoreClient createDataStoreClient(String dataStore)
185202
{
186203
KeyStore trustStore = null;
187204
char[] keyStorePassword = null;
@@ -200,9 +217,11 @@ protected DataStoreClient createDataStoreClient()
200217
keyStore = readKeyStore(certificatePath, privateKeyPath, privateKeyPassword, keyStorePassword);
201218
}
202219

220+
final ReceiveDataStoreConfig.DataStoreConnectionValues dataStoreConfig = dataStoreConnectionMap.get(dataStore);
221+
203222
return new DataStoreClientImpl(trustStore, keyStore, keyStorePassword, connectTimeout, socketTimeout,
204-
connectionRequestTimeout, dataStoreServerBasicAuthUsername, dataStoreServerBasicAuthPassword,
205-
dataStoreServerBearerToken, dataStoreServerBase, proxyUrl, proxyUsername, proxyPassword,
223+
connectionRequestTimeout, dataStoreConfig.getUsername(), dataStoreConfig.getPassword(),
224+
dataStoreConfig.getBearerToken(), dataStoreConfig.getBaseUrl(), proxyUrl, proxyUsername, proxyPassword,
206225
hapiClientVerbose, fhirContext, searchBundleOverride, dataStoreFhirClientClass,
207226
useChainedParameterNotLogicalReference, dataLogger);
208227
}

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

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive;
22

3-
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.BPMN_EXECUTION_VARIABLE_BUNDLE;
4-
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.BPMN_EXECUTION_VARIABLE_CONTINUE_STATUS;
5-
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.CODESYSTEM_NUM_CODEX_DATA_TRANSFER_ERROR_VALUE_INSERT_INTO_CRR_FHIR_REPOSITORY_FAILED;
3+
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.*;
64

75
import java.util.Objects;
6+
import java.util.Optional;
87

98
import org.camunda.bpm.engine.delegate.BpmnError;
109
import org.camunda.bpm.engine.delegate.DelegateExecution;
1110
import org.hl7.fhir.r4.model.Bundle;
11+
import org.hl7.fhir.r4.model.Task;
1212
import org.slf4j.Logger;
1313
import org.slf4j.LoggerFactory;
1414

@@ -18,6 +18,7 @@
1818
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.ContinueStatus;
1919
import dev.dsf.bpe.v1.ProcessPluginApi;
2020
import dev.dsf.bpe.v1.activity.AbstractServiceDelegate;
21+
import dev.dsf.bpe.v1.service.TaskHelper;
2122
import dev.dsf.bpe.v1.variables.Variables;
2223

2324
public class InsertDataIntoCodex extends AbstractServiceDelegate
@@ -49,14 +50,21 @@ protected void doExecute(DelegateExecution execution, Variables variables) throw
4950
{
5051
Bundle bundle = variables.getResource(BPMN_EXECUTION_VARIABLE_BUNDLE);
5152

53+
String studyId = getStudyId(variables.getStartTask());
54+
if (studyId == null || studyId.isEmpty())
55+
{
56+
logger.error("Unable to receive, {} is empty", CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_STUDY_ID);
57+
throw new IllegalArgumentException(CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_STUDY_ID + " is empty");
58+
}
59+
5260
try
5361
{
5462
try
5563
{
56-
logger.info("Executing bundle against FHIR store ...");
64+
logger.info("Executing bundle against FHIR store '{}'", studyId);
5765
dataLogger.logData("Received bundle", bundle);
5866

59-
dataClientFactory.getDataStoreClient().getFhirClient().storeBundle(bundle);
67+
dataClientFactory.getDataStoreClient(studyId).getFhirClient().storeBundle(bundle);
6068

6169
execution.setVariable(BPMN_EXECUTION_VARIABLE_CONTINUE_STATUS, ContinueStatus.SUCCESS);
6270
}
@@ -69,9 +77,18 @@ protected void doExecute(DelegateExecution execution, Variables variables) throw
6977
}
7078
catch (Exception e)
7179
{
72-
logger.warn("Unable to insert data into CRR: {} - {}", e.getClass().getName(), e.getMessage());
80+
logger.warn("Unable to insert data into '{}': {} - {}", studyId, e.getClass().getName(), e.getMessage());
7381
throw new BpmnError(CODESYSTEM_NUM_CODEX_DATA_TRANSFER_ERROR_VALUE_INSERT_INTO_CRR_FHIR_REPOSITORY_FAILED,
74-
"Unable to insert data into CRR");
82+
"Unable to insert data into '" + studyId + "'");
7583
}
7684
}
85+
86+
private String getStudyId(Task task)
87+
{
88+
TaskHelper taskHelper = this.api.getTaskHelper();
89+
Optional<String> studyId = taskHelper.getFirstInputParameterStringValue(task,
90+
CODESYSTEM_NUM_CODEX_DATA_TRANSFER, CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_STUDY_ID);
91+
92+
return studyId.orElse("");
93+
}
7794
}

codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/spring/config/ReceiveConfig.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,7 @@
99
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.message.ContinueTranslateProcess;
1010
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.message.ContinueTranslateProcessWithError;
1111
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.message.ContinueTranslateProcessWithValidationError;
12-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.DecryptData;
13-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.DeleteValidationErrorForDts;
14-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.DownloadDataFromDts;
15-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.EncryptValidationError;
16-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.InsertDataIntoCodex;
17-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.LogError;
18-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.LogSuccess;
19-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.LogValidationError;
20-
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.StoreValidationErrorForDts;
12+
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.*;
2113
import dev.dsf.bpe.v1.ProcessPluginApi;
2214

2315
@Configuration

0 commit comments

Comments
 (0)