From c9567495aba6894b80f95917a220dc3b40f33cf1 Mon Sep 17 00:00:00 2001 From: Nick Livens Date: Tue, 31 May 2016 14:39:43 +0200 Subject: [PATCH] Make sure that the DB drivers are loaded before initiating connections --- .../src/com/cloud/utils/db/DriverLoader.java | 69 +++++++++++++++++++ .../com/cloud/utils/db/TransactionLegacy.java | 18 +---- 2 files changed, 72 insertions(+), 15 deletions(-) create mode 100644 framework/db/src/com/cloud/utils/db/DriverLoader.java diff --git a/framework/db/src/com/cloud/utils/db/DriverLoader.java b/framework/db/src/com/cloud/utils/db/DriverLoader.java new file mode 100644 index 00000000000..06c8da5c355 --- /dev/null +++ b/framework/db/src/com/cloud/utils/db/DriverLoader.java @@ -0,0 +1,69 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.utils.db; + +import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.log4j.Logger; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DriverLoader { + + private static final Logger LOGGER = Logger.getLogger(DriverLoader.class.getName()); + private static final List LOADED_DRIVERS; + private static final Map DRIVERS; + + static { + DRIVERS = new HashMap(); + DRIVERS.put("jdbc:mysql", "com.mysql.jdbc.Driver"); + DRIVERS.put("jdbc:postgresql", "org.postgresql.Driver"); + DRIVERS.put("jdbc:h2", "org.h2.Driver"); + + LOADED_DRIVERS = new ArrayList(); + } + + + public static void loadDriver(String dbDriver) { + String driverClass = DRIVERS.get(dbDriver); + if (driverClass == null) { + LOGGER.error("DB driver type " + dbDriver + " is not supported!"); + throw new CloudRuntimeException("DB driver type " + dbDriver + " is not supported!"); + } + + if (LOADED_DRIVERS.contains(dbDriver)) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("DB driver " + driverClass + " was already loaded."); + } + return; + } + + try { + Class.forName(driverClass).newInstance(); + LOADED_DRIVERS.add(dbDriver); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Successfully loaded DB driver " + driverClass); + } + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + LOGGER.error("Failed to load DB driver " + driverClass); + throw new CloudRuntimeException("Failed to load DB driver " + driverClass, e); + } + } + +} diff --git a/framework/db/src/com/cloud/utils/db/TransactionLegacy.java b/framework/db/src/com/cloud/utils/db/TransactionLegacy.java index 523162e2220..847ec1ee290 100644 --- a/framework/db/src/com/cloud/utils/db/TransactionLegacy.java +++ b/framework/db/src/com/cloud/utils/db/TransactionLegacy.java @@ -20,8 +20,6 @@ import java.io.Closeable; import java.io.File; import java.io.IOException; import java.sql.Connection; -import java.sql.Driver; -import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -1078,7 +1076,7 @@ public class TransactionLegacy implements Closeable { final String cloudConnectionUri = cloudDriver + "://" + cloudHost + (s_dbHAEnabled ? "," + cloudSlaves : "") + ":" + cloudPort + "/" + cloudDbName + "?autoReconnect=" + cloudAutoReconnect + (url != null ? "&" + url : "") + (useSSL ? "&useSSL=true" : "") + (s_dbHAEnabled ? "&" + cloudDbHAParams : "") + (s_dbHAEnabled ? "&loadBalanceStrategy=" + loadBalanceStrategy : ""); - loadDbDriver(cloudConnectionUri); + DriverLoader.loadDriver(cloudDriver); final ConnectionFactory cloudConnectionFactory = new DriverManagerConnectionFactory(cloudConnectionUri, cloudUsername, cloudPassword); @@ -1109,7 +1107,7 @@ public class TransactionLegacy implements Closeable { final String usageConnectionUri = usageDriver + "://" + usageHost + (s_dbHAEnabled ? "," + dbProps.getProperty("db.cloud.slaves") : "") + ":" + usagePort + "/" + usageDbName + "?autoReconnect=" + usageAutoReconnect + (usageUrl != null ? "&" + usageUrl : "") + (s_dbHAEnabled ? "&" + getDBHAParams("usage", dbProps) : "") + (s_dbHAEnabled ? "&loadBalanceStrategy=" + loadBalanceStrategy : ""); - loadDbDriver(usageConnectionUri); + DriverLoader.loadDriver(usageDriver); final ConnectionFactory usageConnectionFactory = new DriverManagerConnectionFactory(usageConnectionUri, usageUsername, usagePassword); @@ -1137,7 +1135,7 @@ public class TransactionLegacy implements Closeable { final String simulatorConnectionUri = simulatorDriver + "://" + simulatorHost + ":" + simulatorPort + "/" + simulatorDbName + "?autoReconnect=" + simulatorAutoReconnect; - loadDbDriver(simulatorConnectionUri); + DriverLoader.loadDriver(simulatorDriver); final ConnectionFactory simulatorConnectionFactory = new DriverManagerConnectionFactory(simulatorConnectionUri, simulatorUsername, simulatorPassword); @@ -1157,16 +1155,6 @@ public class TransactionLegacy implements Closeable { } } - private static void loadDbDriver(String dbConnectionUri) { - try { - Driver driver = DriverManager.getDriver(dbConnectionUri); - s_logger.debug("Successfully loaded DB driver " + driver.getClass().getName() + " for connection " + dbConnectionUri); - } catch (SQLException e) { - s_logger.error("Failed to load DB driver for connection " + dbConnectionUri, e); - throw new CloudRuntimeException("Failed to load DB driver for connection " + dbConnectionUri, e); - } - } - private static String getDBHAParams(String dbName, Properties dbProps) { StringBuilder sb = new StringBuilder(); sb.append("failOverReadOnly=" + dbProps.getProperty("db." + dbName + ".failOverReadOnly"));