Commit 9c4a9324 authored by pm's avatar pm
Browse files

Error handling added

parent 7c8f091a
Pipeline #275315 failed with stages
in 15 minutes and 37 seconds
......@@ -10,6 +10,7 @@ import org.apache.commons.text.similarity.LevenshteinDistance;
import net.ihe.gazelle.app.patientregistryapi.business.GenderCode;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.patient.PatientDB;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.references.CrossReferenceDB;
import net.ihe.gazelle.app.patientregistryservice.application.exceptions.CrossReferenceApplicationException;
import net.ihe.gazelle.framework.loggerservice.application.GazelleLogger;
import net.ihe.gazelle.framework.loggerservice.application.GazelleLoggerFactory;
......@@ -31,25 +32,33 @@ public class PatientCrossReferenceApplication {
/**
* Static method to compare one Patient to a collection of Patient
*
* The comparison includes these fields with their respective criteria :
* - The birthDate of the patients. Must be the same
* - The Gender of the patients. Must be the same
* - The familyName of the patients. Must have a levenshtein distance less than 3
* - The givenName of the patients. Must have a levenshtein distance less than 3
* @param toCompare : the Patient to create or update in the Database and so to check if any CrossReference for it already exists
* @param comparing : the collection of Patient to compare the similarities
* @return a CrossReferenceDB object containing the created/updated patient.
* @throws CrossReferenceApplicationException
*/
public static CrossReferenceDB crossReferenciable(PatientDB toCompare, List<PatientDB> comparing) {
public static CrossReferenceDB crossReferenciable(PatientDB toCompare, List<PatientDB> comparing) throws CrossReferenceApplicationException {
if (null == toCompare) {
throw new CrossReferenceApplicationException("Patient toCompare is empty and cannot be processed.");
}
if (null == comparing) {
throw new CrossReferenceApplicationException("List of Patient toCompare is empty and cannot be processed.");
}
if (!isValid(toCompare)) {
throw new CrossReferenceApplicationException("Patient toCompare does not have the minimum required fields to be crossreferenced");
}
LocalDate birthDate = convertDateToLocalDate(toCompare.getDateOfBirth());
GenderCode gender = toCompare.getGenderCode().toGenderCode();
String familyName = toCompare.getLastName();
String givenName = toCompare.getFirstName();
for (PatientDB patou : comparing) {
if (compare(birthDate, gender, familyName, givenName, patou)) {
return patou.getPixReference();
LOGGER.debug(String.format("Checking for a Cross Reference for Patient [%s] [%s]", toCompare.getLastName(), toCompare.getLastName()));
for (PatientDB patient : comparing) {
if (!isValid(patient)) {
throw new CrossReferenceApplicationException("Patient from Database does not have the minimum required fields to be crossreferenced");
}
if (isEquals(toCompare, patient)) {
return patient.getPixReference();
}
}
......@@ -68,40 +77,78 @@ public class PatientCrossReferenceApplication {
/**
* Private method to compare a single Patient to the collection of data from the created/updated patient.
* Private method to compare a single Patient with another one.
* The comparison includes these fields with their respective criteria :
* - The birthDate of the patients. Must be the same
* - The Gender of the patients. Must be the same
* - The familyName of the patients. Must have a levenshtein distance less than 3
* - The givenName of the patients. Must have a levenshtein distance less than 3
*
* @param birthDate from the created/updated patient
* @param gender from the created/updated patient
* @param familyName from the created/updated patient
* @param givenName from the created/updated patient
* @param toCompare The PAtient in the Database to compare all these fields with
* @param toCompare The Patient we are creating/updating
* @param comparing the Patient in the database
* @return true if the Patient falls under the threshold of comparison, false if not
*/
private static boolean compare(LocalDate birthDate, GenderCode gender, String familyName, String givenName, PatientDB toCompare) {
LocalDate compareBirthDate = convertDateToLocalDate(toCompare.getDateOfBirth());
private static boolean isEquals(PatientDB toCompare, PatientDB comparing) {
LOGGER.debug(String.format("Comparing Patients [%s] [%s] and [%s] [%s]", toCompare.getLastName(), toCompare.getFirstName(), comparing.getLastName(), comparing.getFirstName()));
LocalDate birthDate = convertDateToLocalDate(toCompare.getDateOfBirth());
GenderCode gender = toCompare.getGenderCode().toGenderCode();
String familyName = toCompare.getLastName();
String givenName = toCompare.getFirstName();
LocalDate compareBirthDate = convertDateToLocalDate(comparing.getDateOfBirth());
if (!birthDate.isEqual(compareBirthDate)) {
LOGGER.debug("Birth Date from both Patient aren't the same, they will not be crossreferenced.");
return false;
}
GenderCode compareGender = toCompare.getGenderCode().toGenderCode();
GenderCode compareGender = comparing.getGenderCode().toGenderCode();
if (gender != compareGender) {
LOGGER.debug("Gender from both Patient aren't the same, they will not be crossreferenced.");
return false;
}
LevenshteinDistance stringCompare = new LevenshteinDistance();
String compareFamilyName = toCompare.getLastName();
String compareFamilyName = comparing.getLastName();
if (stringCompare.apply(familyName, compareFamilyName) >= 3) {
LOGGER.warn(String.format("The last names [%s] and [%s] have a Levenshtein Distance of [%d] which is deemed too much for crossreferenciation", familyName, compareFamilyName, stringCompare.apply(familyName, compareFamilyName)));
LOGGER.debug(String.format("The last names [%s] and [%s] have a Levenshtein Distance of [%d] which is deemed too much for crossreferenciation", familyName, compareFamilyName, stringCompare.apply(familyName, compareFamilyName)));
return false;
}
String compareGivenName = toCompare.getFirstName();
String compareGivenName = comparing.getFirstName();
if (stringCompare.apply(givenName, compareGivenName) >= 3 ) {
LOGGER.warn(String.format("The first names [%s] and [%s] have a Levenshtein Distance of [%d] which is deemed too much for crossreferenciation", givenName, compareGivenName, stringCompare.apply(givenName, compareGivenName)));
LOGGER.debug(String.format("The first names [%s] and [%s] have a Levenshtein Distance of [%d] which is deemed too much for crossreferenciation", givenName, compareGivenName, stringCompare.apply(givenName, compareGivenName)));
return false;
}
return true;
}
/**
* Private method to check if the minimum fields required for cross referenciation is present in the patient.
*
* @param patient : the patient to verify the fields.
* @return true if the patient is valid for cross referenciation, false otherwise.
*/
private static boolean isValid(PatientDB patient) {
if (null == patient.getDateOfBirth()) {
return false;
}
if (null == patient.getGenderCode().toGenderCode()) {
return false;
}
if (patient.getLastName().equals(null) || patient.getLastName().equals("")) {
return false;
}
if (patient.getFirstName().equals(null) || patient.getFirstName().equals("")) {
return false;
}
return true;
}
}
package net.ihe.gazelle.app.patientregistryservice.application.exceptions;
public class CrossReferenceApplicationException extends Exception {
/**
* Constructs a new exception with {@code null} as its detail message.
* The cause is not initialized, and may subsequently be initialized by a
* call to {@link #initCause}.
*/
public CrossReferenceApplicationException() {
super();
}
/**
* Constructs a new exception with the specified detail message. The
* cause is not initialized, and may subsequently be initialized by
* a call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public CrossReferenceApplicationException(String message) {
super(message);
}
/**
* Constructs a new exception with the specified detail message and
* cause. <p>Note that the detail message associated with
* {@code cause} is <i>not</i> automatically incorporated in
* this exception's detail message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public CrossReferenceApplicationException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new exception with the specified cause and a detail
* message of {@code (cause==null ? null : cause.toString())} (which
* typically contains the class and detail message of {@code cause}).
* This constructor is useful for exceptions that are little more than
* wrappers for other throwables (for example, {@link
* java.security.PrivilegedActionException}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public CrossReferenceApplicationException(Throwable cause) {
super(cause);
}
/**
* Constructs a new exception with the specified detail message,
* cause, suppression enabled or disabled, and writable stack
* trace enabled or disabled.
*
* @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @param enableSuppression whether or not suppression is enabled
* or disabled
* @param writableStackTrace whether or not the stack trace should
* be writable
* @since 1.7
*/
public CrossReferenceApplicationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
......@@ -19,12 +19,13 @@ import io.qameta.allure.Story;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.patient.GenderCodeDB;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.patient.PatientDB;
import net.ihe.gazelle.app.patientregistryservice.adapter.dao.pamsimulator.model.references.CrossReferenceDB;
import net.ihe.gazelle.app.patientregistryservice.application.exceptions.CrossReferenceApplicationException;
import net.ihe.gazelle.framework.loggerservice.application.GazelleLogger;
import net.ihe.gazelle.framework.loggerservice.application.GazelleLoggerFactory;
@Feature("XRefAlgorithm")
public class PatientCrossReferenceApplicationTest {
private static final GazelleLogger LOGGER = GazelleLoggerFactory.getInstance().getLogger(PatientCrossReferenceApplicationTest.class);
PatientCrossReferenceApplication patientCrossReferenceApplication;
......@@ -38,23 +39,23 @@ public class PatientCrossReferenceApplicationTest {
@Description("Test on creating/updating a Patient if it is added to an existing crossReference deemed close enough")
@Severity(SeverityLevel.CRITICAL)
@Story("core")
public void crossRefenrecationSuccessfulTest() {
public void crossRefenrecationSuccessfulTest() throws CrossReferenceApplicationException {
PatientDB patientToCompare = createPatient("Alain", "Allal", GenderCodeDB.M, LocalDate.of(1990,6,19));
PatientDB list1 = createPatient("Alan", "Alan", GenderCodeDB.M, LocalDate.of(1990,6,19));
CrossReferenceDB crossReference = new CrossReferenceDB();
list1.setPixReference(crossReference);
List<PatientDB> patientsList = new ArrayList<>();
patientsList.add(list1);
crossReference.setPatients(patientsList );
assertTrue(crossReference.equals(patientCrossReferenceApplication.crossReferenciable(patientToCompare, patientsList)));
}
@Test
@Description("Testing two Patients are not in the same crossReference if their birth date are different")
@Severity(SeverityLevel.CRITICAL)
@Story("core")
public void crossRefenrecationBadBirthDate() {
public void crossRefenrecationBadBirthDate() throws CrossReferenceApplicationException {
PatientDB patientToCompare = createPatient("Alain", "Allal", GenderCodeDB.M, LocalDate.of(1990,6,19));
PatientDB list1 = createPatient("Alain", "Allal", GenderCodeDB.M, LocalDate.of(1990,6,20));
CrossReferenceDB crossReference = new CrossReferenceDB();
......@@ -64,49 +65,49 @@ public class PatientCrossReferenceApplicationTest {
crossReference.setPatients(patientsList );
assertFalse(crossReference.equals(patientCrossReferenceApplication.crossReferenciable(patientToCompare, patientsList)));
}
@Test
@Description("Testing two Patients are not in the same crossReference if their gender are different")
@Severity(SeverityLevel.CRITICAL)
@Story("core")
public void crossRefenrecationBadGender() {
public void crossRefenrecationBadGender() throws CrossReferenceApplicationException {
PatientDB patientToCompare = createPatient("Alain", "Allal", GenderCodeDB.M, LocalDate.of(1990,6,19));
PatientDB list1 = createPatient("Alain", "Allal", GenderCodeDB.F, LocalDate.of(1990,6,19));
CrossReferenceDB crossReference = new CrossReferenceDB();
list1.setPixReference(crossReference);
List<PatientDB> patientsList = new ArrayList<>();
patientsList.add(list1);
crossReference.setPatients(patientsList );
assertFalse(crossReference.equals(patientCrossReferenceApplication.crossReferenciable(patientToCompare, patientsList)));
}
@Test
@Description("Testing two Patients are not in the same crossReference if their family name are too different")
@Severity(SeverityLevel.CRITICAL)
@Story("core")
public void crossRefenrecationBadFamilyName() {
public void crossRefenrecationBadFamilyName() throws CrossReferenceApplicationException {
PatientDB patientToCompare = createPatient("Alain", "Annan", GenderCodeDB.M, LocalDate.of(1990,6,19));
PatientDB list1 = createPatient("Alain", "Allal", GenderCodeDB.M, LocalDate.of(1990,6,19));
CrossReferenceDB crossReference = new CrossReferenceDB();
list1.setPixReference(crossReference);
List<PatientDB> patientsList = new ArrayList<>();
patientsList.add(list1);
crossReference.setPatients(patientsList );
assertFalse(crossReference.equals(patientCrossReferenceApplication.crossReferenciable(patientToCompare, patientsList)));
}
@Test
@Description("Testing two Patients are not in the same crossReference if their given name are too different")
@Severity(SeverityLevel.CRITICAL)
@Story("core")
public void crossRefenrecationBadGivenName() {
public void crossRefenrecationBadGivenName() throws CrossReferenceApplicationException {
PatientDB patientToCompare = createPatient("Alain", "Allal", GenderCodeDB.M, LocalDate.of(1990,6,19));
PatientDB list1 = createPatient("Silvain", "Allal", GenderCodeDB.M, LocalDate.of(1990,6,19));
CrossReferenceDB crossReference = new CrossReferenceDB();
list1.setPixReference(crossReference);
List<PatientDB> patientsList = new ArrayList<>();
patientsList.add(list1);
crossReference.setPatients(patientsList );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment