diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseDataDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseDataDto.java index 4b6f6dae81d..3ce4e25417d 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseDataDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseDataDto.java @@ -49,6 +49,8 @@ import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; import de.symeda.sormas.api.person.PersonDto; import de.symeda.sormas.api.person.PersonReferenceDto; +import de.symeda.sormas.api.sormastosormas.S2SIgnoreProperty; +import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; import de.symeda.sormas.api.sormastosormas.SormasToSormasOriginInfoDto; import de.symeda.sormas.api.symptoms.SymptomsDto; import de.symeda.sormas.api.therapy.TherapyDto; @@ -389,16 +391,20 @@ public class CaseDataDto extends PseudonymizableDto implements SormasToSormasEnt @SensitiveData @Size(max = COLUMN_LENGTH_DEFAULT, message = Validations.textTooLong) private String pointOfEntryDetails; + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS) @SensitiveData @Size(max = COLUMN_LENGTH_DEFAULT, message = Validations.textTooLong) private String additionalDetails; @HideForCountriesExcept(countries = { COUNTRY_CODE_GERMANY, COUNTRY_CODE_SWITZERLAND }) + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID) @Size(max = COLUMN_LENGTH_DEFAULT, message = Validations.textTooLong) private String externalID; + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN) @Size(max = COLUMN_LENGTH_DEFAULT, message = Validations.textTooLong) private String externalToken; + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN) @Size(max = COLUMN_LENGTH_TEXT, message = Validations.textTooLong) private String internalToken; private boolean sharedToCountry; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactDto.java index 8dd30fd18dc..f09d11f4fdb 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactDto.java @@ -41,6 +41,8 @@ import de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto; import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; import de.symeda.sormas.api.person.PersonReferenceDto; +import de.symeda.sormas.api.sormastosormas.S2SIgnoreProperty; +import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; import de.symeda.sormas.api.sormastosormas.SormasToSormasOriginInfoDto; import de.symeda.sormas.api.user.UserReferenceDto; import de.symeda.sormas.api.utils.DataHelper; @@ -209,10 +211,13 @@ public class ContactDto extends PseudonymizableDto implements SormasToSormasEnti @HideForCountriesExcept(countries = { COUNTRY_CODE_GERMANY, COUNTRY_CODE_SWITZERLAND }) + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID) @Size(max = COLUMN_LENGTH_DEFAULT, message = Validations.textTooLong) private String externalID; + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN) @Size(max = COLUMN_LENGTH_DEFAULT, message = Validations.textTooLong) private String externalToken; + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN) @Size(max = COLUMN_LENGTH_TEXT, message = Validations.textTooLong) private String internalToken; @@ -283,6 +288,7 @@ public class ContactDto extends PseudonymizableDto implements SormasToSormasEnti COUNTRY_CODE_SWITZERLAND }) private Date quarantineOfficialOrderSentDate; @SensitiveData + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS) @Size(max = COLUMN_LENGTH_BIG, message = Validations.textTooLong) private String additionalDetails; private EpiDataDto epiData; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventDto.java index 5de2b8dadfc..782c25b830f 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventDto.java @@ -31,6 +31,8 @@ import de.symeda.sormas.api.importexport.format.ImportExportFormat; import de.symeda.sormas.api.importexport.format.ImportFormat; import de.symeda.sormas.api.location.LocationDto; +import de.symeda.sormas.api.sormastosormas.S2SIgnoreProperty; +import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; import de.symeda.sormas.api.sormastosormas.SormasToSormasOriginInfoDto; import de.symeda.sormas.api.user.UserReferenceDto; import de.symeda.sormas.api.utils.DataHelper; @@ -120,8 +122,10 @@ public class EventDto extends PseudonymizableDto implements SormasToSormasEntity private Date eventInvestigationStartDate; private Date eventInvestigationEndDate; private EventManagementStatus eventManagementStatus; + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID) @Size(max = COLUMN_LENGTH_DEFAULT, message = Validations.textTooLong) private String externalId; + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN) @Size(max = COLUMN_LENGTH_DEFAULT, message = Validations.textTooLong) private String externalToken; @Size(max = COLUMN_LENGTH_DEFAULT, message = Validations.textTooLong) @@ -211,6 +215,7 @@ public class EventDto extends PseudonymizableDto implements SormasToSormasEntity private boolean ownershipHandedOver; @HideForCountriesExcept + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN) @Size(max = COLUMN_LENGTH_TEXT, message = Validations.textTooLong) private String internalToken; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationDto.java index 15a4f64d3a1..8c6d01b513c 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationDto.java @@ -32,6 +32,8 @@ import de.symeda.sormas.api.infrastructure.facility.FacilityType; import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; import de.symeda.sormas.api.person.PersonReferenceDto; +import de.symeda.sormas.api.sormastosormas.S2SIgnoreProperty; +import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; import de.symeda.sormas.api.sormastosormas.SormasToSormasOriginInfoDto; import de.symeda.sormas.api.user.UserReferenceDto; import de.symeda.sormas.api.utils.DataHelper; @@ -103,6 +105,7 @@ public class ImmunizationDto extends PseudonymizableDto implements SormasToSorma @SensitiveData(mandatoryField = true) private String meansOfImmunizationDetails; private ImmunizationManagementStatus immunizationManagementStatus; + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID) @Size(max = COLUMN_LENGTH_SMALL, message = Validations.textTooLong) @SensitiveData(mandatoryField = true) private String externalId; @@ -135,6 +138,7 @@ public class ImmunizationDto extends PseudonymizableDto implements SormasToSorma private YesNoUnknown previousInfection; private Date lastInfectionDate; + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS) @Size(max = COLUMN_LENGTH_TEXT, message = Validations.textTooLong) @SensitiveData private String additionalDetails; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/person/PersonDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/person/PersonDto.java index 91fda171b2b..32b41520ea7 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/person/PersonDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/person/PersonDto.java @@ -38,6 +38,8 @@ import de.symeda.sormas.api.infrastructure.facility.FacilityType; import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; import de.symeda.sormas.api.location.LocationDto; +import de.symeda.sormas.api.sormastosormas.S2SIgnoreProperty; +import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.api.utils.Diseases; import de.symeda.sormas.api.utils.EmbeddedPersonalData; @@ -320,11 +322,14 @@ public class PersonDto extends PseudonymizableDto { private SymptomJournalStatus symptomJournalStatus; @SensitiveData @HideForCountriesExcept(countries = CountryHelper.COUNTRY_CODE_GERMANY) + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID) @Size(max = COLUMN_LENGTH_DEFAULT, message = Validations.textTooLong) private String externalId; @HideForCountriesExcept(countries = CountryHelper.COUNTRY_CODE_GERMANY) + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN) @Size(max = COLUMN_LENGTH_DEFAULT, message = Validations.textTooLong) private String externalToken; + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN) @Size(max = COLUMN_LENGTH_TEXT, message = Validations.textTooLong) private String internalToken; @@ -335,6 +340,7 @@ public class PersonDto extends PseudonymizableDto { @SensitiveData private CountryReferenceDto citizenship; @SensitiveData + @S2SIgnoreProperty(configProperty = SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS) @Size(max = COLUMN_LENGTH_TEXT, message = Validations.textTooLong) private String additionalDetails; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/S2SIgnoreProperty.java b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/S2SIgnoreProperty.java new file mode 100644 index 00000000000..b112be8cb80 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/S2SIgnoreProperty.java @@ -0,0 +1,38 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2021 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.symeda.sormas.api.sormastosormas; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author Alex Vidrean + * @since 07-Oct-21 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface S2SIgnoreProperty { + + /** + * Property from sormas.properties file populated trough {@link de.symeda.sormas.api.ConfigFacade} + */ + String configProperty(); +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasConfig.java b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasConfig.java index 294443be8d4..98b9fa601b8 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasConfig.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasConfig.java @@ -1,6 +1,8 @@ package de.symeda.sormas.api.sormastosormas; import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; public class SormasToSormasConfig implements Serializable { @@ -12,6 +14,11 @@ public class SormasToSormasConfig implements Serializable { // resort in the REST client, as it needs to be shared between REST client and sormas-rest. public static final String SENDER_SERVER_ID = "senderServerId"; + public static final String SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS = "sormas2sormas.ignoreProperty.additionalDetails"; + public static final String SORMAS2SORMAS_IGNORE_EXTERNAL_ID = "sormas2sormas.ignoreProperty.externalId"; + public static final String SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN = "sormas2sormas.ignoreProperty.externalToken"; + public static final String SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN = "sormas2sormas.ignoreProperty.internalToken"; + private String id; private String path; private String keystoreName; @@ -19,7 +26,13 @@ public class SormasToSormasConfig implements Serializable { private String rootCaAlias; private String truststoreName; private String truststorePass; - private boolean retainCaseExternalToken; + private Map ignoreProperties = new HashMap<>(); + { + this.ignoreProperties.put(SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, true); + this.ignoreProperties.put(SORMAS2SORMAS_IGNORE_EXTERNAL_ID, true); + this.ignoreProperties.put(SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN, true); + this.ignoreProperties.put(SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN, true); + } private String oidcServer; private String oidcRealm; @@ -76,12 +89,12 @@ public void setTruststorePass(String truststorePass) { this.truststorePass = truststorePass; } - public boolean getRetainCaseExternalToken() { - return retainCaseExternalToken; + public Map getIgnoreProperties() { + return ignoreProperties; } - public void setRetainCaseExternalToken(boolean retainCaseExternalToken) { - this.retainCaseExternalToken = retainCaseExternalToken; + public void setIgnoreProperties(Map ignoreProperties) { + this.ignoreProperties = ignoreProperties; } @Override diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/ConfigFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/ConfigFacadeEjb.java index edb0000dbf7..955ac0d70ae 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/ConfigFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/ConfigFacadeEjb.java @@ -17,8 +17,10 @@ import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Properties; import java.util.regex.Pattern; +import java.util.stream.Collectors; import javax.annotation.Resource; import javax.ejb.LocalBean; @@ -138,14 +140,14 @@ public class ConfigFacadeEjb implements ConfigFacade { public static final String SORMAS2SORMAS_TRUSTSTORE_NAME = "sormas2sormas.truststoreName"; public static final String SORMAS2SORMAS_TRUSTSTORE_PASS = "sormas2sormas.truststorePass"; + private static final String SORMAS2SORMAS_IGNORE_PROPERTY_PREFIX = "sormas2sormas.ignoreProperty."; + private static final String SORMAS2SORMAS_OIDC_REALM = "sormas2sormas.oidc.realm"; private static final String SORMAS2SORMAS_OIDC_CLIENT_ID = "sormas2sormas.oidc.clientId"; private static final String SORMAS2SORMAS_OIDC_CLIENT_SECRET = "sormas2sormas.oidc.clientSecret"; private static final String SORMAS2SORMAS_ETCD_KEY_PREFIX = "sormas2sormas.etcd.keyPrefix"; - private static final String SORMAS2SORMAS_RETAIN_CASE_EXTERNAL_TOKEN = "sormas2sormas.retainCaseExternalToken"; - private static final String EXTERNAL_SURVEILLANCE_TOOL_GATEWAY_URL = "survnet.url"; private static final String DASHBOARD_MAP_MARKER_LIMIT = "dashboardMapMarkerLimit"; @@ -516,16 +518,23 @@ public SormasToSormasConfig getS2SConfig() { config.setTruststoreName(getProperty(SORMAS2SORMAS_TRUSTSTORE_NAME, null)); config.setTruststorePass(getProperty(SORMAS2SORMAS_TRUSTSTORE_PASS, null)); config.setRootCaAlias(getProperty(SORMAS2SORMAS_ROOT_CA_ALIAS, null)); - config.setRetainCaseExternalToken(getBoolean(SORMAS2SORMAS_RETAIN_CASE_EXTERNAL_TOKEN, true)); config.setId(getProperty(SORMAS2SORMAS_ID, null)); config.setOidcServer(getProperty(CENTRAL_OIDC_URL, null)); config.setOidcRealm(getProperty(SORMAS2SORMAS_OIDC_REALM, null)); config.setOidcClientId(getProperty(SORMAS2SORMAS_OIDC_CLIENT_ID, null)); config.setOidcClientSecret(getProperty(SORMAS2SORMAS_OIDC_CLIENT_SECRET, null)); config.setKeyPrefix(getProperty(SORMAS2SORMAS_ETCD_KEY_PREFIX, null)); + config.getIgnoreProperties().putAll(getS2SIgnoreProperties()); return config; } + private Map getS2SIgnoreProperties() { + return props.stringPropertyNames().stream() + .filter(property -> property.startsWith(SORMAS2SORMAS_IGNORE_PROPERTY_PREFIX)) + .collect(Collectors.toMap(property -> property, property -> getBoolean(property, true))); + + } + @Override public String getExternalSurveillanceToolGatewayUrl() { return getProperty(EXTERNAL_SURVEILLANCE_TOOL_GATEWAY_URL, null); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/data/received/ReceivedDataProcessorHelper.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/data/received/ReceivedDataProcessorHelper.java index 624eb4bd469..2b82d86ba38 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/data/received/ReceivedDataProcessorHelper.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/data/received/ReceivedDataProcessorHelper.java @@ -15,8 +15,10 @@ package de.symeda.sormas.backend.sormastosormas.data.received; +import java.lang.reflect.Field; import java.util.Date; +import javax.annotation.Nullable; import javax.ejb.EJB; import javax.ejb.LocalBean; import javax.ejb.Stateless; @@ -27,6 +29,8 @@ import de.symeda.sormas.api.infrastructure.country.CountryReferenceDto; import de.symeda.sormas.api.location.LocationDto; import de.symeda.sormas.api.person.PersonDto; +import de.symeda.sormas.api.sormastosormas.S2SIgnoreProperty; +import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; import de.symeda.sormas.api.sormastosormas.SormasToSormasOriginInfoDto; import de.symeda.sormas.api.sormastosormas.sharerequest.SormasToSormasPersonPreview; import de.symeda.sormas.api.sormastosormas.validation.ValidationErrorGroup; @@ -35,18 +39,29 @@ import de.symeda.sormas.api.user.UserReferenceDto; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.api.utils.SormasToSormasEntityDto; +import de.symeda.sormas.backend.caze.Case; +import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; +import de.symeda.sormas.backend.contact.Contact; +import de.symeda.sormas.backend.event.EventParticipant; +import de.symeda.sormas.backend.person.PersonFacadeEjb.PersonFacadeEjbLocal; import de.symeda.sormas.backend.sormastosormas.data.infra.InfrastructureValidator; import de.symeda.sormas.backend.sormastosormas.entities.SormasToSormasEntity; import de.symeda.sormas.backend.user.UserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Stateless @LocalBean public class ReceivedDataProcessorHelper { + private static final Logger LOGGER = LoggerFactory.getLogger(ReceivedDataProcessorHelper.class); + @EJB private UserService userService; @EJB private InfrastructureValidator infraValidator; + @EJB + private ConfigFacadeEjbLocal configFacade; public ValidationErrors processOriginInfo(SormasToSormasOriginInfoDto originInfo, String validationGroupCaption) { if (originInfo == null) { @@ -74,14 +89,12 @@ public ValidationErrors processOriginInfo(SormasToSormasOriginInfoDto originInfo return validationErrors; } - public ValidationErrors processPerson(PersonDto person) { + public ValidationErrors processPerson(PersonDto person, PersonDto existingPerson) { ValidationErrors validationErrors = new ValidationErrors(); infraValidator.validateLocation(person.getAddress(), Captions.Person, validationErrors); - person.getAddresses().forEach(address -> { - infraValidator.validateLocation(address, Captions.Person, validationErrors); - }); + person.getAddresses().forEach(address -> infraValidator.validateLocation(address, Captions.Person, validationErrors)); CountryReferenceDto birthCountry = processCountry(person.getBirthCountry(), Captions.Person_birthCountry, validationErrors); person.setBirthCountry(birthCountry); @@ -89,6 +102,8 @@ public ValidationErrors processPerson(PersonDto person) { CountryReferenceDto citizenship = processCountry(person.getCitizenship(), Captions.Person_citizenship, validationErrors); person.setCitizenship(citizenship); + handleIgnoredProperties(person, existingPerson); + return validationErrors; } @@ -133,4 +148,44 @@ public void updateReportingUser(SormasToSormasEntityDto entity, SormasToSormasEn entity.setReportingUser(reportingUser); } + public void handleIgnoredProperties(T receivedEntity, T originalEntity) { + Class dtoType = receivedEntity.getClass(); + SormasToSormasConfig s2SConfig = configFacade.getS2SConfig(); + for (Field field : dtoType.getDeclaredFields()) { + if (field.isAnnotationPresent(S2SIgnoreProperty.class)) { + String s2sConfigProperty = field.getAnnotation(S2SIgnoreProperty.class).configProperty(); + if (s2SConfig.getIgnoreProperties().get(s2sConfigProperty)) { + field.setAccessible(true); + try { + Object originalValue = originalEntity != null ? field.get(originalEntity) : null; + field.set(receivedEntity, originalValue); + } catch (IllegalAccessException e) { + LOGGER.error("Could not set field {} for {}", field.getName(), dtoType.getSimpleName()); + } + field.setAccessible(false); + } + } + } + } + + public PersonDto getExitingPerson(@Nullable Case existingCase) { + if (existingCase == null) { + return null; + } + return PersonFacadeEjbLocal.toDto(existingCase.getPerson()); + } + + public PersonDto getExistingPerson(@Nullable Contact existingContact) { + if (existingContact == null) { + return null; + } + return PersonFacadeEjbLocal.toDto(existingContact.getPerson()); + } + + public PersonDto getExistingPerson(@Nullable EventParticipant existingEventParticipant) { + if (existingEventParticipant == null) { + return null; + } + return PersonFacadeEjbLocal.toDto(existingEventParticipant.getPerson()); + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ShareDataBuilder.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ShareDataBuilder.java index 9dd6557df19..e2381ab9dc3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ShareDataBuilder.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ShareDataBuilder.java @@ -15,13 +15,6 @@ package de.symeda.sormas.backend.sormastosormas.entities; -import java.util.ArrayList; -import java.util.List; - -import javax.ejb.EJB; -import javax.ejb.LocalBean; -import javax.ejb.Stateless; - import de.symeda.sormas.api.immunization.ImmunizationDto; import de.symeda.sormas.api.sormastosormas.SormasToSormasDto; import de.symeda.sormas.api.sormastosormas.SormasToSormasEntityDto; @@ -47,6 +40,12 @@ import de.symeda.sormas.backend.sormastosormas.share.sharerequest.ShareRequestPreviews; import de.symeda.sormas.backend.user.User; +import javax.ejb.EJB; +import javax.ejb.LocalBean; +import javax.ejb.Stateless; +import java.util.ArrayList; +import java.util.List; + @Stateless @LocalBean public class ShareDataBuilder { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/caze/CaseShareDataBuilder.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/caze/CaseShareDataBuilder.java index 08d60fb077f..ce507cd76c7 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/caze/CaseShareDataBuilder.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/caze/CaseShareDataBuilder.java @@ -26,6 +26,10 @@ import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.caze.CaseFacadeEjb; import de.symeda.sormas.backend.common.ConfigFacadeEjb; +import de.symeda.sormas.backend.contact.Contact; +import de.symeda.sormas.backend.contact.ContactService; +import de.symeda.sormas.backend.infrastructure.facility.FacilityFacadeEjb; +import de.symeda.sormas.backend.infrastructure.pointofentry.PointOfEntryFacadeEjb; import de.symeda.sormas.backend.infrastructure.community.CommunityFacadeEjb; import de.symeda.sormas.backend.infrastructure.district.DistrictFacadeEjb; import de.symeda.sormas.backend.infrastructure.facility.FacilityFacadeEjb; @@ -44,8 +48,6 @@ public class CaseShareDataBuilder implements ShareDataBuilder> infrastructureAndErrors = infraValidator.validateInfrastructure(caze); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/contact/ReceivedContactProcessor.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/contact/ReceivedContactProcessor.java index 6f2cd881278..50c1c937453 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/contact/ReceivedContactProcessor.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/contact/ReceivedContactProcessor.java @@ -32,6 +32,7 @@ import de.symeda.sormas.api.sormastosormas.validation.ValidationErrors; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.backend.contact.Contact; +import de.symeda.sormas.backend.contact.ContactFacadeEjb; import de.symeda.sormas.backend.contact.ContactService; import de.symeda.sormas.backend.sormastosormas.data.infra.InfrastructureValidator; import de.symeda.sormas.backend.sormastosormas.data.received.ReceivedDataProcessor; @@ -75,7 +76,7 @@ public ValidationErrors processReceivedPreview(SormasToSormasContactPreview prev private ValidationErrors processContactData(ContactDto contact, PersonDto person, Contact existingContact) { ValidationErrors validationErrors = new ValidationErrors(); - ValidationErrors personValidationErrors = dataProcessorHelper.processPerson(person); + ValidationErrors personValidationErrors = dataProcessorHelper.processPerson(person, dataProcessorHelper.getExistingPerson(existingContact)); validationErrors.addAll(personValidationErrors); contact.setPerson(person.toReference()); @@ -91,7 +92,7 @@ private ValidationErrors processContactData(ContactDto contact, PersonDto person })); dataProcessorHelper.processEpiData(contact.getEpiData(), validationErrors); - + dataProcessorHelper.handleIgnoredProperties(contact, ContactFacadeEjb.ContactFacadeEjbLocal.toDto(existingContact)); return validationErrors; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/event/EventShareDataBuilder.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/event/EventShareDataBuilder.java index fc90c630501..2b3290c6867 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/event/EventShareDataBuilder.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/event/EventShareDataBuilder.java @@ -63,6 +63,8 @@ private EventDto getEventDto(Event event, Pseudonymizer pseudonymizer) { eventDto.setReportingUser(null); eventDto.setSormasToSormasOriginInfo(null); + dataBuilderHelper.clearIgnoredProperties(eventDto); + return eventDto; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/event/ReceivedEventProcessor.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/event/ReceivedEventProcessor.java index f311544c903..bdd4b8ff661 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/event/ReceivedEventProcessor.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/event/ReceivedEventProcessor.java @@ -32,6 +32,7 @@ import de.symeda.sormas.api.sormastosormas.validation.ValidationErrors; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.backend.event.Event; +import de.symeda.sormas.backend.event.EventFacadeEjb; import de.symeda.sormas.backend.event.EventService; import de.symeda.sormas.backend.sormastosormas.data.infra.InfrastructureValidator; import de.symeda.sormas.backend.sormastosormas.data.received.ReceivedDataProcessor; @@ -81,6 +82,7 @@ private ValidationErrors processEventData(EventDto event, Event existingEvent) { ValidationErrors validationErrors = new ValidationErrors(); dataProcessorHelper.updateReportingUser(event, existingEvent); + dataProcessorHelper.handleIgnoredProperties(event, EventFacadeEjb.EventFacadeEjbLocal.toDto(existingEvent)); if (existingEvent == null || existingEvent.getResponsibleUser() == null) { event.setResponsibleUser(userService.getCurrentUser().toReference()); } else { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/eventparticipant/EventParticipantShareDataBuilder.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/eventparticipant/EventParticipantShareDataBuilder.java index e4d4aa529e9..690ef5984f8 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/eventparticipant/EventParticipantShareDataBuilder.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/eventparticipant/EventParticipantShareDataBuilder.java @@ -45,14 +45,15 @@ public SormasToSormasEventParticipantDto buildShareData(EventParticipant data, S Pseudonymizer pseudonymizer = dataBuilderHelper.createPseudonymizer(requestInfo.isPseudonymizedPersonalData(), requestInfo.isPseudonymizedSensitiveData()); - EventParticipantDto dto = eventParticipantFacade.convertToDto(data, pseudonymizer); + EventParticipantDto eventParticipantDto = eventParticipantFacade.convertToDto(data, pseudonymizer); - dto.setReportingUser(null); - dto.setSormasToSormasOriginInfo(null); + eventParticipantDto.setReportingUser(null); + eventParticipantDto.setSormasToSormasOriginInfo(null); + dataBuilderHelper.clearIgnoredProperties(eventParticipantDto.getPerson()); - dataBuilderHelper.pseudonymiePerson(dto.getPerson(), requestInfo.isPseudonymizedPersonalData(), requestInfo.isPseudonymizedSensitiveData()); + dataBuilderHelper.pseudonymiePerson(eventParticipantDto.getPerson(), requestInfo.isPseudonymizedPersonalData(), requestInfo.isPseudonymizedSensitiveData()); - return new SormasToSormasEventParticipantDto(dto); + return new SormasToSormasEventParticipantDto(eventParticipantDto); } @Override diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/eventparticipant/ReceivedEventParticipantProcessor.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/eventparticipant/ReceivedEventParticipantProcessor.java index b118797567a..19f85572f47 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/eventparticipant/ReceivedEventParticipantProcessor.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/eventparticipant/ReceivedEventParticipantProcessor.java @@ -60,7 +60,7 @@ public ValidationErrors processReceivedData(SormasToSormasEventParticipantDto re ValidationErrors validationErrors = new ValidationErrors(); - ValidationErrors personValidationErrors = dataProcessorHelper.processPerson(eventParticipant.getPerson()); + ValidationErrors personValidationErrors = dataProcessorHelper.processPerson(eventParticipant.getPerson(), dataProcessorHelper.getExistingPerson(existingData)); validationErrors.addAll(personValidationErrors); DataHelper.Pair> infrastructureAndErrors = diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/immunization/ImmunizationShareDataBuilder.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/immunization/ImmunizationShareDataBuilder.java index 7f0d7b1f368..35ab606907c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/immunization/ImmunizationShareDataBuilder.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/immunization/ImmunizationShareDataBuilder.java @@ -45,6 +45,7 @@ public SormasToSormasEntityDto buildShareData(Immunization immu ImmunizationDto immunizationDto = immunizationFacade.convertToDto(immunization, pseudonymizer); immunizationDto.setReportingUser(null); immunizationDto.setSormasToSormasOriginInfo(null); + dataBuilderHelper.clearIgnoredProperties(immunizationDto); return new SormasToSormasEntityDto<>(immunizationDto); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/immunization/ReceivedImmunizationProcessor.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/immunization/ReceivedImmunizationProcessor.java index e3543ad4882..3d0639f624b 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/immunization/ReceivedImmunizationProcessor.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/immunization/ReceivedImmunizationProcessor.java @@ -30,6 +30,7 @@ import de.symeda.sormas.api.sormastosormas.validation.ValidationErrors; import de.symeda.sormas.api.user.UserReferenceDto; import de.symeda.sormas.api.utils.DataHelper; +import de.symeda.sormas.backend.immunization.ImmunizationFacadeEjb; import de.symeda.sormas.backend.immunization.ImmunizationService; import de.symeda.sormas.backend.immunization.entity.Immunization; import de.symeda.sormas.backend.sormastosormas.data.infra.InfrastructureValidator; @@ -64,6 +65,7 @@ public ValidationErrors processReceivedData(SormasToSormasEntityDto> infrastructureAndErrors = infraValidator.validateInfrastructure( diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/ShareDataBuilderHelper.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/ShareDataBuilderHelper.java index d2aa7859d99..919a4b245a7 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/ShareDataBuilderHelper.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/ShareDataBuilderHelper.java @@ -15,15 +15,13 @@ package de.symeda.sormas.backend.sormastosormas.share; -import javax.ejb.EJB; -import javax.ejb.LocalBean; -import javax.ejb.Stateless; - import de.symeda.sormas.api.contact.ContactDto; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.person.PersonDto; +import de.symeda.sormas.api.sormastosormas.S2SIgnoreProperty; import de.symeda.sormas.api.sormastosormas.SormasServerDescriptor; +import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; import de.symeda.sormas.api.sormastosormas.SormasToSormasOptionsDto; import de.symeda.sormas.api.sormastosormas.SormasToSormasOriginInfoDto; import de.symeda.sormas.api.sormastosormas.sharerequest.SormasToSormasContactPreview; @@ -40,30 +38,30 @@ import de.symeda.sormas.backend.location.LocationFacadeEjb; import de.symeda.sormas.backend.person.Person; import de.symeda.sormas.backend.person.PersonFacadeEjb; -import de.symeda.sormas.backend.sample.AdditionalTestFacadeEjb; -import de.symeda.sormas.backend.sample.PathogenTestFacadeEjb; -import de.symeda.sormas.backend.sample.SampleFacadeEjb; import de.symeda.sormas.backend.sormastosormas.origin.SormasToSormasOriginInfo; import de.symeda.sormas.backend.sormastosormas.share.shareinfo.ShareRequestInfo; import de.symeda.sormas.backend.user.User; import de.symeda.sormas.backend.util.Pseudonymizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ejb.EJB; +import javax.ejb.LocalBean; +import javax.ejb.Stateless; +import java.lang.reflect.Field; @Stateless @LocalBean public class ShareDataBuilderHelper { + private static final Logger LOGGER = LoggerFactory.getLogger(ShareDataBuilderHelper.class); + @EJB private PersonFacadeEjb.PersonFacadeEjbLocal personFacade; @EJB private ContactFacadeEjb.ContactFacadeEjbLocal contactFacade; @EJB private ConfigFacadeEjb.ConfigFacadeEjbLocal configFacadeEjb; - @EJB - private SampleFacadeEjb.SampleFacadeEjbLocal sampleFacade; - @EJB - private PathogenTestFacadeEjb.PathogenTestFacadeEjbLocal pathogenTestFacade; - @EJB - private AdditionalTestFacadeEjb.AdditionalTestFacadeEjbLocal additionalTestFacade; public Pseudonymizer createPseudonymizer(boolean pseudonymizePersonalData, boolean pseudonymizeSensitiveData) { Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultNoCheckers(false); @@ -83,6 +81,8 @@ public PersonDto getPersonDto(Person person, Pseudonymizer pseudonymizer, boolea pseudonymiePerson(personDto, pseudonymizedPersonalData, pseudonymizedSensitiveData); + clearIgnoredProperties(personDto); + return personDto; } @@ -101,6 +101,8 @@ public ContactDto getContactDto(Contact contact, Pseudonymizer pseudonymizer) { contactDto.setResultingCaseUser(null); contactDto.setSormasToSormasOriginInfo(null); + clearIgnoredProperties(contactDto); + return contactDto; } @@ -193,4 +195,23 @@ public SormasToSormasOptionsDto createOptionsFromOriginInfoDto(SormasToSormasOri return options; } + + public void clearIgnoredProperties(T dto) { + SormasToSormasConfig s2SConfig = configFacadeEjb.getS2SConfig(); + Class dtoType = dto.getClass(); + for (Field field : dtoType.getDeclaredFields()) { + if (field.isAnnotationPresent(S2SIgnoreProperty.class)) { + String s2sConfigProperty = field.getAnnotation(S2SIgnoreProperty.class).configProperty(); + if (s2SConfig.getIgnoreProperties().get(s2sConfigProperty)) { + field.setAccessible(true); + try { + field.set(dto, null); + } catch (IllegalAccessException e) { + LOGGER.error("Could not clear field {} for {}", field.getName(), dtoType.getSimpleName()); + } + field.setAccessible(false); + } + } + } + } } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java index 4d581023aa6..79410a90b14 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java @@ -23,6 +23,12 @@ import javax.persistence.EntityManager; import javax.persistence.Query; +import de.symeda.sormas.api.customizableenum.CustomizableEnumFacade; +import de.symeda.sormas.backend.customizableenum.CustomizableEnumFacadeEjb; +import de.symeda.sormas.backend.customizableenum.CustomizableEnumValueService; +import de.symeda.sormas.backend.sormastosormas.data.received.ReceivedDataProcessorHelper; +import de.symeda.sormas.backend.sormastosormas.entities.caze.ReceivedCaseProcessor; +import de.symeda.sormas.backend.sormastosormas.share.ShareDataBuilderHelper; import org.junit.Before; import de.symeda.sormas.api.ConfigFacade; @@ -592,6 +598,14 @@ public CustomizableEnumValueService getCustomizableEnumValueService() { public CustomizableEnumFacade getCustomizableEnumFacade() { return getBean(CustomizableEnumFacadeEjb.class); } + public ShareDataBuilderHelper getShareDataBuilderHelper() { + return getBean(ShareDataBuilderHelper.class); + } + + public ReceivedDataProcessorHelper getReceivedDataProcessorHelper() { + return getBean(ReceivedDataProcessorHelper.class); + } + protected UserDto useSurveillanceOfficerLogin(TestDataCreator.RDCF rdcf) { if (rdcf == null) { rdcf = creator.createRDCF("Region", "District", "Community", "Facility"); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/SormasToSormasFacadeTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/SormasToSormasFacadeTest.java index d6b4f54a0e4..f51229e3046 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/SormasToSormasFacadeTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/SormasToSormasFacadeTest.java @@ -77,9 +77,7 @@ public abstract class SormasToSormasFacadeTest extends AbstractBeanTest { // values are set in server-list.csv located in serveraccessdefault and serveraccesssecond public static final String DEFAULT_SERVER_ID = "2.sormas.id.sormas_a"; - public static final SormasServerDescriptor DEFAULT_SERVER = new SormasServerDescriptor("2.sormas.id.sormas_a", "sormas_a", "sormas_a:6048"); public static final String SECOND_SERVER_ID = "2.sormas.id.sormas_b"; - public static final SormasServerDescriptor SECOND_SERVER = new SormasServerDescriptor("2.sormas.id.sormas_b", "sormas_b", "sormas_b:6048"); private ObjectMapper objectMapper; @Override diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/data/received/ReceivedDataProcessorHelperTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/data/received/ReceivedDataProcessorHelperTest.java new file mode 100644 index 00000000000..c9f232fac99 --- /dev/null +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/data/received/ReceivedDataProcessorHelperTest.java @@ -0,0 +1,352 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2021 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.symeda.sormas.backend.sormastosormas.data.received; + +import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.caze.CaseDataDto; +import de.symeda.sormas.api.contact.ContactDto; +import de.symeda.sormas.api.event.EventDto; +import de.symeda.sormas.api.immunization.ImmunizationDto; +import de.symeda.sormas.api.immunization.ImmunizationManagementStatus; +import de.symeda.sormas.api.immunization.ImmunizationStatus; +import de.symeda.sormas.api.immunization.MeansOfImmunization; +import de.symeda.sormas.api.person.PersonDto; +import de.symeda.sormas.api.person.PersonReferenceDto; +import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; +import de.symeda.sormas.api.user.UserReferenceDto; +import de.symeda.sormas.api.user.UserRole; +import de.symeda.sormas.api.utils.DateHelper; +import de.symeda.sormas.backend.AbstractBeanTest; +import de.symeda.sormas.backend.MockProducer; +import de.symeda.sormas.backend.TestDataCreator; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.Date; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +/** + * @author Alex Vidrean + * @since 11-Oct-21 + */ +@RunWith(MockitoJUnitRunner.class) +public class ReceivedDataProcessorHelperTest extends AbstractBeanTest { + + @Test + public void testIgnoredPropertiesAreNotOverwrittenWithNewValuesForCase() throws CloneNotSupportedException { + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + PersonDto personDto = creator.createPerson(); + UserReferenceDto officer = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + CaseDataDto existingCaseDto = creator.createCase(officer, rdcf, dto -> { + dto.setPerson(personDto.toReference()); + dto.setSurveillanceOfficer(officer); + dto.setClassificationUser(officer); + dto.setAdditionalDetails("oldAdditionalDetails"); + dto.setExternalID("oldExternalId"); + dto.setExternalToken("oldExternalToken"); + dto.setInternalToken("oldInternalToken"); + }); + + CaseDataDto receivedCaseDto = (CaseDataDto) existingCaseDto.clone(); + receivedCaseDto.setAdditionalDetails("newAdditionalDetails"); + receivedCaseDto.setExternalID("newExternalId"); + receivedCaseDto.setExternalToken("newExternalToken"); + receivedCaseDto.setInternalToken("newInternalToken"); + + getReceivedDataProcessorHelper().handleIgnoredProperties(receivedCaseDto, existingCaseDto); + + assertThat(receivedCaseDto.getAdditionalDetails(), is("oldAdditionalDetails")); + assertThat(receivedCaseDto.getExternalID(), is("oldExternalId")); + assertThat(receivedCaseDto.getExternalToken(), is("oldExternalToken")); + assertThat(receivedCaseDto.getInternalToken(), is("oldInternalToken")); + + } + + @Test + public void testIgnoredPropertiesAreOverwrittenWithNewValuesForCase() throws CloneNotSupportedException { + + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN, Boolean.FALSE.toString()); + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + PersonDto personDto = creator.createPerson(); + UserReferenceDto officer = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + CaseDataDto existingCaseDto = creator.createCase(officer, rdcf, dto -> { + dto.setPerson(personDto.toReference()); + dto.setSurveillanceOfficer(officer); + dto.setClassificationUser(officer); + dto.setAdditionalDetails("oldAdditionalDetails"); + dto.setExternalID("oldExternalId"); + dto.setExternalToken("oldExternalToken"); + dto.setInternalToken("oldInternalToken"); + }); + + CaseDataDto receivedCaseDto = (CaseDataDto) existingCaseDto.clone(); + receivedCaseDto.setAdditionalDetails("newAdditionalDetails"); + receivedCaseDto.setExternalID("newExternalId"); + receivedCaseDto.setExternalToken("newExternalToken"); + receivedCaseDto.setInternalToken("newInternalToken"); + + getReceivedDataProcessorHelper().handleIgnoredProperties(receivedCaseDto, existingCaseDto); + + assertThat(receivedCaseDto.getAdditionalDetails(), is("newAdditionalDetails")); + assertThat(receivedCaseDto.getExternalID(), is("newExternalId")); + assertThat(receivedCaseDto.getExternalToken(), is("newExternalToken")); + assertThat(receivedCaseDto.getInternalToken(), is("newInternalToken")); + + } + + + @Test + public void testIgnoredPropertiesAreNotOverwrittenWithNewValuesForContact() throws CloneNotSupportedException { + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + PersonReferenceDto personReferenceDto = creator.createPerson().toReference(); + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + ContactDto existingContactDto = creator.createContact(officerReferenceDto, personReferenceDto); + existingContactDto.setAdditionalDetails("oldAdditionalDetails"); + existingContactDto.setExternalID("oldExternalId"); + existingContactDto.setExternalToken("oldExternalToken"); + existingContactDto.setInternalToken("oldInternalToken"); + + ContactDto receivedContactDto = (ContactDto) existingContactDto.clone(); + receivedContactDto.setAdditionalDetails("newAdditionalDetails"); + receivedContactDto.setExternalID("newExternalId"); + receivedContactDto.setExternalToken("newExternalToken"); + receivedContactDto.setInternalToken("newInternalToken"); + + getReceivedDataProcessorHelper().handleIgnoredProperties(receivedContactDto, existingContactDto); + + assertThat(receivedContactDto.getAdditionalDetails(), is("oldAdditionalDetails")); + assertThat(receivedContactDto.getExternalID(), is("oldExternalId")); + assertThat(receivedContactDto.getExternalToken(), is("oldExternalToken")); + assertThat(receivedContactDto.getInternalToken(), is("oldInternalToken")); + } + + @Test + public void testIgnoredPropertiesAreOverwrittenWithNewValuesForContact() throws CloneNotSupportedException { + + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN, Boolean.FALSE.toString()); + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + PersonReferenceDto personReferenceDto = creator.createPerson().toReference(); + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + ContactDto existingContactDto = creator.createContact(officerReferenceDto, personReferenceDto); + existingContactDto.setAdditionalDetails("oldAdditionalDetails"); + existingContactDto.setExternalID("oldExternalId"); + existingContactDto.setExternalToken("oldExternalToken"); + existingContactDto.setInternalToken("oldInternalToken"); + + ContactDto receivedContactDto = (ContactDto) existingContactDto.clone(); + receivedContactDto.setAdditionalDetails("newAdditionalDetails"); + receivedContactDto.setExternalID("newExternalId"); + receivedContactDto.setExternalToken("newExternalToken"); + receivedContactDto.setInternalToken("newInternalToken"); + + getReceivedDataProcessorHelper().handleIgnoredProperties(receivedContactDto, existingContactDto); + + assertThat(receivedContactDto.getAdditionalDetails(), is("newAdditionalDetails")); + assertThat(receivedContactDto.getExternalID(), is("newExternalId")); + assertThat(receivedContactDto.getExternalToken(), is("newExternalToken")); + assertThat(receivedContactDto.getInternalToken(), is("newInternalToken")); + } + + @Test + public void testIgnoredPropertiesAreNotOverwrittenWithNewValuesForEvent() throws CloneNotSupportedException { + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + EventDto existingEventDto = creator.createEvent(officerReferenceDto); + existingEventDto.setDisease(Disease.CORONAVIRUS); + existingEventDto.setExternalId("oldExternalId"); + existingEventDto.setExternalToken("oldExternalToken"); + existingEventDto.setInternalToken("oldInternalToken"); + + EventDto receivedEventDto = (EventDto) existingEventDto.clone(); + receivedEventDto.setExternalId("newExternalId"); + receivedEventDto.setExternalToken("newExternalToken"); + receivedEventDto.setInternalToken("newInternalToken"); + + getReceivedDataProcessorHelper().handleIgnoredProperties(receivedEventDto, existingEventDto); + + assertThat(receivedEventDto.getExternalId(), is("oldExternalId")); + assertThat(receivedEventDto.getExternalToken(), is("oldExternalToken")); + assertThat(receivedEventDto.getInternalToken(), is("oldInternalToken")); + } + + @Test + public void testIgnoredPropertiesAreOverwrittenWithNewValuesForEvent() throws CloneNotSupportedException { + + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN, Boolean.FALSE.toString()); + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + EventDto existingEventDto = creator.createEvent(officerReferenceDto); + existingEventDto.setDisease(Disease.CORONAVIRUS); + existingEventDto.setExternalId("oldExternalId"); + existingEventDto.setExternalToken("oldExternalToken"); + existingEventDto.setInternalToken("oldInternalToken"); + + EventDto receivedEventDto = (EventDto) existingEventDto.clone(); + receivedEventDto.setExternalId("newExternalId"); + receivedEventDto.setExternalToken("newExternalToken"); + receivedEventDto.setInternalToken("newInternalToken"); + + getReceivedDataProcessorHelper().handleIgnoredProperties(receivedEventDto, existingEventDto); + + assertThat(receivedEventDto.getExternalId(), is("newExternalId")); + assertThat(receivedEventDto.getExternalToken(), is("newExternalToken")); + assertThat(receivedEventDto.getInternalToken(), is("newInternalToken")); + } + + @Test + public void testIgnoredPropertiesAreNotOverwrittenWithNewValuesForPerson() throws CloneNotSupportedException { + + PersonDto existingPersonDto = creator.createPerson(); + existingPersonDto.setAdditionalDetails("oldAdditionalDetails"); + existingPersonDto.setExternalId("oldExternalId"); + existingPersonDto.setExternalToken("oldExternalToken"); + existingPersonDto.setInternalToken("oldInternalToken"); + + PersonDto receivedPersonDto = (PersonDto) existingPersonDto.clone(); + existingPersonDto.setAdditionalDetails("newAdditionalDetails"); + existingPersonDto.setExternalId("newExternalId"); + existingPersonDto.setExternalToken("newExternalToken"); + existingPersonDto.setInternalToken("newInternalToken"); + + getReceivedDataProcessorHelper().handleIgnoredProperties(receivedPersonDto, existingPersonDto); + + assertThat(receivedPersonDto.getAdditionalDetails(), is("newAdditionalDetails")); + assertThat(receivedPersonDto.getExternalId(), is("newExternalId")); + assertThat(receivedPersonDto.getExternalToken(), is("newExternalToken")); + assertThat(receivedPersonDto.getInternalToken(), is("newInternalToken")); + } + + @Test + public void testIgnoredPropertiesAreOverwrittenWithNewValuesForPerson() throws CloneNotSupportedException { + + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN, Boolean.FALSE.toString()); + + PersonDto existingPersonDto = creator.createPerson(); + existingPersonDto.setAdditionalDetails("oldAdditionalDetails"); + existingPersonDto.setExternalId("oldExternalId"); + existingPersonDto.setExternalToken("oldExternalToken"); + existingPersonDto.setInternalToken("oldInternalToken"); + + PersonDto receivedPersonDto = (PersonDto) existingPersonDto.clone(); + receivedPersonDto.setAdditionalDetails("newAdditionalDetails"); + receivedPersonDto.setExternalId("newExternalId"); + receivedPersonDto.setExternalToken("newExternalToken"); + receivedPersonDto.setInternalToken("newInternalToken"); + + getReceivedDataProcessorHelper().handleIgnoredProperties(receivedPersonDto, existingPersonDto); + + assertThat(receivedPersonDto.getAdditionalDetails(), is("newAdditionalDetails")); + assertThat(receivedPersonDto.getExternalId(), is("newExternalId")); + assertThat(receivedPersonDto.getExternalToken(), is("newExternalToken")); + assertThat(receivedPersonDto.getInternalToken(), is("newInternalToken")); + } + + @Test + public void testIgnoredPropertiesAreNotOverwrittenWithNewValuesForImmunization() throws CloneNotSupportedException { + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + PersonReferenceDto personReferenceDto = creator.createPerson().toReference(); + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + ImmunizationDto existingImmunizationDto = creator.createImmunization(Disease.CORONAVIRUS, personReferenceDto, officerReferenceDto, + ImmunizationStatus.ACQUIRED, + MeansOfImmunization.VACCINATION, + ImmunizationManagementStatus.COMPLETED, + rdcf, + DateHelper.subtractDays(new Date(), 10), + DateHelper.subtractDays(new Date(), 5), + DateHelper.subtractDays(new Date(), 1), + null); + existingImmunizationDto.setAdditionalDetails("oldAdditionalDetails"); + existingImmunizationDto.setExternalId("oldExternalId"); + + ImmunizationDto receivedImmunizationDto = (ImmunizationDto) existingImmunizationDto.clone(); + receivedImmunizationDto.setAdditionalDetails("newAdditionalDetails"); + receivedImmunizationDto.setExternalId("newExternalId"); + + getReceivedDataProcessorHelper().handleIgnoredProperties(receivedImmunizationDto, existingImmunizationDto); + + assertThat(receivedImmunizationDto.getAdditionalDetails(), is("oldAdditionalDetails")); + assertThat(receivedImmunizationDto.getExternalId(), is("oldExternalId")); + + } + + @Test + public void testIgnoredPropertiesAreOverwrittenWithNewValuesForImmunization() throws CloneNotSupportedException { + + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN, Boolean.FALSE.toString()); + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + PersonReferenceDto personReferenceDto = creator.createPerson().toReference(); + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + ImmunizationDto existingImmunizationDto = creator.createImmunization(Disease.CORONAVIRUS, personReferenceDto, officerReferenceDto, + ImmunizationStatus.ACQUIRED, + MeansOfImmunization.VACCINATION, + ImmunizationManagementStatus.COMPLETED, + rdcf, + DateHelper.subtractDays(new Date(), 10), + DateHelper.subtractDays(new Date(), 5), + DateHelper.subtractDays(new Date(), 1), + null); + existingImmunizationDto.setAdditionalDetails("oldAdditionalDetails"); + existingImmunizationDto.setExternalId("oldExternalId"); + + ImmunizationDto receivedImmunizationDto = (ImmunizationDto) existingImmunizationDto.clone(); + receivedImmunizationDto.setAdditionalDetails("newAdditionalDetails"); + receivedImmunizationDto.setExternalId("newExternalId"); + + getReceivedDataProcessorHelper().handleIgnoredProperties(receivedImmunizationDto, existingImmunizationDto); + + assertThat(receivedImmunizationDto.getAdditionalDetails(), is("newAdditionalDetails")); + assertThat(receivedImmunizationDto.getExternalId(), is("newExternalId")); + + } + +} diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasCaseFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasCaseFacadeEjbTest.java index 5cd4e5d5b18..1ddac258ccf 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasCaseFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasCaseFacadeEjbTest.java @@ -33,6 +33,9 @@ import javax.ws.rs.core.Response; +import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; +import de.symeda.sormas.backend.sormastosormas.SormasToSormasFacadeTest; +import de.symeda.sormas.backend.sormastosormas.share.ShareRequestData; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentMatchers; @@ -523,6 +526,8 @@ public void testShareCaseWithPseudonymizePersonalData() throws SormasToSormasExc options.setOrganization(new SormasServerDescriptor(SECOND_SERVER_ID)); options.setPseudonymizePersonalData(true); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + Mockito .when( MockProducer.getSormasToSormasClient() @@ -565,6 +570,8 @@ public void testShareCaseWithPseudonymizeSensitiveData() throws SormasToSormasEx options.setOrganization(new SormasServerDescriptor(SECOND_SERVER_ID)); options.setPseudonymizeSensitiveData(true); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + Mockito .when( MockProducer.getSormasToSormasClient() @@ -966,6 +973,8 @@ public void testSyncCases() throws SormasToSormasValidationException, SormasToSo SormasToSormasEncryptedDataDto encryptedData = encryptShareData(new SyncDataDto(shareData, new ShareTreeCriteria(caze.getUuid(), null, false))); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + Mockito .when( MockProducer.getManagedScheduledExecutorService() diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasContactFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasContactFacadeEjbTest.java index 548a1d0d071..c0dbc951c4e 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasContactFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasContactFacadeEjbTest.java @@ -30,6 +30,9 @@ import javax.ws.rs.core.Response; +import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; +import de.symeda.sormas.backend.sormastosormas.SormasToSormasFacadeTest; +import de.symeda.sormas.backend.sormastosormas.entities.SyncDataDto; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentMatchers; @@ -409,6 +412,8 @@ public void testSyncContacts() throws SormasToSormasValidationException, SormasT SormasToSormasEncryptedDataDto encryptedData = encryptShareData(new SyncDataDto(shareData, new ShareTreeCriteria(contact.getUuid(), null, false))); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + Mockito .when( MockProducer.getManagedScheduledExecutorService() diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasLabMessageFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasLabMessageFacadeEjbTest.java index 142655267d8..d7afc81a99e 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasLabMessageFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasLabMessageFacadeEjbTest.java @@ -34,8 +34,6 @@ import de.symeda.sormas.api.labmessage.LabMessageDto; import de.symeda.sormas.api.labmessage.LabMessageStatus; -import de.symeda.sormas.api.sample.PathogenTestResultType; -import de.symeda.sormas.api.sample.PathogenTestType; import de.symeda.sormas.api.sample.SampleMaterial; import de.symeda.sormas.api.sormastosormas.SormasServerDescriptor; import de.symeda.sormas.api.sormastosormas.SormasToSormasEncryptedDataDto; @@ -81,7 +79,7 @@ public void testSendLabMessage() throws SormasToSormasException { } @Test - public void testSaveLabMessages() throws JsonProcessingException, SormasToSormasException, SormasToSormasValidationException { + public void testSaveLabMessages() throws SormasToSormasException, SormasToSormasValidationException { LabMessageDto labMessage = LabMessageDto.build(); Date dateNow = new Date(); setLabMessageFields(labMessage, dateNow); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/share/ShareDataBuilderHelperTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/share/ShareDataBuilderHelperTest.java new file mode 100644 index 00000000000..27948d7cb58 --- /dev/null +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/share/ShareDataBuilderHelperTest.java @@ -0,0 +1,307 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2021 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.symeda.sormas.backend.sormastosormas.share; + +import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.caze.CaseDataDto; +import de.symeda.sormas.api.contact.ContactDto; +import de.symeda.sormas.api.event.EventDto; +import de.symeda.sormas.api.immunization.ImmunizationDto; +import de.symeda.sormas.api.immunization.ImmunizationManagementStatus; +import de.symeda.sormas.api.immunization.ImmunizationStatus; +import de.symeda.sormas.api.immunization.MeansOfImmunization; +import de.symeda.sormas.api.person.PersonDto; +import de.symeda.sormas.api.person.PersonReferenceDto; +import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; +import de.symeda.sormas.api.user.UserReferenceDto; +import de.symeda.sormas.api.user.UserRole; +import de.symeda.sormas.api.utils.DateHelper; +import de.symeda.sormas.backend.AbstractBeanTest; +import de.symeda.sormas.backend.MockProducer; +import de.symeda.sormas.backend.TestDataCreator; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.Date; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +/** + * @author Alex Vidrean + * @since 11-Oct-21 + */ + +@RunWith(MockitoJUnitRunner.class) +public class ShareDataBuilderHelperTest extends AbstractBeanTest { + + @Test + public void testClearIgnoredPropertiesForCase() { + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + PersonDto personDto = creator.createPerson(); + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + CaseDataDto caseDataDto = creator.createCase(officerReferenceDto, rdcf, dto -> { + dto.setPerson(personDto.toReference()); + dto.setSurveillanceOfficer(officerReferenceDto); + dto.setClassificationUser(officerReferenceDto); + dto.setAdditionalDetails("additionalDetails"); + dto.setExternalID("externalId"); + dto.setExternalToken("externalToken"); + dto.setInternalToken("internalToken"); + }); + + getShareDataBuilderHelper().clearIgnoredProperties(caseDataDto); + + assertThat(caseDataDto.getAdditionalDetails(), is(nullValue())); + assertThat(caseDataDto.getExternalID(), is(nullValue())); + assertThat(caseDataDto.getExternalToken(), is(nullValue())); + assertThat(caseDataDto.getInternalToken(), is(nullValue())); + assertThat(caseDataDto.getPerson(), not(nullValue())); + } + + @Test + public void testDoNotClearIgnoredPropertiesForCase() { + + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN, Boolean.FALSE.toString()); + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + PersonDto personDto = creator.createPerson(); + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + CaseDataDto caseDataDto = creator.createCase(officerReferenceDto, rdcf, dto -> { + dto.setPerson(personDto.toReference()); + dto.setSurveillanceOfficer(officerReferenceDto); + dto.setClassificationUser(officerReferenceDto); + dto.setAdditionalDetails("additionalDetails"); + dto.setExternalID("externalId"); + dto.setExternalToken("externalToken"); + dto.setInternalToken("internalToken"); + }); + + getShareDataBuilderHelper().clearIgnoredProperties(caseDataDto); + + assertThat(caseDataDto.getPerson(), not(nullValue())); + assertThat(caseDataDto.getAdditionalDetails(), is("additionalDetails")); + assertThat(caseDataDto.getExternalID(), is("externalId")); + assertThat(caseDataDto.getExternalToken(), is("externalToken")); + assertThat(caseDataDto.getInternalToken(), is("internalToken")); + } + + @Test + public void testClearIgnoredPropertiesForContact() { + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + PersonReferenceDto personReferenceDto = creator.createPerson().toReference(); + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + ContactDto contactDto = creator.createContact(officerReferenceDto, personReferenceDto); + contactDto.setAdditionalDetails("additionalDetails"); + contactDto.setExternalID("externalId"); + contactDto.setExternalToken("externalToken"); + contactDto.setInternalToken("internalToken"); + + getShareDataBuilderHelper().clearIgnoredProperties(contactDto); + + assertThat(contactDto.getPerson(), not(nullValue())); + assertThat(contactDto.getAdditionalDetails(), is(nullValue())); + assertThat(contactDto.getExternalID(), is(nullValue())); + assertThat(contactDto.getExternalToken(), is(nullValue())); + assertThat(contactDto.getInternalToken(), is(nullValue())); + } + + @Test + public void testDoNotClearIgnoredPropertiesForContact() { + + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN, Boolean.FALSE.toString()); + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + PersonReferenceDto personReferenceDto = creator.createPerson().toReference(); + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + ContactDto contactDto = creator.createContact(officerReferenceDto, personReferenceDto); + contactDto.setAdditionalDetails("additionalDetails"); + contactDto.setExternalID("externalId"); + contactDto.setExternalToken("externalToken"); + contactDto.setInternalToken("internalToken"); + + getShareDataBuilderHelper().clearIgnoredProperties(contactDto); + + assertThat(contactDto.getPerson(), not(nullValue())); + assertThat(contactDto.getAdditionalDetails(), is("additionalDetails")); + assertThat(contactDto.getExternalID(), is("externalId")); + assertThat(contactDto.getExternalToken(), is("externalToken")); + assertThat(contactDto.getInternalToken(), is("internalToken")); + } + + @Test + public void testClearIgnoredPropertiesForEvent() { + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + EventDto eventDto = creator.createEvent(officerReferenceDto); + eventDto.setDisease(Disease.CORONAVIRUS); + eventDto.setExternalId("externalId"); + eventDto.setExternalToken("externalToken"); + eventDto.setInternalToken("internalToken"); + + getShareDataBuilderHelper().clearIgnoredProperties(eventDto); + + assertThat(eventDto.getDisease(), not(nullValue())); + assertThat(eventDto.getExternalId(), is(nullValue())); + assertThat(eventDto.getExternalToken(), is(nullValue())); + assertThat(eventDto.getInternalToken(), is(nullValue())); + } + + @Test + public void testDoNotClearIgnoredPropertiesForEvent() { + + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN, Boolean.FALSE.toString()); + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + EventDto eventDto = creator.createEvent(officerReferenceDto); + eventDto.setDisease(Disease.CORONAVIRUS); + eventDto.setExternalId("externalId"); + eventDto.setExternalToken("externalToken"); + eventDto.setInternalToken("internalToken"); + + getShareDataBuilderHelper().clearIgnoredProperties(eventDto); + + assertThat(eventDto.getDisease(), not(nullValue())); + assertThat(eventDto.getExternalId(), is("externalId")); + assertThat(eventDto.getExternalToken(), is("externalToken")); + assertThat(eventDto.getInternalToken(), is("internalToken")); + } + + @Test + public void testClearIgnoredPropertiesForPerson() { + + PersonDto personDto = creator.createPerson(); + personDto.setAdditionalDetails("additionalDetails"); + personDto.setExternalId("externalId"); + personDto.setExternalToken("externalToken"); + personDto.setInternalToken("internalToken"); + + getShareDataBuilderHelper().clearIgnoredProperties(personDto); + + assertThat(personDto.getFirstName(), not(nullValue())); + assertThat(personDto.getExternalId(), is(nullValue())); + assertThat(personDto.getExternalToken(), is(nullValue())); + assertThat(personDto.getInternalToken(), is(nullValue())); + } + + @Test + public void testDoNotClearIgnoredPropertiesForPerson() { + + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN, Boolean.FALSE.toString()); + + PersonDto personDto = creator.createPerson(); + personDto.setAdditionalDetails("additionalDetails"); + personDto.setExternalId("externalId"); + personDto.setExternalToken("externalToken"); + personDto.setInternalToken("internalToken"); + + getShareDataBuilderHelper().clearIgnoredProperties(personDto); + + assertThat(personDto.getFirstName(), not(nullValue())); + assertThat(personDto.getAdditionalDetails(), is("additionalDetails")); + assertThat(personDto.getExternalId(), is("externalId")); + assertThat(personDto.getExternalToken(), is("externalToken")); + assertThat(personDto.getInternalToken(), is("internalToken")); + } + + @Test + public void testClearIgnoredPropertiesForImmunization() { + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + PersonReferenceDto personReferenceDto = creator.createPerson().toReference(); + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + ImmunizationDto immunizationDto = creator.createImmunization(Disease.CORONAVIRUS, personReferenceDto, officerReferenceDto, + ImmunizationStatus.ACQUIRED, + MeansOfImmunization.VACCINATION, + ImmunizationManagementStatus.COMPLETED, + rdcf, + DateHelper.subtractDays(new Date(), 10), + DateHelper.subtractDays(new Date(), 5), + DateHelper.subtractDays(new Date(), 1), + null); + + immunizationDto.setAdditionalDetails("additionalDetails"); + immunizationDto.setExternalId("externalId"); + + getShareDataBuilderHelper().clearIgnoredProperties(immunizationDto); + + assertThat(immunizationDto.getAdditionalDetails(), is(nullValue())); + assertThat(immunizationDto.getExternalId(), is(nullValue())); + assertThat(immunizationDto.getPerson(), not(nullValue())); + } + + @Test + public void testDoNotClearIgnoredPropertiesForImmunization() { + + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_ADDITIONAL_DETAILS, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_ID, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_EXTERNAL_TOKEN, Boolean.FALSE.toString()); + MockProducer.getProperties().setProperty(SormasToSormasConfig.SORMAS2SORMAS_IGNORE_INTERNAL_TOKEN, Boolean.FALSE.toString()); + + TestDataCreator.RDCF rdcf = creator.createRDCF(); + + PersonReferenceDto personReferenceDto = creator.createPerson().toReference(); + UserReferenceDto officerReferenceDto = creator.createUser(rdcf, UserRole.SURVEILLANCE_OFFICER).toReference(); + ImmunizationDto immunizationDto = creator.createImmunization(Disease.CORONAVIRUS, personReferenceDto, officerReferenceDto, + ImmunizationStatus.ACQUIRED, + MeansOfImmunization.VACCINATION, + ImmunizationManagementStatus.COMPLETED, + rdcf, + DateHelper.subtractDays(new Date(), 10), + DateHelper.subtractDays(new Date(), 5), + DateHelper.subtractDays(new Date(), 1), + null); + + immunizationDto.setAdditionalDetails("additionalDetails"); + immunizationDto.setExternalId("externalId"); + + getShareDataBuilderHelper().clearIgnoredProperties(immunizationDto); + + assertThat(immunizationDto.getAdditionalDetails(), is("additionalDetails")); + assertThat(immunizationDto.getExternalId(), is("externalId")); + assertThat(immunizationDto.getPerson(), not(nullValue())); + } + +} diff --git a/sormas-base/setup/sormas.properties b/sormas-base/setup/sormas.properties index 51f00529f41..843331d7307 100644 --- a/sormas-base/setup/sormas.properties +++ b/sormas-base/setup/sormas.properties @@ -1,6 +1,6 @@ ############################################################################### # SORMAS® - Surveillance Outbreak Response Management & Analysis System -# Copyright © 2016-2018 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) +# Copyright © 2016-2021 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -308,10 +308,14 @@ app.url= # The etcd key prefix which is used to store s2s related information #sormas2sormas.etcd.keyPrefix= -# Determines whether external tokens are retained when sharing entities. +# Control which values are ignored when shared / overwritten trough S2S +# This are applied to all entities shared trough S2S # Default: true # Possible Values: true, false -#sormas2sormas.retainCaseExternalToken=true +#sormas2sormas.ignoreProperty.additionalDetails=true +#sormas2sormas.ignoreProperty.externalId=true +#sormas2sormas.ignoreProperty.externalToken=true +#sormas2sormas.ignoreProperty.internalToken=true # SURVNET INTERFACE @@ -356,4 +360,4 @@ app.url= # JNDI name of the DEMIS adapter that is connected to this SORMAS instance. Specifies where additionally deployed modules are stored. # Example: java:global/sormas-demis-adapter/DemisLabResultsAdapter -#interface.demis.jndiName= +#interface.demis.jndiName= \ No newline at end of file