diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/AbstractDatabaseAdminDAO.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/AbstractDatabaseAdminDAO.java index 83bdc94cd7dcd57cc9bf87955a5a48f0fed6b6c6..35f17a4728f48838a07f7d8aa08d01d27020ccef 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/AbstractDatabaseAdminDAO.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/AbstractDatabaseAdminDAO.java @@ -45,6 +45,8 @@ public abstract class AbstractDatabaseAdminDAO extends SimpleJdbcDaoSupport impl protected final String readOnlyGroupOrNull; + protected final String readWriteGroupOrNull; + protected final String databaseName; protected final String databaseURL; @@ -57,17 +59,19 @@ public abstract class AbstractDatabaseAdminDAO extends SimpleJdbcDaoSupport impl * @param massUploader A class that can perform mass (batch) uploads into database tables. * @param owner Owner to be created if it doesn't exist. * @param readOnlyGroupOrNull Group name that gets read-only access. + * @param readWriteGroupOrNull Group that should be granted read-write access. * @param databaseName Name of the database. * @param databaseURL URL of the database. */ public AbstractDatabaseAdminDAO(DataSource dataSource, ISqlScriptExecutor scriptExecutor, - IMassUploader massUploader, String owner, String readOnlyGroupOrNull, String databaseName, - String databaseURL) + IMassUploader massUploader, String owner, String readOnlyGroupOrNull, + String readWriteGroupOrNull, String databaseName, String databaseURL) { this.scriptExecutor = scriptExecutor; this.massUploader = massUploader; this.owner = owner; this.readOnlyGroupOrNull = readOnlyGroupOrNull; + this.readWriteGroupOrNull = readWriteGroupOrNull; this.databaseName = databaseName; this.databaseURL = databaseURL; setDataSource(dataSource); diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DBMigrationEngine.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DBMigrationEngine.java index 64bb61c1fbd3cda9079528988fc7f60334df7d2b..98c54609fe3c9350b33caba2b38795b847ed5cfc 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DBMigrationEngine.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DBMigrationEngine.java @@ -189,7 +189,7 @@ public final class DBMigrationEngine private final void setupDatabase(final String version) { adminDAO.createOwner(); - adminDAO.createReadOnlyGroup(); + adminDAO.createGroups(); if (scriptProvider.isDumpRestore(version)) { adminDAO.restoreDatabaseFromDump(scriptProvider.getDumpFolder(version), version); diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DatabaseConfigurationContext.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DatabaseConfigurationContext.java index 193f930fb1dac97a41efc706f0358f6cdf2dd007..13334e65c5bbf4600732a58716f47b5abc5d9d6c 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DatabaseConfigurationContext.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DatabaseConfigurationContext.java @@ -84,6 +84,8 @@ public class DatabaseConfigurationContext implements DisposableBean private String readOnlyGroup; + private String readWriteGroup; + private String password; private String basicDatabaseName; @@ -93,7 +95,7 @@ public class DatabaseConfigurationContext implements DisposableBean private String urlHostPart; private String databaseInstance; - + public DatabaseConfigurationContext() { setOwner(null); @@ -293,9 +295,27 @@ public class DatabaseConfigurationContext implements DisposableBean /** * Sets the name of the group that should be granted read-only access. */ - public void setReadOnlyGroup(String readOnlyUser) + public void setReadOnlyGroup(String readOnlyGroup) + { + this.readOnlyGroup = readOnlyGroup; + } + + /** + * Sets the name of group that gets read-write access to all database objects. If + * <var>readWriteGroup</var> is <code>null</code> or empty, then no read-write group will be + * created. + */ + public String getReadWriteGroup() + { + return readWriteGroup; + } + + /** + * Sets the name of the group that should be granted read-write access. + */ + public void setReadWriteGroup(String readWriteGroup) { - this.readOnlyGroup = readOnlyUser; + this.readWriteGroup = readWriteGroup; } /** diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IDatabaseAdminDAO.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IDatabaseAdminDAO.java index 524666b8063b978aee21139834b81a31b711d3f5..2af6ece438304a1c04a7adf77df13edcbad75dac 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IDatabaseAdminDAO.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IDatabaseAdminDAO.java @@ -34,12 +34,12 @@ public interface IDatabaseAdminDAO * Returns the complete URL of the database to be created / dropped. */ public String getDatabaseURL(); - + /** * Returns meta data and maximum primary keys of all tables. */ public DatabaseDefinition getDatabaseDefinition(); - + /** * Creates the owner/user of the database. Implementation should handle the case of already * existing owner/user gracefully. @@ -47,10 +47,10 @@ public interface IDatabaseAdminDAO public void createOwner(); /** - * Creates the group that should be granted read-only access to all objects in this database. - * Implementation should handle the case of already existing group gracefully. + * Creates the groups that should be granted read-only and read-write access to all objects in + * this database. Implementation should handle the case of already existing group gracefully. */ - public void createReadOnlyGroup(); + public void createGroups(); /** * Creates the database and the 'database_version_logs' table. diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/h2/H2AdminDAO.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/h2/H2AdminDAO.java index 9585e7104bb395b5c261e8cc645ed8749272047a..a147da624f2c1c2f2a53a80e5dfaa978c5497d63 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/h2/H2AdminDAO.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/h2/H2AdminDAO.java @@ -78,7 +78,7 @@ public class H2AdminDAO extends AbstractDatabaseAdminDAO public H2AdminDAO(DataSource dataSource, ISqlScriptExecutor scriptExecutor, IMassUploader massUploader, String databaseName, String databaseURL) { - super(dataSource, scriptExecutor, massUploader, null, null, databaseName, databaseURL); + super(dataSource, scriptExecutor, massUploader, null, null, null, databaseName, databaseURL); final Matcher dbDirPartMatcherOrNull = dbDirPartPattern.matcher(databaseURL); if (dbDirPartMatcherOrNull.matches()) { @@ -94,7 +94,7 @@ public class H2AdminDAO extends AbstractDatabaseAdminDAO // Creation of the user happens "on the fly" with H2 } - public void createReadOnlyGroup() + public void createGroups() { // Creation of the user happens "on the fly" with H2 } diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/postgresql/PostgreSQLAdminDAO.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/postgresql/PostgreSQLAdminDAO.java index 4c479a113c9b28bdc328d4512d3b5f2abfad4711..d71ea874b5839c432fbd532ed9f3f6520745412f 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/postgresql/PostgreSQLAdminDAO.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/postgresql/PostgreSQLAdminDAO.java @@ -22,6 +22,7 @@ import java.util.Arrays; import javax.sql.DataSource; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.dao.DataAccessException; @@ -69,15 +70,16 @@ public class PostgreSQLAdminDAO extends AbstractDatabaseAdminDAO * @param massUploader A class that can perform mass (batch) uploads into database tables. * @param owner Owner to be created if it doesn't exist. * @param readOnlyGroup Group that should be granted read-only access. + * @param readWriteGroup Group that should be granted read-write access. * @param databaseName Name of the database. * @param databaseURL URL of the database. */ public PostgreSQLAdminDAO(DataSource dataSource, ISqlScriptExecutor scriptExecutor, - IMassUploader massUploader, String owner, String readOnlyGroup, String databaseName, - String databaseURL) + IMassUploader massUploader, String owner, String readOnlyGroup, String readWriteGroup, + String databaseName, String databaseURL) { - super(dataSource, scriptExecutor, massUploader, owner, readOnlyGroup, databaseName, - databaseURL); + super(dataSource, scriptExecutor, massUploader, owner, readOnlyGroup, readWriteGroup, + databaseName, databaseURL); } public void createOwner() @@ -105,32 +107,56 @@ public class PostgreSQLAdminDAO extends AbstractDatabaseAdminDAO } } - public void createReadOnlyGroup() + public void createGroups() { - if (readOnlyGroupOrNull == null) + if (StringUtils.isNotBlank(readOnlyGroupOrNull)) { - return; - } - try - { - getJdbcTemplate().execute("create role " + readOnlyGroupOrNull); - if (operationLog.isInfoEnabled()) + try + { + getJdbcTemplate().execute("create role " + readOnlyGroupOrNull); + if (operationLog.isInfoEnabled()) + { + operationLog.info("Created role '" + readOnlyGroupOrNull + "'."); + } + } catch (DataAccessException ex) { - operationLog.info("Created role '" + readOnlyGroupOrNull + "'."); + if (DBUtilities.isDuplicateObjectException(ex)) + { + if (operationLog.isInfoEnabled()) + { + operationLog.info("Role '" + readOnlyGroupOrNull + "' already exists."); + } + } else + { + operationLog.error("Database role '" + readOnlyGroupOrNull + + "' couldn't be created:", ex); + throw ex; + } } - } catch (DataAccessException ex) + } + if (StringUtils.isNotBlank(readWriteGroupOrNull)) { - if (DBUtilities.isDuplicateObjectException(ex)) + try { + getJdbcTemplate().execute("create role " + readWriteGroupOrNull); if (operationLog.isInfoEnabled()) { - operationLog.info("Role '" + readOnlyGroupOrNull + "' already exists."); + operationLog.info("Created role '" + readWriteGroupOrNull + "'."); } - } else + } catch (DataAccessException ex) { - operationLog - .error("Database role '" + readOnlyGroupOrNull + "' couldn't be created:", ex); - throw ex; + if (DBUtilities.isDuplicateObjectException(ex)) + { + if (operationLog.isInfoEnabled()) + { + operationLog.info("Role '" + readWriteGroupOrNull + "' already exists."); + } + } else + { + operationLog.error("Database role '" + readWriteGroupOrNull + + "' couldn't be created:", ex); + throw ex; + } } } } diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/postgresql/PostgreSQLDAOFactory.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/postgresql/PostgreSQLDAOFactory.java index 71597100f9a08c23290556debabba16a044170aa..e648aa869e5998810c470fc72548e0ccb0af1882 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/postgresql/PostgreSQLDAOFactory.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/postgresql/PostgreSQLDAOFactory.java @@ -74,7 +74,8 @@ public class PostgreSQLDAOFactory implements IDAOFactory databaseDAO = new PostgreSQLAdminDAO(context.getAdminDataSource(), sqlScriptExecutor, massUploader, context.getOwner(), context.getReadOnlyGroup(), context - .getDatabaseName(), context.getDatabaseURL()); + .getReadWriteGroup(), context.getDatabaseName(), context + .getDatabaseURL()); } public IDatabaseAdminDAO getDatabaseDAO() diff --git a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/DBMigrationEngineTest.java b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/DBMigrationEngineTest.java index 15e482d83b410e4dcc91bf149f153dbb2f1a7a03..28c923bf9e221e15e8580a6bab254c2774d0a1ab 100644 --- a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/DBMigrationEngineTest.java +++ b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/DBMigrationEngineTest.java @@ -152,7 +152,7 @@ public class DBMigrationEngineTest one(adminDAO).getDatabaseName(); will(returnValue("my 1. database")); one(adminDAO).createOwner(); - one(adminDAO).createReadOnlyGroup(); + one(adminDAO).createGroups(); one(scriptProvider).isDumpRestore(version); will(returnValue(false)); one(adminDAO).createDatabase(); @@ -205,7 +205,7 @@ public class DBMigrationEngineTest one(adminDAO).getDatabaseName(); will(returnValue("my 1. database")); one(adminDAO).createOwner(); - one(adminDAO).createReadOnlyGroup(); + one(adminDAO).createGroups(); one(scriptProvider).isDumpRestore(version); will(returnValue(true)); @@ -300,7 +300,7 @@ public class DBMigrationEngineTest one(adminDAO).getDatabaseName(); will(returnValue("my 1. database")); one(adminDAO).createOwner(); - one(adminDAO).createReadOnlyGroup(); + one(adminDAO).createGroups(); one(scriptProvider).isDumpRestore(version); will(returnValue(false)); one(adminDAO).createDatabase(); @@ -350,7 +350,7 @@ public class DBMigrationEngineTest one(adminDAO).getDatabaseName(); will(returnValue("my 1. database")); one(adminDAO).createOwner(); - one(adminDAO).createReadOnlyGroup(); + one(adminDAO).createGroups(); one(scriptProvider).isDumpRestore(version); will(returnValue(false)); one(adminDAO).createDatabase(); @@ -402,7 +402,7 @@ public class DBMigrationEngineTest one(adminDAO).getDatabaseName(); will(returnValue("my 1. database")); one(adminDAO).createOwner(); - one(adminDAO).createReadOnlyGroup(); + one(adminDAO).createGroups(); one(scriptProvider).isDumpRestore(version); will(returnValue(false)); one(adminDAO).createDatabase();