Skip to content

Commit

Permalink
Merge pull request #136 from NUM-Forschungsdatenplattform/feature/mul…
Browse files Browse the repository at this point in the history
…tiple_mandates

Feature/multiple mandates
  • Loading branch information
schwzr authored Oct 15, 2024
2 parents 9ce44ec + 39d54a4 commit cf4cca4
Show file tree
Hide file tree
Showing 21 changed files with 502 additions and 118 deletions.
15 changes: 13 additions & 2 deletions codex-process-data-transfer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>6.0.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
Expand Down Expand Up @@ -102,7 +113,7 @@
<createDependencyReducedPom>false</createDependencyReducedPom>
<artifactSet>
<excludes>

</excludes>
</artifactSet>
</configuration>
Expand Down Expand Up @@ -263,4 +274,4 @@
</plugin>
</plugins>
</build>
</project>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public interface ConstantsDataTransfer
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_EXPORT_TO = "export-to";
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_DATA_REFERENCE = "data-reference";
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_DRY_RUN = "dry-run";
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_STUDY_ID = "study-id";
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_ENCRYPTED_BUNDLE_SIZE = "encrypted-bundle-size";
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_LOCAL_VALIDATION_SUCCESSFUL = "local-validation-successful";
String CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_ENCRYPTED_BUNDLE_RESOURCES_COUNT = "encrypted-bundle-resources-count";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,7 @@
import java.util.List;
import java.util.Map;

import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.ProcessPluginDeploymentConfig;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.ReceiveConfig;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.SendConfig;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.TransferDataConfig;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.TransferDataSerializerConfig;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.TranslateConfig;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.TriggerConfig;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.ValidationConfig;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.*;
import dev.dsf.bpe.v1.ProcessPluginDefinition;

public class DataTransferProcessPluginDefinition implements ProcessPluginDefinition
Expand Down Expand Up @@ -49,7 +42,7 @@ public List<Class<?>> getSpringConfigurations()
{
return List.of(TransferDataConfig.class, TransferDataSerializerConfig.class, ValidationConfig.class,
TriggerConfig.class, SendConfig.class, TranslateConfig.class, ReceiveConfig.class,
ProcessPluginDeploymentConfig.class);
ReceiveDataStoreConfig.class, ProcessPluginDeploymentConfig.class);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.UUID;

import org.bouncycastle.pkcs.PKCSException;
Expand All @@ -20,13 +21,15 @@
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.client.fhir.DataStoreFhirClient;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.client.fhir.DataStoreFhirClientStub;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.logging.DataLogger;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.spring.config.ReceiveDataStoreConfig;
import de.rwh.utils.crypto.CertificateHelper;
import de.rwh.utils.crypto.io.CertificateReader;
import de.rwh.utils.crypto.io.PemIo;

public class DataStoreClientFactory
{
private static final Logger logger = LoggerFactory.getLogger(DataStoreClientFactory.class);
private static final String DEFAULT_DATA_STORE = "default";

private static final class DataStoreClientStub implements DataStoreClient
{
Expand Down Expand Up @@ -91,10 +94,7 @@ public boolean shouldUseChainedParameterNotLogicalReference()
private final int socketTimeout;
private final int connectionRequestTimeout;

private final String dataStoreServerBase;
private final String dataStoreServerBasicAuthUsername;
private final String dataStoreServerBasicAuthPassword;
private final String dataStoreServerBearerToken;
private final Map<String, ReceiveDataStoreConfig.DataStoreConnectionValues> dataStoreConnectionMap;

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

this.dataStoreServerBase = dataStoreServerBase;
this.dataStoreServerBasicAuthUsername = dataStoreServerBasicAuthUsername;
this.dataStoreServerBasicAuthPassword = dataStoreServerBasicAuthPassword;
this.dataStoreServerBearerToken = dataStoreServerBearerToken;
this.dataStoreConnectionMap = dataStoreConnectionMap;
this.dataStoreConnectionMap.put(DEFAULT_DATA_STORE,
new ReceiveDataStoreConfig.DataStoreConnectionValues(dataStoreServerBase,
dataStoreServerBasicAuthUsername, dataStoreServerBasicAuthPassword,
dataStoreServerBearerToken));

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

public String getServerBase()
{
return dataStoreServerBase;
return dataStoreConnectionMap.get(DEFAULT_DATA_STORE).getBaseUrl();
}

public void testConnection()
{
try
{
logger.info(
"Testing connection to Data Store FHIR server with {trustStorePath: {}, certificatePath: {}, privateKeyPath: {}, privateKeyPassword: {},"
+ " basicAuthUsername: {}, basicAuthPassword: {}, bearerToken: {}, serverBase: {}, proxy: values from 'DEV_DSF_PROXY'... config}",
trustStorePath, certificatePath, privateKeyPath, privateKeyPassword != null ? "***" : "null",
dataStoreServerBasicAuthUsername, dataStoreServerBasicAuthPassword != null ? "***" : "null",
dataStoreServerBearerToken != null ? "***" : "null", dataStoreServerBase);

getDataStoreClient().testConnection();
for (String client : dataStoreConnectionMap.keySet())
{
final ReceiveDataStoreConfig.DataStoreConnectionValues value = dataStoreConnectionMap.get(client);
logger.info(
"Testing connection to Data Store FHIR server with {trustStorePath: {}, certificatePath: {}, privateKeyPath: {}, privateKeyPassword: {},"
+ " basicAuthUsername: {}, basicAuthPassword: {}, bearerToken: {}, serverBase: {}, proxy: values from 'DEV_DSF_PROXY'... config}",
trustStorePath, certificatePath, privateKeyPath, privateKeyPassword != null ? "***" : "null",
value.getBaseUrl(), value.getPassword() != null ? "***" : "null",
value.getBearerToken() != null ? "***" : "null", value.getUsername());

getDataStoreClient(client).testConnection();
}
}
catch (Exception e)
{
Expand All @@ -170,18 +176,29 @@ public void testConnection()

public DataStoreClient getDataStoreClient()
{
if (configured())
return createDataStoreClient();
return getDataStoreClient(DEFAULT_DATA_STORE);
}

public DataStoreClient getDataStoreClient(String client)
{
if (configured(client))
return createDataStoreClient(client);
else
return new DataStoreClientStub(fhirContext, dataLogger);
}

private boolean configured()
private boolean configured(String client)
{
return dataStoreServerBase != null && !dataStoreServerBase.isBlank();
return dataStoreConnectionMap.get(client).getBaseUrl() != null
&& !dataStoreConnectionMap.get(client).getBaseUrl().isBlank();
}

protected DataStoreClient createDataStoreClient()
{
return createDataStoreClient(DEFAULT_DATA_STORE);
}

protected DataStoreClient createDataStoreClient(String dataStore)
{
KeyStore trustStore = null;
char[] keyStorePassword = null;
Expand All @@ -200,9 +217,11 @@ protected DataStoreClient createDataStoreClient()
keyStore = readKeyStore(certificatePath, privateKeyPath, privateKeyPassword, keyStorePassword);
}

final ReceiveDataStoreConfig.DataStoreConnectionValues dataStoreConfig = dataStoreConnectionMap.get(dataStore);

return new DataStoreClientImpl(trustStore, keyStore, keyStorePassword, connectTimeout, socketTimeout,
connectionRequestTimeout, dataStoreServerBasicAuthUsername, dataStoreServerBasicAuthPassword,
dataStoreServerBearerToken, dataStoreServerBase, proxyUrl, proxyUsername, proxyPassword,
connectionRequestTimeout, dataStoreConfig.getUsername(), dataStoreConfig.getPassword(),
dataStoreConfig.getBearerToken(), dataStoreConfig.getBaseUrl(), proxyUrl, proxyUsername, proxyPassword,
hapiClientVerbose, fhirContext, searchBundleOverride, dataStoreFhirClientClass,
useChainedParameterNotLogicalReference, dataLogger);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive;

import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.BPMN_EXECUTION_VARIABLE_BUNDLE;
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.BPMN_EXECUTION_VARIABLE_CONTINUE_STATUS;
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.CODESYSTEM_NUM_CODEX_DATA_TRANSFER_ERROR_VALUE_INSERT_INTO_CRR_FHIR_REPOSITORY_FAILED;
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.*;

import java.util.Objects;
import java.util.Optional;

import org.camunda.bpm.engine.delegate.BpmnError;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -18,6 +18,7 @@
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.ContinueStatus;
import dev.dsf.bpe.v1.ProcessPluginApi;
import dev.dsf.bpe.v1.activity.AbstractServiceDelegate;
import dev.dsf.bpe.v1.service.TaskHelper;
import dev.dsf.bpe.v1.variables.Variables;

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

String studyId = getStudyId(variables.getStartTask());
if (studyId == null || studyId.isEmpty())
{
logger.error("Unable to receive, {} is empty", CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_STUDY_ID);
throw new IllegalArgumentException(CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_STUDY_ID + " is empty");
}

try
{
try
{
logger.info("Executing bundle against FHIR store ...");
logger.info("Executing bundle against FHIR store '{}'", studyId);
dataLogger.logData("Received bundle", bundle);

dataClientFactory.getDataStoreClient().getFhirClient().storeBundle(bundle);
dataClientFactory.getDataStoreClient(studyId).getFhirClient().storeBundle(bundle);

execution.setVariable(BPMN_EXECUTION_VARIABLE_CONTINUE_STATUS, ContinueStatus.SUCCESS);
}
Expand All @@ -69,9 +77,18 @@ protected void doExecute(DelegateExecution execution, Variables variables) throw
}
catch (Exception e)
{
logger.warn("Unable to insert data into CRR: {} - {}", e.getClass().getName(), e.getMessage());
logger.warn("Unable to insert data into '{}': {} - {}", studyId, e.getClass().getName(), e.getMessage());
throw new BpmnError(CODESYSTEM_NUM_CODEX_DATA_TRANSFER_ERROR_VALUE_INSERT_INTO_CRR_FHIR_REPOSITORY_FAILED,
"Unable to insert data into CRR");
"Unable to insert data into '" + studyId + "'");
}
}

private String getStudyId(Task task)
{
TaskHelper taskHelper = this.api.getTaskHelper();
Optional<String> studyId = taskHelper.getFirstInputParameterStringValue(task,
CODESYSTEM_NUM_CODEX_DATA_TRANSFER, CODESYSTEM_NUM_CODEX_DATA_TRANSFER_VALUE_STUDY_ID);

return studyId.orElse("");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,7 @@
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.message.ContinueTranslateProcess;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.message.ContinueTranslateProcessWithError;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.message.ContinueTranslateProcessWithValidationError;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.DecryptData;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.DeleteValidationErrorForDts;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.DownloadDataFromDts;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.EncryptValidationError;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.InsertDataIntoCodex;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.LogError;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.LogSuccess;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.LogValidationError;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.StoreValidationErrorForDts;
import de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.receive.*;
import dev.dsf.bpe.v1.ProcessPluginApi;

@Configuration
Expand Down
Loading

0 comments on commit cf4cca4

Please sign in to comment.