Skip to content

Commit

Permalink
Incorporated the directory-sync library into the code
Browse files Browse the repository at this point in the history
Took the code from https://github.com/samply/directory-sync and added
it to this repository. This means that there is no dependency with
the directory-sync repository any more. The original rational behind
the separation was that the library might be used elsewhere, not just
in a standalone service. This never actually happened, hence the
decision to combine service and library, which makes the code easier
to maintain.
  • Loading branch information
DavidCroftDKFZ committed Aug 20, 2024
1 parent 177b6ae commit dfbee60
Show file tree
Hide file tree
Showing 29 changed files with 4,608 additions and 81 deletions.
98 changes: 53 additions & 45 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>
<groupId>de.samply</groupId>
<artifactId>directory_sync_service</artifactId>
<version>1.3.3</version>
<version>1.3.5</version>
<name>directory_sync_service</name>
<description>Directory sync</description>
<url>https://github.com/samply/directory_sync_service</url>
Expand All @@ -26,62 +26,70 @@

<properties>
<java.version>19</java.version>
<hapi.version>6.2.2</hapi.version>
<jackson.version>2.13.3</jackson.version>
</properties>



<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>

<dependency>
<groupId>de.samply</groupId>
<artifactId>directory-sync</artifactId>
<version>0.3.3</version>
</dependency>

<dependency>
<groupId>de.samply</groupId>
<artifactId>common-http</artifactId>
<version>7.4.4</version>
</dependency>

<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-r4</artifactId>
<version>6.2.2</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-client</artifactId>
<version>6.2.2</version>
</dependency>

<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>

<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-r4</artifactId>
<version>${hapi.version}</version>
</dependency>

<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-client</artifactId>
<version>${hapi.version}</version>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version>
</dependency>

<dependency>
<groupId>io.vavr</groupId>
<artifactId>vavr</artifactId>
<version>0.10.4</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>

<build>
Expand Down
40 changes: 40 additions & 0 deletions src/main/java/de/samply/directory_sync_service/Util.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package de.samply.directory_sync_service;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.Gson;

public class Util {

public static <K, V> Map<K, V> mapOf() {
return new HashMap<>();
}

/**
* Creates a new map with a single entry consisting of the specified key and value.
*
* @param key the key for the entry
* @param value the value associated with the key
* @return a new map containing the specified key-value pair
*/
public static <K, V> Map<K, V> mapOf(K key, V value) {
HashMap<K, V> map = new HashMap<>();
map.put(key, value);
return map;
}

/**
* Get a printable stack trace from an Exception object.
* @param e
* @return
*/
public static String traceFromException(Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
return sw.toString();
}
}
21 changes: 0 additions & 21 deletions src/main/java/de/samply/directory_sync_service/Utils.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package de.samply.directory_sync_service.converter;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.samply.directory_sync_service.Util;
import de.samply.directory_sync_service.directory.model.DirectoryCollectionPut;
import de.samply.directory_sync_service.fhir.model.FhirCollection;

/**
* Takes a list of FhirCollection objects and converts them into a
* DirectoryCollectionPut object.
*
* This is a kind of FHIR to Directory conversion, so there are differences
* in vocabularies, and it is the job of this converter to impedence match them.
*/
public class FhirCollectionToDirectoryCollectionPutConverter {
private static final Logger logger = LoggerFactory.getLogger(FhirCollectionToDirectoryCollectionPutConverter.class);

public static DirectoryCollectionPut convert(List<FhirCollection> fhirCollections) {
DirectoryCollectionPut directoryCollectionPut = new DirectoryCollectionPut();

for (FhirCollection fhirCollection: fhirCollections)
if (convert(directoryCollectionPut, fhirCollection) == null) {
directoryCollectionPut = null;
break;
}

return directoryCollectionPut;
}

private static DirectoryCollectionPut convert(DirectoryCollectionPut directoryCollectionPut, FhirCollection fhirCollection) {
try {
convertSize(directoryCollectionPut, fhirCollection);
convertNumberOfDonors(directoryCollectionPut, fhirCollection);
convertSex(directoryCollectionPut, fhirCollection);
convertAgeLow(directoryCollectionPut, fhirCollection);
convertAgeHigh(directoryCollectionPut, fhirCollection);
convertMaterials(directoryCollectionPut, fhirCollection);
convertStorageTemperatures(directoryCollectionPut, fhirCollection);
// convertDiagnosisAvailableEmpty(directoryCollectionPut, fhirCollection);
convertDiagnosisAvailable(directoryCollectionPut, fhirCollection);
} catch(Exception e) {
logger.error("Problem converting FHIR attributes to Directory attributes. " + Util.traceFromException(e));
return null;
}

return directoryCollectionPut;
}

private static void convertSize(DirectoryCollectionPut directoryCollectionPut, FhirCollection fhirCollection) {
String id = fhirCollection.getId();
Integer size = fhirCollection.getSize();
directoryCollectionPut.setSize(id, size);
// Order of magnitude is mandatory in the Directory and can be derived from size
directoryCollectionPut.setOrderOfMagnitude(id, (int) Math.floor(Math.log10(size)));
}

public static void convertNumberOfDonors(DirectoryCollectionPut directoryCollectionPut, FhirCollection fhirCollection) {
String id = fhirCollection.getId();
Integer size = fhirCollection.getNumberOfDonors();
directoryCollectionPut.setNumberOfDonors(id, size);
// Order of magnitude is mandatory in the Directory and can be derived from size
directoryCollectionPut.setOrderOfMagnitudeDonors(id, (int) Math.floor(Math.log10(size)));
}

public static void convertSex(DirectoryCollectionPut directoryCollectionPut, FhirCollection fhirCollection) {
String id = fhirCollection.getId();
List<String> sex = fhirCollection.getSex();

List<String> ucSex = sex.stream()
.map(s -> FhirToDirectoryAttributeConverter.convertSex(s))
.filter(Objects::nonNull) // Use a method reference to check for non-null values
.distinct() // Remove duplicate elements
.collect(Collectors.toList());

directoryCollectionPut.setSex(id, ucSex);
}

public static void convertAgeLow(DirectoryCollectionPut directoryCollectionPut, FhirCollection fhirCollection) {
String id = fhirCollection.getId();
Integer ageLow = fhirCollection.getAgeLow();
// No conversion needed
directoryCollectionPut.setAgeLow(id, ageLow);
}

public static void convertAgeHigh(DirectoryCollectionPut directoryCollectionPut, FhirCollection fhirCollection) {
String id = fhirCollection.getId();
Integer ageHigh = fhirCollection.getAgeHigh();
// No conversion needed
directoryCollectionPut.setAgeHigh(id, ageHigh);
}

public static void convertMaterials(DirectoryCollectionPut directoryCollectionPut, FhirCollection fhirCollection) {
String id = fhirCollection.getId();
List<String> materials = fhirCollection.getMaterials();

if (materials == null)
materials = new ArrayList<String>();

List<String> directoryMaterials = materials.stream()
.map(s -> FhirToDirectoryAttributeConverter.convertMaterial(s))
.filter(Objects::nonNull) // Use a method reference to check for non-null values
.distinct() // Remove duplicate elements
.collect(Collectors.toList());

directoryCollectionPut.setMaterials(id, directoryMaterials);
}

public static void convertStorageTemperatures(DirectoryCollectionPut directoryCollectionPut, FhirCollection fhirCollection) {
String id = fhirCollection.getId();
List<String> storageTemperatures = fhirCollection.getStorageTemperatures();

if (storageTemperatures == null)
storageTemperatures = new ArrayList<String>();

List<String> directoryStorageTemperatures = storageTemperatures.stream()
.map(s -> FhirToDirectoryAttributeConverter.convertStorageTemperature(s))
.filter(Objects::nonNull) // Use a method reference to check for non-null values
.distinct() // Remove duplicate elements
.collect(Collectors.toList());

directoryCollectionPut.setStorageTemperatures(id, directoryStorageTemperatures);
}

public static void convertDiagnosisAvailableEmpty(DirectoryCollectionPut directoryCollectionPut, FhirCollection fhirCollection) {
String id = fhirCollection.getId();
// The Directory is very picky about which ICD10 codes it will accept, and some
// of the codes that are in our test data are not known to the Directory and
// give rise to errors, which lead to the entire PUT to the Directory being
// rejected. So, for the time being, I am turning off the diagnosis conversion.
directoryCollectionPut.setDiagnosisAvailable(id, new ArrayList<String>());
}

public static void convertDiagnosisAvailable(DirectoryCollectionPut directoryCollectionPut, FhirCollection fhirCollection) {
String id = fhirCollection.getId();
List<String> diagnoses = fhirCollection.getDiagnosisAvailable();

if (diagnoses == null)
diagnoses = new ArrayList<String>();

List<String> miriamDiagnoses = diagnoses.stream()
.map(icd -> FhirToDirectoryAttributeConverter.convertDiagnosis(icd))
.filter(Objects::nonNull) // Use a method reference to check for non-null values
.distinct() // Remove duplicate diagnoses
.collect(Collectors.toList());

directoryCollectionPut.setDiagnosisAvailable(id, miriamDiagnoses);
}
}
Loading

0 comments on commit dfbee60

Please sign in to comment.