Skip to content

Commit

Permalink
Merge branch 'develop' into feature/trans
Browse files Browse the repository at this point in the history
  • Loading branch information
vincenzo-ingenito committed Sep 27, 2024
2 parents e9d93ec + 636b2c6 commit f3a21a7
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ private ResourceDTO callFhirMappingEngine(String transformId, String engineId,
final String cda, final String documentSha256) {
String sha1 = StringUtility.encodeSHA1(bytePDF);
final ResourceDTO fhirResourcesDTO = documentReferenceSRV.createFhirResources(cda,jwtPayloadToken.getSubject_role(), jsonObj, bytePDF.length, documentSha256,transformId, engineId,
jwtPayloadToken.getSubject_organization_id(),sha1);
jwtPayloadToken.getSubject_organization_id(),jwtPayloadToken.getLocality(),sha1);

if(!isNullOrEmpty(fhirResourcesDTO.getErrorMessage())) {
final ErrorResponseDTO error = ErrorResponseDTO.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
public interface IFhirSRV {

ResourceDTO createFhirResources(String cda, String authorRole, PublicationCreateReplaceMetadataDTO requestBody,
Integer size, String hash, String transformId, String engineId, String organizationId,String sha1);
Integer size, String hash, String transformId, String engineId, String organizationId, String authorInstitution,String sha1);

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
*/
package it.finanze.sanita.fse2.ms.gtw.dispatcher.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
Expand All @@ -37,7 +39,6 @@
import it.finanze.sanita.fse2.ms.gtw.dispatcher.dto.response.client.TransformResDTO;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.enums.AdministrativeReqEnum;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.enums.AttivitaClinicaEnum;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.enums.DocumentTypeEnum;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.enums.LowLevelDocEnum;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.exceptions.BusinessException;
import it.finanze.sanita.fse2.ms.gtw.dispatcher.service.IConfigSRV;
Expand All @@ -56,25 +57,26 @@ public class FhirSRV implements IFhirSRV {
private static final String EXTENSION_ATTRIBUTE = "extension";

private static final String REFERENCE_ID_LIST_SUFFIX = "&ISO^urn:ihe:iti:xds:2013:order";

@Autowired
private FhirMappingClient client;

@Autowired
private IConfigSRV configSrv;

@Override
public ResourceDTO createFhirResources(final String cda, String authorRole,final PublicationCreateReplaceMetadataDTO requestBody,
final Integer size, final String hash, String transformId, String engineId, String organizationId,String sha1) {
final Integer size, final String hash, String transformId, String engineId, String organizationId,
final String authorInstitution,String sha1) {

final ResourceDTO output = new ResourceDTO();
final org.jsoup.nodes.Document docCDA = Jsoup.parse(cda);
final String encodedCDA = Base64.getEncoder().encodeToString(cda.getBytes());

final DocumentReferenceDTO documentReferenceDTO = buildDocumentReferenceDTO(encodedCDA, requestBody, size, hash);
FhirResourceDTO req = buildFhirResourceDTO(documentReferenceDTO, cda, transformId, engineId);
AuthorSlotDTO authorSlot = buildAuthorSlotDTO(authorRole,docCDA);

AuthorSlotDTO authorSlot = buildAuthorSlotDTO(authorInstitution,authorRole,docCDA);

try {
final SubmissionSetEntryDTO submissionSetEntryDTO = createSubmissionSetEntry(docCDA, requestBody.getTipoAttivitaClinica().getCode(),
Expand Down Expand Up @@ -148,7 +150,7 @@ private SubmissionSetEntryDTO createSubmissionSetEntry(final org.jsoup.nodes.Doc
sse.setAuthorInstitution(authorSlotDTO.getAuthorInstitution());
sse.setAuthorRole(authorSlotDTO.getAuthorRole());
sse.setPatientId(buildPatient(docCDA));

String sourceId = StringUtility.sanitizeSourceId(organizationId);
sse.setSourceId(SOURCE_ID_PREFIX+sourceId);
sse.setUniqueID(identificativoSottomissione);
Expand All @@ -163,8 +165,6 @@ private SubmissionSetEntryDTO createSubmissionSetEntry(final org.jsoup.nodes.Doc
}
return sse;
}



private DocumentEntryDTO createDocumentEntry(final org.jsoup.nodes.Document docCDA,
final PublicationCreateReplaceMetadataDTO requestBody, final Integer size, final String sha1,
Expand Down Expand Up @@ -201,7 +201,8 @@ private DocumentEntryDTO createDocumentEntry(final org.jsoup.nodes.Document docC

de.setUniqueId(requestBody.getIdentificativoDoc());
de.setMimeType("application/pdf+text/x-cda-r2+xml");
de.setCreationTime(new SimpleDateFormat(Constants.Misc.INI_DATE_PATTERN).format(new Date()));
String effectiveTime = docCDA.select("ClinicalDocument > effectiveTime").val();
de.setCreationTime(DateUtility.convertDateCda(effectiveTime));
de.setHash(sha1);
de.setSize(size);
if(requestBody.getAdministrativeRequest() != null) {
Expand Down Expand Up @@ -242,42 +243,33 @@ private DocumentEntryDTO createDocumentEntry(final org.jsoup.nodes.Document docC
if (requestBody.getDataFinePrestazione() != null && DateUtility.isValidDateFormat(requestBody.getDataFinePrestazione(), "yyyyMMddHHmmss")) {
de.setServiceStopTime(requestBody.getDataFinePrestazione());
}

String path = "";
final String code = docCDA.select("code").get(0).attr("code");
DocumentTypeEnum extractedDocType = DocumentTypeEnum.getByCode(code);

//Se è uguale a VPS
String oid = "";
if(DocumentTypeEnum.CODE_59258_4.equals(extractedDocType)) {
path = "ClinicalDocument > component > structuredBody > component > section[ID='Piano_Cura_Dimissione'] > entry > act > reference > externalAct > id ";
oid = "2.16.840.1.113883.2.9.4.3.13";
} else {
path = "ClinicalDocument > inFulfillmentOf > order > id ";
oid = "2.16.840.1.113883.2.9.4.3.8";

List<String> referenceIdList = buildReferenceIdList(docCDA, "ClinicalDocument > inFulfillmentOf > order > id");
if(!referenceIdList.isEmpty()) {
de.setReferenceIdList(referenceIdList);
}

List<String> referenceIdList = buildReferenceIdList(docCDA, path,oid);
de.setReferenceIdList(referenceIdList);



} catch(final Exception ex) {
log.error("Error while create document entry : " , ex);
throw new BusinessException("Error while create document entry : " , ex);
}
return de;
}

private List<String> buildReferenceIdList(final org.jsoup.nodes.Document docCDA, final String path,
final String oid) {

private List<String> buildReferenceIdList(final org.jsoup.nodes.Document docCDA, final String path) {
List<String> out = new ArrayList<>();
Elements elements = docCDA.select(path);
if(!elements.isEmpty()) {
for(Element el : elements) {
String extension = el.attr(EXTENSION_ATTRIBUTE);
out.add(extension+"^^^&"+oid+REFERENCE_ID_LIST_SUFFIX);
String nre = el.attr("root");
if("2.16.840.1.113883.2.9.4.3.9".equals(nre)) {
String extension = el.attr(EXTENSION_ATTRIBUTE);
out.add(extension+"^^^&2.16.840.1.113883.2.9.4.3.8"+REFERENCE_ID_LIST_SUFFIX);
}
}
}

return out;
}

Expand All @@ -293,21 +285,10 @@ private String buildPatient(final org.jsoup.nodes.Document docCDA) {
}


private static AuthorSlotDTO buildAuthorSlotDTO(final String authorRole,final org.jsoup.nodes.Document docCDA) {
private static AuthorSlotDTO buildAuthorSlotDTO(final String authorInstitution,final String authorRole,final org.jsoup.nodes.Document docCDA) {
AuthorSlotDTO author = new AuthorSlotDTO();
author.setAuthorRole(authorRole);
String representedOrganizationTag = "ClinicalDocument > author > assignedAuthor > representedOrganization";
final Element authorInstitutionElement = docCDA.select(representedOrganizationTag + " > id").first();
final Element authorInstitutionName = docCDA.select(representedOrganizationTag + " > name").first();
if (authorInstitutionElement != null && authorInstitutionName!=null) {
String extension = authorInstitutionElement.attr(EXTENSION_ATTRIBUTE);
String root = authorInstitutionElement.attr("root");
String name = authorInstitutionName.text();
author.setAuthorInstitution(name + "^^^^^&" + root + "&ISO^^^^" + extension);
} else {
author.setAuthorInstitution("AUTHOR_INSTITUTION_NOT_PRESENT");
}

author.setAuthorInstitution(authorInstitution);
final Element authorElement = docCDA.select("ClinicalDocument > author > assignedAuthor > id").first();
if (authorElement != null) {
String cfAuthor = authorElement.attr(EXTENSION_ATTRIBUTE);
Expand All @@ -318,5 +299,6 @@ private static AuthorSlotDTO buildAuthorSlotDTO(final String authorRole,final or
return author;
}




}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -72,8 +74,7 @@ private IniEdsInvocationETY buildETY(final String workflowInstanceId, final Stri
Document submissionSetEntryDoc = new Document("submissionSetEntry" ,Document.parse(submissionSetEntryJson));
Document documentEntryDoc = new Document("documentEntry" ,Document.parse(documentEntryJson));
Document tokenEntry = new Document("tokenEntry", new Document("payload",Document.parse(tokenEntryJson)));

metadata.add(submissionSetEntryDoc);
metadata.add(submissionSetEntryDoc);
metadata.add(documentEntryDoc);
metadata.add(tokenEntry);

Expand All @@ -96,5 +97,4 @@ public Boolean replace(String workflowInstanceId, ResourceDTO fhirResourceDTO, J
}
return output;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.util.regex.Pattern;

import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -64,10 +66,11 @@ public SystemTypeEnum getSystemByIssuer(String issuer) {

@Override
public void validatePayloadForCreate(JWTPayloadDTO payload) {
performCommonValidation(payload);
checkNull(payload.getResource_hl7_type(), "resource_hl7_type");
validateActionCoherence(payload, ActionEnum.CREATE);
performCommonValidation(payload);
validatePurposeOfUseCoherence(payload, PurposeOfUseEnum.TREATMENT);
isValidLocality(payload.getLocality());
}

@Override
Expand All @@ -76,6 +79,7 @@ public void validatePayloadForReplace(JWTPayloadDTO payload) {
checkNull(payload.getResource_hl7_type(), "resource_hl7_type");
validateActionCoherence(payload, ActionEnum.UPDATE);
validatePurposeOfUseCoherence(payload, PurposeOfUseEnum.UPDATE);
isValidLocality(payload.getLocality());
}

@Override
Expand Down Expand Up @@ -225,7 +229,7 @@ public void checkFiscalCode(String givenValue, String fieldName) {
throw new ValidationException(error);
}
}


private boolean isValidOid(String oid) {
if (oid == null)
Expand All @@ -244,6 +248,24 @@ private boolean isValidOid(String oid) {

return true;
}

private ValidationException buildValidationException() {
ErrorResponseDTO error = ErrorResponseDTO.builder()
.type(RestExecutionResultEnum.INVALID_TOKEN_FIELD.getType())
.title(RestExecutionResultEnum.INVALID_TOKEN_FIELD.getTitle())
.instance(ErrorInstanceEnum.JWT_MALFORMED_FIELD.getInstance())
.detail("Il campo Locality non è valorizzato correttamente")
.build();
return new ValidationException(error);
}


public void isValidLocality(String input) {
String regex = "^[a-zA-Z0-9]+[^\\^]*\\^\\^\\^\\^\\^\\&[^&]*\\&ISO\\^\\^\\^\\^[^\\^&]*$";
boolean isValid = Pattern.matches(regex, input);
if (!isValid) {
throw buildValidationException();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,24 @@
*/
package it.finanze.sanita.fse2.ms.gtw.dispatcher.utility;

import static it.finanze.sanita.fse2.ms.gtw.dispatcher.config.Constants.Misc.INI_DATE_PATTERN;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

import it.finanze.sanita.fse2.ms.gtw.dispatcher.exceptions.BusinessException;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DateUtility {

private DateUtility() {}


public static long getDifferenceDays(Date d1, Date d2) {
long diff = d2.getTime() - d1.getTime();
return TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
Expand Down Expand Up @@ -53,5 +59,16 @@ public static boolean isValidDateFormat(String dateStr, String format) {
}
}

public static String convertDateCda(String data) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(INI_DATE_PATTERN);

if (data.length() == INI_DATE_PATTERN.length() + 5) {
sdf = new SimpleDateFormat(INI_DATE_PATTERN + "Z");
data = data.substring(0, INI_DATE_PATTERN.length()) + data.substring(INI_DATE_PATTERN.length()).replace(":", ""); //Se nel fusoorario mi vengono passati i : li rimuovo
}

sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
return new SimpleDateFormat(INI_DATE_PATTERN).format(sdf.parse(data));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void createDocumentReferenceOkTest() {
String cda = new String(cdaFile);
PublicationCreationReqDTO reqDTO = buildPublicationReqDTO(workflowInstanceId);
String documentSha = StringUtility.encodeSHA256(cdaFile);
ResourceDTO resourceDTO = documentReferenceSRV.createFhirResources(cda,"",reqDTO, documentSha.length(), documentSha, "", "","","");
ResourceDTO resourceDTO = documentReferenceSRV.createFhirResources(cda,"",reqDTO, documentSha.length(), documentSha, "", "","","","");
assertNotNull(resourceDTO.getDocumentEntryJson());
assertNotNull(resourceDTO.getSubmissionSetEntryJson());
assertNull(resourceDTO.getErrorMessage());
Expand Down Expand Up @@ -124,7 +124,7 @@ void createDocumentReferenceErrorTest() {
PublicationCreationReqDTO reqDTO = buildPublicationReqDTO(workflowInstanceId);
String documentSha = StringUtility.encodeSHA256(cdaFile);
ResourceDTO resourceDTO = documentReferenceSRV.createFhirResources(cda, "",reqDTO, documentSha.length(), documentSha,
"PersonId", "", "","");
"PersonId", "", "","","");
ResourceDTO expectedOutputDTO = new ResourceDTO();
expectedOutputDTO.setErrorMessage("errorMessage");
assertEquals(expectedOutputDTO, resourceDTO);
Expand All @@ -143,7 +143,7 @@ void createDocumentReferenceConnectionRefusedTest() {
PublicationCreationReqDTO reqDTO = buildPublicationReqDTO(workflowInstanceId);
String documentSha = StringUtility.encodeSHA256(cdaFile);
assertThrows(ConnectionRefusedException.class, () -> documentReferenceSRV.createFhirResources(cda,"", reqDTO, documentSha.length(), documentSha,
"PersonId", "","",""));
"PersonId", "","","",""));
}

@Test
Expand All @@ -159,6 +159,6 @@ void createDocumentReferenceErrorBusinessException() {
PublicationCreationReqDTO reqDTO = buildPublicationReqDTO(workflowInstanceId);
String documentSha = StringUtility.encodeSHA256(cdaFile);
assertThrows(BusinessException.class, () -> documentReferenceSRV.createFhirResources(cda,"", reqDTO, documentSha.length(), documentSha,
"PersonId", "", "",""));
"PersonId", "", "","",""));
}
}

0 comments on commit f3a21a7

Please sign in to comment.