Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/multiple mandates #136

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading