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 7aa70fadfda80b420fe8df945cfb22d12d8a8a0b..de9c9130a28fe5d1d7724b50df87ee0725233ee5 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 @@ -26,6 +26,8 @@ import java.util.Map; import ch.ethz.sis.openbis.generic.asapi.v3.dto.attachment.Attachment; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentPermId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.ProjectPermId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SamplePermId; import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.common.ServiceFinderUtils; import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.config.SyncConfig; import ch.systemsx.cisd.common.concurrent.ITaskExecutor; @@ -39,7 +41,12 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Identifier; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewProject; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifierFactory; /** * @@ -53,8 +60,6 @@ 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) { @@ -69,12 +74,29 @@ final class AttachmentSynchronizationTaskExecutor implements ITaskExecutor<Ident TechId techId = null; ICommonServer commonServer = ServiceFinderUtils.getCommonServer(ServiceProvider.getConfigProvider().getOpenBisServerUrl()); String localSessionToken = ServiceFinderUtils.login(commonServer, config.getHarvesterUser(), config.getHarvesterPass()); + IAttachmentsOperationsHandler attachmentsOperationsHandler = null; if (item instanceof NewExperiment) { Experiment experiment = service.tryGetExperiment(ExperimentIdentifierFactory.parse(item.getIdentifier())); techId = new TechId(experiment.getId()); attachmentsOperationsHandler = new ExperimentAttachmentsOperationsHandler(config, commonServer, localSessionToken); } + else if (item instanceof NewSample) + { + Sample sample = service.tryGetSampleByPermId(item.getPermID()); + techId = new TechId(sample.getId()); + attachmentsOperationsHandler = new SampleAttachmentsOperationsHandler(config, commonServer, localSessionToken); + } + else if (item instanceof NewProject) + { + Project project = service.tryGetProject(ProjectIdentifierFactory.parse(item.getIdentifier())); + techId = new TechId(project.getId()); + attachmentsOperationsHandler = new ProjectAttachmentsOperationsHandler(config, commonServer, localSessionToken); + } + else + { + return Status.createError("Attachments can be synchronized for only Projects, Experiments and Samples"); + } List<Attachment> incomingAttachments = attachmentsOperationsHandler.listAttachmentsDataSource(config, item.getPermID()); // place the incoming attachments in a map @@ -85,7 +107,7 @@ final class AttachmentSynchronizationTaskExecutor implements ITaskExecutor<Ident } List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> existingAttachments = - attachmentsOperationsHandler.listAttachmentsHarvester(item.getIdentifier()); + attachmentsOperationsHandler.listAttachmentsHarvester(item.getPermID()); Map<String, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> existingAttachmentMap = new HashMap<String, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment>(); @@ -109,14 +131,14 @@ final class AttachmentSynchronizationTaskExecutor implements ITaskExecutor<Ident if (incoming.getVersion() < version) { // Harvester has a later version of the attachment. Delete it from harvester - replaceAttachment(techId, incoming); + replaceAttachment(techId, incoming, attachmentsOperationsHandler); } else if (incoming.getVersion() == version) { // check last sync date and meta data if (incoming.getRegistrationDate().after(lastSyncTimestamp)) { - replaceAttachment(techId, incoming); + replaceAttachment(techId, incoming, attachmentsOperationsHandler); } else { @@ -150,7 +172,7 @@ final class AttachmentSynchronizationTaskExecutor implements ITaskExecutor<Ident attachmentsOperationsHandler.deleteAttachment(techId, existing.getFileName()); } } - return null; + return Status.OK; } private boolean equalsNullable(String s1OrNull, String s2OrNull) @@ -167,13 +189,13 @@ final class AttachmentSynchronizationTaskExecutor implements ITaskExecutor<Ident } } - private void replaceAttachment(TechId techId, Attachment incoming) + private void replaceAttachment(TechId techId, Attachment incoming, IAttachmentsOperationsHandler attachmentsOperationsHandler) { attachmentsOperationsHandler.deleteAttachment(techId, incoming.getFileName()); addAttachments(incoming, 1, techId, attachmentsOperationsHandler); } - private void addAttachments(Attachment attachment, int fromVersion, TechId techId, AttachmentsOperationsHandler handler) + private void addAttachments(Attachment attachment, int fromVersion, TechId techId, IAttachmentsOperationsHandler handler) { Integer version = attachment.getVersion(); @@ -201,11 +223,11 @@ final class AttachmentSynchronizationTaskExecutor implements ITaskExecutor<Ident } } -interface AttachmentsOperationsHandler +interface IAttachmentsOperationsHandler { List<Attachment> listAttachmentsDataSource(SyncConfig config, String permId); - List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listAttachmentsHarvester(String identifier); + List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listAttachmentsHarvester(String permId); void addAttachment(TechId techId, NewAttachment attachment); @@ -214,7 +236,7 @@ interface AttachmentsOperationsHandler void updateAttachment(TechId experimentId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment); } -class ExperimentAttachmentsOperationsHandler implements AttachmentsOperationsHandler +abstract class AbstractEntityAttachmentsOperationsHandler implements IAttachmentsOperationsHandler { final ICommonServer commonServer; @@ -222,18 +244,36 @@ class ExperimentAttachmentsOperationsHandler implements AttachmentsOperationsHan final SyncConfig config; - /** - * @param config - * @param commonServer - * @param localSessionToken - */ - public ExperimentAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, String sessionToken) + AbstractEntityAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, String sessionToken) { this.commonServer = commonServer; this.sessionToken = sessionToken; this.config = config; } + @Override + public abstract List<Attachment> listAttachmentsDataSource(SyncConfig config, String permId); + + @Override + public abstract List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listAttachmentsHarvester(String permId); + + @Override + public abstract void addAttachment(TechId techId, NewAttachment attachment); + + @Override + public abstract void deleteAttachment(TechId experimentId, String fileName); + + @Override + public abstract void updateAttachment(TechId experimentId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment); +} + +class ExperimentAttachmentsOperationsHandler extends AbstractEntityAttachmentsOperationsHandler +{ + ExperimentAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, String sessionToken) + { + super(config, commonServer, sessionToken); + } + @Override public List<Attachment> listAttachmentsDataSource(SyncConfig config, String permId) { @@ -243,10 +283,10 @@ class ExperimentAttachmentsOperationsHandler implements AttachmentsOperationsHan } @Override - public List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listAttachmentsHarvester(String identifier) + public List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listAttachmentsHarvester(String permId) { IEncapsulatedOpenBISService service = ServiceProvider.getOpenBISService(); - Experiment experiment = service.tryGetExperiment(ExperimentIdentifierFactory.parse(identifier)); + Experiment experiment = service.tryGetExperimentByPermId(permId); return service.listAttachments(AttachmentHolderKind.EXPERIMENT, experiment.getId()); } @@ -269,4 +309,92 @@ class ExperimentAttachmentsOperationsHandler implements AttachmentsOperationsHan { commonServer.updateExperimentAttachments(sessionToken, experimentId, attachment); } +} + +class SampleAttachmentsOperationsHandler extends AbstractEntityAttachmentsOperationsHandler +{ + SampleAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, String sessionToken) + { + super(config, commonServer, sessionToken); + } + + @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.getSampleAttachments(sessionToken, new SamplePermId(permId)); + } + + @Override + public List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listAttachmentsHarvester(String permId) + { + IEncapsulatedOpenBISService service = ServiceProvider.getOpenBISService(); + Sample sample = service.tryGetSampleByPermId(permId); + return service.listAttachments(AttachmentHolderKind.SAMPLE, sample.getId()); + } + + @Override + public void addAttachment(TechId techId, NewAttachment attachment) + { + commonServer.addSampleAttachments(sessionToken, techId, attachment); + } + + @Override + public void deleteAttachment(TechId sampleId, String fileName) + { + commonServer.deleteSampleAttachments(sessionToken, sampleId, Arrays.asList(fileName), + "Synchronization from data source " + config.getDataSourceAlias() + + " Attachment no longer exists on data source."); + } + + @Override + public void updateAttachment(TechId sampleId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment) + { + commonServer.updateSampleAttachments(sessionToken, sampleId, attachment); + } +} + +class ProjectAttachmentsOperationsHandler extends AbstractEntityAttachmentsOperationsHandler +{ + ProjectAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, String sessionToken) + { + super(config, commonServer, sessionToken); + } + + @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.getProjectAttachments(sessionToken, new ProjectPermId(permId)); + } + + @Override + public List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listAttachmentsHarvester(String permId) + { + IEncapsulatedOpenBISService service = ServiceProvider.getOpenBISService(); + Project project = service.tryGetProjectByPermId(permId); + return service.listAttachments(AttachmentHolderKind.PROJECT, project.getId()); + } + + @Override + public void addAttachment(TechId techId, NewAttachment attachment) + { + commonServer.addProjectAttachments(sessionToken, techId, attachment); + } + + @Override + public void deleteAttachment(TechId projectId, String fileName) + { + commonServer.deleteProjectAttachments(sessionToken, projectId, Arrays.asList(fileName), + "Synchronization from data source " + config.getDataSourceAlias() + + " Attachment no longer exists on data source."); + } + + @Override + public void updateAttachment(TechId projectId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment) + { + commonServer.updateProjectAttachments(sessionToken, projectId, 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 e3f13e43c0a3450eb272c2163dd7ef0c9bc64ee2..c502be29850eb891feedd1a04747b72eb5f0ef1c 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); + processAttachments(entitiesWithAttachments); // register physical data sets without any hierarchy // Note that container/component and parent/child relationships are established post-reg. 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 d83f38d770acde119544c30ee69c4cbb49251609..8e75f7d9cd76f31ab8e5c0662817ea342117704e 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 @@ -27,6 +27,12 @@ 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; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.fetchoptions.ProjectFetchOptions; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.IProjectId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.fetchoptions.SampleFetchOptions; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId; import ch.ethz.sis.openbis.generic.dssapi.v3.IDataStoreServerApi; import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.DataSetFile; import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.download.DataSetFileDownloadOptions; @@ -79,9 +85,7 @@ public class V3Utils ExperimentFetchOptions fetchOptions = new ExperimentFetchOptions(); 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()); + fetchOptions.withAttachments().withPreviousVersion().withContentUsing(fetchOptions.withAttachments().withContent()); Map<IExperimentId, Experiment> experiments = as.getExperiments(sessionToken, Arrays.asList(experimentId), fetchOptions); if(experiments.size() == 1) { Experiment experiment = experiments.get(experimentId); @@ -90,6 +94,36 @@ public class V3Utils return null; } + public List<Attachment> getSampleAttachments(String sessionToken, ISampleId sampleId) + { + SampleFetchOptions fetchOptions = new SampleFetchOptions(); + fetchOptions.withAttachments().withContent(); + fetchOptions.withAttachments().withPreviousVersion().withPreviousVersionUsing(fetchOptions.withAttachments()); + fetchOptions.withAttachments().withPreviousVersion().withContentUsing(fetchOptions.withAttachments().withContent()); + Map<ISampleId, Sample> samples = as.getSamples(sessionToken, Arrays.asList(sampleId), fetchOptions); + if (samples.size() == 1) + { + Sample sample = samples.get(sampleId); + return sample.getAttachments(); + } + return null; + } + + public List<Attachment> getProjectAttachments(String sessionToken, IProjectId projectId) + { + ProjectFetchOptions fetchOptions = new ProjectFetchOptions(); + fetchOptions.withAttachments().withContent(); + fetchOptions.withAttachments().withPreviousVersion().withPreviousVersionUsing(fetchOptions.withAttachments()); + fetchOptions.withAttachments().withPreviousVersion().withContentUsing(fetchOptions.withAttachments().withContent()); + Map<IProjectId, Project> projects = as.getProjects(sessionToken, Arrays.asList(projectId), fetchOptions); + if (projects.size() == 1) + { + Project project = projects.get(projectId); + return project.getAttachments(); + } + return null; + } + public InputStream downloadFiles(String sessionToken, List<IDataSetFileId> fileIds, DataSetFileDownloadOptions options) { return dss.downloadFiles(sessionToken, fileIds, options);