All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src-main.org.awakefw.sql.servlet.ServerAwakeSqlDispatch Maven / Gradle / Ivy

Go to download

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