From: Aron Roberts Date: Fri, 5 Dec 2014 02:47:39 +0000 (-0800) Subject: CSPACE-6520: Move additional database utility code into JDBCTools from ServiceMain. X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=041b33b852e00a68dc4c6b4500ac77256371d770;p=tmp%2Fjakarta-migration.git CSPACE-6520: Move additional database utility code into JDBCTools from ServiceMain. --- diff --git a/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java b/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java index af5517558..b38e41d3b 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java +++ b/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java @@ -491,11 +491,6 @@ public class ServiceMain { * */ private HashSet createNuxeoDatabases() throws Exception { - final String DB_EXISTS_QUERY_PSQL = - "SELECT 1 AS result FROM pg_database WHERE datname=?"; - final String DB_EXISTS_QUERY_MYSQL = - "SELECT 1 AS result FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME=?"; - String nuxeoUser = getBasicDataSourceUsername(JDBCTools.NUXEO_DATASOURCE_NAME); String nuxeoPW = getBasicDataSourcePassword(JDBCTools.NUXEO_DATASOURCE_NAME); @@ -504,89 +499,78 @@ public class ServiceMain { DatabaseProductType dbType = JDBCTools.getDatabaseProductType(JDBCTools.CSADMIN_DATASOURCE_NAME, getServiceConfig().getDbCsadminName()); - String dbExistsQuery = (dbType == DatabaseProductType.POSTGRESQL) ? DB_EXISTS_QUERY_PSQL : - DB_EXISTS_QUERY_MYSQL; Hashtable tenantBindings = tenantBindingConfigReader.getTenantBindings(); HashSet nuxeoDBsChecked = new HashSet(); - PreparedStatement pstmt = null; - Statement stmt = null; - Connection conn = null; - - try { - DataSource csadminDataSource = JDBCTools.getDataSource(JDBCTools.CSADMIN_DATASOURCE_NAME); - conn = csadminDataSource.getConnection(); - pstmt = conn.prepareStatement(dbExistsQuery); // create a statement - stmt = conn.createStatement(); - // First check and create the roles as needed. (nuxeo and reader) - for (TenantBindingType tenantBinding : tenantBindings.values()) { - String tId = tenantBinding.getId(); - String tName = tenantBinding.getName(); - List repoDomainList = tenantBinding.getRepositoryDomain(); - for (RepositoryDomainType repoDomain : repoDomainList) { - String repoDomainName = repoDomain.getName(); - String repositoryName = repoDomain.getRepositoryName(); - String cspaceInstanceId = getCspaceInstanceId(); - String dbName = JDBCTools.getDatabaseName(repositoryName, cspaceInstanceId); - if (nuxeoDBsChecked.contains(dbName)) { - if (logger.isDebugEnabled()) { - logger.debug("Another user of db: " + dbName + ": Repo: " + repoDomainName - + " and tenant: " + tName + " (id:" + tId + ")"); - } - } else { - if (logger.isDebugEnabled()) { - logger.debug("Need to prepare db: " + dbName + " for Repo: " + repoDomainName - + " and tenant: " + tName + " (id:" + tId + ")"); - } - - pstmt.setString(1, dbName); // set dbName param - ResultSet rs = pstmt.executeQuery(); - // extract data from the ResultSet - boolean dbExists = rs.next(); - rs.close(); - if (dbExists) { - if (logger.isDebugEnabled()) { - logger.debug("Database: " + dbName + " already exists."); - } - } else { - // Create the user as needed - JDBCTools.createNewDatabaseUser(JDBCTools.CSADMIN_DATASOURCE_NAME, repositoryName, cspaceInstanceId, dbType, nuxeoUser, nuxeoPW); - if (readerUser != null) { - JDBCTools.createNewDatabaseUser(JDBCTools.CSADMIN_DATASOURCE_NAME, repositoryName, cspaceInstanceId, dbType, readerUser, readerPW); - } - // Create the database - createDatabaseWithRights(conn, dbType, dbName, nuxeoUser, nuxeoPW, readerUser, readerPW); - } - nuxeoDBsChecked.add(dbName); - } - } // Loop on repos for tenant - } // Loop on tenants - } finally { //close resources - try { - if (stmt != null) { - stmt.close(); - } - if (conn != null) { - conn.close(); - } - } catch(SQLException se) { - se.printStackTrace(); - } - } + // First check and create the roles as needed. (nuxeo and reader) + for (TenantBindingType tenantBinding : tenantBindings.values()) { + String tId = tenantBinding.getId(); + String tName = tenantBinding.getName(); + List repoDomainList = tenantBinding.getRepositoryDomain(); + for (RepositoryDomainType repoDomain : repoDomainList) { + String repoDomainName = repoDomain.getName(); + String repositoryName = repoDomain.getRepositoryName(); + String cspaceInstanceId = getCspaceInstanceId(); + String dbName = JDBCTools.getDatabaseName(repositoryName, cspaceInstanceId); + if (nuxeoDBsChecked.contains(dbName)) { + if (logger.isDebugEnabled()) { + logger.debug("Another user of db: " + dbName + ": Repo: " + repoDomainName + + " and tenant: " + tName + " (id:" + tId + ")"); + } + } else { + if (logger.isDebugEnabled()) { + logger.debug("Need to prepare db: " + dbName + " for Repo: " + repoDomainName + + " and tenant: " + tName + " (id:" + tId + ")"); + } + boolean dbExists = JDBCTools.hasDatabase(dbType, dbName); + if (dbExists) { + if (logger.isDebugEnabled()) { + logger.debug("Database: " + dbName + " already exists."); + } + } else { + // Create the user as needed + JDBCTools.createNewDatabaseUser(JDBCTools.CSADMIN_DATASOURCE_NAME, repositoryName, cspaceInstanceId, dbType, nuxeoUser, nuxeoPW); + if (readerUser != null) { + JDBCTools.createNewDatabaseUser(JDBCTools.CSADMIN_DATASOURCE_NAME, repositoryName, cspaceInstanceId, dbType, readerUser, readerPW); + } + // Create the database + createDatabaseWithRights(dbType, dbName, nuxeoUser, nuxeoPW, readerUser, readerPW); + } + nuxeoDBsChecked.add(dbName); + } + } // Loop on repos for tenant + } // Loop on tenants return nuxeoDBsChecked; } - private void createDatabaseWithRights(Connection conn, DatabaseProductType dbType, String dbName, String ownerName, + /** + * Creates a Nuxeo-managed database, sets up an owner for that + * database, and adds (at least) connection privileges to a reader + * of that database. + * + * @param conn + * @param dbType + * @param dbName + * @param ownerName + * @param ownerPW + * @param readerName + * @param readerPW + * @throws Exception + */ + private void createDatabaseWithRights(DatabaseProductType dbType, String dbName, String ownerName, String ownerPW, String readerName, String readerPW) throws Exception { + Connection conn = null; Statement stmt = null; try { + DataSource csadminDataSource = JDBCTools.getDataSource(JDBCTools.CSADMIN_DATASOURCE_NAME); + conn = csadminDataSource.getConnection(); stmt = conn.createStatement(); if (dbType == DatabaseProductType.POSTGRESQL) { - // Postgres does not need passwords. + // PostgreSQL does not need passwords in grant statements. String sql = "CREATE DATABASE " + dbName + " ENCODING 'UTF8' OWNER " + ownerName; stmt.executeUpdate(sql); if (logger.isDebugEnabled()) { @@ -629,6 +613,9 @@ public class ServiceMain { if (stmt != null) { stmt.close(); } + if (conn != null) { + conn.close(); + } } catch (SQLException se) { se.printStackTrace(); } diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java b/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java index 55b27395d..a647b0757 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java @@ -627,7 +627,54 @@ public class JDBCTools { } /** - * Identify whether a database user already exists. + * Identify whether a database exists. + * + * @param dbType a database product type. + * @param dbName a database product name. + * @return true if a database with that name exists, false if that database does not exit. + * @throws Exception + */ + public static boolean hasDatabase(DatabaseProductType dbType, String dbName) throws Exception { + PreparedStatement pstmt = null; + Connection conn = null; + String dbExistsQuery = ""; + if (dbType == DatabaseProductType.POSTGRESQL) { + dbExistsQuery = "SELECT 1 AS result FROM pg_database WHERE datname=?"; + } else if (dbType == DatabaseProductType.MYSQL) { + dbExistsQuery = "SELECT 1 AS result FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME=?"; + } else { + throw new UnsupportedOperationException("hasDatabase encountered unknown database product type"); + } + try { + DataSource csadminDataSource = JDBCTools.getDataSource(JDBCTools.CSADMIN_DATASOURCE_NAME); + conn = csadminDataSource.getConnection(); + pstmt = conn.prepareStatement(dbExistsQuery); // create a statement + pstmt.setString(1, dbName); // set dbName param + ResultSet rs = pstmt.executeQuery(); + // extract data from the ResultSet + boolean dbExists = rs.next(); // Will return a value of 1 if database exists + rs.close(); + return dbExists; + } catch (Exception e) { + logger.error("hasDatabase failed on exception: " + e.getLocalizedMessage()); + throw e; + } finally { + try { + if (pstmt != null) { + pstmt.close(); + } + if (conn != null) { + conn.close(); + } + } catch (SQLException sqle) { + // nothing we can do here except log + logger.warn("SQL Exception when closing statement/connection: " + sqle.getLocalizedMessage()); + } + } + } + + /** + * Identify whether a database user exists. * * @param dataSourceName a JDBC datasource name. * @param repositoryName a repository (e.g. RDBMS database) name. @@ -635,6 +682,8 @@ public class JDBCTools { * @param dbType a database product type. * @param username the name of the database user to create. * @param userPW the initial password for that database user. + * @return true if a database user with that name exists, false if that user does not exist. + * @throws Exception */ public static boolean hasDatabaseUser(String dataSourceName, String repositoryName, String cspaceInstanceId, DatabaseProductType dbType, String username) throws Exception {