/******************************************************************************* * Copyright 2016, 2017 Capital One Services, LLC and Bitwise, Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with 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 hydrograph.server.utilities; import hydrograph.server.metadata.exception.ParamsCannotBeNullOrEmpty; import hydrograph.server.service.HydrographService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.sql.*; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; /** * The utility class for the service. This class is meant to be stateless and * provide just static utility methods. There should not be any instance * variables of this class. The constructor has deliberately been made private * in order to discourage users from creating instance of this class * * @author Prabodh */ public class ServiceUtilities { private static final Logger LOG = LoggerFactory.getLogger(ServiceUtilities.class); private static String SERVICE_CONFIG = "ServiceConfig"; /** * */ private ServiceUtilities() { } /** * Returns the {@link ResourceBundle} object for the service config file * * @return the {@link ResourceBundle} object for the service config file */ public static ResourceBundle getServiceConfigResourceBundle() { return getResourceBundle(SERVICE_CONFIG); } private static ResourceBundle getResourceBundle(String resource) { ResourceBundle resBundl = ResourceBundle.getBundle(SERVICE_CONFIG); // Try to get ServiceConfig.properties file from the config folder of // the project // Can also use the default one provided in the package. String basePath = HydrographService.class.getProtectionDomain().getCodeSource().getLocation().getPath(); basePath = basePath.substring(0, basePath.lastIndexOf("/")); basePath = basePath.substring(0, basePath.lastIndexOf("/")) + "/config/"; LOG.info("Base Path:" + basePath); File file = new File(basePath); LOG.info("FILE PATH: " + basePath); if (file.exists()) { LOG.info("Using ServiceConfig from: " + basePath); try { URL[] resourceURLs = {file.toURI().toURL()}; URLClassLoader urlLoader = new URLClassLoader(resourceURLs); resBundl = ResourceBundle.getBundle("ServiceConfigOverride", Locale.getDefault(), urlLoader); LOG.info("PORT:" + resBundl.getString(Constants.PORT_ID)); } catch (MalformedURLException e) { LOG.error("Malformed url exception" + e.getMessage()); } } return resBundl; } /** * Used to set the connection for * <p> * //@param connectionProperties - contain request params details * * @throws ClassNotFoundException * @throws SQLException */ @SuppressWarnings("unchecked") public static boolean getConnectionStatus(Map metadataOperationProperteies, String jdbcClassName, String queryToTest) throws Exception { String jdbcUrl = null; String dbType = metadataOperationProperteies .getOrDefault(Constants.dbType, new ParamsCannotBeNullOrEmpty(Constants.DRIVER_TYPE + " not found in request parameter")) .toString(); String driverType = metadataOperationProperteies .getOrDefault(Constants.DRIVER_TYPE, new ParamsCannotBeNullOrEmpty(Constants.DRIVER_TYPE + " not found in request parameter")) .toString(); String host = metadataOperationProperteies .getOrDefault(Constants.HOST_NAME, new ParamsCannotBeNullOrEmpty(Constants.HOST_NAME + " not found in request parameter")) .toString(); String port = metadataOperationProperteies .getOrDefault(Constants.PORT_NUMBER, new ParamsCannotBeNullOrEmpty(Constants.PORT_NUMBER + " not found in request parameter")) .toString(); String userId = metadataOperationProperteies .getOrDefault(Constants.USERNAME, new ParamsCannotBeNullOrEmpty(Constants.USERNAME + " not found in request parameter")) .toString(); String service_pwd = metadataOperationProperteies .getOrDefault(Constants.SERVICE_PWD, new ParamsCannotBeNullOrEmpty(Constants.SERVICE_PWD + " not found in request parameter")) .toString(); switch (dbType.toLowerCase()) { case Constants.ORACLE: String sid = metadataOperationProperteies .getOrDefault(Constants.SID, new ParamsCannotBeNullOrEmpty(Constants.SID + " Not found in request parameter")) .toString(); jdbcUrl = "jdbc:oracle:" + driverType + "://@" + host + ":" + port + ":" + sid; break; case Constants.MYSQL: String database = metadataOperationProperteies .getOrDefault(Constants.DATABASE_NAME, new ParamsCannotBeNullOrEmpty(Constants.DATABASE_NAME + " not found in request parameter")) .toString(); jdbcUrl = "jdbc:mysql://" + host + ":" + port + "/" + database; break; case Constants.REDSHIFT: String databasename = metadataOperationProperteies .getOrDefault(Constants.DATABASE_NAME, new ParamsCannotBeNullOrEmpty(Constants.DATABASE_NAME + " not found in request parameter")) .toString(); jdbcUrl = "jdbc:redshift://" + host + ":" + port + "/" + databasename; break; case Constants.TERADATA: String database_teradata = metadataOperationProperteies .getOrDefault(Constants.DATABASE_NAME, new ParamsCannotBeNullOrEmpty(Constants.DATABASE_NAME + " not found in request parameter")) .toString(); jdbcUrl = "jdbc:teradata://" + host + "/" + "DBS_PORT" + "=" + port + "," + "DATABASE" + "=" + database_teradata; break; } Class.forName(jdbcClassName); Connection connectionObject=null; boolean testConnectionStatus = false; try { connectionObject = DriverManager.getConnection(jdbcUrl, userId, service_pwd); testConnectionStatus = testConnection(connectionObject, queryToTest); } catch (SQLException e) { LOG.error("Error while connecting to database ", e.getMessage()); throw new Exception(e.getLocalizedMessage()); } finally { safeConnectionClose(connectionObject); } return testConnectionStatus; } /** * Test Validity of a Jdbc Connection * <p> * //@param JDBC connection object * * @return true if a given connection object is a valid one; otherwise * return false. * @throws SQLException */ private static boolean testConnection(Connection connectionObject, String queryToTest) throws SQLException { ResultSet rs = null; Statement stmt = null; try { stmt = connectionObject.createStatement(); if (stmt == null) { return false; } rs = stmt.executeQuery(queryToTest); if (rs == null) { return false; } // connection object is valid: you were able to // connect to the database and return something useful. if (rs.next()) { return true; } // there is no hope any more for the validity // of the Connection object return false; } catch (Exception e) { // Something went wrong: connection is bad LOG.error("Unable to make Connection to Oracle Database" + e.getMessage()); return false; } finally { SQLException exception = null; // close database resources try { safeResultSetClose(rs); } catch (SQLException sqlException) { exception = sqlException; } try { safeStatementClose(stmt); } catch (SQLException sqlException) { exception = sqlException; } if (exception != null) throw exception; } } /** * Close SQL ResultSet connection * <p> * //@param ResultSet object * * @throws SQLException */ public static void safeResultSetClose(ResultSet resultSet) throws SQLException { if (resultSet != null) { try { resultSet.close(); } catch (SQLException sqlException) { LOG.error("Exception in closing sql result set. The error message is " + sqlException.getMessage()); throw sqlException; } } } /** * Close SQL Statement * <p> * //@param Statement object * * @throws SQLException */ public static void safeStatementClose(Statement statement) throws SQLException { if (statement != null) { try { statement.close(); } catch (SQLException sqlException) { LOG.error("Exception in closing sql statement. The error message is " + sqlException.getMessage()); throw sqlException; } } } /** * Close SQL Connection * <p> * //@param Connection object * * @throws SQLException */ public static void safeConnectionClose(Connection connection) throws SQLException { if (connection != null) { try { connection.close(); } catch (SQLException sqlException) { LOG.error("Exception in closing sql connection. The error message is " + sqlException.getMessage()); throw sqlException; } } } /** * Close OutputStream * <p> * //@param OutputStream object * * @throws IOException */ public static void safeOutputStreamClose(OutputStream outputStream) throws IOException { if (outputStream != null) { try { outputStream.close(); } catch (IOException ioException) { LOG.error("Exception in output stream. The error message is " + ioException.getMessage()); throw ioException; } } } /** * Close InputStream * <p> * //@param InputStream object * * @throws IOException */ public static void safeInputStreamClose(InputStream inputStream) throws IOException { if (inputStream != null) { try { inputStream.close(); } catch (IOException ioException) { LOG.error("Exception in closing input stream. The error message is " + ioException.getMessage()); throw ioException; } } } }