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

Commit 56a883a

Browse files
committed
allow the usage of local pseudonyms
1 parent cea20b5 commit 56a883a

5 files changed

Lines changed: 99 additions & 15 deletions

File tree

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717

1818
public class DataTransferProcessPluginDefinition implements ProcessPluginDefinition
1919
{
20-
public static final String VERSION = "1.0.0.0";
21-
public static final LocalDate DATE = LocalDate.of(2023, 10, 11);
20+
public static final String VERSION = "1.0.0.1";
21+
public static final LocalDate DATE = LocalDate.of(2024, 3, 18);
2222

2323
@Override
2424
public String getName()

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,7 @@ public interface FttpClient
1818
*/
1919
Optional<String> getDicPseudonym(String bloomFilter);
2020

21+
Optional<String> getDicPseudonymForLocalPseudonym(String localPseudonym);
22+
2123
void testConnection();
2224
}

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ public Optional<String> getDicPseudonym(String bloomFilter)
6262
return pseudonym;
6363
}
6464

65+
@Override
66+
public Optional<String> getDicPseudonymForLocalPseudonym(String localPseudonym)
67+
{
68+
Optional<String> pseudonym = sha256(localPseudonym).map(p -> "dic_test/" + p);
69+
70+
logger.warn(
71+
"Returning simulated DIC pseudonym '{}' for local pseudonym '{}', fTTP connection not configured.",
72+
pseudonym.orElseThrow(), localPseudonym);
73+
74+
return pseudonym;
75+
}
76+
6577
private Optional<String> sha256(String original)
6678
{
6779
try
@@ -142,7 +154,7 @@ public void testConnection()
142154
{
143155
logger.info(
144156
"Testing connection to fTTP with {trustStorePath: {}, certificatePath: {}, privateKeyPath: {}, privateKeyPassword: {},"
145-
+ " basicAuthUsername {}, basicAuthPassword {}, serverBase: {}, apiKey: {}, study: {}, target: {}, proxyUrl {}, proxyUsername, proxyPassword {}}",
157+
+ " basicAuthUsername: {}, basicAuthPassword: {}, serverBase: {}, apiKey: {}, study: {}, target: {}, proxyUrl: {}, proxyUsername: {}, proxyPassword: {}}",
146158
trustStorePath, certificatePath, privateKeyPath, privateKeyPassword != null ? "***" : "null",
147159
fttpBasicAuthUsername, fttpBasicAuthPassword != null ? "***" : "null", fttpServerBase,
148160
fttpApiKey != null ? "***" : "null", fttpStudy, fttpTarget, proxyUrl, proxyUsername,

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,18 @@ protected Parameters createParametersForPsnWorkflow(String dicSourceAndPseudonym
154154
return p;
155155
}
156156

157+
protected Parameters createParametersForPsnWorkflowLocalPseudonym(String localPseudonym)
158+
{
159+
Parameters p = new Parameters();
160+
p.addParameter("study", fttpStudy);
161+
p.addParameter("original", localPseudonym);
162+
p.addParameter("source", "local");
163+
p.addParameter("target", fttpTarget);
164+
p.addParameter("apikey", fttpApiKey);
165+
166+
return p;
167+
}
168+
157169
@Override
158170
public Optional<String> getDicPseudonym(String bloomFilter)
159171
{
@@ -178,6 +190,30 @@ public Optional<String> getDicPseudonym(String bloomFilter)
178190
}
179191
}
180192

193+
@Override
194+
public Optional<String> getDicPseudonymForLocalPseudonym(String localPseudonym)
195+
{
196+
Objects.requireNonNull(localPseudonym, "localPseudonym");
197+
198+
logger.info("Requesting DIC Pseudonym for local Pseudonym {} ...", localPseudonym);
199+
200+
try
201+
{
202+
IGenericClient client = createGenericClient();
203+
204+
Parameters parameters = client.operation().onServer().named("requestPsnWorkflow")
205+
.withParameters(createParametersForPsnWorkflowLocalPseudonym(localPseudonym))
206+
.accept(Constants.CT_FHIR_XML_NEW).encoded(EncodingEnum.XML).execute();
207+
208+
return getPseudonym(parameters).map(p -> fttpTarget + "/" + p);
209+
}
210+
catch (Exception e)
211+
{
212+
logger.error("Error while retrieving DIC pseudonym: {} - {}", e.getClass().getName(), e.getMessage());
213+
throw new BpmnError(CODESYSTEM_NUM_CODEX_DATA_TRANSFER_ERROR_VALUE_FTTP_NOT_REACHABLE, e.getMessage());
214+
}
215+
}
216+
181217
protected Parameters createParametersForBfWorkflow(String bloomFilter)
182218
{
183219
Parameters p = new Parameters();

codex-process-data-transfer/src/main/java/de/netzwerk_universitaetsmedizin/codex/processes/data_transfer/service/send/ResolvePsn.java

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
package de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.service.send;
22

3-
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.BPMN_EXECUTION_VARIABLE_PATIENT_REFERENCE;
4-
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.CODESYSTEM_NUM_CODEX_DATA_TRANSFER_ERROR_VALUE_NO_DIC_PSEUDONYM_FOR_BLOOMFILTER;
5-
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.CODESYSTEM_NUM_CODEX_DATA_TRANSFER_ERROR_VALUE_PATIENT_NOT_FOUND;
6-
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.IDENTIFIER_NUM_CODEX_DIC_PSEUDONYM_TYPE_CODE;
7-
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.IDENTIFIER_NUM_CODEX_DIC_PSEUDONYM_TYPE_SYSTEM;
8-
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.NAMING_SYSTEM_NUM_CODEX_BLOOM_FILTER;
9-
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.NAMING_SYSTEM_NUM_CODEX_DIC_PSEUDONYM;
3+
import static de.netzwerk_universitaetsmedizin.codex.processes.data_transfer.ConstantsDataTransfer.*;
104

115
import java.util.Objects;
126
import java.util.Optional;
@@ -94,8 +88,33 @@ private Optional<String> getPseudonym(Patient patient)
9488

9589
private String resolvePseudonymAndUpdatePatient(Patient patient)
9690
{
97-
String bloomFilter = getBloomFilter(patient);
98-
String pseudonym = resolveBloomFilter(bloomFilter);
91+
String pseudonym;
92+
// first try to find a bloom filter
93+
Optional<String> bloomFilter = getBloomFilter(patient);
94+
if (bloomFilter.isPresent())
95+
{
96+
pseudonym = resolveBloomFilter(bloomFilter.get());
97+
}
98+
else
99+
{
100+
// otherwise try to find a local pseudonym
101+
// --> no record linkage
102+
logger.info(
103+
"No bloom filter present for patient {}. Try to use the local pseudonym for data transfer without record linkage",
104+
patient.getIdElement().getValue());
105+
Optional<String> localPseudonym = getLocalPseudonym(patient);
106+
if (localPseudonym.isPresent())
107+
{
108+
pseudonym = resolveLocalPseudonym(localPseudonym.get());
109+
}
110+
else
111+
{
112+
logger.info("No local pseudonym present for patient {}. Aborted", patient.getIdElement().getValue());
113+
throw new RuntimeException("Could not find pseudonym");
114+
}
115+
116+
117+
}
99118

100119
patient.getIdentifier().removeIf(i -> NAMING_SYSTEM_NUM_CODEX_BLOOM_FILTER.equals(i.getSystem()));
101120
patient.addIdentifier().setSystem(NAMING_SYSTEM_NUM_CODEX_DIC_PSEUDONYM).setValue(pseudonym).getType()
@@ -107,12 +126,18 @@ private String resolvePseudonymAndUpdatePatient(Patient patient)
107126
return pseudonym;
108127
}
109128

110-
private String getBloomFilter(Patient patient)
129+
private Optional<String> getBloomFilter(Patient patient)
111130
{
112131
return patient.getIdentifier().stream().filter(Identifier::hasSystem)
113132
.filter(i -> NAMING_SYSTEM_NUM_CODEX_BLOOM_FILTER.equals(i.getSystem())).filter(Identifier::hasValue)
114-
.findFirst().map(Identifier::getValue).orElseThrow(() -> new RuntimeException(
115-
"No bloom filter present in patient " + patient.getIdElement().getValue()));
133+
.findFirst().map(Identifier::getValue);
134+
}
135+
136+
private Optional<String> getLocalPseudonym(Patient patient)
137+
{
138+
return patient.getIdentifier().stream().filter(Identifier::hasSystem)
139+
.filter(i -> RFC_4122_SYSTEM.equals(i.getSystem())).filter(Identifier::hasValue).findFirst()
140+
.map(Identifier::getValue);
116141
}
117142

118143
private String resolveBloomFilter(String bloomFilter)
@@ -123,6 +148,15 @@ private String resolveBloomFilter(String bloomFilter)
123148
"Unable to get DIC pseudonym for given BloomFilter"));
124149
}
125150

151+
private String resolveLocalPseudonym(String localPseudonym)
152+
{
153+
return fttpClientFactory.getFttpClient().getDicPseudonym(localPseudonym)
154+
.orElseThrow(() -> new BpmnError(
155+
CODESYSTEM_NUM_CODEX_DATA_TRANSFER_ERROR_VALUE_NO_DIC_PSEUDONYM_FOR_BLOOMFILTER,
156+
"Unable to get DIC pseudonym for given BloomFilter"));
157+
}
158+
159+
126160
private void updatePatient(Patient patient)
127161
{
128162
dataStoreClientFactory.getDataStoreClient().getFhirClient().updatePatient(patient);

0 commit comments

Comments
 (0)