diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/AttachmentSynchronizationTaskExecutor.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/AttachmentSynchronizationTaskExecutor.java index 4adeaa805c79f60dffc6771992b9994fed87ce53..7aa70fadfda80b420fe8df945cfb22d12d8a8a0b 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/AttachmentSynchronizationTaskExecutor.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/AttachmentSynchronizationTaskExecutor.java @@ -53,6 +53,8 @@ final class AttachmentSynchronizationTaskExecutor implements ITaskExecutor<Ident private final SyncConfig config; private final IEncapsulatedOpenBISService service; + + private AttachmentsOperationsHandler attachmentsOperationsHandler; public AttachmentSynchronizationTaskExecutor(IEncapsulatedOpenBISService service, Date lastSyncTimestamp, SyncConfig config) { @@ -64,103 +66,114 @@ final class AttachmentSynchronizationTaskExecutor implements ITaskExecutor<Ident @Override public Status execute(Identifier<?> item) { - V3Utils dssFileUtils = V3Utils.create(config.getDataSourceOpenbisURL(), config.getDataSourceDSSURL()); - String sessionToken = dssFileUtils.login(config.getUser(), config.getPassword()); + TechId techId = null; + ICommonServer commonServer = ServiceFinderUtils.getCommonServer(ServiceProvider.getConfigProvider().getOpenBisServerUrl()); + String localSessionToken = ServiceFinderUtils.login(commonServer, config.getHarvesterUser(), config.getHarvesterPass()); if (item instanceof NewExperiment) { - List<Attachment> incomingAttachments = dssFileUtils.getExperimentAttachments(sessionToken, new ExperimentPermId(item.getPermID())); + Experiment experiment = service.tryGetExperiment(ExperimentIdentifierFactory.parse(item.getIdentifier())); + techId = new TechId(experiment.getId()); + attachmentsOperationsHandler = new ExperimentAttachmentsOperationsHandler(config, commonServer, localSessionToken); + } + List<Attachment> incomingAttachments = attachmentsOperationsHandler.listAttachmentsDataSource(config, item.getPermID()); - // place the incoming attachments in a map - Map<String, Attachment> incomingAttachmentMap = new HashMap<String, Attachment>(); - for (Attachment incoming : incomingAttachments) - { - incomingAttachmentMap.put(incoming.getFileName(), incoming); - } + // place the incoming attachments in a map + Map<String, Attachment> incomingAttachmentMap = new HashMap<String, Attachment>(); + for (Attachment incoming : incomingAttachments) + { + incomingAttachmentMap.put(incoming.getFileName(), incoming); + } - Experiment experiment = service.tryGetExperiment(ExperimentIdentifierFactory.parse(item.getIdentifier())); - List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> existingAttachments = - service.listAttachments(AttachmentHolderKind.EXPERIMENT, experiment.getId()); - Map<String, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> existingAttachmentMap = - new HashMap<String, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment>(); + List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> existingAttachments = + attachmentsOperationsHandler.listAttachmentsHarvester(item.getIdentifier()); + Map<String, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> existingAttachmentMap = + new HashMap<String, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment>(); - // place the existing attachments in a map - for (ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment : existingAttachments) + // place the existing attachments in a map + for (ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment : existingAttachments) + { + existingAttachmentMap.put(attachment.getFileName(), attachment); + } + + for (Attachment incoming : incomingAttachments) + { + ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment existingAttachment = + existingAttachmentMap.get(incoming.getFileName()); + if (existingAttachment == null) { - existingAttachmentMap.put(attachment.getFileName(), attachment); + addAttachments(incoming, 1, techId, attachmentsOperationsHandler); } - - ICommonServer commonServer = ServiceFinderUtils.getCommonServer(ServiceProvider.getConfigProvider().getOpenBisServerUrl()); - String localSessionToken = ServiceFinderUtils.login(commonServer, config.getHarvesterUser(), config.getHarvesterPass()); - TechId experimentId = new TechId(experiment.getId()); - for (Attachment incoming : incomingAttachments) + else { - ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment existingAttachment = - existingAttachmentMap.get(incoming.getFileName()); - if (existingAttachment == null) + int version = existingAttachment.getVersion(); + if (incoming.getVersion() < version) { - addAttachments(incoming, 1, experimentId, commonServer, localSessionToken); + // Harvester has a later version of the attachment. Delete it from harvester + replaceAttachment(techId, incoming); } - else + else if (incoming.getVersion() == version) { - int version = existingAttachment.getVersion(); - if (incoming.getVersion() < version) + // check last sync date and meta data + if (incoming.getRegistrationDate().after(lastSyncTimestamp)) { - // Harvester has a later version of the attachment. Delete it from harvester - commonServer.deleteExperimentAttachments(localSessionToken, experimentId, - Arrays.asList(incoming.getFileName()), "Synchronization from data source " + config.getDataSourceAlias()); - addAttachments(incoming, 1, experimentId, commonServer, localSessionToken); + replaceAttachment(techId, incoming); } - else if (incoming.getVersion() == version) + else { - // check last sync date and meta data - if (incoming.getRegistrationDate().after(lastSyncTimestamp)) - { - // Data source has the same version number but with a later registration date than the last sync timestamp: - // This means, the attachment was probably deleted in the data source and re-registered. Delete it from harvester - // and re-register - commonServer.deleteExperimentAttachments(localSessionToken, experimentId, - Arrays.asList(incoming.getFileName()), "Synchronization from data source " + config.getDataSourceAlias()); - addAttachments(incoming, 1, experimentId, commonServer, localSessionToken); - } - else + // check if meta data changed + if (equalsNullable(incoming.getTitle(), existingAttachment.getTitle()) == false + || equalsNullable(incoming.getDescription(), existingAttachment.getDescription()) == false) { - // check if meta data changed - if (incoming.getTitle().equals(existingAttachment.getTitle()) == false - || incoming.getDescription().equals(existingAttachment.getDescription())) - { - ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment updateDTO = - new ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment(); - updateDTO.setFileName(existingAttachment.getFileName()); - updateDTO.setVersion(existingAttachment.getVersion()); - updateDTO.setTitle(incoming.getTitle()); - updateDTO.setDescription(incoming.getDescription()); - commonServer.updateExperimentAttachments(localSessionToken, experimentId, updateDTO); - } + ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment updateDTO = + new ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment(); + updateDTO.setFileName(existingAttachment.getFileName()); + updateDTO.setVersion(existingAttachment.getVersion()); + updateDTO.setTitle(incoming.getTitle()); + updateDTO.setDescription(incoming.getDescription()); + attachmentsOperationsHandler.updateAttachment(techId, updateDTO); } } - else - { - // add all new versions from the incoming (do we need to check last sync date) - // Attachment attachmentVersion = getVersion(incoming, version); - addAttachments(incoming, version + 1, experimentId, commonServer, localSessionToken); - } } - } - // loop through existing attachments and if they no longer exist in data source, delete them. - for (ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment existing : existingAttachments) - { - if (incomingAttachmentMap.get(existing.getFileName()) == null) + else { - commonServer.deleteExperimentAttachments(localSessionToken, experimentId, - Arrays.asList(existing.getFileName()), "Synchronization from data source " + config.getDataSourceAlias() - + " Attachment no longer exists on data source."); + // add all new versions from the incoming (do we need to check last sync date) + // Attachment attachmentVersion = getVersion(incoming, version); + addAttachments(incoming, version + 1, techId, attachmentsOperationsHandler); } } } + // loop through existing attachments and if they no longer exist in data source, delete them. + for (ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment existing : existingAttachments) + { + if (incomingAttachmentMap.get(existing.getFileName()) == null) + { + attachmentsOperationsHandler.deleteAttachment(techId, existing.getFileName()); + } + } return null; } - private void addAttachments(Attachment attachment, int fromVersion, TechId techId, ICommonServer commonServer, String sessionToken) + private boolean equalsNullable(String s1OrNull, String s2OrNull) + { + if (s1OrNull == null) + { + return s2OrNull == null ? true : false; + } else if (s2OrNull == null) + { + return false; + } else + { + return s1OrNull.equals(s2OrNull); + } + } + + private void replaceAttachment(TechId techId, Attachment incoming) + { + attachmentsOperationsHandler.deleteAttachment(techId, incoming.getFileName()); + addAttachments(incoming, 1, techId, attachmentsOperationsHandler); + } + + private void addAttachments(Attachment attachment, int fromVersion, TechId techId, AttachmentsOperationsHandler handler) { Integer version = attachment.getVersion(); @@ -182,8 +195,78 @@ final class AttachmentSynchronizationTaskExecutor implements ITaskExecutor<Ident NewAttachment earliestVersion = versions.pollLast(); while (earliestVersion != null) { - commonServer.addExperimentAttachment(sessionToken, techId, earliestVersion); + handler.addAttachment(techId, earliestVersion); earliestVersion = versions.pollLast(); } } } + +interface AttachmentsOperationsHandler +{ + List<Attachment> listAttachmentsDataSource(SyncConfig config, String permId); + + List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listAttachmentsHarvester(String identifier); + + void addAttachment(TechId techId, NewAttachment attachment); + + void deleteAttachment(TechId experimentId, String fileName); + + void updateAttachment(TechId experimentId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment); +} + +class ExperimentAttachmentsOperationsHandler implements AttachmentsOperationsHandler +{ + final ICommonServer commonServer; + + final String sessionToken; + + final SyncConfig config; + + /** + * @param config + * @param commonServer + * @param localSessionToken + */ + public ExperimentAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, String sessionToken) + { + this.commonServer = commonServer; + this.sessionToken = sessionToken; + this.config = config; + } + + @Override + public List<Attachment> listAttachmentsDataSource(SyncConfig config, String permId) + { + V3Utils dssFileUtils = V3Utils.create(config.getDataSourceOpenbisURL(), config.getDataSourceDSSURL()); + String sessionToken = dssFileUtils.login(config.getUser(), config.getPassword()); + return dssFileUtils.getExperimentAttachments(sessionToken, new ExperimentPermId(permId)); + } + + @Override + public List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listAttachmentsHarvester(String identifier) + { + IEncapsulatedOpenBISService service = ServiceProvider.getOpenBISService(); + Experiment experiment = service.tryGetExperiment(ExperimentIdentifierFactory.parse(identifier)); + return service.listAttachments(AttachmentHolderKind.EXPERIMENT, experiment.getId()); + } + + @Override + public void addAttachment(TechId techId, NewAttachment attachment) + { + commonServer.addExperimentAttachment(sessionToken, techId, attachment); + } + + @Override + public void deleteAttachment(TechId experimentId, String fileName) + { + commonServer.deleteExperimentAttachments(sessionToken, experimentId, Arrays.asList(fileName), + "Synchronization from data source " + config.getDataSourceAlias() + + " Attachment no longer exists on data source."); + } + + @Override + public void updateAttachment(TechId experimentId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment) + { + commonServer.updateExperimentAttachments(sessionToken, experimentId, attachment); + } +} \ No newline at end of file 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 911498dccc71db1f8a41636b8cf18ad7ed3a0e1f..e3f13e43c0a3450eb272c2163dd7ef0c9bc64ee2 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 @@ -219,7 +219,7 @@ public class EntitySynchronizer operationLog.info("entity operation result: " + operationResult); operationLog.info("processing attachments..."); - // processAttachments(entitiesWithAttachments, lastSyncTimestamp); + // processAttachments(entitiesWithAttachments); // register physical data sets without any hierarchy // Note that container/component and parent/child relationships are established post-reg. @@ -1014,6 +1014,7 @@ public class EntitySynchronizer } return ProjectIdentifierFactory.parse(projectIdentifier); } + private List<Sample> getChildSamples(Sample sampleWithExperiment) { ListSampleCriteria criteria = ListSampleCriteria.createForParent(new TechId(sampleWithExperiment.getId())); @@ -1032,7 +1033,6 @@ public class EntitySynchronizer return null; } - private final class DataSetRegistrationTaskExecutor implements ITaskExecutor<DataSetWithConnections> { private DataSetRegistrationSummary dsRegistrationSummary; diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/V3Utils.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/V3Utils.java index f3c5e4573bfa566735b74ee420654770f9da0c5d..d83f38d770acde119544c30ee69c4cbb49251609 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/V3Utils.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/V3Utils.java @@ -23,7 +23,6 @@ import java.util.Map; import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi; import ch.ethz.sis.openbis.generic.asapi.v3.dto.attachment.Attachment; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.attachment.fetchoptions.AttachmentFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentFetchOptions; @@ -78,9 +77,11 @@ public class V3Utils public List<Attachment> getExperimentAttachments(String sessionToken, IExperimentId experimentId) { ExperimentFetchOptions fetchOptions = new ExperimentFetchOptions(); - AttachmentFetchOptions attachmentFetchOptions = fetchOptions.withAttachments(); - attachmentFetchOptions.withContent(); - attachmentFetchOptions.withPreviousVersion().withContent(); + fetchOptions.withAttachments().withContent(); + fetchOptions.withAttachments().withPreviousVersion().withPreviousVersionUsing(fetchOptions.withAttachments()); + fetchOptions.withAttachments().withPreviousVersion().withContentUsing(fetchOptions.withAttachments().withContent());// attachmentFetchOptions.withContent(); + // attachmentFetchOptions.withPreviousVersion().withPreviousVersionUsing(fetchOptions.withAttachments()); + // .withContentUsing(attachmentFetchOptions.withContent()); Map<IExperimentId, Experiment> experiments = as.getExperiments(sessionToken, Arrays.asList(experimentId), fetchOptions); if(experiments.size() == 1) { Experiment experiment = experiments.get(experimentId);