// Set our AuthN's datasource to be the cspaceDataSource\r
//\r
AuthN.setDataSource(cspaceDataSource);\r
- String repoName = repoDomain.getName();\r
- String dbName = /* repoDomain.getRepositoryName()?? */ "nuxeo";\r
+\r
+ // Get the NuxeoDS info and create the necessary databases.\r
+ // Consider the tenant bindings to find and get the data sources for each tenant.\r
+ // There may be only one, one per tenant, or something in between.\r
+ DatabaseProductType dbType = JDBCTools.getDatabaseProductType(); // only returns PG or MYSQL\r
+ String dbExistsQuery = (dbType==DatabaseProductType.POSTGRESQL)?\r
+ DB_EXISTS_QUERY_PSQL : DB_EXISTS_QUERY_MYSQL;\r
+\r
+ Hashtable<String, TenantBindingType> tenantBindings =\r
+ tenantBindingConfigReader.getTenantBindings();\r
+ HashSet<String> nuxeoDBsChecked = new HashSet<String>();\r
+ PreparedStatement pstmt = null;\r
+ Statement stmt = null;\r
+ Connection conn = null;\r
+ \r
+ try {\r
+ conn = nuxeoMgrDataSource.getConnection();\r
+ // First check and create the roles as needed. (nuxeo and reader)\r
+\r
+ \r
+ pstmt = conn.prepareStatement(dbExistsQuery); // create a statement\r
+ stmt = conn.createStatement();\r
+ \r
+ for (TenantBindingType tenantBinding : tenantBindings.values()) {\r
+ String tId = tenantBinding.getId();\r
+ String tName = tenantBinding.getName();\r
+ List<RepositoryDomainType> repoDomainList = tenantBinding.getRepositoryDomain();\r
+ for (RepositoryDomainType repoDomain : repoDomainList) {\r
- logger.debug("Another user of db: "+dbName+": Repo: "+repoName+" and tenant: "\r
++ String repoDomainName = repoDomain.getName();\r
++ String dbName = JDBCTools.getDatabaseName(repoDomain.getRepositoryName());\r
+ if(nuxeoDBsChecked.contains(dbName)) {\r
+ if (logger.isDebugEnabled()) {\r
- logger.debug("Need to prepare db: "+dbName+" for Repo: "+repoName+" and tenant: "\r
++ logger.debug("Another user of db: "+dbName+": Repo: "+repoDomainName+" and tenant: "\r
+ +tName+" (id:"+tId+")");\r
+ }\r
+ } else {\r
+ if (logger.isDebugEnabled()) {\r
++ logger.debug("Need to prepare db: "+dbName+" for Repo: "+repoDomainName+" and tenant: "\r
+ +tName+" (id:"+tId+")");\r
+ }\r
+\r
+ pstmt.setString(1, dbName); // set dbName param\r
+ ResultSet rs = pstmt.executeQuery();\r
+ // extract data from the ResultSet\r
+ boolean dbExists = rs.next(); \r
+ rs.close();\r
+ if(dbExists) {\r
+ if (logger.isDebugEnabled()) {\r
+ logger.debug("Database: "+dbName+" already exists.");\r
+ }\r
+ } else {\r
+ // Create the user as needed\r
+ createUserIfNotExists(conn, dbType, nuxeoUser, nuxeoPW);\r
+ createUserIfNotExists(conn, dbType, readerUser, readerPW);\r
+ // Create the database\r
+ createDatabaseWithRights(conn, dbType, dbName, nuxeoUser, nuxeoPW, readerUser, readerPW);\r
+ }\r
+ nuxeoDBsChecked.add(dbName);\r
+ }\r
+ } // Loop on repos for tenant\r
+ } // Loop on tenants\r
+ } catch(SQLException se) {\r
+ //Handle errors for JDBC\r
+ se.printStackTrace();\r
+ } catch(Exception e) {\r
+ //Handle errors for Class.forName\r
+ e.printStackTrace();\r
+ } finally { //close resources\r
+ try {\r
+ if(stmt!=null) {\r
+ stmt.close();\r
+ }\r
+ } catch(SQLException se2) {\r
+ // nothing we can do\r
+ }\r
+ try{\r
+ if(conn!=null) {\r
+ conn.close();\r
+ }\r
+ }catch(SQLException se){\r
+ se.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+ \r
+ private void createUserIfNotExists(Connection conn, DatabaseProductType dbType,\r
+ String username, String userPW) throws Exception {\r
+ PreparedStatement pstmt = null;\r
+ Statement stmt = null;\r
+ final String USER_EXISTS_QUERY_PSQL = \r
+ "SELECT 1 AS result FROM pg_roles WHERE rolname=?";\r
+ String userExistsQuery;\r
+ if(dbType==DatabaseProductType.POSTGRESQL) {\r
+ userExistsQuery = USER_EXISTS_QUERY_PSQL;\r
+ } else {\r
+ throw new UnsupportedOperationException("CreateUserIfNotExists only supports PSQL - MySQL NYI!");\r
+ }\r
+ try {\r
+ pstmt = conn.prepareStatement(userExistsQuery); // create a statement\r
+ pstmt.setString(1, username); // set dbName param\r
+ ResultSet rs = pstmt.executeQuery();\r
+ // extract data from the ResultSet\r
+ boolean userExists = rs.next();\r
+ rs.close();\r
+ if(userExists) {\r
+ if (logger.isDebugEnabled()) {\r
+ logger.debug("User: "+username+" already exists.");\r
+ }\r
+ } else {\r
+ stmt = conn.createStatement();\r
+ String sql = "CREATE ROLE "+username+" WITH PASSWORD '"+userPW+"' LOGIN";\r
+ stmt.executeUpdate(sql);\r
+ // Really should do the grants as well. \r
+ if (logger.isDebugEnabled()) {\r
+ logger.debug("Created Users: '"+username+"' and 'reader'");\r
+ }\r
+ }\r
+ } catch(Exception e) {\r
+ logger.error("createUserIfNotExists failed on exception: " + e.getLocalizedMessage());\r
+ throw e; // propagate\r
+ } finally { //close resources\r
+ try {\r
+ if(pstmt!=null) {\r
+ pstmt.close();\r
+ }\r
+ if(stmt!=null) {\r
+ stmt.close();\r
+ }\r
+ } catch(SQLException se) {\r
+ // nothing we can do\r
+ }\r
+ }\r
+ }\r
+ \r
+ private void createDatabaseWithRights(Connection conn, DatabaseProductType dbType, String dbName,\r
+ String ownerName, String ownerPW, String readerName, String readerPW) throws Exception {\r
+ Statement stmt = null;\r
+ try {\r
+ stmt = conn.createStatement();\r
+ if(dbType==DatabaseProductType.POSTGRESQL) {\r
+ // Postgres does not need passwords.\r
+ String sql = "CREATE DATABASE "+dbName+" ENCODING 'UTF8' OWNER "+ownerName;\r
+ stmt.executeUpdate(sql);\r
+ sql = "GRANT CONNECT ON DATABASE nuxeo TO "+readerName;\r
+ stmt.executeUpdate(sql);\r
+ if (logger.isDebugEnabled()) {\r
+ logger.debug("Created db: '"+dbName+"' with owner: '"+ownerName+"'");\r
+ logger.debug(" Granted connect rights on: '"+dbName+"' to reader: '"+readerName+"'");\r
+ }\r
+ // Note that select rights for reader must be granted after Nuxeo startup.\r
+ } else if(dbType==DatabaseProductType.MYSQL) {\r
+ String sql = "CREATE database "+dbName+" DEFAULT CHARACTER SET utf8";\r
+ stmt.executeUpdate(sql);\r
+ sql = "GRANT ALL PRIVILEGES ON "+dbName+".* TO '"+ownerName+"'@'localhost' IDENTIFIED BY '"\r
+ +ownerPW+"' WITH GRANT OPTION";\r
+ stmt.executeUpdate(sql);\r
+ sql = "GRANT SELECT ON "+dbName+".* TO '"+readerName+"'@'localhost' IDENTIFIED BY '"\r
+ +readerPW+"' WITH GRANT OPTION";\r
+ stmt.executeUpdate(sql);\r
+ if (logger.isDebugEnabled()) {\r
+ logger.debug("Created db: '"+dbName+"' with owner: '"+ownerName+"'");\r
+ logger.debug(" Granted SELECT rights on: '"+dbName+"' to reader: '"+readerName+"'");\r
+ }\r
+ } else {\r
+ throw new UnsupportedOperationException("createDatabaseWithRights only supports PSQL - MySQL NYI!");\r
+ }\r
+ } catch(Exception e) {\r
+ logger.error("createDatabaseWithRights failed on exception: " + e.getLocalizedMessage());\r
+ throw e; // propagate\r
+ } finally { //close resources\r
+ try {\r
+ if(stmt!=null) {\r
+ stmt.close();\r
+ }\r
+ } catch(SQLException se) {\r
+ // nothing we can do\r
+ }\r
+ }\r
+\r
}\r
\r
private void setServerRootDir() {\r