Commit e6f3e9eb authored by Franck Desaize's avatar Franck Desaize
Browse files

Merge branch 'feature/PATREG-168' into release/2.1.0

parents e8e7bd6a 724138dc
Pipeline #289052 failed with stages
in 13 minutes and 34 seconds
......@@ -84,3 +84,7 @@ target/
**/.allure
**/allure-results
**/.allure**
**/allure-results/**
**/allure-results/**
/patient-registry-service/allure-results/
......@@ -9,7 +9,7 @@
The current supported APIs are :
- Patient feed service :
```java
String feedPatient(Patient patient) throws PatientFeedException;
String createPatient(Patient patient) throws PatientFeedException;
```
- Patient retrieve service
```java
......
sudo cp patient-registry-service/target/patient-registry-1.0.1-SNAPSHOT.jar /usr/local/wildfly18/standalone/deployments/patient-registry.jar
sudo cp patient-registry-service/target/patient-registry-2.0.1-SNAPSHOT.jar /usr/local/wildfly18/standalone/deployments/patient-registry.jar
......@@ -12,6 +12,12 @@
<name>Patient Registry Feed Client</name>
<version>2.0.1-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<allure-junit5.version>2.14.0</allure-junit5.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
......@@ -46,7 +52,18 @@
<artifactId>lib.unit-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-ri</artifactId>
<version>2.3.3</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-junit5</artifactId>
<version>${allure-junit5.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......@@ -30,21 +30,34 @@ import static net.ihe.gazelle.app.patientregistryapi.adapter.ws.PatientProcessin
*/
public class PatientFeedClient implements PatientFeedService {
public static final String EXCEPTION_WHILE_MAPPING_WITH_GITB_ELEMENTS = "Exception while Mapping with GITB elements !";
public static final String INVALID_RESPONSE_FROM_DISTANT_PATIENT_FEED_PROCESSING_SERVICE = "Invalid Response from distant " +
"PatientFeedProcessingService !";
public static final String INVALID_OPERATION_USED_ON_DISTANT_PATIENT_FEED_PROCESSING_SERVICE = "Invalid operation used on distant " +
"PatientFeedProcessingService !";
public static final String INVALID_REQUEST_SENT_TO_DISTANT_PATIENT_FEED_PROCESSING_SERVICE = "Invalid Request sent to distant " +
"PatientFeedProcessingService !";
public static final String EMPTY_RESPONSE_FROM_THE_DISTANT_PATIENT_FEED_PROCESSING_SERVICE = "Empty Response from the distant " +
"PatientFeedProcessingService !";
public static final String InvalidResponse = "Response from the distant PatientFeedProcessingService shall contain a report with " +
"the success status of the operation !";
private ProcessingService processingClient;
/**
* Constructor used for test purposes.
*
* @param processingService : processing service to be used by the PatientFeedClient.
*/
public PatientFeedClient(ProcessingService processingService){
public PatientFeedClient(ProcessingService processingService) {
this.processingClient = processingService;
}
/**
* Default constructor for the class. The Client will create the GITB Processing Service client based on the URL.
*
* @param processingServiceURL : URL of the remote Processing Service.
*/
public PatientFeedClient(URL processingServiceURL){
public PatientFeedClient(URL processingServiceURL) {
this.processingClient = new GITBClientProcessImpl(processingServiceURL, PATIENT_PROCESSING_SERVICE, PATIENT_PROCESSING_SERVICE_PORT);
}
......@@ -52,64 +65,197 @@ public class PatientFeedClient implements PatientFeedService {
* {@inheritDoc}
*/
@Override
public String feedPatient(Patient patient) throws PatientFeedException {
public String createPatient(Patient patient) throws PatientFeedException {
ProcessRequest processRequest = new ProcessRequest();
processRequest.setOperation(PatientProcessingWebserviceConstants.PATIENT_FEED_OPERATION);
processRequest.setOperation(PatientProcessingWebserviceConstants.PATIENT_CREATE_OPERATION);
AnyContent patientToFeedAnyContent = null;
try {
patientToFeedAnyContent = new MapperObjectToAnyContent().getAnyContent(PATIENT_INPUT_NAME, patient);
processRequest.getInput().add(patientToFeedAnyContent);
ProcessResponse processResponse = processingClient.process(processRequest);
return extractUUIDFromProcessResponse(processResponse);
} catch (MappingException e){
throw new PatientFeedException("Exception while Mapping with GITB elements !", e);
} catch (PatientFeedProcessResponseException e){
throw new PatientFeedException("Invalid Response from distant PatientFeedProcessingService !", e);
} catch (UnsupportedOperationException e){
throw new PatientFeedException("Invalid operation used on distant PatientFeedProcessingService !", e);
} catch (IllegalArgumentException e){
throw new PatientFeedException("Invalid Request sent to distant PatientFeedProcessingService !", e);
} catch (MappingException e) {
throw new PatientFeedException(EXCEPTION_WHILE_MAPPING_WITH_GITB_ELEMENTS, e);
} catch (PatientFeedProcessResponseException e) {
throw new PatientFeedException(INVALID_RESPONSE_FROM_DISTANT_PATIENT_FEED_PROCESSING_SERVICE, e);
} catch (UnsupportedOperationException e) {
throw new PatientFeedException(INVALID_OPERATION_USED_ON_DISTANT_PATIENT_FEED_PROCESSING_SERVICE, e);
} catch (IllegalArgumentException e) {
throw new PatientFeedException(INVALID_REQUEST_SENT_TO_DISTANT_PATIENT_FEED_PROCESSING_SERVICE, e);
}
}
/**
* {@inheritDoc}
*/
@Override
public Patient updatePatient(Patient patient) throws PatientFeedException {
ProcessRequest processRequest = new ProcessRequest();
processRequest.setOperation(PatientProcessingWebserviceConstants.PATIENT_UPDATE_OPERATION);
AnyContent patientToFeedAnyContent = null;
try {
patientToFeedAnyContent = new MapperObjectToAnyContent().getAnyContent(PATIENT_INPUT_NAME, patient);
processRequest.getInput().add(patientToFeedAnyContent);
ProcessResponse processResponse = processingClient.process(processRequest);
return extractPatientFromProcessResponse(processResponse);
} catch (MappingException e) {
throw new PatientFeedException(EXCEPTION_WHILE_MAPPING_WITH_GITB_ELEMENTS, e);
} catch (PatientFeedProcessResponseException e) {
throw new PatientFeedException(INVALID_RESPONSE_FROM_DISTANT_PATIENT_FEED_PROCESSING_SERVICE, e);
} catch (UnsupportedOperationException e) {
throw new PatientFeedException(INVALID_OPERATION_USED_ON_DISTANT_PATIENT_FEED_PROCESSING_SERVICE, e);
} catch (IllegalArgumentException e) {
throw new PatientFeedException(INVALID_REQUEST_SENT_TO_DISTANT_PATIENT_FEED_PROCESSING_SERVICE, e);
}
}
/**
* {@inheritDoc}
*/
@Override
public String mergePatient(String uuidOfOriginalPatient, String uuidOfDuplicatedPatient) throws PatientFeedException {
ProcessRequest processRequest = new ProcessRequest();
processRequest.setOperation(PatientProcessingWebserviceConstants.PATIENT_MERGE_OPERATION);
AnyContent patientUUIDDuplicated = null;
AnyContent patientUUIDOriginal = null;
try {
patientUUIDDuplicated = new MapperObjectToAnyContent().getAnyContent(UUID_OF_DUPLICATED_PATIENT_INPUT_NAME, uuidOfDuplicatedPatient);
patientUUIDOriginal = new MapperObjectToAnyContent().getAnyContent(UUID_OF_ORIGINAL_PATIENT_INPUT_NAME, uuidOfOriginalPatient);
processRequest.getInput().add(patientUUIDOriginal);
processRequest.getInput().add(patientUUIDDuplicated);
ProcessResponse processResponse = processingClient.process(processRequest);
return extractUUIDFromProcessResponse(processResponse);
} catch (MappingException e) {
throw new PatientFeedException(EXCEPTION_WHILE_MAPPING_WITH_GITB_ELEMENTS, e);
} catch (PatientFeedProcessResponseException e) {
throw new PatientFeedException(INVALID_RESPONSE_FROM_DISTANT_PATIENT_FEED_PROCESSING_SERVICE, e);
} catch (UnsupportedOperationException e) {
throw new PatientFeedException(INVALID_OPERATION_USED_ON_DISTANT_PATIENT_FEED_PROCESSING_SERVICE, e);
} catch (IllegalArgumentException e) {
throw new PatientFeedException(INVALID_REQUEST_SENT_TO_DISTANT_PATIENT_FEED_PROCESSING_SERVICE, e);
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean deletePatient(String uuid) throws PatientFeedException {
ProcessRequest processRequest = new ProcessRequest();
processRequest.setOperation(PatientProcessingWebserviceConstants.PATIENT_DELETE_OPERATION);
AnyContent patientToFeedAnyContent = null;
try {
patientToFeedAnyContent = new MapperObjectToAnyContent().getAnyContent(UUID_PATIENT_TO_DELETE_INPUT_NAME, uuid);
processRequest.getInput().add(patientToFeedAnyContent);
ProcessResponse processResponse = processingClient.process(processRequest);
return extractDeletionResultFromProcessResponse(processResponse);
} catch (MappingException e) {
throw new PatientFeedException(EXCEPTION_WHILE_MAPPING_WITH_GITB_ELEMENTS, e);
} catch (PatientFeedProcessResponseException e) {
throw new PatientFeedException(INVALID_RESPONSE_FROM_DISTANT_PATIENT_FEED_PROCESSING_SERVICE, e);
} catch (UnsupportedOperationException e) {
throw new PatientFeedException(INVALID_OPERATION_USED_ON_DISTANT_PATIENT_FEED_PROCESSING_SERVICE, e);
} catch (IllegalArgumentException e) {
throw new PatientFeedException(INVALID_REQUEST_SENT_TO_DISTANT_PATIENT_FEED_PROCESSING_SERVICE, e);
}
}
/**
* Extract the UUID from the ProcessResponse received from the remote ProcessingService.
*
* @param processResponse : response received.
* @return literal value of the UUID assigned to the fed patient by the remote Repository.
* @throws PatientFeedProcessResponseException : if the ProcessResponse is not valid for a PatientFeed request.
* @throws PatientFeedException : if the Patient Feed raised an exception in the remote Repository.
* @throws PatientFeedException : if the Patient Feed raised an exception in the remote Repository.
*/
private String extractUUIDFromProcessResponse(ProcessResponse processResponse) throws PatientFeedProcessResponseException, PatientFeedException{
if (processResponse == null){
throw new PatientFeedProcessResponseException("Empty Response from the distant PatientFeedProcessingService !");
} else{
if(processResponse.getReport() != null){
if (TestResultType.SUCCESS.equals(processResponse.getReport().getResult())){
private String extractUUIDFromProcessResponse(ProcessResponse processResponse) throws PatientFeedProcessResponseException, PatientFeedException {
if (processResponse == null) {
throw new PatientFeedProcessResponseException(EMPTY_RESPONSE_FROM_THE_DISTANT_PATIENT_FEED_PROCESSING_SERVICE);
} else {
if (processResponse.getReport() != null) {
if (TestResultType.SUCCESS.equals(processResponse.getReport().getResult())) {
return extractUUIDFromOutputs(processResponse.getOutput());
} else if (TestResultType.FAILURE.equals(processResponse.getReport().getResult())){
} else if (TestResultType.FAILURE.equals(processResponse.getReport().getResult())) {
throw createExceptionFromProcessResponseReport(processResponse.getReport());
} else {
throw new PatientFeedProcessResponseException(String.format("Processing response with unexpected type %s ! Expected type is " +
"either %s or %s.",processResponse.getReport().getResult(), TestResultType.SUCCESS, TestResultType.FAILURE));
"either %s or %s.", processResponse.getReport().getResult(), TestResultType.SUCCESS, TestResultType.FAILURE));
}
} else {
throw new PatientFeedProcessResponseException("Response from the distant PatientFeedProcessingService shall contain a report with " +
"the success status of the operation !");
throw new PatientFeedProcessResponseException(InvalidResponse);
}
}
}
/**
* Extract the UUID from the ProcessResponse received from the remote ProcessingService.
*
* @param processResponse : response received.
* @return values of the updated Patient by the remote Repository.
* @throws PatientFeedProcessResponseException : if the ProcessResponse is not valid for a PatientFeed request.
* @throws PatientFeedException : if the Patient Feed raised an exception in the remote Repository.
*/
private Patient extractPatientFromProcessResponse(ProcessResponse processResponse) throws PatientFeedProcessResponseException,
PatientFeedException {
if (processResponse == null) {
throw new PatientFeedProcessResponseException(EMPTY_RESPONSE_FROM_THE_DISTANT_PATIENT_FEED_PROCESSING_SERVICE);
} else {
if (processResponse.getReport() != null) {
if (TestResultType.SUCCESS.equals(processResponse.getReport().getResult())) {
return extractPatientFromOutputs(processResponse.getOutput());
} else if (TestResultType.FAILURE.equals(processResponse.getReport().getResult())) {
throw createExceptionFromProcessResponseReport(processResponse.getReport());
} else {
throw new PatientFeedProcessResponseException(String.format("Processing response with unexpected type %s ! Expected type is " +
"either %s or %s.", processResponse.getReport().getResult(), TestResultType.SUCCESS, TestResultType.FAILURE));
}
} else {
throw new PatientFeedProcessResponseException(InvalidResponse);
}
}
}
/**
* Extract the UUID from the ProcessResponse received from the remote ProcessingService.
*
* @param processResponse : response received.
* @return values of the updated Patient by the remote Repository.
* @throws PatientFeedProcessResponseException : if the ProcessResponse is not valid for a PatientFeed request.
* @throws PatientFeedException : if the Patient Feed raised an exception in the remote Repository.
*/
private boolean extractDeletionResultFromProcessResponse(ProcessResponse processResponse) throws PatientFeedProcessResponseException,
PatientFeedException {
if (processResponse == null) {
throw new PatientFeedProcessResponseException(EMPTY_RESPONSE_FROM_THE_DISTANT_PATIENT_FEED_PROCESSING_SERVICE);
} else {
if (processResponse.getReport() != null) {
if (TestResultType.SUCCESS.equals(processResponse.getReport().getResult())) {
return extractDeleteStatusFromOutputs(processResponse.getOutput());
} else if (TestResultType.FAILURE.equals(processResponse.getReport().getResult())) {
throw createExceptionFromProcessResponseReport(processResponse.getReport());
} else {
throw new PatientFeedProcessResponseException(String.format("Processing response with unexpected type %s ! Expected type is " +
"either %s or %s.", processResponse.getReport().getResult(), TestResultType.SUCCESS, TestResultType.FAILURE));
}
} else {
throw new PatientFeedProcessResponseException(InvalidResponse);
}
}
}
/**
* Extract the UUID from the ProcessResponse.output received from the remote ProcessingService.
*
* @param outputs : list of received outputs.
* @return literal value of the UUID assigned to the fed patient by the remote Repository.
* @throws PatientFeedProcessResponseException : if the ProcessResponse.output is not valid for a PatientFeed request.
*/
private String extractUUIDFromOutputs(List<AnyContent> outputs) throws PatientFeedProcessResponseException{
if (outputs.size() == 1){
private String extractUUIDFromOutputs(List<AnyContent> outputs) throws PatientFeedProcessResponseException {
if (outputs.size() == 1) {
try {
return new MapperAnyContentToObject().getObject(outputs.get(0), String.class);
} catch (MappingException e){
} catch (MappingException e) {
throw new PatientFeedProcessResponseException("Error while mapping processing output from distant PatientFeedProcessingService " +
"to String !");
}
......@@ -119,24 +265,68 @@ public class PatientFeedClient implements PatientFeedService {
}
}
/**
* Extract the Patient from the ProcessResponse.Output received from the remote ProcessingService.
*
* @param outputs : list of received outputs.
* @return literal value of the Patient assigned to the fed patient by the remote Repository.
* @throws PatientFeedProcessResponseException : if the ProcessResponse.Output is not valid for a PatientFeed request.
*/
private Patient extractPatientFromOutputs(List<AnyContent> outputs) throws PatientFeedProcessResponseException {
if (outputs.size() == 1) {
try {
return new MapperAnyContentToObject().getObject(outputs.get(0), Patient.class);
} catch (MappingException e) {
throw new PatientFeedProcessResponseException("Error while mapping processing output from distant PatientFeedProcessingService " +
"to Patient !");
}
} else {
throw new PatientFeedProcessResponseException("Response from the distant PatientFeedProcessingService shall contain a single " +
"output for updated Patient !");
}
}
/**
* Extract the Patient from the ProcessResponse.Output received from the remote ProcessingService.
*
* @param outputs : list of received outputs.
* @return literal value of the Patient assigned to the fed patient by the remote Repository.
* @throws PatientFeedProcessResponseException : if the ProcessResponse.Output is not valid for a PatientFeed request.
*/
private boolean extractDeleteStatusFromOutputs(List<AnyContent> outputs) throws PatientFeedProcessResponseException {
if (outputs.size() == 1) {
try {
String result = new MapperAnyContentToObject().getObject(outputs.get(0), String.class);
return result.equals(DELETE_STATUS_DONE);
} catch (MappingException e) {
throw new PatientFeedProcessResponseException("Error while mapping processing output from distant PatientFeedProcessingService " +
"to String !");
}
} else {
throw new PatientFeedProcessResponseException("Response from the distant PatientFeedProcessingService shall contain a single " +
"output for deleted Patient !");
}
}
/**
* Extract PatientFeedException from ProcessResponse report.
*
* @param report : report found in the received response.
* @return {@link PatientFeedException} to be thrown by the {@link PatientFeedClient}
* @throws PatientFeedProcessResponseException : if the report is not well formed.
* @throws PatientFeedProcessResponseException : if the report is not well-formed.
*/
private PatientFeedException createExceptionFromProcessResponseReport(TAR report) throws PatientFeedProcessResponseException {
if (report.getReports() == null || report.getReports().getInfoOrWarningOrError().size() != 1){
if (report.getReports() == null || report.getReports().getInfoOrWarningOrError().size() != 1) {
throw new PatientFeedProcessResponseException("The report from the ProcessResponse shall not be null and shall contain a single error.");
} else {
try {
BAR error = (BAR) report.getReports().getInfoOrWarningOrError().get(0).getValue();
if (error.getDescription()!= null && !error.getDescription().isEmpty()){
if (error.getDescription() != null && !error.getDescription().isEmpty()) {
return new PatientFeedException(error.getDescription());
} else {
throw new PatientFeedProcessResponseException("Error from ProcessResponse report must have a valid description !");
}
} catch (ClassCastException e){
} catch (ClassCastException e) {
throw new PatientFeedProcessResponseException("Cannot decode error from ProcessResponse report !");
}
}
......
package net.ihe.gazelle.app.patientregistryfeedclient.adapter;
import io.qameta.allure.*;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@Feature("Coverage on exception")
@Story("PatientFeedProcessResponseException")
class PatientFeedProcessResponseExceptionTest {
/**
* Dummy Test for coverage
*
* @throws PatientFeedProcessResponseException testException
*/
@Test
@Description(" PatientFeedProcessResponseException")
@Severity(SeverityLevel.MINOR)
void generateException() {
assertThrows(PatientFeedProcessResponseException.class, () -> {
throw new PatientFeedProcessResponseException("Test");
});
}
/**
* Dummy Test for coverage
*
* @throws PatientFeedProcessResponseException testException
*/
@Test
@Description(" PatientFeedProcessResponseException")
@Severity(SeverityLevel.MINOR)
void generateException1() {
assertThrows(PatientFeedProcessResponseException.class, () -> {
throw new PatientFeedProcessResponseException("Test", new IllegalArgumentException("test"));
});
}
/**
* Dummy Test for coverage
*
* @throws PatientFeedProcessResponseException testException
*/
@Test
@Description(" PatientFeedProcessResponseException")
@Severity(SeverityLevel.MINOR)
void generateException2() {
assertThrows(PatientFeedProcessResponseException.class, () -> {
throw new PatientFeedProcessResponseException(new IllegalArgumentException("test"));
});
}
/**
* Dummy Test for coverage
*
* @throws PatientFeedProcessResponseException testException
*/
@Test
@Description(" PatientFeedProcessResponseException")
@Severity(SeverityLevel.MINOR)
void generateException4() {
assertThrows(PatientFeedProcessResponseException.class, () -> {
throw new PatientFeedProcessResponseException("Test", new IllegalArgumentException("test"), false, true);
});
}
/**
* Dummy Test for coverage
*
* @throws PatientFeedProcessResponseException testException
*/
@Test
@Description(" PatientFeedProcessResponseException")
@Severity(SeverityLevel.MINOR)
void generateException3() {
assertThrows(PatientFeedProcessResponseException.class, () -> {
throw new PatientFeedProcessResponseException();
});
}
}
\ No newline at end of file
......@@ -12,8 +12,20 @@ public class PatientProcessingWebserviceConstants {
public static final String PATIENT_SEARCH_OPERATION = "PatientSearch";
public static final String UUID_OUTPUT_NAME = "UUID";
public static final String PATIENT_INPUT_NAME = "Patient";
public static final String PATIENT_OUTPUT_NAME = "Patient";
public static final String DELETE_STATUS_OUTPUT_NAME = "Delete Status";
public static final String PATIENT_SEARCH_CRITERIA_INPUT_NAME = "PatientSearchCriteria";
public static final String PATIENT_LIST_OUTPUT_NAME = "PatientList";
public static final String PATIENT_CREATE_OPERATION = "PatientCreate";
public static final String PATIENT_UPDATE_OPERATION = "PatientUpdate";
public static final String PATIENT_DELETE_OPERATION = "PatientDelete";
public static final String PATIENT_MERGE_OPERATION = "PatientMerge";
public static final String UUID_PATIENT_TO_DELETE_INPUT_NAME ="UUIDOfPatientToDelete" ;
public static final String UUID_OF_ORIGINAL_PATIENT_INPUT_NAME = "UUIDOfOriginalPatient";
public static final String UUID_OF_DUPLICATED_PATIENT_INPUT_NAME = "UUIDOfDuplicatedPatient";
public static final String DELETE_STATUS_DONE = "Done";
public static final String DELETE_STATUS_GONE = "Gone";
/**
* Private constructor to hide implicit one.
......
package net.ihe.gazelle.app.patientregistryapi.application;
/**
* Interface for the DomainService provided by Patient Registry.
*/
public interface DomainService {
/**
* Checks the Domain exists in the Patient Registry
* @param domainIdentifier Identifier of the domain to check.
* @return a boolean indication whether or not the Domain is known by the Patient Registry
*/
boolean exist(String domainIdentifier);
/**
* Creates the Domain in the Patient Registry so it can be used on new Patient Identifiers.
* @param domainIdentifier Identifier for the Domain to create
* @param domainName Name of the domain to create
*/
void createDomain(String domainIdentifier, String domainName);
}
......@@ -8,10 +8,35 @@ import net.ihe.gazelle.app.patientregistryapi.business.Patient;
public interface PatientFeedService {
/**
* Feed a single patient to the service.
* @param patient Patient to feed to the service
* Create a single patient to the service.
* @param patient Patient to create to the service
* @return the literal value of the UUID assigned by the service to the Patient.
* @throws PatientFeedException if the service is not able to correctly feed the patient.
*/
String feedPatient(Patient patient) throws PatientFeedException;
String createPatient(Patient patient) throws PatientFeedException;
/**
* Update a single Patient in patient Registry </