From 4aa9166e7f83f33ef9d806f790e1ddb4f1627e8f Mon Sep 17 00:00:00 2001 From: gakin <gakin> Date: Sun, 29 Jan 2017 21:28:45 +0000 Subject: [PATCH] SSDM-4614 : OpenbisSync Vocabulary term cleanup + internalnameSpace property fix SVN: 37638 --- .../synchronizer/EntitySynchronizer.java | 21 ++++- .../synchronizer/MasterDataParser.java | 22 +++-- .../synchronizer/MasterDataSynchronizer.java | 80 ++++++++++++++----- 3 files changed, 89 insertions(+), 34 deletions(-) diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java index 4ed145a78d0..a1dd6caab80 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java @@ -146,6 +146,8 @@ public class EntitySynchronizer private final Set<String> blackListedDataSetCodes; + private MasterDataSynchronizer masterDataSyncronizer; + public EntitySynchronizer(IEncapsulatedOpenBISService service, String dataStoreCode, File storeRoot, Date lastSyncTimestamp, Set<String> dataSetsCodesToRetry, Set<String> blackListedDataSetCodes, DataSetProcessingContext context, SyncConfig config, Logger operationLog) @@ -189,6 +191,8 @@ public class EntitySynchronizer processDeletions(data); operationLog.info("registering master data"); + + // masterDataSyncronizer = new MasterDataSynchronizer(data.getMasterData()); // registerMasterData(data); AtomicEntityOperationDetailsBuilder builder = new AtomicEntityOperationDetailsBuilder(); @@ -224,9 +228,23 @@ public class EntitySynchronizer operationLog.info("start linking/un-linking container and component data sets"); establishDataSetRelationships(data.getDataSetsToProcess(), notRegisteredDataSets, physicalDSMap); + // cleanup(); + return data.getResourceListTimestamp(); } + private void cleanup() + { + operationLog.info("Cleaning up unused master data"); + try + { + masterDataSyncronizer.cleanupUnusedMasterData(); + } catch (Exception e) + { + operationLog.warn(e.getMessage()); + } + } + private void establishDataSetRelationships(Map<String, DataSetWithConnections> dataSetsToProcess, List<String> notRegisteredDataSets, Map<String, DataSetWithConnections> physicalDSMap) { @@ -422,8 +440,7 @@ public class EntitySynchronizer private void registerMasterData(ResourceListParserData data) { - MasterDataSynchronizer sync = new MasterDataSynchronizer(data.getMasterData()); - sync.synchronizeMasterData(); + masterDataSyncronizer.synchronizeMasterData(); } private void processDeletions(ResourceListParserData data) throws NoSuchAlgorithmException, UnsupportedEncodingException diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataParser.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataParser.java index 4ab55c835ec..65fb0e249c9 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataParser.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataParser.java @@ -41,6 +41,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType; @@ -205,7 +206,7 @@ public class MasterDataParser materialType.setDescription(getAttribute(materialTypeElement, "description")); materialTypes.put(materialType.getCode(), materialType); - parsePropertyAssignments(materialType, materialTypeElement.getElementsByTagName("propertyAssignments")); + parsePropertyAssignments(EntityKind.MATERIAL, materialType, materialTypeElement.getElementsByTagName("propertyAssignments")); } } } @@ -225,7 +226,7 @@ public class MasterDataParser expType.setDescription(getAttribute(expTypeElement, "description")); experimentTypes.put(expType.getCode(), expType); - parsePropertyAssignments(expType, expTypeElement.getElementsByTagName("propertyAssignments")); + parsePropertyAssignments(EntityKind.EXPERIMENT, expType, expTypeElement.getElementsByTagName("propertyAssignments")); } } } @@ -251,7 +252,7 @@ public class MasterDataParser sampleType.setGeneratedCodePrefix(getAttribute(sampleTypeElement, "generatedCodePrefix")); sampleTypes.put(sampleType.getCode(), sampleType); - parsePropertyAssignments(sampleType, sampleTypeElement.getElementsByTagName("propertyAssignments")); + parsePropertyAssignments(EntityKind.SAMPLE, sampleType, sampleTypeElement.getElementsByTagName("propertyAssignments")); } } } @@ -290,15 +291,16 @@ public class MasterDataParser dataSetType.setDeletionDisallow(Boolean.valueOf(getAttribute(dataSetTypeElement, "deletionDisallowed"))); dataSetTypes.put(dataSetType.getCode(), dataSetType); - parsePropertyAssignments(dataSetType, dataSetTypeElement.getElementsByTagName("propertyAssignments")); + parsePropertyAssignments(EntityKind.DATA_SET, dataSetType, dataSetTypeElement.getElementsByTagName("propertyAssignments")); } } } - private void parsePropertyAssignments(EntityType entityType, NodeList propertyAssignmentsNode) + private void parsePropertyAssignments(EntityKind entityKind, EntityType entityType, NodeList propertyAssignmentsNode) { if (propertyAssignmentsNode.getLength() == 1) { + List<NewETPTAssignment> list = new ArrayList<NewETPTAssignment>(); Element propertyAssignmentsElement = (Element) propertyAssignmentsNode.item(0); NodeList propertyAssignmentNodes = propertyAssignmentsElement.getElementsByTagName("propertyAssignment"); for (int i = 0; i < propertyAssignmentNodes.getLength(); i++) @@ -314,15 +316,9 @@ public class MasterDataParser assignment.setSection(getAttribute(propertyAssignmentElement, "section")); assignment.setOrdinal(Long.valueOf(getAttribute(propertyAssignmentElement, "ordinal"))); assignment.setShownInEditView(Boolean.valueOf(getAttribute(propertyAssignmentElement, "showInEdit"))); - - List<NewETPTAssignment> list = entityPropertyAssignments.get(entityType.getCode()); - if (list == null) - { - list = new ArrayList<NewETPTAssignment>(); - entityPropertyAssignments.put(entityType.getEntityKind().name(), entityType.getCode(), list); - } list.add(assignment); } + entityPropertyAssignments.put(entityType.getEntityKind().name(), entityType.getCode(), list); } } @@ -346,7 +342,7 @@ public class MasterDataParser newPropertyType.setInternalNamespace(Boolean.valueOf(getAttribute(propertyTypeElement, "internalNamespace"))); newPropertyType.setCode(CodeConverter.tryToBusinessLayer(code, newPropertyType.isInternalNamespace())); - propertyTypes.put(CodeConverter.tryToDatabase(code), newPropertyType); + propertyTypes.put(newPropertyType.getCode(), newPropertyType); if (dataTypeCode.equals(DataTypeCode.CONTROLLEDVOCABULARY)) { String vocabularyCode = getAttribute(propertyTypeElement, "vocabulary"); diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataSynchronizer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataSynchronizer.java index d57feaea6c2..3bd0f9d96c0 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataSynchronizer.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataSynchronizer.java @@ -56,18 +56,21 @@ public class MasterDataSynchronizer final ResourceListParserData.MasterData masterData; + final Map<TechId, List<VocabularyTerm>> vocabularyTermsToBeDeleted; + public MasterDataSynchronizer(ResourceListParserData.MasterData masterData) { String openBisServerUrl = ServiceProvider.getConfigProvider().getOpenBisServerUrl(); this.sessionToken = ServiceProvider.getOpenBISService().getSessionToken(); this.commonServer = ServiceFinderUtils.getCommonServer(sessionToken, openBisServerUrl); this.masterData = masterData; + vocabularyTermsToBeDeleted = new HashMap<TechId, List<VocabularyTerm>>(); } public void synchronizeMasterData() { MultiKeyMap<String, List<NewETPTAssignment>> propertyAssignmentsToProcess = masterData.getPropertyAssignmentsToProcess(); processVocabularies(masterData.getVocabulariesToProcess()); - // materials are registered but their property assignments are deferred untilafter property types are processed + // materials are registered but their property assignments are deferred until after property types are processed processEntityTypes(masterData.getMaterialTypesToProcess(), propertyAssignmentsToProcess); processPropertyTypes(masterData.getPropertyTypesToProcess()); processEntityTypes(masterData.getSampleTypesToProcess(), propertyAssignmentsToProcess); @@ -76,6 +79,15 @@ public class MasterDataSynchronizer processDeferredMaterialTypePropertyAssignments(propertyAssignmentsToProcess); } + public void cleanupUnusedMasterData() + { + for (TechId vocabularyId : vocabularyTermsToBeDeleted.keySet()) + { + commonServer.deleteVocabularyTerms(sessionToken, vocabularyId, vocabularyTermsToBeDeleted.get(vocabularyId), + Collections.<ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTermReplacement> emptyList()); + } + } + private void processDeferredMaterialTypePropertyAssignments(MultiKeyMap<String, List<NewETPTAssignment>> propertyAssignmentsToProcess) { List<? extends EntityType> existingEntityTypes = getExistingEntityTypes(EntityKind.MATERIAL); @@ -134,7 +146,6 @@ public class MasterDataSynchronizer List<VocabularyTerm> termsToBeAdded = new ArrayList<VocabularyTerm>(); List<VocabularyTerm> termsToBeUpdated = new ArrayList<VocabularyTerm>(); - List<VocabularyTerm> termsToBeDeleted = new ArrayList<VocabularyTerm>(); for (VocabularyTerm incomingTerm : incomingTerms) { String termCode = incomingTerm.getCode(); @@ -152,6 +163,7 @@ public class MasterDataSynchronizer } } + List<VocabularyTerm> termsToBeDeleted = new ArrayList<VocabularyTerm>(); for (VocabularyTerm term : existingVocabulary.getTerms()) { String termCode = term.getCode(); @@ -160,16 +172,17 @@ public class MasterDataSynchronizer termsToBeDeleted.add(term); } } + + // defer deletions of vocabulary terms until after the entities referencing the terms are synced + if (termsToBeDeleted.isEmpty() == false) + { + vocabularyTermsToBeDeleted.put(new TechId(existingVocabulary.getId()), termsToBeDeleted); + } commonServer.addVocabularyTerms(sessionToken, new TechId(existingVocabulary.getId()), termsToBeAdded, null, true); for (VocabularyTerm term : termsToBeUpdated) { commonServer.updateVocabularyTerm(sessionToken, term); } - if (termsToBeDeleted.isEmpty() == false) - { - commonServer.deleteVocabularyTerms(sessionToken, new TechId(existingVocabulary.getId()), termsToBeDeleted, - Collections.<ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTermReplacement> emptyList()); - } } private VocabularyTerm findTermInVocabulary(Vocabulary existingVocabulary, String termCode) @@ -236,20 +249,13 @@ public class MasterDataSynchronizer @SuppressWarnings("rawtypes") private void processPropertyAssignments(EntityType existingEntityType, - List<NewETPTAssignment> list) + List<NewETPTAssignment> incomingAssignmentsList) { - assert list != null : "Null assignments list"; - for (NewETPTAssignment newETPTAssignment : list) + assert incomingAssignmentsList != null : "Null assignments list"; + List<? extends EntityTypePropertyType> assignedPropertyTypes = existingEntityType.getAssignedPropertyTypes(); + for (NewETPTAssignment newETPTAssignment : incomingAssignmentsList) { - List<? extends EntityTypePropertyType> assignedPropertyTypes = existingEntityType.getAssignedPropertyTypes(); - boolean found = false; - for (EntityTypePropertyType entityTypePropertyType : assignedPropertyTypes) - { - if (entityTypePropertyType.getPropertyType().getCode().equals(newETPTAssignment.getPropertyTypeCode())) - { - found = true; - } - } + boolean found = findInExistingPropertyAssignments(newETPTAssignment, assignedPropertyTypes); if (found) { commonServer.updatePropertyTypeAssignment(sessionToken, newETPTAssignment); @@ -259,6 +265,42 @@ public class MasterDataSynchronizer commonServer.assignPropertyType(sessionToken, newETPTAssignment); } } + // remove property assignments that are no longer valid + for (EntityTypePropertyType etpt : assignedPropertyTypes) + { + if (findInIncomingPropertyAssignments(etpt, incomingAssignmentsList) == false) + { + commonServer.unassignPropertyType(sessionToken, existingEntityType.getEntityKind(), etpt.getPropertyType().getCode(), etpt + .getEntityType().getCode()); + } + } + } + + @SuppressWarnings("rawtypes") + private boolean findInIncomingPropertyAssignments(EntityTypePropertyType existingEtpt, List<NewETPTAssignment> incomingAssignmentsList) + { + for (NewETPTAssignment newETPTAssignment : incomingAssignmentsList) + { + if (newETPTAssignment.getPropertyTypeCode().equals(existingEtpt.getPropertyType().getCode())) + { + return true; + } + } + return false; + } + + @SuppressWarnings("rawtypes") + private boolean findInExistingPropertyAssignments(NewETPTAssignment incomingETPTAssignment, + List<? extends EntityTypePropertyType> assignedPropertyTypes) + { + for (EntityTypePropertyType entityTypePropertyType : assignedPropertyTypes) + { + if (entityTypePropertyType.getPropertyType().getCode().equals(incomingETPTAssignment.getPropertyTypeCode())) + { + return true; + } + } + return false; } private void registerEntityType(EntityKind entityKind, EntityType incomingEntityType) -- GitLab