blob: b58b88224b8880121ab280d7776e7ec1b7b8df47 [file] [log] [blame]
/**
* 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
* 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 org.apache.falcon.util;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
import java.util.ArrayList;
import org.apache.commons.io.FileUtils;
import org.hsqldb.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Create a simple hsqldb server and schema to use for testing.
*/
public final class HsqldbTestUtils {
public static final Logger LOG = LoggerFactory.getLogger(HsqldbTestUtils.class);
// singleton server instance.
private static Server server;
private static final String IN_MEM = "mem:/";
private static boolean inMemoryDB = IN_MEM.equals(getServerHost());
private static String dbLocation;
private static String dbBaseDir;
private HsqldbTestUtils() {}
public static String getServerHost() {
String host = System.getProperty("hsql.server.host", IN_MEM);
host = "localhost";
if (!host.endsWith("/")) { host += "/"; }
return host;
}
// Database name can be altered too
private static final String DATABASE_NAME = System.getProperty("hsql.database.name", "db1");
private static final String CUSTOMER_TABLE_NAME = "CUSTOMER";
private static final String DB_URL = "jdbc:hsqldb:hsql://" + getServerHost() + DATABASE_NAME;
private static final String DRIVER_CLASS = "org.hsqldb.jdbcDriver";
public static String getUrl() {
return DB_URL;
}
public static String getDatabaseName() {
return DATABASE_NAME;
}
/**
* start the server.
*/
public static void start() {
if (null == server) {
LOG.info("Starting new hsqldb server; database=" + DATABASE_NAME);
String tmpDir = System.getProperty("test.build.data", "/tmp/");
dbBaseDir = tmpDir + "/falcon";
dbLocation = dbBaseDir + "/testdb.file";
deleteHSQLDir();
server = new Server();
server.setDatabaseName(0, DATABASE_NAME);
server.putPropertiesFromString("database.0=" + dbLocation + ";no_system_exit=true;");
server.start();
LOG.info("Started server with url=" + DB_URL);
}
}
public static void stop() {
if (null != server) {
server.stop();
}
deleteHSQLDir();
}
private static void deleteHSQLDir() {
try {
FileUtils.deleteDirectory(new File(dbBaseDir));
LOG.info("Ok, Deleted HSQL temp dir at {}", dbBaseDir);
} catch(IOException ioe) {
LOG.info("Error deleting HSQL temp dir at {}", dbBaseDir);
}
}
public static void tearDown() throws SQLException {
dropExistingSchema();
stop();
}
public static void createSqoopUser(String user, String password) throws Exception {
Connection connection = null;
Statement st = null;
LOG.info("Creating user {} with password {}", user, password);
try {
connection = getConnectionSystem();
st = connection.createStatement();
boolean result = st.execute("CREATE USER " + user + " PASSWORD " + password + " ADMIN");
LOG.info("CREATE USER returned {}", result);
connection.commit();
} finally {
if (null != st) {
st.close();
}
if (null != connection) {
connection.close();
}
}
}
public static void changeSAPassword(String passwd) throws Exception {
Connection connection = null;
Statement st = null;
LOG.info("Changing password for SA");
try {
connection = getConnectionSystem();
st = connection.createStatement();
boolean result = st.execute("SET PASSWORD \"" + passwd + "\"");
LOG.info("Change PASSWORD for SA returned {}", result);
connection.commit();
} finally {
if (null != st) {
st.close();
}
if (null != connection) {
connection.close();
}
}
}
private static Connection getConnectionSystem() throws SQLException {
return getConnection("SA", "");
}
private static Connection getConnection() throws SQLException {
return getConnection("sqoop_user", "sqoop");
}
private static Connection getConnection(String user, String password) throws SQLException {
try {
Class.forName(DRIVER_CLASS);
} catch (ClassNotFoundException cnfe) {
LOG.error("Could not get connection; driver class not found: "
+ DRIVER_CLASS);
return null;
}
Connection connection = DriverManager.getConnection(DB_URL, user, password);
connection.setAutoCommit(false);
LOG.info("Connection for user {} password {} is open {}", user, password, !connection.isClosed());
return connection;
}
/**
* Returns database URL for the server instance.
* @return String representation of DB_URL
*/
public static String getDbUrl() {
return DB_URL;
}
public static int getNumberOfRows() throws SQLException {
Connection connection = null;
Statement st = null;
try {
connection = getConnection();
st = connection.createStatement();
ResultSet rs = st.executeQuery("SELECT COUNT(*) FROM " + CUSTOMER_TABLE_NAME);
int rowCount = 0;
if (rs.next()) {
rowCount = rs.getInt(1);
}
return rowCount;
} finally {
if (null != st) {
st.close();
}
if (null != connection) {
connection.close();
}
}
}
public static void createAndPopulateCustomerTable() throws SQLException, ClassNotFoundException {
LOG.info("createAndPopulateCustomerTable");
Connection connection = null;
Statement st = null;
try {
connection = getConnection();
st = connection.createStatement();
boolean r = st.execute("DROP TABLE " + CUSTOMER_TABLE_NAME + " IF EXISTS");
r = st.execute("CREATE TABLE " + CUSTOMER_TABLE_NAME + "(id INT NOT NULL PRIMARY KEY, name VARCHAR(64))");
LOG.info("CREATE TABLE returned {}", r);
r=st.execute("INSERT INTO " + CUSTOMER_TABLE_NAME + " VALUES(1, 'Apple')");
LOG.info("INSERT INTO returned {}", r);
r=st.execute("INSERT INTO " + CUSTOMER_TABLE_NAME + " VALUES(2, 'Blackberry')");
LOG.info("INSERT INTO returned {}", r);
r=st.execute("INSERT INTO " + CUSTOMER_TABLE_NAME + " VALUES(3, 'Caterpillar')");
LOG.info("INSERT INTO returned {}", r);
r=st.execute("INSERT INTO " + CUSTOMER_TABLE_NAME + " VALUES(4, 'DuPont')");
LOG.info("INSERT INTO returned {}", r);
connection.commit();
} finally {
if (null != st) {
st.close();
}
if (null != connection) {
connection.close();
}
}
}
/**
* Delete any existing tables.
*/
public static void dropExistingSchema() throws SQLException {
String [] tables = listTables();
if (null != tables) {
Connection conn = getConnection();
for (String table : tables) {
Statement s = conn.createStatement();
try {
s.executeUpdate("DROP TABLE " + table);
conn.commit();
} finally {
s.close();
}
}
}
}
public static String[] listTables() {
ResultSet results = null;
String [] tableTypes = {"TABLE"};
try {
try {
DatabaseMetaData metaData = getConnection().getMetaData();
results = metaData.getTables(null, null, null, tableTypes);
} catch (SQLException sqlException) {
LOG.error("Error reading database metadata: "
+ sqlException.toString(), sqlException);
return null;
}
if (null == results) {
return null;
}
try {
ArrayList<String> tables = new ArrayList<String>();
while (results.next()) {
String tableName = results.getString("TABLE_NAME");
tables.add(tableName);
}
return tables.toArray(new String[0]);
} catch (SQLException sqlException) {
LOG.error("Error reading from database: "
+ sqlException.toString(), sqlException);
return null;
}
} finally {
if (null != results) {
try {
results.close();
getConnection().commit();
} catch (SQLException sqlE) {
LOG.error("Exception closing ResultSet: "
+ sqlE.toString(), sqlE);
}
}
}
}
}