branch feature/7739 created (now 83695e3)
This is an automated email from the git hooks/post-receive script. New change to branch feature/7739 in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git at 83695e3 Introduction des deux services à utiliser pour effectuer la synchronisation unidirectionnelle de référentiel (See #7739) This branch includes the following new commits: new 83695e3 Introduction des deux services à utiliser pour effectuer la synchronisation unidirectionnelle de référentiel (See #7739) The 1 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 83695e353f3c94d6de13c0741439e3bb76a4015b Author: Tony CHEMIT <chemit@codelutin.com> Date: Tue Jun 28 10:47:44 2016 +0200 Introduction des deux services à utiliser pour effectuer la synchronisation unidirectionnelle de référentiel (See #7739) -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/7739 in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit 83695e353f3c94d6de13c0741439e3bb76a4015b Author: Tony CHEMIT <chemit@codelutin.com> Date: Tue Jun 28 10:47:44 2016 +0200 Introduction des deux services à utiliser pour effectuer la synchronisation unidirectionnelle de référentiel (See #7739) --- .../actions/synchro/LocalReferentialStates.java | 73 +++++++++++++ .../actions/synchro/RemoteReferentialDiff.java | 78 ++++++++++++++ ...ectionalReferentialSynchronizeLocalService.java | 47 ++++++++ ...ctionalReferentialSynchronizeRemoteService.java | 24 +++++ ...nalReferentialSynchronizeLocalServiceTopia.java | 118 +++++++++++++++++++++ ...alReferentialSynchronizeRemoteServiceTopia.java | 92 ++++++++++++++++ 6 files changed, 432 insertions(+) diff --git a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/LocalReferentialStates.java b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/LocalReferentialStates.java new file mode 100644 index 0000000..d770f36 --- /dev/null +++ b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/LocalReferentialStates.java @@ -0,0 +1,73 @@ +package fr.ird.observe.services.service.actions.synchro; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.TreeMap; + +/** + * Contient les états des référentiels de la source locale à synchroniser. + * + * Created on 27/06/16. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 5.0 + */ +public class LocalReferentialStates implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * Contient pour chaque type de référentiel la version de chaque référentiel indexé par son nom. + */ + private final Map<String, Map<String, Long>> referentialVersionsByType; + + /** + * Contient la liste des identifiants des référentiels désactivés indexé par son nom. + */ + private final Multimap<String, String> referentialDisabledIdsByType; + + public LocalReferentialStates() { + this.referentialVersionsByType = new TreeMap<>(); + this.referentialDisabledIdsByType = ArrayListMultimap.create(); + } + + /** + * @param referentialName le nom de référentiel + * @return la collection des versions de référentiel du nom demandé. + */ + public Map<String, Long> getReferentialVersions(String referentialName) { + return referentialVersionsByType.get(referentialName); + } + + /** + * @param referentialName le nom de référentiel + * @return la collection des identifiants de référentiel désactivés du nom demandé. + */ + public Collection<String> getReferentialDisabled(String referentialName) { + return referentialDisabledIdsByType.get(referentialName); + } + + /** + * Pour ajouter un référentiel. + * + * @param referentialName le nom du référentiel + * @param id l'identifiant du référentiel à ajouter + * @param version la version du référentiel à ajouter + * @param disabled {@code true} si le référentiel est désactivé + */ + void addReferentialVersion(String referentialName, String id, long version, boolean disabled) { + Map<String, Long> map = referentialVersionsByType.get(referentialName); + if (map == null) { + map = new TreeMap<>(); + referentialVersionsByType.put(referentialName, map); + } + map.put(id, version); + if (disabled) { + referentialDisabledIdsByType.put(referentialName, id); + } + } +} diff --git a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/RemoteReferentialDiff.java b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/RemoteReferentialDiff.java new file mode 100644 index 0000000..2aa4b8d --- /dev/null +++ b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/RemoteReferentialDiff.java @@ -0,0 +1,78 @@ +package fr.ird.observe.services.service.actions.synchro; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import fr.ird.observe.services.dto.referential.ReferentialDto; +import fr.ird.observe.services.dto.referential.ReferentialReference; + +import java.io.Serializable; +import java.util.Collection; + +/** + * Contient le différentiel de référentiels calculé sur la source centrale à partir des états de la source à synchroniser. + * + * Created on 27/06/16. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 5.0 + */ +public class RemoteReferentialDiff implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * Les référentiels à ajouter (indexé par nom de référentiel). + */ + private final Multimap<String, ReferentialDto> referentialsToAdd; + /** + * Les référentiels à mettre à jour (indexé par nom de référentiel). + */ + private final Multimap<String, ReferentialDto> referentialsToUpdate; + /** + * Les références de référentiels à supprimer (indexé par nom de référentiel). + */ + private final Multimap<String, ReferentialReference> referentialsToRemove; + /** + * Les références de référentiels à changer (ils sont devenus obsolètes) (indexé par nom de référentiel). + */ + private final Multimap<String, ReferentialReference> referentialsToFix; + + public RemoteReferentialDiff() { + referentialsToAdd = ArrayListMultimap.create(); + referentialsToUpdate = ArrayListMultimap.create(); + referentialsToRemove = ArrayListMultimap.create(); + referentialsToFix = ArrayListMultimap.create(); + } + + public Collection<ReferentialDto> getReferentialsToAdd(String referentialName) { + return referentialsToAdd.get(referentialName); + } + + public Collection<ReferentialDto> getReferentialsToUpdate(String referentialName) { + return referentialsToUpdate.get(referentialName); + } + + public Collection<ReferentialReference> getReferentialsToRemove(String referentialName) { + return referentialsToRemove.get(referentialName); + } + + public Collection<ReferentialReference> getReferentialsToFix(String referentialName) { + return referentialsToFix.get(referentialName); + } + + void addReferentialToAdd(String referentialName, ReferentialDto referentialDto) { + referentialsToAdd.put(referentialName, referentialDto); + } + + void addReferentialToUpdate(String referentialName, ReferentialDto referentialDto) { + referentialsToUpdate.put(referentialName, referentialDto); + } + + void addReferentialToDelete(String referentialName, ReferentialReference referentialReference) { + referentialsToRemove.put(referentialName, referentialReference); + } + + void addReferentialToFix(String entityName, ReferentialReference referentialReference) { + referentialsToFix.put(entityName, referentialReference); + } +} diff --git a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalService.java b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalService.java new file mode 100644 index 0000000..3c3f570 --- /dev/null +++ b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalService.java @@ -0,0 +1,47 @@ +package fr.ird.observe.services.service.actions.synchro; + +import fr.ird.observe.services.dto.referential.ReferentialReferenceSet; +import fr.ird.observe.services.spi.ReadReferentialPermission; + +import java.util.Collection; +import java.util.Set; + +/** + * Service pour effectuer une synchronisation de référentiel unidirectionnelle du côte de la source centrale. + * + * Created on 27/06/16. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 5.0 + */ +public interface UnidirectionalReferentialSynchronizeLocalService { + + /** + * Récupération sur la source à synchroniser des versions de ses référentiels. + * + * @return les versions de tous les référentiels de la base à synchroniser. + */ + @ReadReferentialPermission + LocalReferentialStates getLocalSourceReferentialStates(); + + /** + * Pour un référentiel d'un type donné (son nom est donné), détecte les référentiels dont + * les identifiants sont passés en paramètres qui sont réellement utilisés dans la source locale. + * + * @param referentialName le nom du référentiel + * @param ids l'identifiant du référentiel dont on recherche le nombre d'utilisation + * @return les identifiants des référentiels passés en paramètres qui sont réellement utilisés dans la source locale. + */ + @ReadReferentialPermission + Set<String> filterIdsUsedInLocalSource(String referentialName, Collection<String> ids); + + /** + * Pour récupérer un ensemble de référentiels non désactivés pour un type donné (et ceci afin de remplacer + * un référentiel de même type supprimé ou désactivé). + * + * @param referentialName le nom du référentiel + * @return l'ensemble des référentiels non désactivés du type demandé + */ + @ReadReferentialPermission + ReferentialReferenceSet getLocalSourceEnabledReferenceSet(String referentialName); +} diff --git a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeRemoteService.java b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeRemoteService.java new file mode 100644 index 0000000..66983a3 --- /dev/null +++ b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeRemoteService.java @@ -0,0 +1,24 @@ +package fr.ird.observe.services.service.actions.synchro; + +import fr.ird.observe.services.spi.ReadReferentialPermission; + +/** + * Service pour effectuer une synchronisation de référentiel unidirectionnelle. + * + * Created on 27/06/16. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 5.0 + */ +public interface UnidirectionalReferentialSynchronizeRemoteService { + + /** + * Récupération sur la source centrale du différentiel des référentiel. + * + * @param localReferentialStates les états de référentiel de la source à synchroniser. + * @return le résultat de calcul de différentiel de référentiel. + */ + @ReadReferentialPermission + RemoteReferentialDiff getReferentialDifferential(LocalReferentialStates localReferentialStates); + +} diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalServiceTopia.java b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalServiceTopia.java new file mode 100644 index 0000000..69c87f7 --- /dev/null +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeLocalServiceTopia.java @@ -0,0 +1,118 @@ +package fr.ird.observe.services.service.actions.synchro; + +import fr.ird.observe.ObserveEntityEnum; +import fr.ird.observe.ObserveTopiaPersistenceContext; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.constants.ReferenceStatusPersist; +import fr.ird.observe.entities.referentiel.ObserveReferentialEntity; +import fr.ird.observe.services.ObserveServiceTopia; +import fr.ird.observe.services.binder.BinderEngine; +import fr.ird.observe.services.dto.referential.ReferentialDto; +import fr.ird.observe.services.dto.referential.ReferentialReferenceSet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.TopiaDao; +import org.nuiton.topia.persistence.TopiaEntity; + +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Created on 27/06/16. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 5.0 + */ +public class UnidirectionalReferentialSynchronizeLocalServiceTopia extends ObserveServiceTopia implements UnidirectionalReferentialSynchronizeLocalService { + + /** Logger. */ + private static final Log log = LogFactory.getLog(UnidirectionalReferentialSynchronizeLocalServiceTopia.class); + + @Override + public LocalReferentialStates getLocalSourceReferentialStates() { + + if (log.isTraceEnabled()) { + log.trace("getLocalSourceReferentialStates()"); + } + + LocalReferentialStates localReferentialStates = new LocalReferentialStates(); + for (ObserveEntityEnum referenceEntity : Entities.REFERENCE_ENTITIES) { + Class entityType = referenceEntity.getContract(); + getLocalSourceReferentialVersions0(referenceEntity.name(), entityType, localReferentialStates); + } + return localReferentialStates; + + } + + @Override + public Set<String> filterIdsUsedInLocalSource(String referentialName, Collection<String> ids) { + + if (log.isTraceEnabled()) { + log.trace("filterIdsUsedInLocalSource(" + referentialName + ", " + ids + ")"); + } + + ObserveEntityEnum entityEnum = ObserveEntityEnum.valueOf(referentialName); + Class entityType = entityEnum.getContract(); + Set<String> result = new LinkedHashSet<>(); + for (String id : ids) { + int count = countUsage0(entityType, id); + if (count > 0) { + result.add(id); + } + } + return result; + + } + + @Override + public ReferentialReferenceSet getLocalSourceEnabledReferenceSet(String referentialName) { + + if (log.isTraceEnabled()) { + log.trace("getLocalSourceEnabledReferenceSet(" + referentialName + ")"); + } + + ObserveEntityEnum entityEnum = ObserveEntityEnum.valueOf(referentialName); + Class entityType = entityEnum.getContract(); + Class dtoType = BinderEngine.get().getReferentialDtoType(entityType); + ReferentialReferenceSet result = getLocalSourceEnabledReferenceSet0(entityType, dtoType); + return result; + + } + + private <E extends ObserveReferentialEntity> void getLocalSourceReferentialVersions0(String entityName, Class<E> entityType, LocalReferentialStates localReferentialStates) { + + TopiaDao<E> dao = getTopiaPersistenceContext().getDao(entityType); + for (E e : dao) { + localReferentialStates.addReferentialVersion(entityName, e.getTopiaId(), e.getTopiaVersion(), e.isDisabled()); + } + + } + + private <E extends ObserveReferentialEntity> int countUsage0(Class<E> entityType, String id) { + + TopiaDao<E> dao = getTopiaPersistenceContext().getDao(entityType); + E e = dao.forTopiaIdEquals(id).findUnique(); + Map<Class<? extends TopiaEntity>, List<? extends TopiaEntity>> allUsages = dao.findAllUsages(e); + int count = 0; + for (List<? extends TopiaEntity> entities : allUsages.values()) { + count += entities.size(); + } + return count; + + } + + private <E extends ObserveReferentialEntity, R extends ReferentialDto> ReferentialReferenceSet<R> getLocalSourceEnabledReferenceSet0(Class<E> entityType, Class<R> dtoType) { + + ObserveTopiaPersistenceContext persistenceContext = getTopiaPersistenceContext(); + TopiaDao<E> dao = persistenceContext.getDao(entityType); + List<E> entities = dao.forEquals(ObserveReferentialEntity.PROPERTY_STATUS, ReferenceStatusPersist.enabled).findAll(); + ReferentialReferenceSet<R> result = toReferentialReferenceSet(dtoType, entities, null); + return result; + + } + + +} diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeRemoteServiceTopia.java b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeRemoteServiceTopia.java new file mode 100644 index 0000000..3d9cba1 --- /dev/null +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/UnidirectionalReferentialSynchronizeRemoteServiceTopia.java @@ -0,0 +1,92 @@ +package fr.ird.observe.services.service.actions.synchro; + +import fr.ird.observe.ObserveEntityEnum; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.referentiel.ObserveReferentialEntity; +import fr.ird.observe.services.ObserveServiceTopia; +import fr.ird.observe.services.binder.BinderEngine; +import fr.ird.observe.services.dto.constants.ReferentialLocale; +import fr.ird.observe.services.dto.referential.ReferentialDto; +import fr.ird.observe.services.dto.referential.ReferentialReference; +import org.nuiton.topia.persistence.TopiaDao; + +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Created on 27/06/16. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 5.0 + */ +public class UnidirectionalReferentialSynchronizeRemoteServiceTopia extends ObserveServiceTopia implements UnidirectionalReferentialSynchronizeRemoteService { + + @Override + public RemoteReferentialDiff getReferentialDifferential(LocalReferentialStates localReferentialStates) { + + RemoteReferentialDiff result = new RemoteReferentialDiff(); + for (ObserveEntityEnum referenceEntity : Entities.REFERENCE_ENTITIES) { + Class entityType = referenceEntity.getContract(); + getReferentialDifferential0(referenceEntity.name(), entityType, localReferentialStates, result); + } + return result; + + } + + private <E extends ObserveReferentialEntity> void getReferentialDifferential0(String entityName, Class<E> entityType, LocalReferentialStates localReferentialStates, RemoteReferentialDiff result) { + + ReferentialLocale referentialLocale = getReferentialLocale(); + BinderEngine binderEngine = BinderEngine.get(); + Class<ReferentialDto> referentialDtoType = binderEngine.getReferentialDtoType(entityType); + Map<String, Long> localReferentialVersions = localReferentialStates.getReferentialVersions(entityName); + Collection<String> localReferentialDisabled = localReferentialStates.getReferentialDisabled(entityName); + TopiaDao<E> dao = getTopiaPersistenceContext().getDao(entityType); + for (E centralReferentialEntity : dao) { + + String id = centralReferentialEntity.getTopiaId(); + Long localVersion = localReferentialVersions.get(id); + + if (localVersion == null) { + + // nouvelle entité + ReferentialDto dto = binderEngine.transformEntityToReferentialDto(referentialLocale, centralReferentialEntity); + result.addReferentialToAdd(entityName, dto); + continue; + } + + long centralVersion = centralReferentialEntity.getTopiaVersion(); + + if (centralVersion > localVersion) { + + // entité à mettre à jour + ReferentialDto dto = binderEngine.transformEntityToReferentialDto(referentialLocale, centralReferentialEntity); + result.addReferentialToUpdate(entityName, dto); + } + + if (centralReferentialEntity.isDisabled() && !localReferentialDisabled.contains(id)) { + + // entité qui passe en mode désactivé, il faudra que l'utilisateur la change + ReferentialReference<ReferentialDto> referentialReference = binderEngine.transformEntityToReferentialReferenceDto(referentialLocale, centralReferentialEntity); + result.addReferentialToFix(entityName, referentialReference); + } + + } + + // entités supprimées + Set<String> idsToDelete = new LinkedHashSet<>(localReferentialVersions.keySet()); + + List<String> centralIds = dao.findAllIds(); + idsToDelete.removeAll(centralIds); + + for (String id : idsToDelete) { + E e = dao.forTopiaIdEquals(id).findUnique(); + ReferentialReference<ReferentialDto> referentialReference = binderEngine.transformEntityToReferentialReferenceDto(referentialLocale, e); + result.addReferentialToDelete(entityName, referentialReference); + } + + } + +} -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
participants (1)
-
codelutin.com scm