ARTEMIS-1124 JDBC Network Timeout configuration
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/258d5959 Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/258d5959 Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/258d5959 Branch: refs/heads/master Commit: 258d5959721d82211a1806aea85d4e58d668b5db Parents: d018a58 Author: Francesco Nigro <[email protected]> Authored: Thu Apr 20 12:43:40 2017 +0200 Committer: Martyn Taylor <[email protected]> Committed: Thu Apr 20 19:43:10 2017 +0100 ---------------------------------------------------------------------- .../config/ActiveMQDefaultConfiguration.java | 8 ++++++ .../jdbc/store/drivers/AbstractJDBCDriver.java | 29 ++++++++++++++++++++ .../store/file/JDBCSequentialFileFactory.java | 8 ++++++ .../storage/DatabaseStorageConfiguration.java | 10 +++++++ .../deployers/impl/FileConfigurationParser.java | 1 + .../paging/impl/PagingStoreFactoryDatabase.java | 12 ++++++-- .../impl/journal/JDBCJournalStorageManager.java | 19 +++++++++++-- .../resources/schema/artemis-configuration.xsd | 7 +++++ .../test/resources/artemis-configuration.xsd | 7 +++++ docs/user-manual/en/persistence.md | 5 ++++ 10 files changed, 102 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/258d5959/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java ---------------------------------------------------------------------- diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java index 6d3cb81..8c0b973 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java @@ -16,6 +16,8 @@ */ package org.apache.activemq.artemis.api.config; +import java.util.concurrent.TimeUnit; + import org.apache.activemq.artemis.ArtemisConstants; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.core.server.DivertConfigurationRoutingType; @@ -429,6 +431,8 @@ public final class ActiveMQDefaultConfiguration { // Default large messages table name, used with Database storage type private static final String DEFAULT_PAGE_STORE_TABLE_NAME = "PAGE_STORE"; + private static final int DEFAULT_JDBC_NETWORK_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(20); + // Default period to wait between connection TTL checks public static final long DEFAULT_CONNECTION_TTL_CHECK_INTERVAL = 2000; @@ -1181,6 +1185,10 @@ public final class ActiveMQDefaultConfiguration { return DEFAULT_PAGE_STORE_TABLE_NAME; } + public static int getDefaultJdbcNetworkTimeout() { + return DEFAULT_JDBC_NETWORK_TIMEOUT; + } + public static long getDefaultConnectionTtlCheckInterval() { return DEFAULT_CONNECTION_TTL_CHECK_INTERVAL; } http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/258d5959/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java ---------------------------------------------------------------------- diff --git a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java index 1828911..fcbf90d 100644 --- a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java +++ b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java @@ -26,6 +26,7 @@ import java.sql.SQLWarning; import java.sql.Statement; import java.util.Arrays; import java.util.Properties; +import java.util.concurrent.Executor; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -51,18 +52,28 @@ public abstract class AbstractJDBCDriver { private DataSource dataSource; + private Executor networkTimeoutExecutor; + + private int networkTimeoutMillis; + public AbstractJDBCDriver() { + this.networkTimeoutExecutor = null; + this.networkTimeoutMillis = -1; } public AbstractJDBCDriver(SQLProvider sqlProvider, String jdbcConnectionUrl, String jdbcDriverClass) { this.jdbcConnectionUrl = jdbcConnectionUrl; this.jdbcDriverClass = jdbcDriverClass; this.sqlProvider = sqlProvider; + this.networkTimeoutExecutor = null; + this.networkTimeoutMillis = -1; } public AbstractJDBCDriver(DataSource dataSource, SQLProvider provider) { this.dataSource = dataSource; this.sqlProvider = provider; + this.networkTimeoutExecutor = null; + this.networkTimeoutMillis = -1; } public void start() throws SQLException { @@ -76,6 +87,8 @@ public abstract class AbstractJDBCDriver { public AbstractJDBCDriver(Connection connection, SQLProvider sqlProvider) { this.connection = connection; this.sqlProvider = sqlProvider; + this.networkTimeoutExecutor = null; + this.networkTimeoutMillis = -1; } public void stop() throws SQLException { @@ -127,6 +140,17 @@ public abstract class AbstractJDBCDriver { throw e; } } + if (this.networkTimeoutMillis >= 0 && this.networkTimeoutExecutor != null) { + try { + connection.setNetworkTimeout(this.networkTimeoutExecutor, this.networkTimeoutMillis); + } catch (SQLException e) { + logger.warn(JDBCUtils.appendSQLExceptionDetails(new StringBuilder(), e)); + ActiveMQJournalLogger.LOGGER.warn("Unable to set a network timeout on the JDBC connection"); + } catch (Throwable throwable) { + //it included SecurityExceptions and UnsupportedOperationException + logger.warn("Unable to set a network timeout on the JDBC connection", throwable); + } + } } } @@ -240,4 +264,9 @@ public abstract class AbstractJDBCDriver { this.dataSource = dataSource; } + public void setNetworkTimeout(Executor executor, int milliseconds) { + this.networkTimeoutExecutor = executor; + this.networkTimeoutMillis = milliseconds; + } + } http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/258d5959/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/file/JDBCSequentialFileFactory.java ---------------------------------------------------------------------- diff --git a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/file/JDBCSequentialFileFactory.java b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/file/JDBCSequentialFileFactory.java index d5a92a2..ae2e793 100644 --- a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/file/JDBCSequentialFileFactory.java +++ b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/file/JDBCSequentialFileFactory.java @@ -101,6 +101,14 @@ public class JDBCSequentialFileFactory implements SequentialFileFactory, ActiveM return dbDriver; } + /** + * @see Connection#setNetworkTimeout(Executor, int) + **/ + public JDBCSequentialFileFactory setNetworkTimeout(Executor executor, int milliseconds) { + this.dbDriver.setNetworkTimeout(executor, milliseconds); + return this; + } + @Override public SequentialFileFactory setDatasync(boolean enabled) { return this; http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/258d5959/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/storage/DatabaseStorageConfiguration.java ---------------------------------------------------------------------- diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/storage/DatabaseStorageConfiguration.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/storage/DatabaseStorageConfiguration.java index eb8b435..76626c0 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/storage/DatabaseStorageConfiguration.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/storage/DatabaseStorageConfiguration.java @@ -40,6 +40,8 @@ public class DatabaseStorageConfiguration implements StoreConfiguration { private SQLProvider.Factory sqlProviderFactory; + private int jdbcNetworkTimeout = ActiveMQDefaultConfiguration.getDefaultJdbcNetworkTimeout(); + @Override public StoreType getStoreType() { return StoreType.DATABASE; @@ -125,4 +127,12 @@ public class DatabaseStorageConfiguration implements StoreConfiguration { public void setSqlProvider(SQLProvider.Factory sqlProviderFactory) { this.sqlProviderFactory = sqlProviderFactory; } + + public int getJdbcNetworkTimeout() { + return this.jdbcNetworkTimeout; + } + + public void setJdbcNetworkTimeout(int jdbcNetworkTimeout) { + this.jdbcNetworkTimeout = jdbcNetworkTimeout; + } } http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/258d5959/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java ---------------------------------------------------------------------- diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java index 030f531..6f666b6 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java @@ -1292,6 +1292,7 @@ public final class FileConfigurationParser extends XMLConfigurationUtil { conf.setPageStoreTableName(getString(storeNode, "page-store-table-name", conf.getPageStoreTableName(), Validators.NO_CHECK)); conf.setJdbcConnectionUrl(getString(storeNode, "jdbc-connection-url", conf.getJdbcConnectionUrl(), Validators.NO_CHECK)); conf.setJdbcDriverClassName(getString(storeNode, "jdbc-driver-class-name", conf.getJdbcDriverClassName(), Validators.NO_CHECK)); + conf.setJdbcNetworkTimeout(getInteger(storeNode, "jdbc-network-timeout", conf.getJdbcNetworkTimeout(), Validators.NO_CHECK)); return conf; } http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/258d5959/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryDatabase.java ---------------------------------------------------------------------- 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 12e2b35..2daa89e 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 @@ -127,6 +127,10 @@ public class PagingStoreFactoryDatabase implements PagingStoreFactory { String driverClassName = dbConf.getJdbcDriverClassName(); pagingFactoryFileFactory = new JDBCSequentialFileFactory(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, pageStoreTableNamePrefix, SQLProvider.DatabaseStoreType.PAGE), executorFactory.getExecutor(), criticalErrorListener); } + final int jdbcNetworkTimeout = dbConf.getJdbcNetworkTimeout(); + if (jdbcNetworkTimeout >= 0) { + pagingFactoryFileFactory.setNetworkTimeout(this.executorFactory.getExecutor(), jdbcNetworkTimeout); + } pagingFactoryFileFactory.start(); started = true; } @@ -234,8 +238,12 @@ public class PagingStoreFactoryDatabase implements PagingStoreFactory { } else { sqlProvider = JDBCUtils.getSQLProvider(dbConf.getJdbcDriverClassName(), getTableNameForGUID(directoryName), SQLProvider.DatabaseStoreType.PAGE); } - - return new JDBCSequentialFileFactory(pagingFactoryFileFactory.getDbDriver().getConnection(), sqlProvider, executorFactory.getExecutor(), criticalErrorListener); + final JDBCSequentialFileFactory fileFactory = new JDBCSequentialFileFactory(pagingFactoryFileFactory.getDbDriver().getConnection(), sqlProvider, executorFactory.getExecutor(), criticalErrorListener); + final int jdbcNetworkTimeout = dbConf.getJdbcNetworkTimeout(); + if (jdbcNetworkTimeout >= 0) { + fileFactory.setNetworkTimeout(this.executorFactory.getExecutor(), jdbcNetworkTimeout); + } + return fileFactory; } private String getTableNameForGUID(String guid) { http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/258d5959/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JDBCJournalStorageManager.java ---------------------------------------------------------------------- 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 5592c9e..4b8392d 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 @@ -55,8 +55,10 @@ public class JDBCJournalStorageManager extends JournalStorageManager { @Override protected synchronized void init(Configuration config, IOCriticalErrorListener criticalErrorListener) { try { - DatabaseStorageConfiguration dbConf = (DatabaseStorageConfiguration) config.getStoreConfiguration(); - + final DatabaseStorageConfiguration dbConf = (DatabaseStorageConfiguration) config.getStoreConfiguration(); + final JDBCJournalImpl bindingsJournal; + final JDBCJournalImpl messageJournal; + final JDBCSequentialFileFactory largeMessagesFactory; if (dbConf.getDataSource() != null) { SQLProvider.Factory sqlProviderFactory = dbConf.getSqlProviderFactory(); if (sqlProviderFactory == null) { @@ -71,6 +73,19 @@ public class JDBCJournalStorageManager extends JournalStorageManager { messageJournal = new JDBCJournalImpl(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, dbConf.getMessageTableName(), SQLProvider.DatabaseStoreType.MESSAGE_JOURNAL), scheduledExecutorService, executorFactory.getExecutor(), criticalErrorListener); largeMessagesFactory = new JDBCSequentialFileFactory(dbConf.getJdbcConnectionUrl(), driverClassName, JDBCUtils.getSQLProvider(driverClassName, dbConf.getLargeMessageTableName(), SQLProvider.DatabaseStoreType.LARGE_MESSAGE), executor, criticalErrorListener); } + final int networkTimeout = dbConf.getJdbcNetworkTimeout(); + if (networkTimeout >= 0) { + bindingsJournal.setNetworkTimeout(executorFactory.getExecutor(), networkTimeout); + } + if (networkTimeout >= 0) { + messageJournal.setNetworkTimeout(executorFactory.getExecutor(), networkTimeout); + } + if (networkTimeout >= 0) { + largeMessagesFactory.setNetworkTimeout(executorFactory.getExecutor(), networkTimeout); + } + this.bindingsJournal = bindingsJournal; + this.messageJournal = messageJournal; + this.largeMessagesFactory = largeMessagesFactory; largeMessagesFactory.start(); } catch (Exception e) { criticalErrorListener.onIOException(e, e.getMessage(), null); http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/258d5959/artemis-server/src/main/resources/schema/artemis-configuration.xsd ---------------------------------------------------------------------- diff --git a/artemis-server/src/main/resources/schema/artemis-configuration.xsd b/artemis-server/src/main/resources/schema/artemis-configuration.xsd index 6fdef44..e6eaf8b 100644 --- a/artemis-server/src/main/resources/schema/artemis-configuration.xsd +++ b/artemis-server/src/main/resources/schema/artemis-configuration.xsd @@ -1715,6 +1715,13 @@ </xsd:documentation> </xsd:annotation> </xsd:element> + <xsd:element name="jdbc-network-timeout" type="xsd:int" minOccurs="0" maxOccurs="1"> + <xsd:annotation> + <xsd:documentation> + The JDBC network connection timeout in milliseconds. + </xsd:documentation> + </xsd:annotation> + </xsd:element> </xsd:all> </xsd:complexType> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/258d5959/artemis-tools/src/test/resources/artemis-configuration.xsd ---------------------------------------------------------------------- diff --git a/artemis-tools/src/test/resources/artemis-configuration.xsd b/artemis-tools/src/test/resources/artemis-configuration.xsd index 090f968..eda0932 100644 --- a/artemis-tools/src/test/resources/artemis-configuration.xsd +++ b/artemis-tools/src/test/resources/artemis-configuration.xsd @@ -1640,6 +1640,13 @@ </xsd:documentation> </xsd:annotation> </xsd:element> + <xsd:element name="jdbc-network-timeout" type="xsd:int" minOccurs="0" maxOccurs="1"> + <xsd:annotation> + <xsd:documentation> + The JDBC network connection timeout in milliseconds. + </xsd:documentation> + </xsd:annotation> + </xsd:element> </xsd:all> </xsd:complexType> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/258d5959/docs/user-manual/en/persistence.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/persistence.md b/docs/user-manual/en/persistence.md index de1f3a1..e6bfe5c 100644 --- a/docs/user-manual/en/persistence.md +++ b/docs/user-manual/en/persistence.md @@ -462,6 +462,11 @@ To configure Apache ActiveMQ Artemis to use a database for persisting messages a The fully qualified class name of the desired database Driver. +- `jdbc-network-timeout` + + The JDBC network connection timeout in milliseconds. The default value + is 20000 milliseconds (ie 20 seconds). + Note that some DBMS (e.g. Oracle, 30 chars) have restrictions on the size of table names, this should be taken into consideration when configuring table names for the Artemis database store, pay particular attention to the page store table name, which can be appended with a unique ID of up to 20 characters. (for Oracle this would mean configuring a page-store-table-name of max size of 10 chars). ## Configuring Apache ActiveMQ Artemis for Zero Persistence
