diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPluginType.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPluginType.java index 14d8ab3ffba62a7d2dd0f2c09cf106fd0a3eea23..801ffdf31f790ac704bbd43d7f9024f8525617f1 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPluginType.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPluginType.java @@ -56,5 +56,17 @@ public enum DssPluginType implements IPluginType { return pluginType.isUniquePluginNameRequired(); } + + @Override + public String getPluginKey(String technology, String pluginFolderName) + { + return pluginFolderName; + } + + @Override + public String getPrefix() + { + return ""; + } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/coreplugin/CorePluginsInjectingPropertyPlaceholderConfigurer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/coreplugin/CorePluginsInjectingPropertyPlaceholderConfigurer.java index 29dbde883ae3d75ecf186eb84500722ac742fdd8..afad1045608cf455f7d627f96628a9c7faaf7508 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/coreplugin/CorePluginsInjectingPropertyPlaceholderConfigurer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/coreplugin/CorePluginsInjectingPropertyPlaceholderConfigurer.java @@ -21,6 +21,7 @@ import java.util.Properties; import ch.systemsx.cisd.common.maintenance.MaintenanceTaskUtils; import ch.systemsx.cisd.common.spring.ExposablePropertyPlaceholderConfigurer; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.DataStoreServerBasedDataSourceProvider; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CustomImport; import ch.systemsx.cisd.openbis.generic.shared.coreplugin.CorePluginScanner.ScannerType; import ch.systemsx.cisd.openbis.generic.shared.coreplugin.CorePluginsInjector; @@ -40,6 +41,7 @@ public class CorePluginsInjectingPropertyPlaceholderConfigurer extends protected void loadProperties(Properties properties) throws IOException { super.loadProperties(properties); + PluginType dssDataSources = createPluginTypeDssDataSources(); PluginType maintenanceTasks = new PluginType("maintenance-tasks", MaintenanceTaskUtils.DEFAULT_MAINTENANCE_PLUGINS_PROPERTY_NAME); @@ -50,8 +52,28 @@ public class CorePluginsInjectingPropertyPlaceholderConfigurer extends PluginType miscellaneous = new PluginType("miscellaneous", null); new CorePluginsInjector(ScannerType.AS, new IPluginType[] - { maintenanceTasks, customImports, queryDatabases, miscellaneous }) + { dssDataSources, maintenanceTasks, customImports, queryDatabases, miscellaneous }) .injectCorePlugins(properties); } + private PluginType createPluginTypeDssDataSources() + { + return new PluginType("dss-data-sources", DataStoreServerBasedDataSourceProvider.ROOT_KEY + + "." + DataStoreServerBasedDataSourceProvider.DATA_STORE_SERVERS_KEY) + { + + @Override + public String getPluginKey(String technology, String pluginFolderName) + { + return pluginFolderName + "[" + technology + "]"; + } + + @Override + public String getPrefix() + { + return DataStoreServerBasedDataSourceProvider.ROOT_KEY + "."; + } + }; + } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/DataStoreServerBasedDataSourceProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/DataStoreServerBasedDataSourceProvider.java index e3e2f099f0c6e8d9f98d3e84e7f87a3590a7b2fc..33c0a31e35e04b43d8334ab07cda987f26e560ab 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/DataStoreServerBasedDataSourceProvider.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/DataStoreServerBasedDataSourceProvider.java @@ -42,9 +42,9 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; public class DataStoreServerBasedDataSourceProvider implements IDataSourceProvider, InitializingBean { - private static final String ROOT_KEY = "dss-based-data-source-provider"; + public static final String ROOT_KEY = "dss-based-data-source-provider"; - static final String DATA_STORE_SERVERS_KEY = "data-store-servers"; + public static final String DATA_STORE_SERVERS_KEY = "data-store-servers"; @Resource(name = ExposablePropertyPlaceholderConfigurer.PROPERTY_CONFIGURER_BEAN_NAME) private ExposablePropertyPlaceholderConfigurer configurer; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjector.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjector.java index 05734855461fb3d01e5a1b29087b426521cc597b..9e5ae1c94400f5e765a5eefdb13592ffac71a9de 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjector.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjector.java @@ -42,6 +42,7 @@ import ch.systemsx.cisd.common.logging.Log4jSimpleLogger; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; import ch.systemsx.cisd.common.logging.LogLevel; +import ch.systemsx.cisd.common.shared.basic.utils.CommaSeparatedListBuilder; import ch.systemsx.cisd.common.utilities.PropertyParametersUtil; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CorePlugin; import ch.systemsx.cisd.openbis.generic.shared.coreplugin.CorePluginScanner.ScannerType; @@ -129,21 +130,24 @@ public class CorePluginsInjector Map<String, NamedCorePluginFolder> map = entry.getValue(); for (Entry<String, NamedCorePluginFolder> entry2 : map.entrySet()) { - String pluginName = entry2.getKey(); + String fullPluginName = entry2.getKey(); NamedCorePluginFolder plugin = entry2.getValue(); File definingFolder = plugin.getDefiningFolder(); if (new File(definingFolder, DISABLED_MARKER_FILE_NAME).exists()) { continue; } + String technology = plugin.getTechnology(); Properties pluginProperties = getPluginProperties(definingFolder); if (pluginType.isUniquePluginNameRequired()) { - pluginKeyBundles.addPluginNameFor(pluginType, pluginName); + String pluginKey = pluginType.getPluginKey(technology, plugin.getName()); + pluginKeyBundles.addPluginNameFor(pluginType, pluginKey); + String prefix = pluginType.getPrefix() + pluginKey + "."; for (Entry<Object, Object> keyValuePair : pluginProperties.entrySet()) { String value = keyValuePair.getValue().toString(); - injectProperty(properties, pluginName + "." + keyValuePair.getKey(), value); + injectProperty(properties, prefix + keyValuePair.getKey(), value); } } else { @@ -219,7 +223,7 @@ public class CorePluginsInjector String technology = corePlugin.getName(); if (isTechnologyEnabled(enabledTechnologies, technology) == false) { - DEFAULT_LOGGER.log(LogLevel.INFO, "Core plugins for technology '" + technology + logger.log(LogLevel.INFO, "Core plugins for technology '" + technology + "' are not enabled."); continue; } @@ -244,10 +248,13 @@ public class CorePluginsInjector String pluginName = pluginFolder.getName(); NamedCorePluginFolder plugin = new NamedCorePluginFolder(technology, pluginType, pluginFolder); - String fullPluginName = plugin.getName(); + String fullPluginName = plugin.getFullPluginName(); if (isDisabled(disabledPlugins, fullPluginName) == false) { - assertAndAddPluginName(pluginName, pluginNames, pluginType); + String fullPluginKey = + pluginType.getPrefix() + + pluginType.getPluginKey(technology, pluginName); + assertAndAddPluginName(fullPluginKey, pluginNames, pluginType); Map<String, NamedCorePluginFolder> map = typeToPluginsMap.get(pluginType); if (map == null) @@ -256,7 +263,7 @@ public class CorePluginsInjector new LinkedHashMap<String, CorePluginsInjector.NamedCorePluginFolder>(); typeToPluginsMap.put(pluginType, map); } - map.put(pluginName, plugin); + map.put(fullPluginKey, plugin); } } } @@ -364,7 +371,8 @@ public class CorePluginsInjector String key = pluginType.getKeyOfKeyListPropertyOrNull(); if (key != null) { - keyBundles.put(pluginType, new KeyBundle(properties, key)); + keyBundles.put(pluginType, new KeyBundle(properties, pluginType.getPrefix(), + key)); } } } @@ -391,12 +399,12 @@ public class CorePluginsInjector } } - void addPluginNameFor(IPluginType pluginType, String pluginName) + void addPluginNameFor(IPluginType pluginType, String pluginKey) { KeyBundle keyBundle = keyBundles.get(pluginType); if (keyBundle != null) { - keyBundle.addKey(pluginName); + keyBundle.addKey(pluginKey); } } @@ -415,8 +423,11 @@ public class CorePluginsInjector private final Set<String> keys; - KeyBundle(Properties properties, String key) + private final String prefix; + + KeyBundle(Properties properties, String prefix, String key) { + this.prefix = prefix; this.key = key; keys = new TreeSet<String>(); String keysAsString = properties.getProperty(key); @@ -436,13 +447,14 @@ public class CorePluginsInjector { for (String keyPrefix : keys) { - if (pluginNames.contains(keyPrefix)) + String fullPrefix = prefix + keyPrefix; + if (pluginNames.contains(fullPrefix)) { - throw new ConfigurationFailureException("Property key '" + keyPrefix + throw new ConfigurationFailureException("Property key '" + fullPrefix + "' for key list '" + key + "' is already defined in some other key list."); } - pluginNames.add(keyPrefix); + pluginNames.add(fullPrefix); } } @@ -450,13 +462,9 @@ public class CorePluginsInjector { if (keys.isEmpty() == false) { - StringBuilder builder = new StringBuilder(); + CommaSeparatedListBuilder builder = new CommaSeparatedListBuilder(); for (String k : keys) { - if (builder.length() > 0) - { - builder.append(", "); - } builder.append(k); } properties.setProperty(key, builder.toString()); @@ -466,15 +474,19 @@ public class CorePluginsInjector private static final class NamedCorePluginFolder { - private final String name; + private final String fullPluginName; private final File definingFolder; + private final String technology; + + private final String name; + NamedCorePluginFolder(String technology, IPluginType pluginType, File definingFolder) { - name = - technology + ":" + pluginType.getSubFolderName() + ":" - + definingFolder.getName(); + this.technology = technology; + name = definingFolder.getName(); + fullPluginName = technology + ":" + pluginType.getSubFolderName() + ":" + name; this.definingFolder = definingFolder; if (definingFolder.isDirectory() == false) { @@ -482,11 +494,21 @@ public class CorePluginsInjector } } + String getTechnology() + { + return technology; + } + String getName() { return name; } + String getFullPluginName() + { + return fullPluginName; + } + File getDefiningFolder() { return definingFolder; @@ -495,7 +517,7 @@ public class CorePluginsInjector @Override public String toString() { - return name + " [" + definingFolder + "]"; + return fullPluginName + " [" + definingFolder + "]"; } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/IPluginType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/IPluginType.java index 643a3cee955fd9a307bf34574c774281e27d67a1..d3291b362b6a1b7db9e3330b3ce031884f81a6a2 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/IPluginType.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/IPluginType.java @@ -17,9 +17,9 @@ package ch.systemsx.cisd.openbis.generic.shared.coreplugin; /** - * A core plugin type is defined by a name which is used as a folder and an optional - * property which lists all keys of the plugins of this type. - * + * A core plugin type is defined by a name which is used as a folder and an optional property which + * lists all keys of the plugins of this type. + * * @author Franz-Josef Elmer */ public interface IPluginType @@ -29,6 +29,10 @@ public interface IPluginType public String getKeyOfKeyListPropertyOrNull(); + public String getPluginKey(String technology, String pluginFolderName); + + public String getPrefix(); + public boolean isUniquePluginNameRequired(); } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/PluginType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/PluginType.java index b0db792052482724304455224868543765b6fb94..b094165c8707cc8666f1db419ad5bba62d61b3d5 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/PluginType.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/PluginType.java @@ -49,4 +49,16 @@ public class PluginType implements IPluginType { return keyOfKeyListPropertyOrNull != null; } + + @Override + public String getPluginKey(String technology, String pluginFolderName) + { + return pluginFolderName; + } + + @Override + public String getPrefix() + { + return ""; + } } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjectorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjectorTest.java index 87b57828b7d109e9443bbcb3201d4f8b235f5972..c6bee6ac1e5e1d2d1abcde6aebf8dc5ed9b0962a 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjectorTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjectorTest.java @@ -78,8 +78,22 @@ public class CorePluginsInjectorTest extends AbstractFileSystemTestCase PluginType type3 = new PluginType("services", PLUGIN_SERVICES_LIST_KEY); PluginType type4 = new PluginType("miscellaneous", null); PluginType type5 = new PluginType("processing-plugins", "processing-plugins"); + PluginType type6 = new PluginType("dss-data-sources", "prefix.dss") + { + @Override + public String getPluginKey(String technology, String pluginFolderName) + { + return pluginFolderName + "[" + technology + "]"; + } + + @Override + public String getPrefix() + { + return "prefix."; + } + }; injector = new CorePluginsInjector(ScannerType.DSS, new IPluginType[] - { type1, type2, type3, type4, type5 }, logger); + { type1, type2, type3, type4, type5, type6 }, logger); corePluginsFolder = new File(workingDirectory, "core-plugins"); corePluginsFolder.mkdirs(); corePluginsFolderProperty = @@ -334,6 +348,7 @@ public class CorePluginsInjectorTest extends AbstractFileSystemTestCase properties.setProperty(DISABLED_CORE_PLUGINS_KEY, "screening:miscellaneous, screening:drop-boxes:dp1"); preparePluginNameLog("screening:drop-boxes:dp2 [" + dp2 + "]"); + prepareNotEnabledTechnology("proteomics"); injector.injectCorePlugins(properties); @@ -402,6 +417,82 @@ public class CorePluginsInjectorTest extends AbstractFileSystemTestCase context.assertIsSatisfied(); } + @Test + public void testDssDataSource() + { + File pluginFolder = new File(corePluginsFolder, "screening/1/dss/dss-data-sources/dss1"); + pluginFolder.mkdirs(); + FileUtilities.writeToFile(new File(pluginFolder, PLUGIN_PROPERTIES_FILE_NAME), + "driver = alpha\nurl = blabla"); + Properties properties = createProperties(); + properties.setProperty("prefix.dss", "dss1[proteomics]"); + properties.setProperty("prefix.dss1[proteomics].driver", "gamma"); + preparePluginNameLog("screening:dss-data-sources:dss1 [" + pluginFolder + "]"); + + injector.injectCorePlugins(properties); + + assertProperties(corePluginsFolderProperty + enabledScreeningProperty + + "prefix.dss = dss1[proteomics], dss1[screening]\n" + + "prefix.dss1[proteomics].driver = gamma\n" + + "prefix.dss1[screening].driver = alpha\n" + + "prefix.dss1[screening].url = blabla\n", properties); + + context.assertIsSatisfied(); + } + + @Test + public void testDssDataSourcesForDifferentTechnologiesButSameDSS() + { + File screeningPluginFolder = + new File(corePluginsFolder, "screening/1/dss/dss-data-sources/dss1"); + screeningPluginFolder.mkdirs(); + FileUtilities.writeToFile(new File(screeningPluginFolder, PLUGIN_PROPERTIES_FILE_NAME), + "driver = alpha\nurl = blabla"); + File proteomicsPluginFolder = + new File(corePluginsFolder, "proteomics/1/dss/dss-data-sources/dss1"); + proteomicsPluginFolder.mkdirs(); + FileUtilities.writeToFile(new File(proteomicsPluginFolder, PLUGIN_PROPERTIES_FILE_NAME), + "driver = beta\nurl = blub"); + Properties properties = createProperties("screening, proteomics"); + preparePluginNameLog("screening:dss-data-sources:dss1 [" + screeningPluginFolder + "]"); + preparePluginNameLog("proteomics:dss-data-sources:dss1 [" + proteomicsPluginFolder + "]"); + + injector.injectCorePlugins(properties); + + assertProperties(corePluginsFolderProperty + + ch.systemsx.cisd.openbis.generic.shared.Constants.ENABLED_TECHNOLOGIES_KEY + + " = screening, proteomics\n" + "prefix.dss = dss1[proteomics], dss1[screening]\n" + + "prefix.dss1[proteomics].driver = beta\n" + + "prefix.dss1[proteomics].url = blub\n" + + "prefix.dss1[screening].driver = alpha\n" + + "prefix.dss1[screening].url = blabla\n", properties); + + context.assertIsSatisfied(); + } + + @Test + public void testDssDataSourceFailedBecauseOfDuplicatedPlugin() + { + File pluginFolder = new File(corePluginsFolder, "screening/1/dss/dss-data-sources/dss1"); + pluginFolder.mkdirs(); + FileUtilities.writeToFile(new File(pluginFolder, PLUGIN_PROPERTIES_FILE_NAME), + "driver = alpha\nurl = blabla"); + Properties properties = createProperties(); + properties.setProperty("prefix.dss", "dss1[screening]"); + properties.setProperty("prefix.dss1[screening].driver", "gamma"); + + try + { + injector.injectCorePlugins(properties); + fail("ConfigurationFailureException expected."); + } catch (ConfigurationFailureException ex) + { + assertEquals("There is already a plugin named 'prefix.dss1[screening]'.", + ex.getMessage()); + } + context.assertIsSatisfied(); + } + private void preparePluginNameLog(final String... fullPluginNames) { context.checking(new Expectations() @@ -415,6 +506,17 @@ public class CorePluginsInjectorTest extends AbstractFileSystemTestCase }); } + private void prepareNotEnabledTechnology(final String technology) + { + context.checking(new Expectations() + { + { + one(logger).log(LogLevel.INFO, + "Core plugins for technology '" + technology + "' are not enabled."); + } + }); + } + private void assertProperties(String expectedProperties, Properties properties) { Set<Entry<Object, Object>> entrySet = properties.entrySet();