VIVO-773 guard against RDB data that has not been migrated.

This commit is contained in:
Jim Blake 2014-06-09 15:37:54 -04:00
parent ae6a2a7251
commit 7cf03661d4
3 changed files with 118 additions and 45 deletions

View file

@ -147,10 +147,9 @@ public class ConfigurationPropertiesSmokeTests implements
connectionProps.put("user", username);
connectionProps.put("password", password);
Connection conn = null;
try {
conn = DriverManager.getConnection(url, connectionProps);
closeConnection(conn);
try (Connection conn = DriverManager
.getConnection(url, connectionProps)) {
// Just open the connection and close it.
} catch (SQLException e) {
ss.fatal(this, "Can't connect to the database: " + PROPERTY_DB_URL
+ "='" + url + "', " + PROPERTY_DB_USERNAME + "='"
@ -167,26 +166,21 @@ public class ConfigurationPropertiesSmokeTests implements
Properties connectionProps, StartupStatus ss, String dbType) {
String testString = "ABC\u00CE\u0123";
Connection conn = null;
Statement stmt = null;
PreparedStatement pstmt = null;
try {
// Get the connection.
conn = DriverManager.getConnection(url, connectionProps);
try (Connection conn = DriverManager
.getConnection(url, connectionProps);
Statement stmt = conn.createStatement()) {
// Create the temporary table.
stmt = conn.createStatement();
stmt.executeUpdate("CREATE TEMPORARY TABLE smoke_test (contents varchar(100))");
// Write the test string, encoding in UTF-8 on the way in.
try {
pstmt = conn
.prepareStatement("INSERT INTO smoke_test values ( ? )");
try (PreparedStatement pstmt = conn
.prepareStatement("INSERT INTO smoke_test values ( ? )")) {
pstmt.setBytes(1, testString.getBytes("UTF-8"));
pstmt.executeUpdate();
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
pstmt.executeUpdate();
// Read it back as a String. Does the database decode it properly?
ResultSet rs = stmt.executeQuery("SELECT * FROM smoke_test");
@ -213,10 +207,6 @@ public class ConfigurationPropertiesSmokeTests implements
}
} catch (SQLException e) {
ss.fatal(this, "Failed to check handling of Unicode characters", e);
} finally {
closeStatement(pstmt);
closeStatement(stmt);
closeConnection(conn);
}
}
@ -231,32 +221,6 @@ public class ConfigurationPropertiesSmokeTests implements
return u.toString();
}
/**
* Close the statement, catching any exception.
*/
private void closeStatement(Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
log.error("Failed to close SQL statement", e);
}
}
}
/**
* Close the connection, catching any exception.
*/
private void closeConnection(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
log.error("Failed to close database connection", e);
}
}
}
/**
* Confirm that the default namespace is specified and a syntactically valid
* URI. It should also end with "/individual/".

View file

@ -0,0 +1,106 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
* If there are RDB tables in the database that have not been converted to TDB,
* throw an error.
*
* The ConfigurationPropertiesSmokeTests has already run, so we know we can
* access the database. A table named "jena_graph", means that the database
* contains RDB. A table named "vivo_rdb_migrated" means that the conversion
* utility has been run.
*/
public class GuardAgainstUnmigratedRDB implements ServletContextListener {
private static final String PROPERTY_DB_URL = "VitroConnection.DataSource.url";
private static final String PROPERTY_DB_USERNAME = "VitroConnection.DataSource.username";
private static final String PROPERTY_DB_PASSWORD = "VitroConnection.DataSource.password";
private static final String TABLE_NAME_RDB = "jena_graph";
private static final String TABLE_NAME_CONVERSION = "vivo_rdb_migrated";
private static final String MESSAGE_PROBLEM = "The database at %s"
+ " contains data from an earlier VIVO (before 1.7). "
+ "It does not appear that this data has been migrated. "
+ "The upgrade guide has instructions on migrating "
+ "this data to the current VIVO.";
private static final String MESSAGE_TECHNICAL = "More technically: "
+ "the database contains tables used by Jena RDB ('jena_graph' and "
+ "others). It does not contain the table 'vivo_rdb_migrated', "
+ "which is created when the data is migrated to Jena TDB files.";
private static final String MESSAGE_WHAT_NOW = "You must either migrate "
+ "the obsolete RDB data or remove it from your database.";
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
ConfigurationProperties props = ConfigurationProperties.getBean(ctx);
StartupStatus ss = StartupStatus.getBean(ctx);
String url = props.getProperty(PROPERTY_DB_URL);
String username = props.getProperty(PROPERTY_DB_USERNAME);
String password = props.getProperty(PROPERTY_DB_PASSWORD);
Properties connectionProps = new Properties();
connectionProps.put("user", username);
connectionProps.put("password", password);
try (Connection conn = DriverManager
.getConnection(url, connectionProps)) {
boolean hasRdb = checkForRdbTables(conn);
boolean hasBeenConverted = checkForConversionTable(conn);
if (hasRdb && !hasBeenConverted) {
ss.fatal(this, String.format(MESSAGE_PROBLEM, url));
ss.fatal(this, String.format(MESSAGE_TECHNICAL, url));
ss.fatal(this, String.format(MESSAGE_WHAT_NOW, url));
}
} catch (SQLException e) {
ss.fatal(this, "Can't connect to the database: " + PROPERTY_DB_URL
+ "='" + url + "', " + PROPERTY_DB_USERNAME + "='"
+ username + "'", e);
return;
}
}
private boolean checkForRdbTables(Connection conn) throws SQLException {
DatabaseMetaData md = conn.getMetaData();
try (ResultSet rs = md.getTables(null, null, TABLE_NAME_RDB, null);) {
while (rs.next()) {
return true;
}
}
return false;
}
private boolean checkForConversionTable(Connection conn)
throws SQLException {
DatabaseMetaData md = conn.getMetaData();
try (ResultSet rs = md.getTables(null, null, TABLE_NAME_CONVERSION,
null);) {
while (rs.next()) {
return true;
}
}
return false;
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// Nothing to tear down.
}
}

View file

@ -11,6 +11,9 @@ edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSetup
edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSmokeTests
# For the conversion from 1.6 or earlier (RDB) to 1.7 or later (TDB)
edu.cornell.mannlib.vitro.webapp.servlet.setup.GuardAgainstUnmigratedRDB
edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings$Setup
edu.cornell.mannlib.vitro.webapp.application.ApplicationImpl$Setup