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 7bf852bc58dee53f73070a08c7255287ac85f21f..cc79b2b28eb9eb3eb8ccd56286a0c71922522d0b 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 @@ -196,31 +196,31 @@ public class DataStoreServerBasedDataSourceProvider implements IDataSourceProvid Properties props = ExtendedProperties.createWith(properties); if (definitionOrNull != null) { - if (properties.getProperty(DRIVER_KEY) == null) - { - props.setProperty(DRIVER_KEY, definitionOrNull.getDriverClassName()); - } - if (properties.getProperty(USER_KEY) == null) - { - props.setProperty(USER_KEY, definitionOrNull.getUsername()); - } - if (properties.getProperty(PASSWORD_KEY) == null) - { - props.setProperty(PASSWORD_KEY, definitionOrNull.getPassword()); - } - if (properties.getProperty(URL_KEY) == null) - { - DatabaseEngine engine = - DatabaseEngine.getEngineForDriverClass(definitionOrNull - .getDriverClassName()); - String url = - engine.getURL(definitionOrNull.getHostPart(), definitionOrNull.getSid()); + String driverClassName = definitionOrNull.getDriverClassName(); + setProperty(props, DRIVER_KEY, driverClassName); + setProperty(props, USER_KEY, definitionOrNull.getUsername()); + setProperty(props, PASSWORD_KEY, definitionOrNull.getPassword()); + String hostPart = definitionOrNull.getHostPart(); + String sid = definitionOrNull.getSid(); + if (properties.getProperty(URL_KEY) == null && driverClassName != null + && hostPart != null && sid != null) + { + DatabaseEngine engine = DatabaseEngine.getEngineForDriverClass(driverClassName); + String url = engine.getURL(hostPart, sid); props.setProperty(URL_KEY, url); } } return props; } + private void setProperty(Properties properties, String key, String valueOrNull) + { + if (properties.getProperty(key) == null && valueOrNull != null) + { + properties.setProperty(key, valueOrNull); + } + } + @Override public synchronized void handle(String dataStoreCode, List<DataSourceDefinition> dataSourceDefinitions) diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/DataStoreServerBasedDataSourceProviderTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/DataStoreServerBasedDataSourceProviderTest.java index 581d2c7657d9e9a72dd78b84965d910104e31fcb..50cfb045257c76c40504c9767c37aefaee59b46c 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/DataStoreServerBasedDataSourceProviderTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/DataStoreServerBasedDataSourceProviderTest.java @@ -16,6 +16,8 @@ package ch.systemsx.cisd.openbis.generic.server.dataaccess; +import static ch.systemsx.cisd.dbmigration.SimpleDatabaseConfigurationContext.PASSWORD_KEY; +import static ch.systemsx.cisd.dbmigration.SimpleDatabaseConfigurationContext.USER_KEY; import static ch.systemsx.cisd.openbis.generic.server.dataaccess.DataStoreServerBasedDataSourceProvider.DATA_STORE_SERVERS_KEY; import java.io.File; @@ -55,6 +57,8 @@ import ch.systemsx.cisd.openbis.generic.shared.util.IDataSourceFactory; */ public class DataStoreServerBasedDataSourceProviderTest extends AbstractFileSystemTestCase { + private static final String PLUGIN_KEY = "key"; + private static final String DRIVER_CLASS = DatabaseEngine.POSTGRESQL.getDriverClass(); private static class MockDataSource extends MonitoringDataSource @@ -93,6 +97,7 @@ public class DataStoreServerBasedDataSourceProviderTest extends AbstractFileSyst daofactory = context.mock(IDAOFactory.class); dataStoreDAO = context.mock(IDataStoreDAO.class); mappingFile = new File(workingDirectory, "mapping.txt"); + mappingFile.delete(); context.checking(new Expectations() { { @@ -163,6 +168,142 @@ public class DataStoreServerBasedDataSourceProviderTest extends AbstractFileSyst context.assertIsSatisfied(); } + @Test + public void testRestartDSS2WithChangedDatabase() + { + DataSourceConfigBuilder builder = new DataSourceConfigBuilder(); + builder.plugin("DSS", null).property(PLUGIN_KEY, "DSS"); + props = builder.get(); + FileUtilities.writeToFile(mappingFile, "*.*.config = DSS\n" + + "*.screening.data-source-code = imaging_db\n"); + DataStorePE dss1 = + dataStore("DSS1", new DataSourceDefinitionBuilder().code("imaging_db") + .driverClassName(DRIVER_CLASS).hostPart("ab").sid("imaging_dev").get()); + DataStorePE dss2 = + dataStore("DSS2", new DataSourceDefinitionBuilder().code("imaging_db") + .driverClassName(DRIVER_CLASS).hostPart("abc").sid("imaging_dev").get()); + prepareListDataStores(dss1, dss2); + DataStoreServerBasedDataSourceProvider dataSourceProvider = createDataSourceProvider(); + DataSource ds1 = dataSourceProvider.getDataSourceByDataStoreServerCode("dss1", "screening"); + assertSame(ds1, dataSourceProvider.getDataSourceByDataStoreServerCode("dss1", "screening")); + assertSame(ds1, dataSourceProvider.getDataSourceByDataStoreServerCode("dss1", "screening")); + assertDataSourceProps("[database-driver=org.postgresql.Driver, " + + "database-url=jdbc:postgresql://ab/imaging_dev, key=DSS]", ds1); + DataSource ds2 = dataSourceProvider.getDataSourceByDataStoreServerCode("dss2", "screening"); + assertSame(ds2, dataSourceProvider.getDataSourceByDataStoreServerCode("dss2", "screening")); + final DataStorePE dataStore2 = dataStore("DSS2"); + prepareLoadAndUpdateDataStore(dataStore2); + + dataSourceProvider.handle( + "DSS2", + Arrays.asList(new DataSourceDefinitionBuilder().code("imaging_db") + .driverClassName(DRIVER_CLASS).hostPart("ab").sid("imaging_dev").get())); + + assertSame(ds1, dataSourceProvider.getDataSourceByDataStoreServerCode("dss1", "screening")); + assertEquals(false, ((MockDataSource) ds1).closed); + assertEquals(true, ((MockDataSource) ds2).closed); + DataSource ds22 = + dataSourceProvider.getDataSourceByDataStoreServerCode("dss2", "screening"); + assertDataSourceProps("[database-driver=org.postgresql.Driver, " + + "database-url=jdbc:postgresql://ab/imaging_dev, key=DSS]", ds22); + assertNotSame(ds2, ds22); + assertEquals( + "code=imaging_db\tdriverClassName=org.postgresql.Driver\thostPart=ab\tsid=imaging_dev\t\n", + dataStore2.getSerializedDataSourceDefinitions()); + context.assertIsSatisfied(); + } + + @Test + public void testRestartDSS2WithUnchangedDatabase() + { + DataSourceConfigBuilder builder = new DataSourceConfigBuilder(); + builder.plugin("DSS", null).property(PLUGIN_KEY, "DSS"); + props = builder.get(); + FileUtilities.writeToFile(mappingFile, "*.*.config = DSS\n" + + "*.screening.data-source-code = imaging_db\n"); + DataStorePE dss1 = + dataStore("DSS1", new DataSourceDefinitionBuilder().code("imaging_db") + .driverClassName(DRIVER_CLASS).hostPart("abc").sid("imaging_dev").get()); + DataStorePE dss2 = + dataStore("DSS2", new DataSourceDefinitionBuilder().code("imaging_db") + .driverClassName(DRIVER_CLASS).hostPart("abc").sid("imaging_dev").get()); + prepareListDataStores(dss1, dss2); + DataStoreServerBasedDataSourceProvider dataSourceProvider = createDataSourceProvider(); + DataSource ds1 = dataSourceProvider.getDataSourceByDataStoreServerCode("dss1", "screening"); + assertDataSourceProps("[database-driver=org.postgresql.Driver, " + + "database-url=jdbc:postgresql://abc/imaging_dev, key=DSS]", ds1); + assertSame(ds1, dataSourceProvider.getDataSourceByDataStoreServerCode("dss2", "screening")); + assertSame(ds1, dataSourceProvider.getDataSourceByDataStoreServerCode("dss2", "screening")); + final DataStorePE dataStore2 = dataStore("DSS2"); + prepareLoadAndUpdateDataStore(dataStore2); + + dataSourceProvider.handle( + "DSS2", + Arrays.asList(new DataSourceDefinitionBuilder().code("imaging_db") + .driverClassName(DRIVER_CLASS).hostPart("abc").sid("imaging_dev").get())); + + assertSame(ds1, dataSourceProvider.getDataSourceByDataStoreServerCode("dss1", "screening")); + assertSame(ds1, dataSourceProvider.getDataSourceByDataStoreServerCode("dss2", "screening")); + assertEquals( + "code=imaging_db\tdriverClassName=org.postgresql.Driver\thostPart=abc\tsid=imaging_dev\t\n", + dataStore2.getSerializedDataSourceDefinitions()); + context.assertIsSatisfied(); + } + + @Test + public void testKeepUsernameAndPasswordOfASCorePluginIgnoreDSSSettings() + { + DataSourceConfigBuilder builder = new DataSourceConfigBuilder(); + builder.plugin("DSS", null).property(PLUGIN_KEY, "DSS").property(USER_KEY, "einstein") + .property(PASSWORD_KEY, "c is constant"); + props = builder.get(); + FileUtilities.writeToFile(mappingFile, "*.*.config = DSS\n" + + "*.screening.data-source-code = imaging_db\n"); + DataStorePE dss1 = + dataStore( + "DSS1", + new DataSourceDefinitionBuilder().code("imaging_db") + .driverClassName(DRIVER_CLASS).hostPart("abc").sid("imaging_dev") + .username("newton").password("no limits").get()); + prepareListDataStores(dss1); + DataStoreServerBasedDataSourceProvider dataSourceProvider = createDataSourceProvider(); + + DataSource ds1 = dataSourceProvider.getDataSourceByDataStoreServerCode("dss1", "screening"); + + assertDataSourceProps("[database-driver=org.postgresql.Driver, " + + "database-password=c is constant, " + + "database-url=jdbc:postgresql://abc/imaging_dev, " + + "database-username=einstein, key=DSS]", ds1); + context.assertIsSatisfied(); + } + + @Test + public void testKeepUsernameAndPasswordOfASCorePluginIgnoreMappingFile() + { + DataSourceConfigBuilder builder = new DataSourceConfigBuilder(); + builder.plugin("DSS", null).property(PLUGIN_KEY, "DSS").property(USER_KEY, "einstein") + .property(PASSWORD_KEY, "c is constant"); + props = builder.get(); + FileUtilities.writeToFile(mappingFile, "*.*.config = DSS\n" + + "*.screening.data-source-code = imaging_db\n" + "*.screening.username = bohr\n"); + DataStorePE dss1 = + dataStore( + "DSS1", + new DataSourceDefinitionBuilder().code("imaging_db") + .driverClassName(DRIVER_CLASS).hostPart("abc").sid("imaging_dev") + .username("newton").password("no limits").get()); + prepareListDataStores(dss1); + DataStoreServerBasedDataSourceProvider dataSourceProvider = createDataSourceProvider(); + + DataSource ds1 = dataSourceProvider.getDataSourceByDataStoreServerCode("dss1", "screening"); + + assertDataSourceProps("[database-driver=org.postgresql.Driver, " + + "database-password=c is constant, " + + "database-url=jdbc:postgresql://abc/imaging_dev, " + + "database-username=einstein, key=DSS]", ds1); + context.assertIsSatisfied(); + } + /** * This use case simulates the following use case: * <ol> @@ -176,7 +317,7 @@ public class DataStoreServerBasedDataSourceProviderTest extends AbstractFileSyst public void testThreeDssDBOneAtDSSTwoOnAS() { DataSourceConfigBuilder builder = new DataSourceConfigBuilder(); - builder.plugin("all", "screening").property("key", "all[screening]"); + builder.plugin("all", "screening").property(PLUGIN_KEY, "all[screening]"); props = builder.get(); FileUtilities.writeToFile(mappingFile, "# example mapping file\n" + "*.proteomics.config = all[proteomics]\n" @@ -252,6 +393,19 @@ public class DataStoreServerBasedDataSourceProviderTest extends AbstractFileSyst }); } + private void prepareLoadAndUpdateDataStore(final DataStorePE dataStore) + { + context.checking(new Expectations() + { + { + one(dataStoreDAO).tryToFindDataStoreByCode(dataStore.getCode()); + will(returnValue(dataStore)); + + one(dataStoreDAO).createOrUpdateDataStore(dataStore); + } + }); + } + private DataStorePE dataStore(String code, DataSourceDefinition... definitions) { DataStorePE dataStore = new DataStorePE();