diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreService.java index 861f277a405c269549399ab5e8915e34c7c813b8..248a9ef81e26288318de333616b8a6f0e0ff1951 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreService.java @@ -60,10 +60,12 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.IHierarchicalContentProvider; import ch.systemsx.cisd.openbis.dss.generic.shared.IShareIdManager; import ch.systemsx.cisd.openbis.dss.generic.shared.ProcessingStatus; import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v2.ISequenceDatabase; import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SequenceSearchResult; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CustomImportFile; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocation; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkModel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel; @@ -502,6 +504,49 @@ public class DataStoreService extends AbstractServiceWithLogger<IDataStoreServic QueueingPathRemoverService.removeRecursively(sessionWorkspace); } } + + @Override + public List<SequenceSearchResult> searchForDataSetsWithSequences(String sessionToken, + String preferredSequenceDatabaseOrNull, String sequenceSnippet, + Map<String, String> optionalParametersOrNull) + { + PluginTaskProvider<ISequenceDatabase> provider = pluginTaskInfoProvider.getSequenceDatabasesProvider(); + ISequenceDatabase sequenceDatabase = findSequenceDatabase(provider, preferredSequenceDatabaseOrNull); + if (sequenceDatabase != null) + { + List<SequenceSearchResult> result = sequenceDatabase.search(sequenceSnippet, optionalParametersOrNull); + for (SequenceSearchResult sequenceSearchResult : result) + { + sequenceSearchResult.setSequenceDatabaseName(sequenceDatabase.getName()); + } + return result; + } + operationLog.warn("No available sequence database found."); + return new ArrayList<SequenceSearchResult>(); + } + + private ISequenceDatabase findSequenceDatabase(PluginTaskProvider<ISequenceDatabase> provider, + String preferredSequenceDatabaseOrNull) + { + List<DatastoreServiceDescription> pluginDescriptions = provider.getPluginDescriptions(); + ISequenceDatabase availableDatabase = null; + for (DatastoreServiceDescription description : pluginDescriptions) + { + ISequenceDatabase database = provider.getPluginInstance(description.getKey()); + if (database.isAvailable()) + { + if (description.getKey().equals(preferredSequenceDatabaseOrNull)) + { + return database; + } + if (availableDatabase == null) + { + availableDatabase = database; + } + } + } + return availableDatabase; + } private PutDataSetService getPutDataSetService() { diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceLogger.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceLogger.java index 86859ebe1a448e06e73404bf7198119eeabbb113..1466957fab368b7466c8d53ce83835e631241990 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceLogger.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceLogger.java @@ -26,8 +26,9 @@ import ch.systemsx.cisd.common.resource.IInitializable; import ch.systemsx.cisd.common.serviceconversation.ServiceMessage; import ch.systemsx.cisd.openbis.common.spring.IInvocationLoggerContext; import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CustomImportFile; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SequenceSearchResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CustomImportFile; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocation; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkModel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel; @@ -194,4 +195,14 @@ class DataStoreServiceLogger implements IDataStoreService, IInitializable { log("cleanupSession", "USER_SESSION(%s)", userSessionToken); } + + @Override + public List<SequenceSearchResult> searchForDataSetsWithSequences(String sessionToken, + String preferredSequenceDatabaseOrNull, String sequenceSnippet, + Map<String, String> optionalParametersOrNull) + { + log("searchForDataSetsWithSequences", "SEQUENCE_DATABASE(%s) SEQUENCE_SNIPPET(%s)", + preferredSequenceDatabaseOrNull, sequenceSnippet); + return null; + } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v2/sequencedatabases/AbstractSequenceDatabase.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v2/sequencedatabases/AbstractSequenceDatabase.java new file mode 100644 index 0000000000000000000000000000000000000000..41f119859f94c0cd64a0d13ad3e6604bad22b1c1 --- /dev/null +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v2/sequencedatabases/AbstractSequenceDatabase.java @@ -0,0 +1,46 @@ +/* + * Copyright 2014 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.systemsx.cisd.openbis.dss.generic.server.api.v2.sequencedatabases; + +import java.io.File; +import java.util.Properties; + +import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.PluginTaskFactory; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v2.ISequenceDatabase; + +/** + * Abstract super class of all {@link ISequenceDatabase} implementations which get the name from + * the property {@link PluginTaskFactory#LABEL_PROPERTY_NAME}. + * + * @author Franz-Josef Elmer + */ +public abstract class AbstractSequenceDatabase implements ISequenceDatabase +{ + private final String name; + + protected AbstractSequenceDatabase(Properties properties, File storeRoot) + { + name = properties.getProperty(PluginTaskFactory.LABEL_PROPERTY_NAME); + } + + @Override + public String getName() + { + return name; + } + +} diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v2/sequencedatabases/BlastDatabase.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v2/sequencedatabases/BlastDatabase.java new file mode 100644 index 0000000000000000000000000000000000000000..5e8105cb7f43a9d87c54ddb1fc05cd0405c8e5c1 --- /dev/null +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v2/sequencedatabases/BlastDatabase.java @@ -0,0 +1,186 @@ +/* + * Copyright 2014 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.systemsx.cisd.openbis.dss.generic.server.api.v2.sequencedatabases; + +import java.io.File; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.log4j.Logger; + +import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; +import ch.systemsx.cisd.common.fasta.FastaUtilities; +import ch.systemsx.cisd.common.fasta.SequenceType; +import ch.systemsx.cisd.common.filesystem.FileUtilities; +import ch.systemsx.cisd.common.logging.LogCategory; +import ch.systemsx.cisd.common.logging.LogFactory; +import ch.systemsx.cisd.common.process.ProcessExecutionHelper; +import ch.systemsx.cisd.common.process.ProcessResult; +import ch.systemsx.cisd.openbis.dss.generic.shared.utils.BlastUtils; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SequenceSearchResult; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class BlastDatabase extends AbstractSequenceDatabase +{ + public static final Logger operationLog = + LogFactory.getLogger(LogCategory.OPERATION, BlastDatabase.class); + private static final Logger machineLog = + LogFactory.getLogger(LogCategory.MACHINE, BlastDatabase.class); + private static final String QUERY_FILE_NAME_TEMPLATE = "query-{0,date,yyyyMMDDHHmmssSSS}-{1}.fasta"; + private static final Pattern STITLE_PATTERN = Pattern.compile("(.*) \\[Data set: (.*), File: (.*)\\]$"); + + private final File databaseFolder; + private final String blastn; + private final String blastp; + private final boolean available; + private final File queriesFolder; + + private AtomicInteger counter = new AtomicInteger(); + + public BlastDatabase(Properties properties, File storeRoot) + { + super(properties, storeRoot); + String blastToolDirectory = BlastUtils.getBLASTToolDirectory(properties); + blastn = blastToolDirectory + "blastn"; + blastp = blastToolDirectory + "blastp"; + available = process(blastn, "-version"); + if (available == false) + { + BlastUtils.logMissingTools(operationLog); + } + databaseFolder = BlastUtils.getBlastDatabaseFolder(properties, storeRoot); + queriesFolder = new File(databaseFolder, "queries-folder"); + queriesFolder.mkdirs(); + } + + @Override + public boolean isAvailable() + { + return available; + } + + @Override + public List<SequenceSearchResult> search(String sequenceSnippet, Map<String, String> optionalParameters) + { + List<SequenceSearchResult> result = new ArrayList<SequenceSearchResult>(); + SequenceType sequenceType = FastaUtilities.determineSequenceType(sequenceSnippet); + String queryFileName = new MessageFormat(QUERY_FILE_NAME_TEMPLATE).format( + new Object[] {new Date(), counter.getAndIncrement()}); + File queryFile = new File(queriesFolder, queryFileName); + try + { + FileUtilities.writeToFile(queryFile, ">query\n" + sequenceSnippet + "\n"); + List<String> command = createCommand(sequenceType, queryFile); + List<String> output = processAndDeliverOutput(command); + for (String line : output) + { + String[] row = line.split("\t"); + Matcher matcher = STITLE_PATTERN.matcher(row[0]); + if (matcher.matches()) + { + SequenceSearchResult sequenceSearchResult = new SequenceSearchResult(); + sequenceSearchResult.setSequenceIdentifier(matcher.group(1)); + sequenceSearchResult.setDataSetCode(matcher.group(2)); + sequenceSearchResult.setPathInDataSet(matcher.group(3)); + sequenceSearchResult.setPositionInSequence(parse(row[1])); + result.add(sequenceSearchResult); + } + } + } finally + { + FileUtilities.delete(queryFile); + } + return result; + } + + private int parse(String number) + { + try + { + return Integer.parseInt(number); + } catch (NumberFormatException ex) + { + return -1; + } + } + + private List<String> createCommand(SequenceType sequenceType, File queryFile) + { + List<String> command = new ArrayList<String>(); + if (sequenceType == SequenceType.NUCL) + { + command.add(blastn); + command.add("-task"); + command.add("blastn"); + } else + { + command.add(blastp); + command.add("-task"); + command.add("blastp"); + } + command.add("-db"); + command.add(databaseFolder.getAbsolutePath() + "/all-" + sequenceType.toString().toLowerCase()); + command.add("-query"); + command.add(queryFile.getAbsolutePath()); + command.add("-outfmt"); + command.add("6 stitle sstart"); + return command; + } + + private boolean process(String... command) + { + ProcessResult processResult = ProcessExecutionHelper.run(Arrays.asList(command), operationLog, machineLog); + if (processResult.isOK()) + { + processResult.logAsInfo(); + } else + { + processResult.log(); + } + return processResult.isOK(); + } + + private List<String> processAndDeliverOutput(List<String> command) + { + ProcessResult processResult = ProcessExecutionHelper.run(command, operationLog, machineLog); + List<String> output = processResult.getOutput(); + if (processResult.isOK()) + { + return output; + } + StringBuilder builder = new StringBuilder("Execution failed: ").append(command); + List<String> lines = processResult.isBinaryOutput() ? processResult.getErrorOutput() : output; + for (String line : lines) + { + builder.append("\n").append(line); + } + processResult.log(); + throw new EnvironmentFailureException(builder.toString()); + } +} diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DecoratingTableModelReportingPlugin.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DecoratingTableModelReportingPlugin.java index a5c2f1dd094f068172d2565ebb7922e948e16f46..6b01307630b2902a4d601f56410b4c9d5f1f1e97 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DecoratingTableModelReportingPlugin.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DecoratingTableModelReportingPlugin.java @@ -25,7 +25,7 @@ import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.properties.ExtendedProperties; import ch.systemsx.cisd.common.properties.PropertyUtils; import ch.systemsx.cisd.common.reflection.ClassUtils; -import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.AbstractPluginTaskFactory; +import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.PluginTaskFactory; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IReportingPluginTask; import ch.systemsx.cisd.openbis.dss.generic.shared.DataSetProcessingContext; import ch.systemsx.cisd.openbis.generic.shared.basic.ITableModelTransformation; @@ -71,7 +71,7 @@ public class DecoratingTableModelReportingPlugin extends AbstractTableModelRepor { String className = PropertyUtils.getMandatoryProperty(pluginProperties, - AbstractPluginTaskFactory.CLASS_PROPERTY_NAME); + PluginTaskFactory.CLASS_PROPERTY_NAME); try { return ClassUtils.create(IReportingPluginTask.class, className, pluginProperties, @@ -87,7 +87,7 @@ public class DecoratingTableModelReportingPlugin extends AbstractTableModelRepor { String className = PropertyUtils.getMandatoryProperty(transformationProperties, - AbstractPluginTaskFactory.CLASS_PROPERTY_NAME); + PluginTaskFactory.CLASS_PROPERTY_NAME); try { return ClassUtils.create(ITableModelTransformation.class, className, diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/IPluginTaskInfoProvider.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/IPluginTaskInfoProvider.java index de73f4669403a1d45537ca661bf5bc3caf2708a1..be60e2671affa58cba50ecdc4082d3271d28558e 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/IPluginTaskInfoProvider.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/IPluginTaskInfoProvider.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks; import java.io.File; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v2.ISequenceDatabase; import ch.systemsx.cisd.openbis.generic.shared.dto.DatastoreServiceDescriptions; /** @@ -41,6 +42,8 @@ public interface IPluginTaskInfoProvider public PluginTaskProvider<IReportingPluginTask> getReportingPluginsProvider(); public PluginTaskProvider<IProcessingPluginTask> getProcessingPluginsProvider(); + + public PluginTaskProvider<ISequenceDatabase> getSequenceDatabasesProvider(); public ArchiverPluginFactory getArchiverPluginFactory(); diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/AbstractPluginTaskFactory.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskFactory.java similarity index 91% rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/AbstractPluginTaskFactory.java rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskFactory.java index 10af3443b24c310b7383f7cc0cd42bb4b186a1a2..42d4f74e9aca3e4ece1c16cc1ca7c1ae79dac7c9 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/AbstractPluginTaskFactory.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskFactory.java @@ -40,22 +40,18 @@ import ch.systemsx.cisd.common.properties.PropertyUtils; import ch.systemsx.cisd.common.properties.PropertyParametersUtil.SectionProperties; import ch.systemsx.cisd.common.reflection.ClassUtils; import ch.systemsx.cisd.openbis.dss.generic.server.IServletPropertiesManager; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v2.ISequenceDatabase; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ReportingPluginType; /** - * Abstract class for a factory of plugin tasks. + * Factory of plugin tasks. * * @author Tomasz Pylak */ -public abstract class AbstractPluginTaskFactory<T> +public class PluginTaskFactory<T> { - /** - * Logs the current parameters to the {@link LogCategory#OPERATION} log. - */ - abstract public void logConfiguration(); - /** Property name which stores a plugin label. */ @Private public final static String LABEL_PROPERTY_NAME = "label"; @@ -81,7 +77,7 @@ public abstract class AbstractPluginTaskFactory<T> public final static String PARAMS_FILE_PATH_PROPERTY_NAME = "properties-file"; private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, - AbstractPluginTaskFactory.class); + PluginTaskFactory.class); private final DatastoreServiceDescription description; @@ -91,10 +87,13 @@ public abstract class AbstractPluginTaskFactory<T> private final T pluginInstance; - protected AbstractPluginTaskFactory(IServletPropertiesManager servletPropertiesManager, - SectionProperties sectionProperties, String datastoreCode, Class<T> clazz, + private final String pluginTaskName; + + public PluginTaskFactory(IServletPropertiesManager servletPropertiesManager, + SectionProperties sectionProperties, String datastoreCode, Class<T> clazz, String pluginTaskName, File storeRoot) { + this.pluginTaskName = pluginTaskName; Properties pluginProperties = sectionProperties.getProperties(); String label = PropertyUtils.getMandatoryProperty(pluginProperties, LABEL_PROPERTY_NAME); Properties props = @@ -129,6 +128,11 @@ public abstract class AbstractPluginTaskFactory<T> this.description = DatastoreServiceDescription.reporting(pluginKey, label, datasetCodes, datastoreCode, type); + } else if (pluginInstance instanceof ISequenceDatabase) + { + this.description = + DatastoreServiceDescription.processing(pluginKey, label, new String[0], + datastoreCode); } else { String[] datasetCodes = extractDatasetCodes(pluginProperties); @@ -137,6 +141,17 @@ public abstract class AbstractPluginTaskFactory<T> datastoreCode); } } + + /** + * Logs the current parameters to the {@link LogCategory#OPERATION} log. + */ + public void logConfiguration() + { + String key = getPluginDescription().getKey(); + operationLog.info(String.format(pluginTaskName + " '%s' configuration:", key)); + logPropertiesConfiguration(); + } + /** * Returns an instance of a plugin task diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskInfoProvider.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskInfoProvider.java index 7597a248b9814440a819fb50ec21ff2d34fc4ca9..0a926633da7a43b96739275f28901be7eb749188 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskInfoProvider.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskInfoProvider.java @@ -17,6 +17,8 @@ package ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks; import java.io.File; +import java.util.ArrayList; +import java.util.List; import java.util.Properties; import ch.rinn.restrictions.Private; @@ -25,6 +27,7 @@ import ch.systemsx.cisd.common.properties.PropertyParametersUtil.SectionProperti import ch.systemsx.cisd.openbis.dss.generic.server.DataStoreServer; import ch.systemsx.cisd.openbis.dss.generic.server.IServletPropertiesManager; import ch.systemsx.cisd.openbis.dss.generic.shared.Constants; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v2.ISequenceDatabase; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.SessionWorkspaceUtil; import ch.systemsx.cisd.openbis.generic.shared.dto.DatastoreServiceDescriptions; @@ -46,12 +49,15 @@ public class PluginTaskInfoProvider implements IPluginTaskInfoProvider private final PluginTaskProvider<IProcessingPluginTask> processingPlugins; + private final PluginTaskProvider<ISequenceDatabase> sequenceDatabasePlugins; + private final ArchiverPluginFactory archiverTaskFactory; private final File storeRoot; private final File sessionWorkspaceRootDir; + /** for external injections */ public static IPluginTaskInfoProvider create() { @@ -83,6 +89,9 @@ public class PluginTaskInfoProvider implements IPluginTaskInfoProvider this.processingPlugins = createProcessingPluginsFactories(serviceProperties, servletPropertiesManager, datastoreCode, storeRoot); + sequenceDatabasePlugins = createPluginsFactories(serviceProperties, servletPropertiesManager, + datastoreCode, storeRoot, ISequenceDatabase.class, "Sequence database", + Constants.SEQUENCE_DATABASES_NAMES); this.archiverTaskFactory = createArchiverTaskFactory(serviceProperties, datastoreCode); } @@ -116,6 +125,12 @@ public class PluginTaskInfoProvider implements IPluginTaskInfoProvider return processingPlugins; } + @Override + public PluginTaskProvider<ISequenceDatabase> getSequenceDatabasesProvider() + { + return sequenceDatabasePlugins; + } + @Override public ArchiverPluginFactory getArchiverPluginFactory() { @@ -126,6 +141,7 @@ public class PluginTaskInfoProvider implements IPluginTaskInfoProvider { processingPlugins.check(true); reportingPlugins.check(false); + sequenceDatabasePlugins.check(false); archiverTaskFactory.check(storeRoot); } @@ -134,6 +150,7 @@ public class PluginTaskInfoProvider implements IPluginTaskInfoProvider { processingPlugins.logConfigurations(); reportingPlugins.logConfigurations(); + sequenceDatabasePlugins.logConfigurations(); archiverTaskFactory.logConfiguration(); } @@ -142,17 +159,8 @@ public class PluginTaskInfoProvider implements IPluginTaskInfoProvider Properties serviceProperties, IServletPropertiesManager configParameters, String datastoreCode, File storeRoot) { - SectionProperties[] sectionsProperties = - extractSectionProperties(serviceProperties, Constants.REPORTING_PLUGIN_NAMES); - ReportingPluginTaskFactory[] factories = - new ReportingPluginTaskFactory[sectionsProperties.length]; - for (int i = 0; i < factories.length; i++) - { - factories[i] = - new ReportingPluginTaskFactory(configParameters, sectionsProperties[i], - datastoreCode, storeRoot); - } - return new PluginTaskProvider<IReportingPluginTask>(factories); + return createPluginsFactories(serviceProperties, configParameters, datastoreCode, storeRoot, + IReportingPluginTask.class, "Reporting plugin", Constants.REPORTING_PLUGIN_NAMES); } @Private @@ -160,17 +168,22 @@ public class PluginTaskInfoProvider implements IPluginTaskInfoProvider Properties serviceProperties, IServletPropertiesManager configParameters, String datastoreCode, File storeRoot) { - SectionProperties[] sectionsProperties = - extractSectionProperties(serviceProperties, Constants.PROCESSING_PLUGIN_NAMES); - ProcessingPluginTaskFactory[] factories = - new ProcessingPluginTaskFactory[sectionsProperties.length]; - for (int i = 0; i < factories.length; i++) + return createPluginsFactories(serviceProperties, configParameters, datastoreCode, storeRoot, + IProcessingPluginTask.class, "Processing plugin", Constants.PROCESSING_PLUGIN_NAMES); + } + + private static <T> PluginTaskProvider<T> createPluginsFactories(Properties serviceProperties, + IServletPropertiesManager configParameters, String datastoreCode, File storeRoot, Class<T> clazz, + String pluginTaskName, String propertySectionName) + { + SectionProperties[] sectionsProperties = extractSectionProperties(serviceProperties, propertySectionName); + List<PluginTaskFactory<T>> factories = new ArrayList<PluginTaskFactory<T>>(); + for (SectionProperties sectionProps : sectionsProperties) { - factories[i] = - new ProcessingPluginTaskFactory(configParameters, sectionsProperties[i], - datastoreCode, storeRoot); + factories.add(new PluginTaskFactory<T>(configParameters, sectionProps, + datastoreCode, clazz, pluginTaskName, storeRoot)); } - return new PluginTaskProvider<IProcessingPluginTask>(factories); + return new PluginTaskProvider<T>(factories); } private ArchiverPluginFactory createArchiverTaskFactory(Properties serviceProperties, diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskProvider.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskProvider.java index a43c6ecb32bf4d3ea9f489504b9d636f1e9b31dc..0b79490ca38290ebf39ebb2febec8b3e5d3a5e36 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskProvider.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskProvider.java @@ -17,7 +17,6 @@ package ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import ch.systemsx.cisd.common.collection.IKeyExtractor; @@ -31,16 +30,16 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescrip */ public class PluginTaskProvider<P> { - private final TableMap<String, AbstractPluginTaskFactory<P>> factories; + private final TableMap<String, PluginTaskFactory<P>> factories; - public PluginTaskProvider(AbstractPluginTaskFactory<P>[] factories) + public PluginTaskProvider(List<PluginTaskFactory<P>> factories) { this.factories = - new TableMap<String, AbstractPluginTaskFactory<P>>(Arrays.asList(factories), - new IKeyExtractor<String, AbstractPluginTaskFactory<P>>() + new TableMap<String, PluginTaskFactory<P>>(factories, + new IKeyExtractor<String, PluginTaskFactory<P>>() { @Override - public String getKey(AbstractPluginTaskFactory<P> factory) + public String getKey(PluginTaskFactory<P> factory) { return factory.getPluginDescription().getKey(); } @@ -64,7 +63,7 @@ public class PluginTaskProvider<P> { List<DatastoreServiceDescription> descriptions = new ArrayList<DatastoreServiceDescription>(); - for (AbstractPluginTaskFactory<?> factory : factories.values()) + for (PluginTaskFactory<?> factory : factories.values()) { descriptions.add(factory.getPluginDescription()); } @@ -74,7 +73,7 @@ public class PluginTaskProvider<P> /** checks that all factories can produce plugins */ public void check(boolean checkIfSerializable) { - for (AbstractPluginTaskFactory<P> factory : factories.values()) + for (PluginTaskFactory<P> factory : factories.values()) { factory.check(checkIfSerializable); } @@ -83,15 +82,15 @@ public class PluginTaskProvider<P> /** Writes information about all plugin factory configurations to the log */ public void logConfigurations() { - for (AbstractPluginTaskFactory<P> factory : factories.values()) + for (PluginTaskFactory<P> factory : factories.values()) { factory.logConfiguration(); } } - private AbstractPluginTaskFactory<P> getFactory(String pluginKey) + private PluginTaskFactory<P> getFactory(String pluginKey) { - AbstractPluginTaskFactory<P> factory = factories.tryGet(pluginKey); + PluginTaskFactory<P> factory = factories.tryGet(pluginKey); if (factory == null) { throw new IllegalArgumentException("No plugin registered for key '" + pluginKey + "'."); diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/ProcessingPluginTaskFactory.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/ProcessingPluginTaskFactory.java deleted file mode 100644 index bbd618e75dcbbeb77cb3fbfe141af4a26ca668c4..0000000000000000000000000000000000000000 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/ProcessingPluginTaskFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2009 ETH Zuerich, CISD - * - * 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.systemsx.cisd.openbis.dss.generic.server.plugins.tasks; - -import java.io.File; - -import org.apache.log4j.Logger; - -import ch.systemsx.cisd.common.logging.LogCategory; -import ch.systemsx.cisd.common.logging.LogFactory; -import ch.systemsx.cisd.common.properties.PropertyParametersUtil.SectionProperties; -import ch.systemsx.cisd.openbis.dss.generic.server.IServletPropertiesManager; - -/** - * Factory of Processing Plugin Tasks. - * - * @author Tomasz Pylak - */ -public class ProcessingPluginTaskFactory extends AbstractPluginTaskFactory<IProcessingPluginTask> -{ - private static final Logger operationLog = - LogFactory.getLogger(LogCategory.OPERATION, ProcessingPluginTaskFactory.class); - - public ProcessingPluginTaskFactory(IServletPropertiesManager servletPropertiesManager, - SectionProperties sectionProperties, String datastoreCode, File storeRoot) - { - super(servletPropertiesManager, sectionProperties, datastoreCode, IProcessingPluginTask.class, - storeRoot); - } - - @Override - public void logConfiguration() - { - operationLog.info(String.format("Processing plugin '%s' configuration:", - getPluginDescription().getKey())); - logPropertiesConfiguration(); - } -} diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/ReportingPluginTaskFactory.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/ReportingPluginTaskFactory.java deleted file mode 100644 index f79bce3d428d1aa4f22de147ce28022ad292c895..0000000000000000000000000000000000000000 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/ReportingPluginTaskFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2009 ETH Zuerich, CISD - * - * 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.systemsx.cisd.openbis.dss.generic.server.plugins.tasks; - -import java.io.File; - -import org.apache.log4j.Logger; - -import ch.systemsx.cisd.common.logging.LogCategory; -import ch.systemsx.cisd.common.logging.LogFactory; -import ch.systemsx.cisd.common.properties.PropertyParametersUtil.SectionProperties; -import ch.systemsx.cisd.openbis.dss.generic.server.IServletPropertiesManager; - -/** - * Factory of Reporting Plugin Tasks. - * - * @author Tomasz Pylak - */ -public class ReportingPluginTaskFactory extends AbstractPluginTaskFactory<IReportingPluginTask> -{ - private static final Logger operationLog = - LogFactory.getLogger(LogCategory.OPERATION, ProcessingPluginTaskFactory.class); - - public ReportingPluginTaskFactory(IServletPropertiesManager servletPropertiesManager, - SectionProperties sectionProperties, String datastoreCode, File storeRoot) - { - super(servletPropertiesManager, sectionProperties, datastoreCode, IReportingPluginTask.class, - storeRoot); - } - - @Override - public void logConfiguration() - { - operationLog.info(String.format("Reporting plugin '%s' configuration:", - getPluginDescription().getKey())); - logPropertiesConfiguration(); - } -} diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/Constants.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/Constants.java index 1b5fe90e9edac7ddd6a0ea7426980ec095d0044a..99f9e73d12d7c0149aef80a1a7b41e8740ece19d 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/Constants.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/Constants.java @@ -36,6 +36,9 @@ public class Constants /** property with processing plugins names separated by delimiter */ public static final String PROCESSING_PLUGIN_NAMES = "processing-plugins"; + /** property with sequnence databases names separated by delimiter */ + public static final String SEQUENCE_DATABASES_NAMES = "sequence-databases"; + /** Key of service property which is a list of data source IDs. */ public static final String DATA_SOURCES_KEY = "data-sources"; diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/internal/v2/ISequenceDatabase.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/internal/v2/ISequenceDatabase.java new file mode 100644 index 0000000000000000000000000000000000000000..95eae980da558faafcda8c147fbb6f30e0843b36 --- /dev/null +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/internal/v2/ISequenceDatabase.java @@ -0,0 +1,40 @@ +/* + * Copyright 2014 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.systemsx.cisd.openbis.dss.generic.shared.api.internal.v2; + +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SequenceSearchResult; + +/** + * Interface for a database for nucleotid or protein sequences. + * Implenting classes should have a public constructor with two arguments: First is an instance of + * {@link Properties} and second is an instance of {@link File} which points to the root of the data set store. + * + * @author Franz-Josef Elmer + */ +public interface ISequenceDatabase +{ + public String getName(); + + public boolean isAvailable(); + + public List<SequenceSearchResult> search(String sequenceSnippet, Map<String, String> optionalParameters); +} diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceTest.java index e1e23a2158a328fb517310a92ba7411ae8a6bb03..f88246a57f3c43a126b86082e98d0b82f0c517d2 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceTest.java @@ -20,7 +20,10 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Properties; import org.jmock.Expectations; import org.jmock.Mockery; @@ -34,11 +37,17 @@ import ch.systemsx.cisd.common.exceptions.InvalidAuthenticationException; import ch.systemsx.cisd.common.exceptions.InvalidSessionException; import ch.systemsx.cisd.common.filesystem.FileUtilities; import ch.systemsx.cisd.common.mail.MailClientParameters; +import ch.systemsx.cisd.common.properties.PropertyParametersUtil.SectionProperties; +import ch.systemsx.cisd.openbis.dss.generic.server.api.v2.sequencedatabases.AbstractSequenceDatabase; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IPluginTaskInfoProvider; +import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.PluginTaskFactory; +import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.PluginTaskProvider; import ch.systemsx.cisd.openbis.dss.generic.shared.IShareIdManager; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v2.ISequenceDatabase; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.PluginUtilTest; import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; import ch.systemsx.cisd.openbis.generic.shared.IServiceForDataStoreServer; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SequenceSearchResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUploadContext; import ch.systemsx.cisd.openbis.generic.shared.dto.builders.DatasetDescriptionBuilder; @@ -48,6 +57,10 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.builders.DatasetDescriptionBu */ public class DataStoreServiceTest extends AssertJUnit { + private static final Map<String, String> OPTIONAL_PARAMETERS = Collections.singletonMap("greeting", "hi"); + + private static final String SEQUENCE_SNIPPET = "GATTACA"; + private static final String INVALID_SESSION_TOKEN_MSG = "Invalid session token."; private static final String CIFEX_URL = "cifexURL"; @@ -55,7 +68,7 @@ public class DataStoreServiceTest extends AssertJUnit private static final File TEST_FOLDER = new File("targets/data-store-service-test"); private static final File TEST_STORE = new File(TEST_FOLDER, "store"); - + private static final class MockDataStoreService extends DataStoreService { private final ICIFEXRPCServiceFactory cifexServiceFactory; @@ -81,6 +94,39 @@ public class DataStoreServiceTest extends AssertJUnit return cifexServiceFactory; } } + + public static final class MockSequenceDatabase extends AbstractSequenceDatabase + { + private static final String DATA_SET_KEY = "data-set"; + private static final String AVAILABLE_KEY = "available"; + + private boolean available; + private String dataSetCode; + + public MockSequenceDatabase(Properties properties, File storeRoot) + { + super(properties, storeRoot); + available = "true".equals(properties.getProperty(AVAILABLE_KEY)); + dataSetCode = properties.getProperty(DATA_SET_KEY); + } + + @Override + public boolean isAvailable() + { + return available; + } + + @Override + public List<SequenceSearchResult> search(String sequenceSnippet, Map<String, String> optionalParameters) + { + assertSame(SEQUENCE_SNIPPET, sequenceSnippet); + assertSame(OPTIONAL_PARAMETERS, optionalParameters); + SequenceSearchResult sequenceSearchResult = new SequenceSearchResult(); + sequenceSearchResult.setDataSetCode(dataSetCode); + return Arrays.asList(sequenceSearchResult); + } + + } private SessionTokenManager sessionTokenManager; @@ -132,6 +178,74 @@ public class DataStoreServiceTest extends AssertJUnit context.assertIsSatisfied(); } + @Test + public void testSearchForDataSetsWithSequencesUndefinedDatabases() + { + pluginTaskParameters = context.mock(IPluginTaskInfoProvider.class); + preparePluginTaskInfoProvider(); + + List<SequenceSearchResult> result = createService().searchForDataSetsWithSequences(sessionToken, + null, SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); + + assertEquals(0, result.size()); + context.assertIsSatisfied(); + } + + @Test + public void testSearchForDataSetsWithSequencesUnAvailableDatabases() + { + pluginTaskParameters = context.mock(IPluginTaskInfoProvider.class); + preparePluginTaskInfoProvider("-1", "-2"); + + List<SequenceSearchResult> result = createService().searchForDataSetsWithSequences(sessionToken, + null, SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); + + assertEquals(0, result.size()); + context.assertIsSatisfied(); + } + + @Test + public void testSearchForDataSetsWithSequencesWithUnspecifiedDatabase() + { + pluginTaskParameters = context.mock(IPluginTaskInfoProvider.class); + preparePluginTaskInfoProvider("1", "2"); + + List<SequenceSearchResult> result = createService().searchForDataSetsWithSequences(sessionToken, + null, SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); + + assertEquals("DS-1", result.get(0).getDataSetCode()); + assertEquals(1, result.size()); + context.assertIsSatisfied(); + } + + @Test + public void testSearchForDataSetsWithSequencesWithSpecifiedAndAvailableDatabase() + { + pluginTaskParameters = context.mock(IPluginTaskInfoProvider.class); + preparePluginTaskInfoProvider("1", "2"); + + List<SequenceSearchResult> result = createService().searchForDataSetsWithSequences(sessionToken, + "db-2", SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); + + assertEquals("DS-2", result.get(0).getDataSetCode()); + assertEquals(1, result.size()); + context.assertIsSatisfied(); + } + + @Test + public void testSearchForDataSetsWithSequencesWithSpecifiedButUnailableDatabase() + { + pluginTaskParameters = context.mock(IPluginTaskInfoProvider.class); + preparePluginTaskInfoProvider("-1", "2", "-3", "4"); + + List<SequenceSearchResult> result = createService().searchForDataSetsWithSequences(sessionToken, + "db-3", SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); + + assertEquals("DS-2", result.get(0).getDataSetCode()); + assertEquals(1, result.size()); + context.assertIsSatisfied(); + } + @Test public void testGetVersionForInvalidSessionToken() { @@ -284,6 +398,38 @@ public class DataStoreServiceTest extends AssertJUnit context.assertIsSatisfied(); } + private void preparePluginTaskInfoProvider(final String... databases) + { + context.checking(new Expectations() + { + { + allowing(pluginTaskParameters).getStoreRoot(); + will(returnValue(TEST_STORE)); + + List<PluginTaskFactory<ISequenceDatabase>> factories + = new ArrayList<PluginTaskFactory<ISequenceDatabase>>(); + for (String database : databases) + { + boolean available = database.startsWith("-") == false; + if (available == false) + { + database = database.substring(1); + } + Properties sectionProperties = new Properties(); + sectionProperties.setProperty(PluginTaskFactory.LABEL_PROPERTY_NAME, database); + sectionProperties.setProperty(PluginTaskFactory.CLASS_PROPERTY_NAME, MockSequenceDatabase.class.getName()); + sectionProperties.setProperty(MockSequenceDatabase.AVAILABLE_KEY, Boolean.toString(available)); + sectionProperties.setProperty(MockSequenceDatabase.DATA_SET_KEY, "DS-" + database.toUpperCase()); + factories.add(new PluginTaskFactory<ISequenceDatabase>(null, + new SectionProperties("db-" + database, sectionProperties), "DSS", + ISequenceDatabase.class, "Test-db-" + database, TEST_STORE)); + } + allowing(pluginTaskParameters).getSequenceDatabasesProvider(); + will(returnValue(new PluginTaskProvider<ISequenceDatabase>(factories))); + } + }); + } + private IDataStoreService createService() { context.checking(new Expectations() diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskParametersTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskParametersTest.java index 64a1423097e1aecf20bd80a78b95b9d0b65d72d1..03b461a65494034cc2cee173064914da92fad414 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskParametersTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskParametersTest.java @@ -61,7 +61,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; * @author Tomasz Pylak */ @Friend(toClasses = - { PluginTaskInfoProvider.class, AbstractPluginTaskFactory.class }) + { PluginTaskInfoProvider.class, PluginTaskFactory.class }) public class PluginTaskParametersTest extends AbstractFileSystemTestCase { private static final File STORE_ROOT = new File("../datastore_server/resource/test-data/" @@ -155,7 +155,7 @@ public class PluginTaskParametersTest extends AbstractFileSystemTestCase final String pluginLabel2 = "Demo Reporting 2"; String datasetCodes2 = "EICML"; setPluginProperties(props, plugin2, pluginLabel2, datasetCodes2, DemoReportingPlugin.class); - setPluginProperty(props, plugin2, AbstractPluginTaskFactory.SERVLETS_PROPERTY_NAME, + setPluginProperty(props, plugin2, PluginTaskFactory.SERVLETS_PROPERTY_NAME, "s1, s2"); setPluginProperty(props, plugin2, "s1.a", "alpha"); setPluginProperty(props, plugin2, "s2.b", "beta"); @@ -254,7 +254,7 @@ public class PluginTaskParametersTest extends AbstractFileSystemTestCase props.setProperty(Constants.PROCESSING_PLUGIN_NAMES, plugin1); setPluginProperties(props, plugin1, "pluginLabel1", "datasetCodes1", DemoProcessingPlugin.class); - setPluginProperty(props, plugin1, AbstractPluginTaskFactory.SERVLET_PROPERTY_NAME + ".a", + setPluginProperty(props, plugin1, PluginTaskFactory.SERVLET_PROPERTY_NAME + ".a", "alpha"); context.checking(new Expectations() { @@ -292,17 +292,17 @@ public class PluginTaskParametersTest extends AbstractFileSystemTestCase private void setPluginProperties(Properties props, String pluginId, String pluginLabel, String datasetCodes, Class<?> pluginClass) throws IOException, FileNotFoundException { - setPluginProperty(props, pluginId, AbstractPluginTaskFactory.LABEL_PROPERTY_NAME, + setPluginProperty(props, pluginId, PluginTaskFactory.LABEL_PROPERTY_NAME, pluginLabel); - setPluginProperty(props, pluginId, AbstractPluginTaskFactory.DATASET_CODES_PROPERTY_NAME, + setPluginProperty(props, pluginId, PluginTaskFactory.DATASET_CODES_PROPERTY_NAME, datasetCodes); - setPluginProperty(props, pluginId, AbstractPluginTaskFactory.CLASS_PROPERTY_NAME, + setPluginProperty(props, pluginId, PluginTaskFactory.CLASS_PROPERTY_NAME, pluginClass.getName()); String[] pluginParams = new String[] { "param1 = X", "param2 = Y" }; File paramsFile = createPluginPropertiesFile(pluginParams); setPluginProperty(props, pluginId, - AbstractPluginTaskFactory.PARAMS_FILE_PATH_PROPERTY_NAME, paramsFile.getPath()); + PluginTaskFactory.PARAMS_FILE_PATH_PROPERTY_NAME, paramsFile.getPath()); } private File createPluginPropertiesFile(String... lines) throws IOException, diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java index f11abe1f38999d9100f89c7f0547505aaef1a565..06945f32ed13bf2c6c4298e129e20b061e3adb0b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java @@ -83,6 +83,7 @@ import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExternalD import ch.systemsx.cisd.openbis.generic.server.authorization.validator.MatchingEntityValidator; import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ProjectValidator; import ch.systemsx.cisd.openbis.generic.server.authorization.validator.SampleValidator; +import ch.systemsx.cisd.openbis.generic.server.authorization.validator.SequenceSearchResultValidator; import ch.systemsx.cisd.openbis.generic.server.authorization.validator.SpaceValidator; import ch.systemsx.cisd.openbis.generic.server.business.IPropertiesBatchManager; import ch.systemsx.cisd.openbis.generic.server.business.bo.DataAccessExceptionTranslator; @@ -155,104 +156,8 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWit import ch.systemsx.cisd.openbis.generic.shared.basic.IIdHolder; import ch.systemsx.cisd.openbis.generic.shared.basic.IdentifierExtractor; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AuthorizationGroup; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AuthorizationGroupUpdates; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.BasicEntityDescription; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.BatchOperationKind; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CorePlugin; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CustomImport; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CustomImportFile; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetRelatedEntities; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetRelationshipRole; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetTypePropertyType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetUpdateResult; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStore; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DeletionType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DynamicPropertyEvaluationInfo; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityHistory; -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.EntityTypePropertyType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityValidationEvaluationInfo; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentTypePropertyType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentUpdateResult; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalDataManagementSystem; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.FileFormatType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Grantee; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.GridCustomFilter; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IExpressionUpdates; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IMetaprojectRegistration; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IMetaprojectUpdates; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IPropertyTypeUpdates; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IScriptUpdates; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ISpaceUpdates; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IVocabularyTermUpdates; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IVocabularyUpdates; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Identifier; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LastModificationState; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkModel; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListMaterialCriteria; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListOrSearchSampleCriteria; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListSampleCriteria; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ManagedUiActionDescription; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MatchingEntity; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialTypePropertyType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignments; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsCount; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsFetchOption; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectCriteria; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAuthorizationGroup; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewBasicExperiment; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewColumnOrFilter; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewDataSet; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewETNewPTAssigments; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewETPTAssignment; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewPTNewAssigment; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewVocabulary; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PhysicalDataSet; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PluginType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyUpdates; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleAssignment; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.*; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleParentWithDerived; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleTypePropertyType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleUpdateResult; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Script; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ScriptType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ScriptUpdateResult; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.UpdatedBasicExperiment; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.UpdatedDataSet; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.UpdatedSample; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTermReplacement; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.IManagedInputWidgetDescription; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.IManagedProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.IManagedUiAction; @@ -1701,6 +1606,20 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt return translateExperiments(sessionToken, experiments); } + @Override + @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) + @ReturnValueFilter(validatorClass = SequenceSearchResultValidator.class) + public List<SequenceSearchResultWithFullDataSet> searchForDataSetsWithSequences(String sessionToken, + String preferredSequenceDatabaseOrNull, String sequenceSnippet, + Map<String, String> optionalParametersOrNull) + { + Session session = getSession(sessionToken); + + IDataSetTable dataSetTable = businessObjectFactory.createDataSetTable(session); + return dataSetTable.searchForDataSetsWithSequences(preferredSequenceDatabaseOrNull, sequenceSnippet, + optionalParametersOrNull); + } + @Override @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) @ReturnValueFilter(validatorClass = ExternalDataValidator.class) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java index ae7a9a20f7c8f28a1b7305644ccb09efc70b4eb1..37ad732eafa3f64504d5b7f6bf21c8188f514574 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java @@ -110,6 +110,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleUpdateResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Script; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ScriptType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ScriptUpdateResult; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SequenceSearchResultWithFullDataSet; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; @@ -695,6 +696,16 @@ final class CommonServerLogger extends AbstractServerLogger implements ICommonSe return null; } + @Override + public List<SequenceSearchResultWithFullDataSet> searchForDataSetsWithSequences(String sessionToken, + String preferredSequenceDatabaseOrNull, String sequenceSnippet, + Map<String, String> optionalParametersOrNull) + { + logAccess(sessionToken, "search_for_datasets_with_sequences", "preferred_database(%s) sequence_snippet(%s)", + preferredSequenceDatabaseOrNull, sequenceSnippet); + return null; + } + @Override public List<AbstractExternalData> searchForDataSets(String sessionToken, DetailedSearchCriteria criteria) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java index e167efeb073559becf7a95d52d08fd47bc5448dd..81955f7a9e2837f5182b0ff6aa7e0aa9b0073dc9 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java @@ -94,6 +94,7 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleFetchOption; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleType; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchableEntityKind; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SequenceSearchResult; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SpaceWithProjectsAndRoleAssignments; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Vocabulary; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.IObjectId; @@ -113,6 +114,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListMaterialCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListSampleCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SequenceSearchResultWithFullDataSet; import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentHolderPE; import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE; import ch.systemsx.cisd.openbis.generic.shared.dto.AuthorizationGroupPE; @@ -141,7 +143,7 @@ import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils; public class GeneralInformationService extends AbstractServer<IGeneralInformationService> implements IGeneralInformationService { - public static final int MINOR_VERSION = 28; + public static final int MINOR_VERSION = 29; @Resource(name = ch.systemsx.cisd.openbis.generic.shared.ResourceNames.COMMON_SERVER) private ICommonServer commonServer; @@ -945,6 +947,26 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio } } + @Override + @Transactional(readOnly = true) + @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) + // There is no @ReturnValueFilter because commonServer.searchForDataSetsWithSequences() does already the filtering. + public List<SequenceSearchResult> searchForDataSetsWithSequences(String sessionToken, + String preferredSequenceDatabaseOrNull, String sequenceSnippet, + Map<String, String> optionalParametersOrNull) + { + checkSession(sessionToken); + + List<SequenceSearchResult> result = new ArrayList<SequenceSearchResult>(); + List<SequenceSearchResultWithFullDataSet> list = commonServer.searchForDataSetsWithSequences(sessionToken, + preferredSequenceDatabaseOrNull, sequenceSnippet, optionalParametersOrNull); + for (SequenceSearchResultWithFullDataSet sequenceSearchResult : list) + { + result.add(sequenceSearchResult.getSearchResult()); + } + return result; + } + @Override @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceLogger.java index b0ef6402de9e01f16f6a2c0af915c3eeb94b0de2..8c810eeab6fe2ec71d004146ad95e763d0f8db29 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceLogger.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceLogger.java @@ -46,6 +46,7 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleFetchOption; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleType; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SequenceSearchResult; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SpaceWithProjectsAndRoleAssignments; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.experiment.IExperimentId; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.metaproject.IMetaprojectId; @@ -294,6 +295,16 @@ class GeneralInformationServiceLogger extends AbstractServerLogger implements return null; } + @Override + public List<SequenceSearchResult> searchForDataSetsWithSequences(String sessionToken, + String preferredSequenceDatabaseOrNull, String sequenceSnippet, + Map<String, String> optionalParametersOrNull) + { + logAccess(sessionToken, "search-for-data-sets-with-sequences", "PREFERRED_DATABASE(%s) SEQUENCE_SNIPPET(%s)", + preferredSequenceDatabaseOrNull, sequenceSnippet); + return null; + } + @Override public List<DataSet> searchForDataSets(String sessionToken, SearchCriteria searchCriteria) { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/SequenceSearchResultValidator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/SequenceSearchResultValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..694c157557f014f2dcfc7fa08ab832d7a13c3a50 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/SequenceSearchResultValidator.java @@ -0,0 +1,37 @@ +/* + * Copyright 2014 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.systemsx.cisd.openbis.generic.server.authorization.validator; + +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SequenceSearchResultWithFullDataSet; +import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE; + +/** + * Validator of @SequenceSearchResult. + * + * @author Franz-Josef Elmer + */ +public class SequenceSearchResultValidator extends AbstractValidator<SequenceSearchResultWithFullDataSet> +{ + private final ExternalDataValidator validator = new ExternalDataValidator(); + + @Override + public boolean doValidation(PersonPE person, SequenceSearchResultWithFullDataSet value) + { + return validator.isValid(person, value.getDataSet()); + } + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java index 2e0c4a7d65eec1df69567cb6413f6cebd7db0f7a..bbec982eb4c4e4e0e1392408a93e9728ee01de3c 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java @@ -36,6 +36,8 @@ import org.springframework.dao.DataIntegrityViolationException; import ch.rinn.restrictions.Private; import ch.systemsx.cisd.common.collection.CollectionUtils; +import ch.systemsx.cisd.common.collection.IKeyExtractor; +import ch.systemsx.cisd.common.collection.TableMap; import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; import ch.systemsx.cisd.common.exceptions.UserFailureException; @@ -55,8 +57,10 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.exception.DataSetDele import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataDAO; import ch.systemsx.cisd.openbis.generic.server.dataaccess.event.DeleteDataSetEventBuilder; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.util.KeyExtractorFactory; import ch.systemsx.cisd.openbis.generic.shared.Constants; import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SequenceSearchResult; import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant; import ch.systemsx.cisd.openbis.generic.shared.basic.TableModelAppender; import ch.systemsx.cisd.openbis.generic.shared.basic.TableModelAppender.TableModelWithDifferentColumnCountException; @@ -70,6 +74,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetBatchUpdateDetai import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkModel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SequenceSearchResultWithFullDataSet; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetBatchUpdatesDTO; @@ -269,6 +274,70 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements this.dataSets = dataSets; } + @Override + public List<SequenceSearchResultWithFullDataSet> searchForDataSetsWithSequences(String preferredSequenceDatabaseOrNull, + String sequenceSnippet, Map<String, String> optionalParametersOrNull) + { + List<SequenceSearchResult> result = askAllDataStoreServers(preferredSequenceDatabaseOrNull, + sequenceSnippet, optionalParametersOrNull); + TableMap<String, AbstractExternalData> fullDataSetsByCode = listFullDataSets(result); + return filterSearchResultAndInjectFullDataSets(result, fullDataSetsByCode); + } + + private List<SequenceSearchResultWithFullDataSet> filterSearchResultAndInjectFullDataSets(List<SequenceSearchResult> result, + TableMap<String, AbstractExternalData> fullDataSetsByCode) + { + List<SequenceSearchResultWithFullDataSet> filteredResult = new ArrayList<SequenceSearchResultWithFullDataSet>(); + for (SequenceSearchResult sequenceSearchResult : result) + { + String dataSetCode = sequenceSearchResult.getDataSetCode(); + AbstractExternalData fullDataSet = fullDataSetsByCode.tryGet(dataSetCode); + if (fullDataSet != null) + { + SequenceSearchResultWithFullDataSet resultWithFullDataSet = new SequenceSearchResultWithFullDataSet(); + resultWithFullDataSet.setDataSet(fullDataSet); + resultWithFullDataSet.setSearchResult(sequenceSearchResult); + filteredResult.add(resultWithFullDataSet); + } + } + return filteredResult; + } + + private TableMap<String, AbstractExternalData> listFullDataSets(List<SequenceSearchResult> result) + { + IKeyExtractor<String, AbstractExternalData> codeKeyExtractor = KeyExtractorFactory.<AbstractExternalData> createCodeKeyExtractor(); + if (result.isEmpty()) + { + return new TableMap<String, AbstractExternalData>(codeKeyExtractor); + } + List<String> codes = new ArrayList<String>(); + for (SequenceSearchResult sequenceSearchResult : result) + { + codes.add(sequenceSearchResult.getDataSetCode()); + } + List<DataPE> fullDataSetPEs = getDataDAO().tryToFindFullDataSetsByCodes(codes, false, false); + List<AbstractExternalData> fullDataSets = DataSetTranslator.translate(fullDataSetPEs, "?", "?", + new HashMap<Long, Set<Metaproject>>(), managedPropertyEvaluatorFactory); + return new TableMap<String, AbstractExternalData>(fullDataSets, codeKeyExtractor); + } + + private List<SequenceSearchResult> askAllDataStoreServers(String preferredSequenceDatabaseOrNull, + String sequenceSnippet, Map<String, String> optionalParametersOrNull) + { + List<SequenceSearchResult> result = new ArrayList<SequenceSearchResult>(); + List<DataStorePE> stores = getDataStoreDAO().listDataStores(); + for (DataStorePE dataStore : stores) + { + IDataStoreService service = tryGetDataStoreService(dataStore); + if (service != null) + { + result.addAll(service.searchForDataSetsWithSequences(dataStore.getSessionToken(), + preferredSequenceDatabaseOrNull, sequenceSnippet, optionalParametersOrNull)); + } + } + return result; + } + @Override public void loadByDataSetCodes(List<String> dataSetCodes, boolean withProperties, boolean lockForUpdate) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataSetTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataSetTable.java index afaeb18469ad2030974a55894e8979a5e72f4aa8..714ba7e419d025600d0b29abdf3003dfecb40451 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataSetTable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataSetTable.java @@ -21,6 +21,7 @@ import java.util.Map; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkModel; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SequenceSearchResultWithFullDataSet; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetBatchUpdatesDTO; @@ -35,6 +36,12 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE; */ public interface IDataSetTable { + /** + * Searchs for data sets with sequences. + */ + List<SequenceSearchResultWithFullDataSet> searchForDataSetsWithSequences(String preferredSequenceDatabaseOrNull, + String sequenceSnippet, Map<String, String> optionalParametersOrNull); + /** * Loads data sets specified by their codes. Data set codes will be ignored if no {@link DataPE} could be found. Properties will be loaded too * depending on <var>withProperties</var> value. Optionally if <var>lockForUpdate</var> is <var>true</var> all updates to loaded data sets from diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java index 8b097adacdf8d81383684b70e23f2e47b31e2f75..c4dc36c00031ef1d4195b902d1b5774ba91458a2 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java @@ -105,6 +105,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleUpdateResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Script; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ScriptType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ScriptUpdateResult; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SequenceSearchResultWithFullDataSet; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; @@ -657,6 +658,14 @@ public interface ICommonServer extends IServer public List<Experiment> searchForExperiments(String sessionToken, DetailedSearchCriteria criteria); + /** + * Searches for data sets which have nucleotid or aminoacid sequences in there files. + */ + @Transactional(readOnly = true) + public List<SequenceSearchResultWithFullDataSet> searchForDataSetsWithSequences(String sessionToken, + String preferredSequenceDatabaseOrNull, String sequenceSnippet, + Map<String, String> optionalParametersOrNull); + /** * Searches for data sets that fulfill the specified search criteria. */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java index 54b6cbd6cd192f500862f230fad1a4e960867ab2..566fa5ae5ce92c7f76ee3ac923aecb4dfd4d5f14 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java @@ -22,6 +22,7 @@ import java.util.Map; import ch.systemsx.cisd.common.exceptions.InvalidAuthenticationException; import ch.systemsx.cisd.openbis.common.conversation.annotation.Conversational; import ch.systemsx.cisd.openbis.common.conversation.annotation.Progress; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SequenceSearchResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CustomImportFile; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocation; @@ -41,7 +42,7 @@ public interface IDataStoreService /** * Every time this interface and related DTO's are changed, we should increment this number. */ - public static final int VERSION = 9; // for release 142 + public static final int VERSION = 10; // for S185 /** * Returns the version of this service. @@ -81,8 +82,8 @@ public interface IDataStoreService /** * Runs the reporting task with the specified id for provided datasets. * <p> - * <i> Ensure that you call {@link #cleanupSession(String)} on closing of the user sesssion - * <var>userSessionToken</var> so that DSS gets the chance to cleanup session files. </i> + * <i> Ensure that you call {@link #cleanupSession(String)} on closing of the user sesssion <var>userSessionToken</var> so that DSS gets the + * chance to cleanup session files. </i> */ @Conversational(progress = Progress.AUTOMATIC) public TableModel createReportFromDatasets(String sessionToken, String userSessionToken, @@ -90,16 +91,13 @@ public interface IDataStoreService String userEmailOrNull); /** - * Schedules the processing task with the specified id for provided datasets and specified - * parameter bindings. + * Schedules the processing task with the specified id for provided datasets and specified parameter bindings. * * @param userSessionToken The session token of the user that initiated the processing. - * @param parameterBindings Contains at least the parameter {@link Constants#USER_PARAMETER} - * with the ID of the user who initiated processing. + * @param parameterBindings Contains at least the parameter {@link Constants#USER_PARAMETER} with the ID of the user who initiated processing. * @param userId id of user who initiated the processing. - * @param userEmailOrNull Email of user who initiated processing and will get a message after - * the processing is finished. It may be null if the user doesn't have email and no - * message will be send in such case. + * @param userEmailOrNull Email of user who initiated processing and will get a message after the processing is finished. It may be null if the + * user doesn't have email and no message will be send in such case. */ public void processDatasets(String sessionToken, String userSessionToken, String serviceKey, List<DatasetDescription> datasets, Map<String, String> parameterBindings, @@ -109,11 +107,10 @@ public interface IDataStoreService * Schedules archiving of provided datasets. * * @param userId id of user who initiated archiving. - * @param userEmailOrNull Email of user who initiated archiving and will get a message after the - * task is finished. It may be null if the user doesn't have email and no message - * will be send in such case. - * @param removeFromDataStore when set to <code>true</code> the data sets will be removed from - * the data store after a successful archiving operation. + * @param userEmailOrNull Email of user who initiated archiving and will get a message after the task is finished. It may be null if the user + * doesn't have email and no message will be send in such case. + * @param removeFromDataStore when set to <code>true</code> the data sets will be removed from the data store after a successful archiving + * operation. */ public void archiveDatasets(String sessionToken, String userSessionToken, List<DatasetDescription> datasets, String userId, String userEmailOrNull, @@ -123,9 +120,8 @@ public interface IDataStoreService * Schedules unarchiving of provided datasets. * * @param userId id of user who initiated unarchiving. - * @param userEmailOrNull Email of user who initiated unarchiving and will get a message after - * the task is finished. It may be null if the user doesn't have email and no message - * will be send in such case. + * @param userEmailOrNull Email of user who initiated unarchiving and will get a message after the task is finished. It may be null if the user + * doesn't have email and no message will be send in such case. */ public void unarchiveDatasets(String sessionToken, String userSessionToken, List<DatasetDescription> datasets, String userId, String userEmailOrNull); @@ -136,8 +132,7 @@ public interface IDataStoreService * @param sessionToken The sessionToken * @param serviceKey The service that should compute the link * @param dataSet The data set we want the link for - * @return A LinkModel that describes the link. The session Id needs to be filled in to retrieve - * the link. + * @return A LinkModel that describes the link. The session Id needs to be filled in to retrieve the link. */ public LinkModel retrieveLinkFromDataSet(String sessionToken, String serviceKey, DatasetDescription dataSet); @@ -145,8 +140,8 @@ public interface IDataStoreService /** * Gets the link from a service that supports the IReportingPluginTask#createLink method. * <p> - * <i> Ensure that you call {@link #cleanupSession(String)} on closing of the user sesssion - * <var>userSessionToken</var> so that DSS gets the chance to cleanup session files. </i> + * <i> Ensure that you call {@link #cleanupSession(String)} on closing of the user sesssion <var>userSessionToken</var> so that DSS gets the + * chance to cleanup session files. </i> * * @param sessionToken The sessionToken. * @param userSessionToken The session token of the user that initiated the processing. @@ -170,4 +165,18 @@ public interface IDataStoreService */ public void cleanupSession(String userSessionToken); + /** + * Searches for the specified sequence snippet. If no preferred sequence database is specified the first available one will be used. If the + * preferred sequence database doesn't exist or isn't available also the first available database will be used. + * + * @param preferredSequenceDatabaseOrNull The key of the preferred sequence database or <code>null</code>. + * @param sequenceSnippet Snippet of nucleotid or aminoacid sequence. + * @param optionalParametersOrNull Optional parameters. Can be <code>null</code>. The semantics depends on the type of the used sequence database. + * @since 10 + */ + @Conversational(progress = Progress.AUTOMATIC) + public List<SequenceSearchResult> searchForDataSetsWithSequences(String sessionToken, + String preferredSequenceDatabaseOrNull, String sequenceSnippet, + Map<String, String> optionalParametersOrNull); + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/SequenceSearchResultWithFullDataSet.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/SequenceSearchResultWithFullDataSet.java new file mode 100644 index 0000000000000000000000000000000000000000..a796500f26e34e0653098fa1e5f96d461fe471ae --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/SequenceSearchResultWithFullDataSet.java @@ -0,0 +1,61 @@ +/* + * Copyright 2014 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.systemsx.cisd.openbis.generic.shared.basic.dto; + +import java.io.Serializable; + +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SequenceSearchResult; + +/** + * Result of a sequence search. + * + * @author Franz-Josef Elmer + */ +public class SequenceSearchResultWithFullDataSet implements Serializable +{ + private static final long serialVersionUID = ServiceVersionHolder.VERSION; + + private AbstractExternalData dataSet; + + private SequenceSearchResult searchResult; + + public AbstractExternalData getDataSet() + { + return dataSet; + } + + public void setDataSet(AbstractExternalData dataSet) + { + this.dataSet = dataSet; + } + + public SequenceSearchResult getSearchResult() + { + return searchResult; + } + + public void setSearchResult(SequenceSearchResult searchResult) + { + this.searchResult = searchResult; + } + + @Override + public String toString() + { + return searchResult.toString(); + } +} diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTableTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTableTest.java index d3cbd3e5cecb99a7c967e5f18e45cd3b95482dc0..b30e2ea5bff158625dae20abb57693cc8c2bccef 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTableTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTableTest.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -45,12 +46,14 @@ import ch.systemsx.cisd.openbis.generic.server.business.ManagerTestTool; import ch.systemsx.cisd.openbis.generic.server.dataaccess.event.DeleteDataSetEventBuilder; import ch.systemsx.cisd.openbis.generic.shared.CommonTestUtils; import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SequenceSearchResult; import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SequenceSearchResultWithFullDataSet; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUploadContext; import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE; @@ -76,6 +79,12 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier; @Friend(toClasses = DataSetTable.class) public final class DataSetTableTest extends AbstractBOTest { + private static final Map<String, String> OPTIONAL_PARAMETERS = Collections.singletonMap("greeting", "hi"); + + private static final String SEQUENCE_SNIPPET = "GATTACA"; + + private static final String SEQUENCE_DATABASE = "MY_DB"; + private IDataStoreServiceFactory dssFactory; private DataStorePE dss1; @@ -153,6 +162,76 @@ public final class DataSetTableTest extends AbstractBOTest }); } + @Test + public void testSearchForDataSetsWithSequences() + { + DataStorePE store1 = new DataStorePE(); + store1.setRemoteUrl("http://abc1.de"); + DataStorePE store2 = new DataStorePE(); + store2.setRemoteUrl("http://abc2.de"); + store2.setSessionToken("session-2"); + DataStorePE store3 = new DataStorePE(); + prepareListDataStores(store1, store2, store3); + prepareSearchSequenceDatabase(store1, dataStoreService1, "ds1", "ds2"); + prepareSearchSequenceDatabase(store2, dataStoreService2, "ds3"); + ExternalDataPE ds1 = createDataSet("ds1", store1); + ExternalDataPE ds2 = createDataSet("ds2", store1); + ExternalDataPE ds3 = createDataSet("ds3", store2); + prepareFindFullDatasets(new ExternalDataPE[] { ds1, ds2, ds3 }, new ExternalDataPE[] { ds1, ds3 }, false, false); + + List<SequenceSearchResultWithFullDataSet> results = + createDataSetTable().searchForDataSetsWithSequences(SEQUENCE_DATABASE, SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); + + assertEquals("Database: test-db, Data set: ds1, path: ds1/path, identifier: [id-ds1], position: 42", + results.get(0).getSearchResult().toString()); + assertEquals(ds1.getCode(), results.get(0).getDataSet().getCode()); + assertEquals("/G1/P1/exp1", results.get(0).getDataSet().getExperiment().getIdentifier()); + assertEquals("Database: test-db, Data set: ds3, path: ds3/path, identifier: [id-ds3], position: 42", + results.get(1).getSearchResult().toString()); + assertEquals(ds3.getCode(), results.get(1).getDataSet().getCode()); + assertEquals("/G1/P1/exp1", results.get(1).getDataSet().getExperiment().getIdentifier()); + assertEquals(2, results.size()); + context.assertIsSatisfied(); + } + + private void prepareListDataStores(final DataStorePE... dataStores) + { + context.checking(new Expectations() + { + { + one(dataStoreDAO).listDataStores(); + will(returnValue(Arrays.asList(dataStores))); + } + }); + } + + private void prepareSearchSequenceDatabase(final DataStorePE dataStore, final IDataStoreService service, + final String... foundDataSets) + { + context.checking(new Expectations() + { + { + one(dssFactory).create(dataStore.getRemoteUrl()); + will(returnValue(service)); + + one(service).searchForDataSetsWithSequences(dataStore.getSessionToken(), + SEQUENCE_DATABASE, SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); + List<SequenceSearchResult> results = new ArrayList<SequenceSearchResult>(); + for (String foundDataSet : foundDataSets) + { + SequenceSearchResult result = new SequenceSearchResult(); + result.setSequenceDatabaseName("test-db"); + result.setDataSetCode(foundDataSet); + result.setPathInDataSet(foundDataSet + "/path"); + result.setPositionInSequence(42); + result.setSequenceIdentifier("id-" + foundDataSet); + results.add(result); + } + will(returnValue(results)); + } + }); + } + @Test public final void testLoadBySampleTechIdWithNullSampleId() { diff --git a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/IGeneralInformationService.java b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/IGeneralInformationService.java index 9075cacc810bca7b6b22e5d4fa18691b0a335d66..75153ba64d53ec09b8e87fd9d37b72524ff028d9 100644 --- a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/IGeneralInformationService.java +++ b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/IGeneralInformationService.java @@ -38,18 +38,18 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Material; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.MaterialIdentifier; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.MetaprojectAssignments; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.PropertyType; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Role; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleFetchOption; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleType; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SequenceSearchResult; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SpaceWithProjectsAndRoleAssignments; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.experiment.IExperimentId; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.metaproject.IMetaprojectId; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.project.IProjectId; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.sample.ISampleId; -import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.PropertyType; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; @@ -397,6 +397,21 @@ public interface IGeneralInformationService extends IRpcService public List<DataSet> getDataSetMetaData(String sessionToken, List<String> dataSetCodes, EnumSet<DataSetFetchOption> fetchOptions); + /** + * Searches for data sets which have nucleotid or amoniacid sequences in there files. + * If no preferred sequence database is specified the first available one will be used. If the + * preferred sequence database doesn't exist or isn't available also the first available database will be used. + * + * @param preferredSequenceDatabaseOrNull The key of the preferred sequence database or <code>null</code>. + * @param sequenceSnippet A snippet of a sequence to search for. + * @param optionalParametersOrNull Optional parameters. Can be <code>null</code>. + * The semantics depends on the type of the used sequence database. + * @since 1.29 + */ + public List<SequenceSearchResult> searchForDataSetsWithSequences(String sessionToken, + String preferredSequenceDatabaseOrNull, String sequenceSnippet, + Map<String, String> optionalParametersOrNull); + /** * Return all data sets matching specified search criteria. Note, that for returned container data sets the contained data sets have only code, * type and registration date set. @@ -405,7 +420,7 @@ public interface IGeneralInformationService extends IRpcService * @since 1.8 */ public List<DataSet> searchForDataSets(String sessionToken, SearchCriteria searchCriteria); - + /** * Return all data sets matching specified search criteria and visible to user <var>userId</var>. Note, that for returned container data sets the * contained data sets have only code, type and registration date set. diff --git a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SequenceSearchResult.java b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SequenceSearchResult.java new file mode 100644 index 0000000000000000000000000000000000000000..bec456d9040047cdcb482fa411cafd3f7b912fb0 --- /dev/null +++ b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SequenceSearchResult.java @@ -0,0 +1,101 @@ +/* + * Copyright 2014 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.systemsx.cisd.openbis.generic.shared.api.v1.dto; + +import java.io.Serializable; + +import ch.systemsx.cisd.base.annotation.JsonObject; + +/** + * Result of a sequence search. Returns the code of the data set where the sequence has been found, + * the path of the file inside the data set which has the found sequence, and the sequence identifier. + * + * @author Franz-Josef Elmer + */ +@JsonObject("SequenceSearchResult") +public class SequenceSearchResult implements Serializable +{ + private static final long serialVersionUID = 1L; + + private String sequenceDatabaseName; + + private String dataSetCode; + + private String pathInDataSet; + + private String sequenceIdentifier; + + private int positionInSequence; + + public String getSequenceDatabaseName() + { + return sequenceDatabaseName; + } + + public void setSequenceDatabaseName(String sequenceDatabaseKey) + { + this.sequenceDatabaseName = sequenceDatabaseKey; + } + + public String getDataSetCode() + { + return dataSetCode; + } + + public void setDataSetCode(String dataSet) + { + this.dataSetCode = dataSet; + } + + public String getPathInDataSet() + { + return pathInDataSet; + } + + public void setPathInDataSet(String pathInDataSet) + { + this.pathInDataSet = pathInDataSet; + } + + public String getSequenceIdentifier() + { + return sequenceIdentifier; + } + + public void setSequenceIdentifier(String sequenceIdentifier) + { + this.sequenceIdentifier = sequenceIdentifier; + } + + public int getPositionInSequence() + { + return positionInSequence; + } + + public void setPositionInSequence(int positionInSequence) + { + this.positionInSequence = positionInSequence; + } + + @Override + public String toString() + { + return "Database: " + sequenceDatabaseName + ", Data set: " + dataSetCode + ", path: " + pathInDataSet + + ", identifier: [" + sequenceIdentifier + "], position: " + positionInSequence; + } + +}