src-main.org.awakefw.sql.servlet.ServerAwakeSqlDispatch Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of awake-sql Show documentation
Show all versions of awake-sql Show documentation
Awake SQL is an open source framework that allows remote and secure JDBC access through HTTP.
The newest version!
/*
* This file is part of Awake SQL.
* Awake SQL: Remote JDBC access over HTTP.
* Copyright (C) 2013, KawanSoft SAS
* (http://www.kawansoft.com). All rights reserved.
*
* Awake SQL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Awake SQL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*
* If you develop commercial activities using Awake SQL, you must:
* a) disclose and distribute all source code of your own product,
* b) license your own product under the GNU General Public License.
*
* You can be released from the requirements of the license by
* purchasing a commercial license. Buying such a license will allow you
* to ship Awake SQL with your closed source products without disclosing
* the source code.
*
* For more information, please contact KawanSoft SAS at this
* address: [email protected]
*
* Any modifications to this file must keep this entire header
* intact.
*/
package org.awakefw.sql.servlet;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Level;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.awakefw.commons.api.server.AwakeCommonsConfigurator;
import org.awakefw.commons.server.util.AwakeServerLogger;
import org.awakefw.file.api.server.AwakeFileConfigurator;
import org.awakefw.file.api.server.fileaction.AwakeFileActionManager;
import org.awakefw.file.api.util.AwakeDebug;
import org.awakefw.file.servlet.KawanNotifier;
import org.awakefw.file.servlet.ServerAwakeFileDispatch;
import org.awakefw.file.servlet.ServerFileUploadAction;
import org.awakefw.file.servlet.ServerUserException;
import org.awakefw.file.util.Tag;
import org.awakefw.file.util.TransferStatus;
import org.awakefw.file.util.parms.Action;
import org.awakefw.file.util.parms.Parameter;
import org.awakefw.file.util.parms.ReturnCode;
import org.awakefw.sql.api.server.AwakeSqlConfigurator;
import org.awakefw.sql.servlet.connection.ConnectionInfoUtil;
import org.awakefw.sql.servlet.connection.ConnectionStore;
import org.awakefw.sql.servlet.connection.ConnectionStoreCleaner;
import org.awakefw.sql.servlet.connection.SavepointUtil;
import org.awakefw.sql.servlet.connection.TransactionUtil;
import org.awakefw.sql.servlet.executor.ServerBatchPrepStatementExecutorNew;
import org.awakefw.sql.servlet.executor.ServerBatchStatementExecutorNew;
import org.awakefw.sql.servlet.executor.ServerSqlExecutorCallable;
import org.awakefw.sql.servlet.executor.ServerSqlExecutorNew;
import org.awakefw.sql.util.ConnectionParms;
import org.awakefw.sql.util.SqlAction;
import org.awakefw.sql.util.SqlActionCallable;
import org.awakefw.sql.util.SqlActionTransaction;
import org.awakefw.sql.util.SqlReturnCode;
import org.awakefw.sql.version.VersionValues;
/**
* @author Nicolas de Pomereu
*
* The method executeRequest() is to to be called from the SqlHttpServer
* Servlet and Class.
* It will execute a client side request with a HttpConnection
* connection.
*
*/
public class ServerAwakeSqlDispatch {
private static boolean DEBUG = AwakeDebug
.isSet(ServerAwakeSqlDispatch.class);
// Errors in SqlHttpServer
private static final String ERR_ACTION_NOT_SET = "ERR_ACTION_NOT_SET";
/**
* Constructor
*/
public ServerAwakeSqlDispatch() {
// Does nothing
}
/**
* Execute the client sent sql request
*
* @param request
* the http request
* @param response
* the http response
* @param servletContextTempDir
* The temp dir used by Servlets
* @param awakeCommonsConfigurator
* the client commons http configurator specific class
* @param awakeFileConfigurator
* the client file http configurator specific class
* @param awakeSqlConfigurator
* the client sql http configurator specific class
* @param awakeFileActionManager
* the file action manager
* @param licenseInfoStore
* the store that contains the license infos
* @param connection
* the Sql Jdbc Connection
* @throws IOException
* if any IOException occurs
*/
public void executeRequest(HttpServletRequest request,
HttpServletResponse response, File servletContextTempDir,
AwakeCommonsConfigurator awakeCommonsConfigurator,
AwakeFileConfigurator awakeFileConfigurator,
AwakeSqlConfigurator awakeSqlConfigurator, AwakeFileActionManager awakeFileActionManager) throws IOException {
// Immediate catch if we are asking a file upload, because parameters
// are
// in unknown sequence. We know it's a upload action if it's mime
// multipart
if (ServletFileUpload.isMultipartContent(request)) {
ServerFileUploadAction serverFileUploadAction = new ServerFileUploadAction();
serverFileUploadAction.executeAction(request, response,
servletContextTempDir, awakeCommonsConfigurator,
awakeFileConfigurator, awakeFileActionManager);
return;
}
PrintWriter out = null;
try {
debug("executeRequest Start");
// Prepare the response
response.setContentType("text/html");
// Get the send string
debug("ACTION retrieval");
String action = null;
// We must trap the IllegalArgumentException to rethrow properly to
// client
// This happens if there is an encryption problem
try {
action = request.getParameter(Parameter.ACTION);
} catch (IllegalArgumentException e) {
debug("IllegalArgumentException : " + e.toString());
out = response.getWriter();
throw e;
}
String username = request.getParameter(Parameter.USERNAME);
debug("Before if (action.equals(Action.LOGIN_ACTION");
if (action.equals(Action.LOGIN_ACTION)
|| action.equals(Action.BEFORE_LOGIN_ACTION)) {
ServerLoginActionSql serverLoginActionSql = new ServerLoginActionSql();
serverLoginActionSql.executeAction(request, response,
awakeCommonsConfigurator, awakeSqlConfigurator, action);
return;
}
debug("ACTION : " + action);
// Redirect to Awake File if it's a File request (Blobs/Clobs)
if (isActionForAwakeFile(action)) {
ServerAwakeFileDispatch serverAwakeFileDispatch = new ServerAwakeFileDispatch();
serverAwakeFileDispatch.executeRequest(request, response, servletContextTempDir,
awakeCommonsConfigurator, awakeFileConfigurator,
awakeFileActionManager);
return;
}
debug("After isActionForAwakeFile");
out = response.getWriter();
if (action == null || action.equals("")) {
// out.println(HttpTransferOne.SEND_FAILED + SPACE +
// ERR_ACTION_NOT_SET);
out.println(TransferStatus.SEND_FAILED);
out.println(ERR_ACTION_NOT_SET);
return;
}
debug("Before if (! ServerAwakeFileDispatch.isTokenValid(username, token, awakeCommonsConfigurator");
String token = request.getParameter(Parameter.TOKEN);
if (! ServerAwakeFileDispatch.isTokenValid(username, token, awakeCommonsConfigurator))
{
out.println(TransferStatus.SEND_OK);
out.println(ReturnCode.INVALID_LOGIN_OR_PASSWORD);
return;
}
String connectionId = request
.getParameter(ConnectionParms.CONNECTION_ID);
// If we are in normal mode (not server stateless mode), transaction
// id is > 0
// So Extract a Connection from the pool and store it memory
if (action
.equals(SqlActionTransaction.ACTION_SQL_INIT_REMOTE_CONNECTION)
&& !connectionId.equals("0")) {
// Create the Connection & store it
ConnectionStore connectionStore = new ConnectionStore(username,
connectionId);
Connection connection = awakeCommonsConfigurator
.getConnection();
connectionStore.put(connection);
debug("ACTION_SQL_INIT_REMOTE_CONNECTION");
debug("username :" + username + ":");
debug("connectionId :" + connectionId + ":");
debug("connection :" + connection + ":"); ;
out.println(TransferStatus.SEND_OK);
return;
}
// If we are not in stateless mode, clean old connections with a Thread
if (!connectionId.equals("0") && !ConnectionStoreCleaner.IS_RUNNING) {
ConnectionStoreCleaner cleaner = new ConnectionStoreCleaner(awakeSqlConfigurator);
cleaner.start();
}
// Notify to Kawan in async mode using a secured Thread that
// the user has successfully logged (done once in JVM session per
// username).
// No notification is done if user.home/.awake/no_notify.txt exists
// or web server name is localhost or 127.0.0.1
if (!KawanNotifier.existsNoNotifyTxt()
&& !KawanNotifier.usernameAlreadyLogged(username)
&& !KawanNotifier.serverNameIsLocalhost()) {
KawanNotifier kawanNotifier = new KawanNotifier(username,
"AwakeSql_" + VersionValues.VERSION);
kawanNotifier.start();
}
if (action.equals(SqlAction.ACTION_SQL_STATEMENT)) {
executeStatement(request, awakeCommonsConfigurator,
awakeFileConfigurator, awakeSqlConfigurator, out);
} else if (action.equals(SqlAction.ACTION_SQL_STATEMENT_BATCH)) {
executeStatementBatch(request, awakeCommonsConfigurator,
awakeFileConfigurator, awakeSqlConfigurator, out);
} else if (action.equals(SqlAction.ACTION_SQL_PREP_STATEMENT_BATCH)) {
executePrepStatementBatch(request, awakeCommonsConfigurator,
awakeFileConfigurator, awakeSqlConfigurator, out);
} else if (action.equals(SqlAction.ACTION_SQL_GET_METADATA)) {
executeGetMetadata(request, awakeCommonsConfigurator,
awakeSqlConfigurator, out);
} else if (action.equals(SqlAction.ACTION_SQL_EXECUTE_RAW)) {
executeRaw(request, awakeCommonsConfigurator,
awakeFileConfigurator, awakeSqlConfigurator, out);
} else if (action
.equals(SqlActionTransaction.ACTION_SQL_GET_TRANSACTION_ISOLATION)) {
getTransactionIsolation(request, awakeCommonsConfigurator, awakeSqlConfigurator, out);
} else if( action.equals(SqlActionCallable.ACTION_SQL_CALLABLE_EXECUTE_RAW)
){
callableExecute(request, awakeCommonsConfigurator,
awakeFileConfigurator, awakeSqlConfigurator, out);
}
else if(action
.equals(SqlActionCallable.ACTION_SQL_CALLABLE_EXECUTE_QUERY)
){
callableExecuteQuery(request, awakeCommonsConfigurator,
awakeFileConfigurator, awakeSqlConfigurator, out);
}
else if( action.equals(SqlActionTransaction.ACTION_SQL_COMMIT)
|| action.equals(SqlActionTransaction.ACTION_SQL_ROLLBACK)
|| action.equals(SqlActionTransaction.ACTION_SQL_CON_CLOSE)
){
setCommitRollbackCloseExecute(request, awakeCommonsConfigurator, awakeSqlConfigurator,
out, action);
}
else if(action
.equals(SqlActionTransaction.ACTION_SQL_SET_AUTOCOMMIT)
|| action.equals(SqlActionTransaction.ACTION_SQL_SET_READ_ONLY)
|| action.equals(SqlActionTransaction.ACTION_SQL_SET_HOLDABILITY)
|| action.equals(SqlActionTransaction.ACTION_SQL_SET_TRANSACTION_ISOLATION)
){
setAutocommitReadOnlyHoldabilityTransactionInsolationExecute(request, awakeCommonsConfigurator,
out, action);
}
else if(action
.equals(SqlActionTransaction.ACTION_SQL_IS_READ_ONLY)
|| action.equals(SqlActionTransaction.ACTION_SQL_GET_HOLDABILITY)
|| action.equals(SqlActionTransaction.ACTION_SQL_GET_AUTOCOMMIT)
){
getAutocommitReadOnlyHoldabilityExecute(request, awakeCommonsConfigurator,
out, action);
}
else if(action
.equals(SqlActionTransaction.ACTION_SQL_SET_SAVEPOINT)
|| action.equals(SqlActionTransaction.ACTION_SQL_SET_SAVEPOINT_NAME)
|| action.equals(SqlActionTransaction.ACTION_SQL_SET_ROLLBACK_SAVEPOINT)
|| action.equals(SqlActionTransaction.ACTION_SQL_SET_RELEASE_SAVEPOINT)
){
setSavepointExecute(request, awakeCommonsConfigurator,
out, action);
}
else if(action
.equals(SqlAction.ACTION_SQL_IS_VALID)
|| action.equals(SqlAction.ACTION_SQL_SET_CLIENT_INFO_NAME)
|| action.equals(SqlAction.ACTION_SQL_SET_CLIENT_INFO_PROP)
|| action.equals(SqlAction.ACTION_SQL_GET_CLIENT_INFO_NAME)
|| action.equals(SqlAction.ACTION_SQL_GET_CLIENT_INFO)
|| action.equals(SqlAction.ACTION_SQL_CREATE_ARRAY_OF)
){
connectionInfoExecute(request, awakeCommonsConfigurator,
out, action);
}
else {
throw new IllegalArgumentException("Invalid Sql Action: "
+ action);
}
} catch (Exception e) {
out.println(TransferStatus.SEND_FAILED);
out.println(e.getClass().getName());
out.println(ServerUserException.getMessage(e));
out.println(ExceptionUtils.getStackTrace(e));
try {
AwakeServerLogger.log(Level.WARNING, Tag.AWAKE_EXCEPTION_RAISED
+ ServerUserException.getMessage(e));
AwakeServerLogger.log(Level.WARNING, Tag.AWAKE_EXCEPTION_RAISED
+ ExceptionUtils.getStackTrace(e));
} catch (Exception e1) {
e1.printStackTrace();
e1.printStackTrace(System.out);
}
}
}
/**
* Returns to client the Connection.getTransactionIsolation() value
*
* @param out
* the servlet print writer
*/
private void getTransactionIsolation(HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator, AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out)
throws SQLException {
String connectionId = request
.getParameter(ConnectionParms.CONNECTION_ID);
int transactionIsolation = -1;
if (connectionId.equals("0")) {
// Server Stateless Mode
Connection connection = null;
try {
connection = awakeCommonsConfigurator.getConnection();
transactionIsolation = connection.getTransactionIsolation();
} finally {
// Release the connection
ConnectionCloser.freeConnection(connection,
awakeSqlConfigurator);
}
} else {
String username = request.getParameter(Parameter.USERNAME);
ConnectionStore connectionStore = new ConnectionStore(username,
connectionId);
Connection connection = connectionStore.get();
if (connection == null) {
out.println(TransferStatus.SEND_OK);
out.println(SqlReturnCode.SESSION_INVALIDATED);
return;
}
else {
transactionIsolation = connection.getTransactionIsolation();
}
}
debug("transactionIsolation: " + transactionIsolation);
out.println(TransferStatus.SEND_OK);
out.println("" + transactionIsolation);
}
/**
* Calls a commit(), rollback() or close() on a Connection
*
* @param request
* @param awakeCommonsConfigurator
* @param awakeSqlConfigurator
* @param out
* @throws IOException
* @throws SQLException
* @throws IllegalArgumentException
*/
private void setCommitRollbackCloseExecute(HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator, AwakeSqlConfigurator awakeSqlConfigurator,
PrintWriter out,
String action)
throws IOException, SQLException, IllegalArgumentException {
TransactionUtil.setCommitRollbackCloseExecute(request, awakeCommonsConfigurator, awakeSqlConfigurator, out, action);
}
/**
* Calls a setAutocommit, setReadOnly(), setHoldbility, setTransactionIsolation
*
* @param request
* @param awakeCommonsConfigurator
* @param out
* @throws IOException
* @throws SQLException
* @throws IllegalArgumentException
*/
private void setAutocommitReadOnlyHoldabilityTransactionInsolationExecute(HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator,
PrintWriter out,
String action)
throws IOException, SQLException, IllegalArgumentException {
TransactionUtil.setAutocommitReadOnlyHoldabilityTransactionInsolationExecute(request, awakeCommonsConfigurator, out, action);
}
/**
* Calls a getAutocommit(), isReadOnly(), getHoldability(?
* @param request
* @param awakeCommonsConfigurator
* @param out
* @param action
*/
private void getAutocommitReadOnlyHoldabilityExecute(
HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator, PrintWriter out,
String action) throws IOException, SQLException, IllegalArgumentException {
TransactionUtil.getAutocommitReadOnlyHoldabilityExecute(request, awakeCommonsConfigurator, out, action);
}
/**
* Calls a getAutocommit(), isReadOnly(), getHoldability(?
* @param request
* @param awakeCommonsConfigurator
* @param out
* @param action
*/
private void setSavepointExecute(
HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator, PrintWriter out,
String action) throws IOException, SQLException, IllegalArgumentException {
SavepointUtil.setSavepointExecute(request, awakeCommonsConfigurator, out, action);
}
private void connectionInfoExecute(HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator, PrintWriter out,
String action) throws IOException, SQLException, IllegalArgumentException {
ConnectionInfoUtil.connectionInfoExecute(request, awakeCommonsConfigurator, out, action);
}
/**
* Execute a CallableStatement.executeQuery()
*
* @param request
* @param awakeCommonsConfigurator
* @param awakeFileConfigurator
* @param awakeSqlConfigurator
* @param out
* @throws IOException
* @throws SQLException
* @throws IllegalArgumentExceptionn
*/
private void callableExecuteQuery(HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator,
AwakeFileConfigurator awakeFileConfigurator,
AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out)
throws IOException, SQLException, IllegalArgumentException {
// Actions that trigger a (Pre)Statement.executeQuery()/executeUppdate()
ServerSqlExecutorCallable serverSqlExecutorCallable = new ServerSqlExecutorCallable(request,
out, awakeCommonsConfigurator, awakeFileConfigurator,
awakeSqlConfigurator);
serverSqlExecutorCallable.executeQuery();
}
/**
* Executes a raw CallableStatement.execute()
*
* @param request
* @param awakeCommonsConfigurator
* @param awakeFileConfigurator
* @param awakeSqlConfigurator
* @param out
* @throws IOException
* @throws SQLException
* @throws IllegalArgumentExceptionn
*/
private void callableExecute(HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator,
AwakeFileConfigurator awakeFileConfigurator,
AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out)
throws IOException, SQLException, IllegalArgumentException {
// Actions that trigger a (Pre)Statement.executeQuery()/executeUppdate()
ServerSqlExecutorCallable serverSqlExecutorCallable = new ServerSqlExecutorCallable(request,
out, awakeCommonsConfigurator, awakeFileConfigurator,
awakeSqlConfigurator);
serverSqlExecutorCallable.execute();
}
/**
* Executes a Statement or a PreparedStatement
*
* @param request
* @param awakeCommonsConfigurator
* @param awakeFileConfigurator
* @param awakeSqlConfigurator
* @param out
* @throws IOException
* @throws SQLException
* @throws IllegalArgumentExceptionn
*/
private void executeStatement(HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator,
AwakeFileConfigurator awakeFileConfigurator,
AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out)
throws IOException, SQLException, IllegalArgumentException {
// Actions that trigger a (Pre)Statement.executeQuery()/executeUppdate()
ServerSqlExecutorNew serverSqlExecutor = new ServerSqlExecutorNew(request,
out, awakeCommonsConfigurator, awakeFileConfigurator,
awakeSqlConfigurator);
serverSqlExecutor.executeQueryOrUpdate();
}
/**
* Execute a Statement Batch
*
* @param request
* @param awakeCommonsConfigurator
* @param awakeFileConfigurator
* @param awakeSqlConfigurator
* @param out
* @throws IOException
* @throws SQLException
* @throws IllegalArgumentException
* @throws SecurityException
*/
private void executeStatementBatch(HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator,
AwakeFileConfigurator awakeFileConfigurator,
AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out)
throws IOException, SQLException, IllegalArgumentException {
// Actions that trigger a Statement batch
ServerBatchStatementExecutorNew serverBatchStatementExecutor = new ServerBatchStatementExecutorNew(
request, out, awakeCommonsConfigurator, awakeFileConfigurator,
awakeSqlConfigurator);
serverBatchStatementExecutor.execute();
}
/**
* Execute a PreparedStatement Batch
*
* @param request
* @param awakeCommonsConfigurator
* @param awakeFileConfigurator
* @param awakeSqlConfigurator
* @param out
* @throws IOException
* @throws SQLException
* @throws IllegalArgumentException
*/
private void executePrepStatementBatch(HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator,
AwakeFileConfigurator awakeFileConfigurator,
AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out)
throws IOException, SQLException, IllegalArgumentException {
// Actions that trigger a PreparedStatement batch
ServerBatchPrepStatementExecutorNew serverBatchPrepStatementExecutor = new ServerBatchPrepStatementExecutorNew(
request, out, awakeCommonsConfigurator, awakeFileConfigurator,
awakeSqlConfigurator);
serverBatchPrepStatementExecutor.execute();
}
/**
* Execute a DatabaseMetaData call
*
* @param request
* @param awakeCommonsConfigurator
* @param awakeSqlConfigurator
* @param out
* @throws Exception
*/
private void executeGetMetadata(HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator,
AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out)
throws Exception {
// Metadata retrieval
DatabaseMetaDataExecutor databaseMetaDataExecutor = new DatabaseMetaDataExecutor(
request, out, awakeCommonsConfigurator, awakeSqlConfigurator);
databaseMetaDataExecutor.execute();
}
/**
* Execute a raw (Prepared)Statement.execute()
*
* @param request
* @param awakeCommonsConfigurator
* @param awakeFileConfigurator
* @param awakeSqlConfigurator
* @param out
*/
private void executeRaw(HttpServletRequest request,
AwakeCommonsConfigurator awakeCommonsConfigurator,
AwakeFileConfigurator awakeFileConfigurator,
AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out)
throws IOException, SQLException, IllegalArgumentException {
ServerSqlExecutorNew serverSqlExecutor = new ServerSqlExecutorNew(request,
out, awakeCommonsConfigurator, awakeFileConfigurator,
awakeSqlConfigurator);
serverSqlExecutor.executeRaw();
}
/**
* Says if an Action asked by the client is for Awake File
*
* @param action
* the action asked by the client side
* @return true if the action is for Awake File
*/
private boolean isActionForAwakeFile(String action) {
if (action.startsWith(SqlAction.ACTION_SQL)) {
return false;
} else {
return true;
}
}
/**
* Method called by children Servlet for debug purpose Println is done only
* if class name name is in awake-debug.ini
*/
public static void debug(String s) {
if (DEBUG) {
AwakeServerLogger.log(s);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy