public static void waitForConnection(final ConnectionConfig connectionConfig,
                                         final String connectionName) {
        final String jdbcUrl = connectionConfig.getUrl();
        final String username = connectionConfig.getUser();
        final String nameText = connectionName != null
                ? connectionName + " "
                : "";
        LOGGER.info("Ensuring database connection {}to [{}] with username [{}] and driver class [{}]",
                nameText, jdbcUrl, username, connectionConfig.getClassName());

        long sleepMs = 500;
        Throwable lastThrowable = null;

        while (true) {
            try (Connection connection = getSingleConnection(connectionConfig)) {
                LOGGER.info("Successfully established connection to {} with username {}", jdbcUrl, username);
                break;
            } catch (SQLException e) {
                if (e.getErrorCode() == ACCESS_DENIED_BAD_UNAME_OR_PWORD ||
                        e.getErrorCode() == ACCESS_DENIED_BAD_DATABASE ||
                        (e.getMessage() != null && e.getMessage().startsWith("Unsupported"))) {

                    // These errors are not due to the DB not being up, so throw it
                    throw new RuntimeException(LogUtil.message(
                            "Error connecting to {} with username {}", jdbcUrl, username), e);
                }
                final Throwable cause = e.getCause();
                final String errorMsg = cause != null
                        ? cause.getMessage()
                        : e.getMessage();
                final int vendorCode = e.getErrorCode();
                LOGGER.warn("Unable to establish database connection due to error: [{}] " +
                                "and vendorCode [{}], will try again " +
                                "in {}ms, enable debug to see stack trace",
                        errorMsg, vendorCode, sleepMs);
                if (LOGGER.isDebugEnabled()) {
                    if (lastThrowable == null || !e.getMessage().equals(lastThrowable.getMessage())) {
                        // Only log the stack when it changes, else it fills up the log pretty quickly
                        LOGGER.debug("Unable to establish database connection due to error", e);
                    }
                    lastThrowable = e;
                }
            }
            try {
                Thread.sleep(sleepMs);
            } catch (InterruptedException e) {
                // Nothing to do here as the
                Thread.currentThread().interrupt();
                break;
            }

            // Gradually increase the sleep time up to a maximum
            sleepMs = (long) (sleepMs * 1.3);
            if (sleepMs >= MAX_SLEEP_TIME_MS) {
                sleepMs = MAX_SLEEP_TIME_MS;
            }
        }
    }
Attempts to connect to the database using the passed connection details. If it fails
it will log a warning, and keep retrying. The retry interval will steadily increase.
<p>
If the connection could not be established and the reason for the failure makes a
retry pointless, e.g. invalid password, then an exception will be thrown.
stroom-db-util/src/main/java/stroom/db/util/DbUtil.java