From 42bf845edbfec01b44645b6dbe0985b7802d45df Mon Sep 17 00:00:00 2001 From: Martyn Taylor Date: Wed, 29 Mar 2017 14:37:45 +0100 Subject: [PATCH] ARTEMIS-1084 Throw RunTime on bad Oracle table size --- .../artemis/jdbc/store/drivers/JDBCUtils.java | 4 ++-- .../store/drivers/derby/DerbySQLProvider.java | 8 ++++---- .../store/drivers/mysql/MySQLSQLProvider.java | 8 ++++---- .../drivers/oracle/Oracle12CSQLProvider.java | 11 +++++++---- .../drivers/postgres/PostgresSQLProvider.java | 8 ++++---- .../jdbc/store/sql/GenericSQLProvider.java | 10 +++++++--- .../artemis/jdbc/store/sql/SQLProvider.java | 7 +++++-- .../jdbc/file/JDBCSequentialFileFactoryTest.java | 3 ++- .../paging/impl/PagingStoreFactoryDatabase.java | 8 ++++---- .../impl/journal/JDBCJournalStorageManager.java | 12 ++++++------ .../impl/DatabaseStoreConfigurationTest.java | 15 +++++++++++++++ .../artemis/tests/util/ActiveMQTestBase.java | 2 +- .../jdbc/store/journal/JDBCJournalTest.java | 2 +- 13 files changed, 62 insertions(+), 36 deletions(-) diff --git a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/JDBCUtils.java b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/JDBCUtils.java index 802d856ad04..bbe4865b716 100644 --- a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/JDBCUtils.java +++ b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/JDBCUtils.java @@ -51,7 +51,7 @@ public static SQLProvider.Factory getSQLProviderFactory(String url) { return factory; } - public static SQLProvider getSQLProvider(String driverClass, String tableName) { + public static SQLProvider getSQLProvider(String driverClass, String tableName, SQLProvider.DatabaseStoreType storeType) { SQLProvider.Factory factory; if (driverClass.contains("derby")) { logger.tracef("getSQLProvider Returning Derby SQL provider for driver::%s, tableName::%s", driverClass, tableName); @@ -69,7 +69,7 @@ public static SQLProvider getSQLProvider(String driverClass, String tableName) { logger.tracef("getSQLProvider Returning generic SQL provider for driver::%s, tableName::%s", driverClass, tableName); factory = new GenericSQLProvider.Factory(); } - return factory.create(tableName); + return factory.create(tableName, storeType); } /** diff --git a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/derby/DerbySQLProvider.java b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/derby/DerbySQLProvider.java index 8f279d17bda..2ffff1471c0 100644 --- a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/derby/DerbySQLProvider.java +++ b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/derby/DerbySQLProvider.java @@ -26,8 +26,8 @@ public class DerbySQLProvider extends GenericSQLProvider { private final String createFileTableSQL; - private DerbySQLProvider(String tableName) { - super(tableName.toUpperCase()); + private DerbySQLProvider(String tableName, DatabaseStoreType databaseStoreType) { + super(tableName.toUpperCase(), databaseStoreType); createFileTableSQL = "CREATE TABLE " + tableName + "(ID BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1)," + @@ -52,8 +52,8 @@ public boolean closeConnectionOnShutdown() { public static class Factory implements SQLProvider.Factory { @Override - public SQLProvider create(String tableName) { - return new DerbySQLProvider(tableName); + public SQLProvider create(String tableName, DatabaseStoreType databaseStoreType) { + return new DerbySQLProvider(tableName, databaseStoreType); } } } diff --git a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/mysql/MySQLSQLProvider.java b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/mysql/MySQLSQLProvider.java index 6e01c45938c..744ccef4e4d 100644 --- a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/mysql/MySQLSQLProvider.java +++ b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/mysql/MySQLSQLProvider.java @@ -29,8 +29,8 @@ public class MySQLSQLProvider extends GenericSQLProvider { private final String copyFileRecordByIdSQL; - private MySQLSQLProvider(String tName) { - super(tName.toLowerCase()); + private MySQLSQLProvider(String tName, DatabaseStoreType databaseStoreType) { + super(tName.toLowerCase(), databaseStoreType); createFileTableSQL = "CREATE TABLE " + tableName + "(ID BIGINT NOT NULL AUTO_INCREMENT," + @@ -68,8 +68,8 @@ public String getCopyFileRecordByIdSQL() { public static class Factory implements SQLProvider.Factory { @Override - public SQLProvider create(String tableName) { - return new MySQLSQLProvider(tableName); + public SQLProvider create(String tableName, DatabaseStoreType databaseStoreType) { + return new MySQLSQLProvider(tableName, databaseStoreType); } } } diff --git a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/oracle/Oracle12CSQLProvider.java b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/oracle/Oracle12CSQLProvider.java index 64e72f884e0..ac58bd33ccb 100644 --- a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/oracle/Oracle12CSQLProvider.java +++ b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/oracle/Oracle12CSQLProvider.java @@ -27,8 +27,11 @@ public class Oracle12CSQLProvider extends GenericSQLProvider { private static final long MAX_BLOB_SIZE = 4294967296L; //4GB - protected Oracle12CSQLProvider(String tableName) { - super(tableName.toUpperCase()); + protected Oracle12CSQLProvider(String tableName, DatabaseStoreType databaseStoreType) { + super(tableName.toUpperCase(), databaseStoreType); + if (tableName.length() > 10 && databaseStoreType == DatabaseStoreType.PAGE) { + throw new RuntimeException("The maximum name size for the paging store table, when using Oracle12C is 10 characters."); + } } @Override @@ -49,8 +52,8 @@ public String[] getCreateJournalTableSQL() { public static class Factory implements SQLProvider.Factory { @Override - public SQLProvider create(String tableName) { - return new Oracle12CSQLProvider(tableName); + public SQLProvider create(String tableName, DatabaseStoreType databaseStoreType) { + return new Oracle12CSQLProvider(tableName, databaseStoreType); } } } diff --git a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/postgres/PostgresSQLProvider.java b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/postgres/PostgresSQLProvider.java index 6deaf6486c7..495f17b08ec 100644 --- a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/postgres/PostgresSQLProvider.java +++ b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/postgres/PostgresSQLProvider.java @@ -28,8 +28,8 @@ public class PostgresSQLProvider extends GenericSQLProvider { private final String[] createJournalTableSQL; - private PostgresSQLProvider(String tName) { - super(tName.toLowerCase()); + private PostgresSQLProvider(String tName, DatabaseStoreType databaseStoreType) { + super(tName.toLowerCase(), databaseStoreType); createFileTableSQL = "CREATE TABLE " + tableName + "(ID BIGSERIAL, FILENAME VARCHAR(255), EXTENSION VARCHAR(10), DATA OID, PRIMARY KEY(ID))"; @@ -57,8 +57,8 @@ public long getMaxBlobSize() { public static class Factory implements SQLProvider.Factory { @Override - public SQLProvider create(String tableName) { - return new PostgresSQLProvider(tableName); + public SQLProvider create(String tableName, DatabaseStoreType databaseStoreType) { + return new PostgresSQLProvider(tableName, databaseStoreType); } } } diff --git a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/GenericSQLProvider.java b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/GenericSQLProvider.java index 3b452cdfdba..923200145d4 100644 --- a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/GenericSQLProvider.java +++ b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/GenericSQLProvider.java @@ -57,9 +57,13 @@ public class GenericSQLProvider implements SQLProvider { private final String countJournalRecordsSQL; - protected GenericSQLProvider(String tableName) { + protected final DatabaseStoreType databaseStoreType; + + protected GenericSQLProvider(String tableName, DatabaseStoreType databaseStoreType) { this.tableName = tableName; + this.databaseStoreType = databaseStoreType; + createFileTableSQL = "CREATE TABLE " + tableName + "(ID BIGINT AUTO_INCREMENT, FILENAME VARCHAR(255), EXTENSION VARCHAR(10), DATA BLOB, PRIMARY KEY(ID))"; @@ -205,8 +209,8 @@ public boolean closeConnectionOnShutdown() { public static class Factory implements SQLProvider.Factory { @Override - public SQLProvider create(String tableName) { - return new GenericSQLProvider(tableName); + public SQLProvider create(String tableName, DatabaseStoreType storeType) { + return new GenericSQLProvider(tableName, storeType); } } } diff --git a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/SQLProvider.java b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/SQLProvider.java index 8d828832d4e..1663179f8d6 100644 --- a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/SQLProvider.java +++ b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/SQLProvider.java @@ -18,6 +18,10 @@ public interface SQLProvider { + enum DatabaseStoreType { + PAGE, MESSAGE_JOURNAL, BINDINGS_JOURNAL, LARGE_MESSAGE + } + long getMaxBlobSize(); String[] getCreateJournalTableSQL(); @@ -59,7 +63,6 @@ public interface SQLProvider { boolean closeConnectionOnShutdown(); interface Factory { - - SQLProvider create(String tableName); + SQLProvider create(String tableName, DatabaseStoreType dbStoreType); } } diff --git a/artemis-jdbc-store/src/test/java/org/apache/activemq/artemis/jdbc/file/JDBCSequentialFileFactoryTest.java b/artemis-jdbc-store/src/test/java/org/apache/activemq/artemis/jdbc/file/JDBCSequentialFileFactoryTest.java index 75bdf443f68..b7d0c9d02f0 100644 --- a/artemis-jdbc-store/src/test/java/org/apache/activemq/artemis/jdbc/file/JDBCSequentialFileFactoryTest.java +++ b/artemis-jdbc-store/src/test/java/org/apache/activemq/artemis/jdbc/file/JDBCSequentialFileFactoryTest.java @@ -35,6 +35,7 @@ import org.apache.activemq.artemis.jdbc.store.drivers.JDBCUtils; import org.apache.activemq.artemis.jdbc.store.file.JDBCSequentialFile; import org.apache.activemq.artemis.jdbc.store.file.JDBCSequentialFileFactory; +import org.apache.activemq.artemis.jdbc.store.sql.SQLProvider; import org.apache.activemq.artemis.utils.ActiveMQThreadFactory; import org.apache.activemq.artemis.utils.ThreadLeakCheckRule; import org.apache.derby.jdbc.EmbeddedDriver; @@ -63,7 +64,7 @@ public void setup() throws Exception { String connectionUrl = "jdbc:derby:target/data;create=true"; String tableName = "FILES"; - factory = new JDBCSequentialFileFactory(connectionUrl, className, JDBCUtils.getSQLProvider(className, tableName), executor); + factory = new JDBCSequentialFileFactory(connectionUrl, className, JDBCUtils.getSQLProvider(className, tableName, SQLProvider.DatabaseStoreType.PAGE), executor); factory.start(); } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryDatabase.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryDatabase.java index b274848233d..31fc7291a41 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryDatabase.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryDatabase.java @@ -114,10 +114,10 @@ public synchronized void start() throws Exception { if (sqlProviderFactory == null) { sqlProviderFactory = new GenericSQLProvider.Factory(); } - pagingFactoryFileFactory = new JDBCSequentialFileFactory(dbConf.getDataSource(), sqlProviderFactory.create(dbConf.getPageStoreTableName()), executorFactory.getExecutor()); + pagingFactoryFileFactory = new JDBCSequentialFileFactory(dbConf.getDataSource(), sqlProviderFactory.create(dbConf.getPageStoreTableName(), SQLProvider.DatabaseStoreType.PAGE), executorFactory.getExecutor()); } else { String driverClassName = dbConf.getJdbcDriverClassName(); - pagingFactoryFileFactory = new JDBCSequentialFileFactory(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, dbConf.getPageStoreTableName()), executorFactory.getExecutor()); + pagingFactoryFileFactory = new JDBCSequentialFileFactory(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, dbConf.getPageStoreTableName(), SQLProvider.DatabaseStoreType.PAGE), executorFactory.getExecutor()); } pagingFactoryFileFactory.start(); started = true; @@ -222,9 +222,9 @@ private synchronized SequentialFileFactory newFileFactory(final String directory SQLProvider sqlProvider = null; if (dbConf.getDataSource() != null) { SQLProvider.Factory sqlProviderFactory = dbConf.getSqlProviderFactory() == null ? new GenericSQLProvider.Factory() : dbConf.getSqlProviderFactory(); - sqlProvider = sqlProviderFactory.create(getTableNameForGUID(directoryName)); + sqlProvider = sqlProviderFactory.create(getTableNameForGUID(directoryName), SQLProvider.DatabaseStoreType.PAGE); } else { - sqlProvider = JDBCUtils.getSQLProvider(dbConf.getJdbcDriverClassName(), getTableNameForGUID(directoryName)); + sqlProvider = JDBCUtils.getSQLProvider(dbConf.getJdbcDriverClassName(), getTableNameForGUID(directoryName), SQLProvider.DatabaseStoreType.PAGE); } return new JDBCSequentialFileFactory(pagingFactoryFileFactory.getDbDriver().getConnection(), sqlProvider, executorFactory.getExecutor()); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JDBCJournalStorageManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JDBCJournalStorageManager.java index 416da0bfb87..86346387945 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JDBCJournalStorageManager.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JDBCJournalStorageManager.java @@ -62,14 +62,14 @@ protected synchronized void init(Configuration config, IOCriticalErrorListener c if (sqlProviderFactory == null) { sqlProviderFactory = new GenericSQLProvider.Factory(); } - bindingsJournal = new JDBCJournalImpl(dbConf.getDataSource(), sqlProviderFactory.create(dbConf.getBindingsTableName()), dbConf.getBindingsTableName(), scheduledExecutorService, executorFactory.getExecutor()); - messageJournal = new JDBCJournalImpl(dbConf.getDataSource(), sqlProviderFactory.create(dbConf.getMessageTableName()), dbConf.getMessageTableName(), scheduledExecutorService, executorFactory.getExecutor()); - largeMessagesFactory = new JDBCSequentialFileFactory(dbConf.getDataSource(), sqlProviderFactory.create(dbConf.getLargeMessageTableName()), executor); + bindingsJournal = new JDBCJournalImpl(dbConf.getDataSource(), sqlProviderFactory.create(dbConf.getBindingsTableName(), SQLProvider.DatabaseStoreType.BINDINGS_JOURNAL), dbConf.getBindingsTableName(), scheduledExecutorService, executorFactory.getExecutor()); + messageJournal = new JDBCJournalImpl(dbConf.getDataSource(), sqlProviderFactory.create(dbConf.getMessageTableName(), SQLProvider.DatabaseStoreType.MESSAGE_JOURNAL), dbConf.getMessageTableName(), scheduledExecutorService, executorFactory.getExecutor()); + largeMessagesFactory = new JDBCSequentialFileFactory(dbConf.getDataSource(), sqlProviderFactory.create(dbConf.getLargeMessageTableName(), SQLProvider.DatabaseStoreType.LARGE_MESSAGE), executor); } else { String driverClassName = dbConf.getJdbcDriverClassName(); - bindingsJournal = new JDBCJournalImpl(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, dbConf.getBindingsTableName()), scheduledExecutorService, executorFactory.getExecutor()); - messageJournal = new JDBCJournalImpl(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, dbConf.getMessageTableName()), scheduledExecutorService, executorFactory.getExecutor()); - largeMessagesFactory = new JDBCSequentialFileFactory(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, dbConf.getLargeMessageTableName()), executor); + bindingsJournal = new JDBCJournalImpl(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, dbConf.getBindingsTableName(), SQLProvider.DatabaseStoreType.BINDINGS_JOURNAL), scheduledExecutorService, executorFactory.getExecutor()); + messageJournal = new JDBCJournalImpl(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, dbConf.getMessageTableName(), SQLProvider.DatabaseStoreType.MESSAGE_JOURNAL), scheduledExecutorService, executorFactory.getExecutor()); + largeMessagesFactory = new JDBCSequentialFileFactory(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, dbConf.getLargeMessageTableName(), SQLProvider.DatabaseStoreType.LARGE_MESSAGE), executor); } largeMessagesFactory.start(); } catch (Exception e) { diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/DatabaseStoreConfigurationTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/DatabaseStoreConfigurationTest.java index 4934cbd592c..27e3593ce77 100644 --- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/DatabaseStoreConfigurationTest.java +++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/DatabaseStoreConfigurationTest.java @@ -20,6 +20,8 @@ import org.apache.activemq.artemis.core.config.FileDeploymentManager; import org.apache.activemq.artemis.core.config.StoreConfiguration; import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl; +import org.apache.activemq.artemis.jdbc.store.drivers.oracle.Oracle12CSQLProvider; +import org.apache.activemq.artemis.jdbc.store.sql.SQLProvider; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.junit.Test; @@ -32,6 +34,19 @@ public void databaseStoreConfigTest() throws Exception { assertEquals(StoreConfiguration.StoreType.DATABASE, server.getConfiguration().getStoreConfiguration().getStoreType()); } + @Test + public void testOracle12TableSize() { + Throwable rte = null; + try { + new Oracle12CSQLProvider.Factory().create("A_TABLE_NAME_THAT_IS_TOO_LONG", SQLProvider.DatabaseStoreType.PAGE); + } catch (Throwable t) { + rte = t; + } + + assertNotNull(rte); + assertTrue(rte.getMessage().contains("The maximum name size for the paging store table, when using Oracle12C is 10 characters.")); + } + protected Configuration createConfiguration(String fileName) throws Exception { FileConfiguration fc = new FileConfiguration(); FileDeploymentManager deploymentManager = new FileDeploymentManager(fileName); diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java index 0bb177dbc5c..55026537afa 100644 --- a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java +++ b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java @@ -474,7 +474,7 @@ public void destroyTables(List tableNames) throws Exception { try { for (String tableName : tableNames) { connection.setAutoCommit(false); - SQLProvider sqlProvider = JDBCUtils.getSQLProvider(getJDBCClassName(), tableName); + SQLProvider sqlProvider = JDBCUtils.getSQLProvider(getJDBCClassName(), tableName, SQLProvider.DatabaseStoreType.LARGE_MESSAGE); try (ResultSet rs = connection.getMetaData().getTables(null, null, sqlProvider.getTableName(), null)) { if (rs.next()) { statement.execute("DROP TABLE " + sqlProvider.getTableName()); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jdbc/store/journal/JDBCJournalTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jdbc/store/journal/JDBCJournalTest.java index d600ac14fa2..ebb5c0eb9f3 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jdbc/store/journal/JDBCJournalTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jdbc/store/journal/JDBCJournalTest.java @@ -77,7 +77,7 @@ public void setup() throws Exception { executorService = Executors.newSingleThreadExecutor(); jdbcUrl = "jdbc:derby:target/data;create=true"; SQLProvider.Factory factory = new DerbySQLProvider.Factory(); - journal = new JDBCJournalImpl(jdbcUrl, DRIVER_CLASS, factory.create(JOURNAL_TABLE_NAME), scheduledExecutorService, executorService); + journal = new JDBCJournalImpl(jdbcUrl, DRIVER_CLASS, factory.create(JOURNAL_TABLE_NAME, SQLProvider.DatabaseStoreType.MESSAGE_JOURNAL), scheduledExecutorService, executorService); journal.start(); }