From d5c5175eb615aab6f0edeeda8c358958a95589c1 Mon Sep 17 00:00:00 2001 From: felmer <franz-josef.elmer@id.ethz.ch> Date: Tue, 12 Mar 2019 12:37:54 +0100 Subject: [PATCH] SSDM-7493: data source provides files of file service if mentioned in some entity properties --- .../datasource/AbstractEntityDeliverer.java | 16 +++- .../sync/datasource/DataSetDeliverer.java | 3 +- .../datasource/DataSourceRequestHandler.java | 12 +++ .../sync/datasource/DeliveryContext.java | 14 ++++ .../datasource/DeliveryExecutionContext.java | 12 +++ .../sync/datasource/ExperimentDeliverer.java | 3 +- .../sync/datasource/FileDeliverer.java | 76 +++++++++++++++++++ .../sync/datasource/MaterialDeliverer.java | 3 +- .../sync/datasource/SampleDeliverer.java | 3 +- 9 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/FileDeliverer.java diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/AbstractEntityDeliverer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/AbstractEntityDeliverer.java index 75e9f98eb09..dc1a18eb2b8 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/AbstractEntityDeliverer.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/AbstractEntityDeliverer.java @@ -23,6 +23,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; @@ -40,6 +42,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment; import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project; import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space; +import ch.ethz.sis.openbis.generic.server.FileServiceServlet; import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; @@ -53,6 +56,9 @@ import ch.systemsx.cisd.openbis.generic.server.batch.IBatchOperation; abstract class AbstractEntityDeliverer<T> implements IDeliverer { private static final int CHUNK_SIZE = 1000; + + private static final Pattern FILE_SERVICE_PATTERN = Pattern.compile("openbis/" + FileServiceServlet.FILE_SERVICE_PATH + + "/([^\"']*)"); private static interface IConsumer<T> { @@ -95,7 +101,7 @@ abstract class AbstractEntityDeliverer<T> implements IDeliverer return context.getV3api(); } - protected void addProperties(XMLStreamWriter writer, Map<String, String> properties) throws XMLStreamException + protected void addProperties(XMLStreamWriter writer, Map<String, String> properties, Set<String> fileServicePaths) throws XMLStreamException { if (properties.isEmpty() == false) { @@ -108,7 +114,13 @@ abstract class AbstractEntityDeliverer<T> implements IDeliverer writer.writeCharacters(entry.getKey()); writer.writeEndElement(); writer.writeStartElement("x:value"); - writer.writeCharacters(entry.getValue()); + String value = entry.getValue(); + Matcher matcher = FILE_SERVICE_PATTERN.matcher(value); + while (matcher.find()) + { + fileServicePaths.add(matcher.group(1)); + } + writer.writeCharacters(value); writer.writeEndElement(); writer.writeEndElement(); } diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DataSetDeliverer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DataSetDeliverer.java index 47c5c04ce20..a350c0dc6c6 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DataSetDeliverer.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DataSetDeliverer.java @@ -52,6 +52,7 @@ public class DataSetDeliverer extends AbstractEntityWithPermIdDeliverer XMLStreamWriter writer = context.getWriter(); String sessionToken = context.getSessionToken(); Set<String> spaces = context.getSpaces(); + Set<String> fileServicePaths = context.getFileServicePaths(); IApplicationServerApi v3api = getV3Api(); List<DataSetPermId> permIds = dataSets.stream().map(DataSetPermId::new).collect(Collectors.toList()); Collection<DataSet> fullDataSets = v3api.getDataSets(sessionToken, permIds, createDataSetFetchOptions()).values(); @@ -77,7 +78,7 @@ public class DataSetDeliverer extends AbstractEntityWithPermIdDeliverer addRegistrator(writer, dataSet); addSample(writer, dataSet.getSample()); addType(writer, dataSet.getType()); - addProperties(writer, dataSet.getProperties()); + addProperties(writer, dataSet.getProperties(), fileServicePaths); addPhysicalData(writer, dataSet, code); addLinkedData(writer, dataSet, code); ConnectionsBuilder connectionsBuilder = new ConnectionsBuilder(); diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DataSourceRequestHandler.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DataSourceRequestHandler.java index f48f43849d6..8356ebb5e93 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DataSourceRequestHandler.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DataSourceRequestHandler.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.TreeSet; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; @@ -76,6 +77,7 @@ public class DataSourceRequestHandler implements IRequestHandler executionContext.setSessionToken(sessionToken); executionContext.setSpaces(requestedSpaces); executionContext.setWriter(context.getWriter()); + executionContext.setFileServicePaths(context.getFileServicePaths()); deliverer.deliverEntities(executionContext); } }; @@ -168,6 +170,8 @@ public class DataSourceRequestHandler implements IRequestHandler deliveryContext.setServletPath(new File(PropertyUtils.getMandatoryProperty(properties, "path")).getParent()); deliveryContext.setServerUrl(PropertyUtils.getMandatoryProperty(properties, "server-url")); deliveryContext.setDownloadUrl(PropertyUtils.getMandatoryProperty(properties, "download-url")); + String fileServiceRepositoryPath = PropertyUtils.getMandatoryProperty(properties, "file-service-repository-path"); + deliveryContext.setFileServiceRepository(new File(fileServiceRepositoryPath)); deliveryContext.setV3api(ServiceProvider.getV3ApplicationService()); deliveryContext.setContentProvider(ServiceProvider.getHierarchicalContentProvider()); deliveryContext.setOpenBisDataSourceName(properties.getProperty("openbis-data-source-name", "openbis-db")); @@ -179,6 +183,7 @@ public class DataSourceRequestHandler implements IRequestHandler deliverers.addDeliverer(new ExperimentDeliverer(deliveryContext)); deliverers.addDeliverer(new SampleDeliverer(deliveryContext)); deliverers.addDeliverer(new DataSetDeliverer(deliveryContext)); + deliverers.addDeliverer(new FileDeliverer(deliveryContext)); deliverer = deliverers; } @@ -277,6 +282,8 @@ public class DataSourceRequestHandler implements IRequestHandler private String sessionToken; private Date requestTimestamp; + + private Set<String> fileServicePaths = new TreeSet<>(); public XMLStreamWriter getWriter() { @@ -347,5 +354,10 @@ public class DataSourceRequestHandler implements IRequestHandler { this.requestTimestamp = requestTimestamp; } + + public Set<String> getFileServicePaths() + { + return fileServicePaths; + } } } diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DeliveryContext.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DeliveryContext.java index 36c45511719..9f57249767d 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DeliveryContext.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DeliveryContext.java @@ -16,6 +16,8 @@ package ch.ethz.sis.openbis.generic.server.dss.plugins.sync.datasource; +import java.io.File; + import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi; import ch.systemsx.cisd.openbis.dss.generic.shared.IHierarchicalContentProvider; @@ -36,6 +38,8 @@ class DeliveryContext private String openBisDataSourceName; + private File fileServiceRepository; + public String getServerUrl() { return serverUrl; @@ -96,4 +100,14 @@ class DeliveryContext this.openBisDataSourceName = openBisDataSourceName; } + public File getFileServiceRepository() + { + return fileServiceRepository; + } + + public void setFileServiceRepository(File fileServiceRepository) + { + this.fileServiceRepository = fileServiceRepository; + } + } diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DeliveryExecutionContext.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DeliveryExecutionContext.java index 8f40605510b..5f3b0530edb 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DeliveryExecutionContext.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/DeliveryExecutionContext.java @@ -38,6 +38,8 @@ class DeliveryExecutionContext private Date requestTimestamp; + private Set<String> fileServicePaths; + public XMLStreamWriter getWriter() { return writer; @@ -87,4 +89,14 @@ class DeliveryExecutionContext { this.requestTimestamp = requestTimestamp; } + + public Set<String> getFileServicePaths() + { + return fileServicePaths; + } + + public void setFileServicePaths(Set<String> fileServicePaths) + { + this.fileServicePaths = fileServicePaths; + } } diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/ExperimentDeliverer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/ExperimentDeliverer.java index ad20d53b45c..9e19a723102 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/ExperimentDeliverer.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/ExperimentDeliverer.java @@ -48,6 +48,7 @@ public class ExperimentDeliverer extends AbstractEntityWithPermIdDeliverer XMLStreamWriter writer = context.getWriter(); String sessionToken = context.getSessionToken(); Set<String> spaces = context.getSpaces(); + Set<String> fileServicePaths = context.getFileServicePaths(); IApplicationServerApi v3api = getV3Api(); List<ExperimentPermId> permIds = experiments.stream().map(ExperimentPermId::new).collect(Collectors.toList()); Collection<Experiment> fullExperiments = v3api.getExperiments(sessionToken, permIds, createFullFetchOptions()).values(); @@ -70,7 +71,7 @@ public class ExperimentDeliverer extends AbstractEntityWithPermIdDeliverer addRegistrator(writer, experiment); addSpace(writer, experiment.getProject().getSpace()); addType(writer, experiment.getType()); - addProperties(writer, experiment.getProperties()); + addProperties(writer, experiment.getProperties(), fileServicePaths); // ConnectionsBuilder connectionsBuilder = new ConnectionsBuilder(); // connectionsBuilder.addConnections(experiment.getSamples()); // connectionsBuilder.addConnections(experiment.getDataSets()); diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/FileDeliverer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/FileDeliverer.java new file mode 100644 index 00000000000..8e1006fdfec --- /dev/null +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/FileDeliverer.java @@ -0,0 +1,76 @@ +/* + * Copyright 2019 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.ethz.sis.openbis.generic.server.dss.plugins.sync.datasource; + +import java.io.File; +import java.io.IOException; +import java.util.Base64; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +import ch.systemsx.cisd.common.filesystem.FileUtilities; + +/** + * @author Franz-Josef Elmer + * + */ +public class FileDeliverer extends AbstractEntityDeliverer<String> +{ + + FileDeliverer(DeliveryContext context) + { + super(context, "file"); + } + + @Override + public void deliverEntities(DeliveryExecutionContext context) throws XMLStreamException + { + Set<String> paths = context.getFileServicePaths(); + if (paths.isEmpty()) + { + return; + } + File repository = this.context.getFileServiceRepository(); + XMLStreamWriter writer = context.getWriter(); + int count = 0; + long totalSize = 0; + for (String path : paths) + { + File file = new File(repository, path); + if (file.isFile()) + { + startUrlElement(writer, "FILE", path, new Date(file.lastModified())); + startXdElement(writer); + writer.writeAttribute("path", path); + byte[] content = FileUtilities.loadToByteArray(file); + String contentAsBase64String = Base64.getEncoder().encodeToString(content); + writer.writeCharacters(contentAsBase64String); + writer.writeEndElement(); + writer.writeEndElement(); + count++; + totalSize += content.length; + } + } + operationLog.info(count + " files (total size: " + FileUtilities.byteCountToDisplaySize(totalSize) + ") have been delivered."); + } + +} diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/MaterialDeliverer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/MaterialDeliverer.java index a6896053db0..fc77302d770 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/MaterialDeliverer.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/MaterialDeliverer.java @@ -60,6 +60,7 @@ public class MaterialDeliverer extends AbstractEntityDeliverer<Material> { XMLStreamWriter writer = context.getWriter(); String sessionToken = context.getSessionToken(); + Set<String> fileServicePaths = context.getFileServicePaths(); IApplicationServerApi v3api = getV3Api(); List<MaterialPermId> permIds = materials.stream().map(Material::getPermId).collect(Collectors.toList()); Collection<Material> fullMaterials = v3api.getMaterials(sessionToken, permIds, createFullFetchOptions()).values(); @@ -84,7 +85,7 @@ public class MaterialDeliverer extends AbstractEntityDeliverer<Material> { allProperties.put(entity.getKey(), entity.getValue().getPermId().toString()); } - addProperties(writer, allProperties); + addProperties(writer, allProperties, fileServicePaths); writer.writeEndElement(); writer.writeEndElement(); } diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/SampleDeliverer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/SampleDeliverer.java index f8e52aa2390..c093c56c975 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/SampleDeliverer.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/datasource/SampleDeliverer.java @@ -48,6 +48,7 @@ public class SampleDeliverer extends AbstractEntityWithPermIdDeliverer XMLStreamWriter writer = context.getWriter(); String sessionToken = context.getSessionToken(); Set<String> spaces = context.getSpaces(); + Set<String> fileServicePaths = context.getFileServicePaths(); IApplicationServerApi v3api = getV3Api(); List<SamplePermId> permIds = samplePermIds.stream().map(SamplePermId::new).collect(Collectors.toList()); Collection<Sample> fullSamples = v3api.getSamples(sessionToken, permIds, createFullFetchOptions()).values(); @@ -73,7 +74,7 @@ public class SampleDeliverer extends AbstractEntityWithPermIdDeliverer addRegistrator(writer, sample); addSpace(writer, sample.getSpace()); addType(writer, sample.getType()); - addProperties(writer, sample.getProperties()); + addProperties(writer, sample.getProperties(), fileServicePaths); ConnectionsBuilder connectionsBuilder = new ConnectionsBuilder(); connectionsBuilder.addConnections(sample.getDataSets()); connectionsBuilder.addChildren(sample.getChildren()); -- GitLab