activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From martyntay...@apache.org
Subject [1/2] activemq-artemis git commit: ARTEMIS-920 Log SQL Exceptions and Warnings
Date Mon, 16 Jan 2017 15:36:50 GMT
Repository: activemq-artemis
Updated Branches:
  refs/heads/master c441625e5 -> 490bec9d9


ARTEMIS-920 Log SQL Exceptions and Warnings


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/837066d4
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/837066d4
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/837066d4

Branch: refs/heads/master
Commit: 837066d40dc1db9ebf161b351551ae5f08b7faba
Parents: c441625
Author: Francesco Nigro <nigro.fra@gmail.com>
Authored: Thu Jan 12 08:39:55 2017 +0100
Committer: Francesco Nigro <nigro.fra@gmail.com>
Committed: Mon Jan 16 14:22:25 2017 +0100

----------------------------------------------------------------------
 .../jdbc/store/drivers/AbstractJDBCDriver.java  | 76 ++++++++++++++++----
 .../artemis/jdbc/store/drivers/JDBCUtils.java   | 57 +++++++++++++++
 .../store/file/JDBCSequentialFileFactory.java   |  2 +-
 .../jdbc/store/journal/JDBCJournalImpl.java     |  2 +-
 4 files changed, 122 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/837066d4/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 7f8c58f..d75ea21 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
@@ -22,9 +22,12 @@ import java.sql.Driver;
 import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.SQLWarning;
 import java.sql.Statement;
 import java.util.Arrays;
 import java.util.Properties;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.activemq.artemis.jdbc.store.sql.SQLProvider;
 import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
@@ -61,7 +64,7 @@ public abstract class AbstractJDBCDriver {
       this.sqlProvider = provider;
    }
 
-   public void start() throws Exception {
+   public void start() throws SQLException {
       connect();
       createSchema();
       prepareStatements();
@@ -69,7 +72,12 @@ public abstract class AbstractJDBCDriver {
 
    public void stop() throws SQLException {
       if (sqlProvider.closeConnectionOnShutdown()) {
-         connection.close();
+         try {
+            connection.close();
+         } catch (SQLException e) {
+            logger.error(JDBCUtils.appendSQLExceptionDetails(new StringBuilder(), e));
+            throw e;
+         }
       }
    }
 
@@ -77,58 +85,100 @@ public abstract class AbstractJDBCDriver {
 
    protected abstract void createSchema() throws SQLException;
 
-   protected void createTable(String... schemaSqls) throws SQLException {
+   protected final void createTable(String... schemaSqls) throws SQLException {
       createTableIfNotExists(connection, sqlProvider.getTableName(), schemaSqls);
    }
 
-   protected void connect() throws Exception {
+   private void connect() throws SQLException {
       if (dataSource != null) {
-         connection = dataSource.getConnection();
+         try {
+            connection = dataSource.getConnection();
+         } catch (SQLException e) {
+            logger.error(JDBCUtils.appendSQLExceptionDetails(new StringBuilder(), e));
+            throw e;
+         }
       } else {
          try {
-            Driver dbDriver = getDriver(jdbcDriverClass);
+            if (jdbcDriverClass == null || jdbcDriverClass.isEmpty()) {
+               throw new IllegalStateException("jdbcDriverClass is null or empty!");
+            }
+            if (jdbcConnectionUrl == null || jdbcConnectionUrl.isEmpty()) {
+               throw new IllegalStateException("jdbcConnectionUrl is null or empty!");
+            }
+            final Driver dbDriver = getDriver(jdbcDriverClass);
             connection = dbDriver.connect(jdbcConnectionUrl, new Properties());
+            if (connection == null) {
+               throw new IllegalStateException("the driver: " + jdbcDriverClass + " isn't
able to connect to the requested url: " + jdbcConnectionUrl);
+            }
          } catch (SQLException e) {
+            logger.error(JDBCUtils.appendSQLExceptionDetails(new StringBuilder(), e));
             ActiveMQJournalLogger.LOGGER.error("Unable to connect to database using URL:
" + jdbcConnectionUrl);
-            throw new RuntimeException("Error connecting to database", e);
+            throw e;
          }
       }
    }
 
    public void destroy() throws Exception {
+      final String dropTableSql = "DROP TABLE " + sqlProvider.getTableName();
       try {
          connection.setAutoCommit(false);
          try (Statement statement = connection.createStatement()) {
-            statement.executeUpdate("DROP TABLE " + sqlProvider.getTableName());
+            statement.executeUpdate(dropTableSql);
          }
          connection.commit();
       } catch (SQLException e) {
-         connection.rollback();
+         logger.error(JDBCUtils.appendSQLExceptionDetails(new StringBuilder(), e, dropTableSql));
+         try {
+            connection.rollback();
+         } catch (SQLException rollbackEx) {
+            logger.error(JDBCUtils.appendSQLExceptionDetails(new StringBuilder(), rollbackEx,
dropTableSql));
+            throw rollbackEx;
+         }
          throw e;
       }
    }
 
-   private static void createTableIfNotExists(Connection connection, String tableName, String...
sqls) throws SQLException {
+   private static void createTableIfNotExists(Connection connection,
+                                              String tableName,
+                                              String... sqls) throws SQLException {
       logger.tracef("Validating if table %s didn't exist before creating", tableName);
       try {
          connection.setAutoCommit(false);
          try (ResultSet rs = connection.getMetaData().getTables(null, null, tableName, null))
{
             if (rs != null && !rs.next()) {
-               logger.tracef("Table %s did not exist, creating it with SQL=%s", tableName,
Arrays.toString(sqls));
+               if (logger.isTraceEnabled()) {
+                  logger.tracef("Table %s did not exist, creating it with SQL=%s", tableName,
Arrays.toString(sqls));
+               }
+               final SQLWarning sqlWarning = rs.getWarnings();
+               if (sqlWarning != null) {
+                  logger.warn(JDBCUtils.appendSQLExceptionDetails(new StringBuilder(), sqlWarning));
+               }
                try (Statement statement = connection.createStatement()) {
                   for (String sql : sqls) {
                      statement.executeUpdate(sql);
+                     final SQLWarning statementSqlWarning = statement.getWarnings();
+                     if (statementSqlWarning != null) {
+                        logger.warn(JDBCUtils.appendSQLExceptionDetails(new StringBuilder(),
statementSqlWarning, sql));
+                     }
                   }
                }
             }
          }
          connection.commit();
       } catch (SQLException e) {
-         connection.rollback();
+         final String sqlStatements = Stream.of(sqls).collect(Collectors.joining("\n"));
+         logger.error(JDBCUtils.appendSQLExceptionDetails(new StringBuilder(), e, sqlStatements));
+         try {
+            connection.rollback();
+         } catch (SQLException rollbackEx) {
+            logger.error(JDBCUtils.appendSQLExceptionDetails(new StringBuilder(), rollbackEx,
sqlStatements));
+            throw rollbackEx;
+         }
+         throw e;
       }
    }
 
-   private Driver getDriver(String className) throws Exception {
+   private Driver getDriver(String className) {
       try {
          Driver driver = (Driver) Class.forName(className).newInstance();
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/837066d4/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/JDBCUtils.java
----------------------------------------------------------------------
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 418fd43..2d85b29 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
@@ -16,6 +16,8 @@
  */
 package org.apache.activemq.artemis.jdbc.store.drivers;
 
+import java.sql.SQLException;
+
 import org.apache.activemq.artemis.jdbc.store.drivers.derby.DerbySQLProvider;
 import org.apache.activemq.artemis.jdbc.store.drivers.mysql.MySQLSQLProvider;
 import org.apache.activemq.artemis.jdbc.store.drivers.postgres.PostgresSQLProvider;
@@ -63,4 +65,59 @@ public class JDBCUtils {
       return factory.create(tableName);
    }
 
+   /**
+    * Append to {@code errorMessage} a detailed description of the provided {@link SQLException}.<br/>
+    * The information appended are:
+    * <ul>
+    * <li>SQL STATEMENTS</li>
+    * <li>SQL EXCEPTIONS details ({@link SQLException#getSQLState},
+    * {@link SQLException#getErrorCode} and {@link SQLException#getMessage}) of the linked
list ({@link SQLException#getNextException}) of exceptions</li>
+    * </ul>
+    *
+    * @param errorMessage  the target where append the exceptions details
+    * @param exception     the SQL exception (or warning)
+    * @param sqlStatements the SQL statements related to the {@code exception}
+    * @return {@code errorMessage}
+    */
+   public static StringBuilder appendSQLExceptionDetails(StringBuilder errorMessage,
+                                                         SQLException exception,
+                                                         CharSequence sqlStatements) {
+      errorMessage.append("\nSQL STATEMENTS: \n").append(sqlStatements);
+      return appendSQLExceptionDetails(errorMessage, exception);
+   }
+
+   /**
+    * Append to {@code errorMessage} a detailed description of the provided {@link SQLException}.<br/>
+    * The information appended are:
+    * <ul>
+    * <li>SQL EXCEPTIONS details ({@link SQLException#getSQLState},
+    * {@link SQLException#getErrorCode} and {@link SQLException#getMessage}) of the linked
list ({@link SQLException#getNextException}) of exceptions</li>
+    * </ul>
+    *
+    * @param errorMessage the target where append the exceptions details
+    * @param exception    the SQL exception (or warning)
+    * @return {@code errorMessage}
+    */
+   public static StringBuilder appendSQLExceptionDetails(StringBuilder errorMessage, SQLException
exception) {
+      errorMessage.append("\nSQL EXCEPTIONS: ");
+      SQLException nextEx = exception;
+      int level = 0;
+      do {
+         errorMessage.append('\n');
+         for (int i = 0; i < level; i++) {
+            errorMessage.append(' ');
+         }
+         formatSqlException(errorMessage, nextEx);
+         nextEx = exception.getNextException();
+         level++;
+      } while (nextEx != null);
+      return errorMessage;
+   }
+
+   private static StringBuilder formatSqlException(StringBuilder errorMessage, SQLException
exception) {
+      final String sqlState = exception.getSQLState();
+      final int errorCode = exception.getErrorCode();
+      final String message = exception.getMessage();
+      return errorMessage.append("SQLState: ").append(sqlState).append(" ErrorCode: ").append(errorCode).append("
Message: ").append(message);
+   }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/837066d4/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 66f00ec..008e000 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
@@ -80,7 +80,7 @@ public class JDBCSequentialFileFactory implements SequentialFileFactory,
ActiveM
             started = true;
          }
       } catch (Exception e) {
-         ActiveMQJournalLogger.LOGGER.error("Could not start file factory, unable to connect
to database");
+         ActiveMQJournalLogger.LOGGER.error("Could not start file factory, unable to connect
to database", e);
          started = false;
       }
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/837066d4/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/journal/JDBCJournalImpl.java
----------------------------------------------------------------------
diff --git a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/journal/JDBCJournalImpl.java
b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/journal/JDBCJournalImpl.java
index ba3dd0d..f718785 100644
--- a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/journal/JDBCJournalImpl.java
+++ b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/journal/JDBCJournalImpl.java
@@ -107,7 +107,7 @@ public class JDBCJournalImpl extends AbstractJDBCDriver implements Journal
{
    }
 
    @Override
-   public void start() throws Exception {
+   public void start() throws SQLException {
       super.start();
       syncTimer = new JDBCJournalSync(scheduledExecutorService, completeExecutor, SYNC_DELAY,
TimeUnit.MILLISECONDS, this);
       started = true;


Mime
View raw message