From b04014ca62e97b58320e56972b0e026b4bdb5e53 Mon Sep 17 00:00:00 2001
From: brinn <brinn>
Date: Tue, 26 May 2009 11:17:37 +0000
Subject: [PATCH] add: support for the read-write group

SVN: 11148
---
 .../dbmigration/AbstractDatabaseAdminDAO.java |  8 ++-
 .../cisd/dbmigration/DBMigrationEngine.java   |  2 +-
 .../DatabaseConfigurationContext.java         | 26 +++++++-
 .../cisd/dbmigration/IDatabaseAdminDAO.java   | 10 +--
 .../cisd/dbmigration/h2/H2AdminDAO.java       |  4 +-
 .../postgresql/PostgreSQLAdminDAO.java        | 66 +++++++++++++------
 .../postgresql/PostgreSQLDAOFactory.java      |  3 +-
 .../dbmigration/DBMigrationEngineTest.java    | 10 +--
 8 files changed, 90 insertions(+), 39 deletions(-)

diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/AbstractDatabaseAdminDAO.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/AbstractDatabaseAdminDAO.java
index 83bdc94cd7d..35f17a4728f 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 64bb61c1fbd..98c54609fe3 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 193f930fb1d..13334e65c5b 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 524666b8063..2af6ece4383 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 9585e7104bb..a147da624f2 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 4c479a113c9..d71ea874b58 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 71597100f9a..e648aa869e5 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 15e482d83b4..28c923bf9e2 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();
-- 
GitLab