com.continuent.tungsten.common.mysql
Class MySQLIOs

java.lang.Object
  extended by com.continuent.tungsten.common.mysql.MySQLIOs

public class MySQLIOs
extends java.lang.Object

Utility class to retrieve the input and output streams of a JDBC Connection to a MySQL server. These IOs serve the mean of fast and direct interactions with the server (also known as pass-through mode).
Current implementation allows IOs retrieval for both MySQL and Drizzle drivers even when behind the SQL-Router or a c3p0 connection pool

Author:
Gilles Rayrat

Nested Class Summary
static class MySQLIOs.ExecuteQueryStatus
           
 
Field Summary
static java.lang.String MYSQL_ERRNO
           
static java.lang.String MYSQL_SQL_STATE
           
static java.lang.String RESULT_KEY
           
static java.lang.String SOCKET_PHASE_CONNECT
           
static java.lang.String SOCKET_PHASE_READ
           
static java.lang.String SOCKET_PHASE_WRITE
           
static java.lang.String STATUS_EXCEPTION
           
static java.lang.String STATUS_KEY
           
static java.lang.String STATUS_MESSAGE_KEY
           
static java.lang.String TIME_TO_CONNECT_MS
           
static java.lang.String TIME_TO_EXEC_QUERY_MS
           
static java.lang.String TIME_TO_INIT_MS
           
 
Method Summary
static boolean connectionIsCompatible(java.sql.Connection conn)
          Tells whether the given connection is one that we can exploit for the purposes of getting access to MySQL IOs.
static byte[] encryptMySQLPassword(java.lang.String password, byte[] seed)
          Do a MySQL specific encryption of the given password
Algorithm is:
stage1_hash = SHA1(password)
token = SHA1(scramble + SHA1(stage1_hash)) XOR stage1_hash
static TungstenProperties executeQueryWithTimeouts(java.lang.String hostname, int port, java.lang.String user, java.lang.String password, java.lang.String db, java.lang.String query, int timeoutMsecs)
          Tries to establish a connection to a MySQL server with given credentials and timeout.
static java.lang.Object extractInnerConnection(java.sql.Connection connection)
          A pooled or SQL-Router JDBC connection wraps the original MySQL connection object.
static java.lang.Object extractInnerConnectionFromBoneCP(java.lang.Object pooledConnection)
          Given a BoneCP pooled connection, extracts the enclosed "real" connection
static java.lang.Object extractInnerConnectionFromC3P0(java.lang.Object pooledConnection)
          Given a C3P0 pooled connection, extracts the enclosed "real" connection
static java.lang.Object extractInnerConnectionFromPooledConnection(java.lang.Object pooledConnection, java.lang.String memberVariableName)
          Given a connection pool connection, extracts the enclosed "real" connection
static java.lang.Object extractInnerConnectionFromSQLR(java.lang.Object sqlrConnection)
          Given a SQL-Router connection, retrieve the encapsulated connection
static void forceClose(java.sql.Connection conn)
           
 java.io.InputStream getInput()
           
static MySQLIOs getMySQLIOs(java.sql.Connection connection)
          Extracts MySQL server input and output streams from the given connection.
 java.io.BufferedOutputStream getOutput()
           
static long getServerThreadID(java.sql.Connection connection)
          Every connection to a MySQL server has a server side ID, called connection ID or server thread ID.
static ResourceState getStateFromQueryStatus(MySQLIOs.ExecuteQueryStatus status)
          Returns the ResourceState that maps to the status of the query execution.
static boolean isAlive(java.lang.String hostname, int port, java.lang.String user, java.lang.String password, java.lang.String db, java.lang.String query, int timeoutMsecs)
          Checks a MySQL server connectivity by running the given query against it.
static void loadStateMappingConfiguration()
           
static java.lang.String showStateMapping()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

STATUS_KEY

public static final java.lang.String STATUS_KEY
See Also:
Constant Field Values

STATUS_EXCEPTION

public static final java.lang.String STATUS_EXCEPTION
See Also:
Constant Field Values

MYSQL_ERRNO

public static final java.lang.String MYSQL_ERRNO
See Also:
Constant Field Values

MYSQL_SQL_STATE

public static final java.lang.String MYSQL_SQL_STATE
See Also:
Constant Field Values

STATUS_MESSAGE_KEY

public static final java.lang.String STATUS_MESSAGE_KEY
See Also:
Constant Field Values

RESULT_KEY

public static final java.lang.String RESULT_KEY
See Also:
Constant Field Values

TIME_TO_CONNECT_MS

public static final java.lang.String TIME_TO_CONNECT_MS
See Also:
Constant Field Values

TIME_TO_INIT_MS

public static final java.lang.String TIME_TO_INIT_MS
See Also:
Constant Field Values

TIME_TO_EXEC_QUERY_MS

public static final java.lang.String TIME_TO_EXEC_QUERY_MS
See Also:
Constant Field Values

SOCKET_PHASE_CONNECT

public static final java.lang.String SOCKET_PHASE_CONNECT
See Also:
Constant Field Values

SOCKET_PHASE_READ

public static final java.lang.String SOCKET_PHASE_READ
See Also:
Constant Field Values

SOCKET_PHASE_WRITE

public static final java.lang.String SOCKET_PHASE_WRITE
See Also:
Constant Field Values
Method Detail

getMySQLIOs

public static MySQLIOs getMySQLIOs(java.sql.Connection connection)
                            throws java.io.IOException
Extracts MySQL server input and output streams from the given connection.
In order to avoid explicit driver dependency, this function uses introspection to retrieve the connection inner field

Parameters:
connection - a jdbc connection object that must be connected to a MySQL server
Returns:
a new MySQLIOs object containing extracted input and output streams of the given connection
Throws:
java.io.IOException - if the streams could not be extracted

extractInnerConnection

public static java.lang.Object extractInnerConnection(java.sql.Connection connection)
                                               throws java.io.IOException
A pooled or SQL-Router JDBC connection wraps the original MySQL connection object. This function allows to extract the MySQL connection object from a given Connection, regardless of the implementing class

Parameters:
connection - a regular, pooled or SQL-Router connection
Returns:
the wrapped MySQL connection as an object, which can be either MySQL jdbc3 or jdbc4 connection
Throws:
java.io.IOException - upon problems getting the inner connection

extractInnerConnectionFromC3P0

public static java.lang.Object extractInnerConnectionFromC3P0(java.lang.Object pooledConnection)
                                                       throws java.io.IOException
Given a C3P0 pooled connection, extracts the enclosed "real" connection

Parameters:
pooledConnection - a c3p0-pooled connection
Returns:
JDBC connection wrapped by the given connection
Throws:
java.io.IOException - if an error occurs retrieving inner connection

extractInnerConnectionFromBoneCP

public static java.lang.Object extractInnerConnectionFromBoneCP(java.lang.Object pooledConnection)
                                                         throws java.io.IOException
Given a BoneCP pooled connection, extracts the enclosed "real" connection

Parameters:
pooledConnection - a boneCP-pooled connection
Returns:
JDBC connection wrapped by the given connection
Throws:
java.io.IOException - if an error occurs retrieving inner connection

extractInnerConnectionFromPooledConnection

public static java.lang.Object extractInnerConnectionFromPooledConnection(java.lang.Object pooledConnection,
                                                                          java.lang.String memberVariableName)
                                                                   throws java.io.IOException
Given a connection pool connection, extracts the enclosed "real" connection

Parameters:
pooledConnection - a c3p0 or boneCP -pooled connection
memberVariableName - name of the inner connection variable
Returns:
JDBC connection wrapped by the given connection
Throws:
java.io.IOException - if an error occurs retrieving inner connection

extractInnerConnectionFromSQLR

public static java.lang.Object extractInnerConnectionFromSQLR(java.lang.Object sqlrConnection)
                                                       throws java.io.IOException
Given a SQL-Router connection, retrieve the encapsulated connection

Parameters:
sqlrConnection - Tungsten SQL-router connection
Returns:
JDBC connection wrapped by the given router connection
Throws:
java.io.IOException - if an error occurs retrieving inner connection

getServerThreadID

public static long getServerThreadID(java.sql.Connection connection)
Every connection to a MySQL server has a server side ID, called connection ID or server thread ID. This function allows getting this ID, currently only on a MySQL driver connection
TODO: implement Drizzle version

Parameters:
connection - the (connected) connection to get ID from
Returns:
the server thread ID of the given connection as a long

connectionIsCompatible

public static boolean connectionIsCompatible(java.sql.Connection conn)
Tells whether the given connection is one that we can exploit for the purposes of getting access to MySQL IOs.

Parameters:
conn - connection to test
Returns:
true if the connection is one of c3p0, SQL-Router, MySQL connector/j or Drizzle connector. Otherwise false.

getInput

public java.io.InputStream getInput()

getOutput

public java.io.BufferedOutputStream getOutput()

isAlive

public static boolean isAlive(java.lang.String hostname,
                              int port,
                              java.lang.String user,
                              java.lang.String password,
                              java.lang.String db,
                              java.lang.String query,
                              int timeoutMsecs)
Checks a MySQL server connectivity by running the given query against it. This function differs for simple JDBC driver connect/execute in the sense that it sets timeout on sockets, so that if the server is unresponsive, the function will return after the timeout expires. If the server is not accepting connections because of "Too many connections error" or if the socket timeout expires, this function will consider the MySQL server as alive (or potentially alive) and return true. For finer-grain diagnosis or request result retrieval, use executeQueryWithTimeouts(String, int, String, String, String, String, int)

Parameters:
hostname -
port -
user -
password -
db - null or empty when not wanting to connect to any DB
query - the query to be executed against the server - only selects are supported
timeoutMsecs - must be positive. Zero timeout is considered as no timeout
Returns:
true if the server is up and running, false otherwise

executeQueryWithTimeouts

public static TungstenProperties executeQueryWithTimeouts(java.lang.String hostname,
                                                          int port,
                                                          java.lang.String user,
                                                          java.lang.String password,
                                                          java.lang.String db,
                                                          java.lang.String query,
                                                          int timeoutMsecs)
Tries to establish a connection to a MySQL server with given credentials and timeout. Upon success, runs the given request (which must be a select!) and returns the result as TungstenProperties holding only the first row, with column names as keys and results as values.

Parameters:
hostname -
port -
user -
password -
db - null or empty when not wanting to connect to any DB
query - the query to be executed against the server - only selects are supported
timeoutMsecs - must be positive. Zero timeout is considered as no timeout
Returns:
null if the server is not alive/accessible, or the query result wrapped inside tungsten properties

encryptMySQLPassword

public static byte[] encryptMySQLPassword(java.lang.String password,
                                          byte[] seed)
Do a MySQL specific encryption of the given password
Algorithm is:
stage1_hash = SHA1(password)
token = SHA1(scramble + SHA1(stage1_hash)) XOR stage1_hash

Parameters:
password - the password to scramble
seed - the server seed to encode the password with
Returns:
and encrypted password ready to be sent to the server

forceClose

public static void forceClose(java.sql.Connection conn)

getStateFromQueryStatus

public static ResourceState getStateFromQueryStatus(MySQLIOs.ExecuteQueryStatus status)
Returns the ResourceState that maps to the status of the query execution.

Parameters:
status -

loadStateMappingConfiguration

public static void loadStateMappingConfiguration()
                                          throws ConfigurationException
Throws:
ConfigurationException

showStateMapping

public static java.lang.String showStateMapping()