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

org.kawanfw.sql.servlet.ServerSqlDispatch Maven / Gradle / Ivy

/*
 * This file is part of AceQL. 
 * AceQL: Remote JDBC access over HTTP.                                     
 * Copyright (C) 2015,  KawanSoft SAS
 * (http://www.kawansoft.com). All rights reserved.                                
 *                                                                               
 * AceQL is free software; you can redistribute it and/or                 
 * modify it under the terms of the GNU Lesser General Public                    
 * License as published by the Free Software Foundation; either                  
 * version 2.1 of the License, or (at your option) any later version.            
 *                                                                               
 * AceQL 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 Lesser General Public              
 * License along with this library; if not, write to the Free Software           
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
 * 02110-1301  USA
 *
 * Any modifications to this file must keep this entire header
 * intact.
 */
package org.kawanfw.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.kawanfw.commons.api.server.CommonsConfigurator;
import org.kawanfw.commons.server.util.ServerLogger;
import org.kawanfw.commons.util.FrameworkDebug;
import org.kawanfw.commons.util.Tag;
import org.kawanfw.commons.util.TransferStatus;
import org.kawanfw.file.api.server.FileConfigurator;
import org.kawanfw.file.servlet.KawanNotifier;
import org.kawanfw.file.servlet.ServerFileDispatch;
import org.kawanfw.file.servlet.ServerFileUploadAction;
import org.kawanfw.file.servlet.ServerUserThrowable;
import org.kawanfw.file.util.parms.Action;
import org.kawanfw.file.util.parms.Parameter;
import org.kawanfw.file.util.parms.ReturnCode;
import org.kawanfw.sql.api.server.SqlConfigurator;
import org.kawanfw.sql.servlet.connection.ConnectionInfoUtil;
import org.kawanfw.sql.servlet.connection.ConnectionStore;
import org.kawanfw.sql.servlet.connection.ConnectionStoreCleaner;
import org.kawanfw.sql.servlet.connection.SavepointUtil;
import org.kawanfw.sql.servlet.connection.TransactionUtil;
import org.kawanfw.sql.servlet.executor.ServerBatchPrepStatementExecutorNew;
import org.kawanfw.sql.servlet.executor.ServerBatchStatementExecutorNew;
import org.kawanfw.sql.servlet.executor.ServerSqlExecutorCallable;
import org.kawanfw.sql.servlet.executor.ServerSqlExecutorNew;
import org.kawanfw.sql.util.ConnectionParms;
import org.kawanfw.sql.util.SqlAction;
import org.kawanfw.sql.util.SqlActionCallable;
import org.kawanfw.sql.util.SqlActionTransaction;
import org.kawanfw.sql.util.SqlReturnCode;
import org.kawanfw.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 RemoteConnection * connection. * */ public class ServerSqlDispatch { private static boolean DEBUG = FrameworkDebug .isSet(ServerSqlDispatch.class); // Errors in SqlHttpServer private static final String ERR_ACTION_NOT_SET = "ERR_ACTION_NOT_SET"; /** * Constructor */ public ServerSqlDispatch() { // 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 commonsConfigurator * the client commons http configurator specific class * @param fileConfigurator * the client file http configurator specific class * @param sqlConfigurator * the client sql http configurator specific class * @param connection * the Sql Jdbc Connection * @throws IOException * if any IOException occurs */ public void executeRequest(HttpServletRequest request, HttpServletResponse response, File servletContextTempDir, CommonsConfigurator commonsConfigurator, FileConfigurator fileConfigurator, SqlConfigurator sqlConfigurator) 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, commonsConfigurator, fileConfigurator); 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, commonsConfigurator, sqlConfigurator, action); return; } debug("ACTION : " + action); // Redirect to Awake FILE if it's a File request (Blobs/Clobs) if (isActionForAwakeFile(action)) { ServerFileDispatch serverFileDispatch = new ServerFileDispatch(); serverFileDispatch.executeRequest(request, response, servletContextTempDir, commonsConfigurator, fileConfigurator); 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 (! ServerFileDispatch.isTokenValid(username, token, commonsConfigurator"); String token = request.getParameter(Parameter.TOKEN); if (!ServerFileDispatch.isTokenValid(username, token, commonsConfigurator)) { 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 = commonsConfigurator.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( sqlConfigurator); 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/.kawansoft/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, "AceQL_" + VersionValues.VERSION); kawanNotifier.start(); } if (action.equals(SqlAction.ACTION_SQL_STATEMENT)) { executeStatement(request, commonsConfigurator, fileConfigurator, sqlConfigurator, out); } else if (action.equals(SqlAction.ACTION_SQL_STATEMENT_BATCH)) { executeStatementBatch(request, commonsConfigurator, fileConfigurator, sqlConfigurator, out); } else if (action.equals(SqlAction.ACTION_SQL_PREP_STATEMENT_BATCH)) { executePrepStatementBatch(request, commonsConfigurator, fileConfigurator, sqlConfigurator, out); } else if (action.equals(SqlAction.ACTION_SQL_GET_METADATA)) { executeGetMetadata(request, commonsConfigurator, sqlConfigurator, out); } else if (action.equals(SqlAction.ACTION_SQL_EXECUTE_RAW)) { executeRaw(request, commonsConfigurator, fileConfigurator, sqlConfigurator, out); } else if (action .equals(SqlActionTransaction.ACTION_SQL_GET_TRANSACTION_ISOLATION)) { getTransactionIsolation(request, commonsConfigurator, sqlConfigurator, out); } else if (action .equals(SqlActionCallable.ACTION_SQL_CALLABLE_EXECUTE_RAW)) { callableExecute(request, commonsConfigurator, fileConfigurator, sqlConfigurator, out); } else if (action .equals(SqlActionCallable.ACTION_SQL_CALLABLE_EXECUTE_QUERY)) { callableExecuteQuery(request, commonsConfigurator, fileConfigurator, sqlConfigurator, out); } else if (action.equals(SqlActionTransaction.ACTION_SQL_COMMIT) || action.equals(SqlActionTransaction.ACTION_SQL_ROLLBACK) || action.equals(SqlActionTransaction.ACTION_SQL_CON_CLOSE) ) { setCommitRollbackCloseExecute(request, commonsConfigurator, sqlConfigurator, 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, commonsConfigurator, 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, commonsConfigurator, 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, commonsConfigurator, 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, commonsConfigurator, 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(ServerUserThrowable.getMessage(e)); out.println(ExceptionUtils.getStackTrace(e)); try { ServerLogger.getLogger().log( Level.WARNING, Tag.PRODUCT_EXCEPTION_RAISED + " " + ServerUserThrowable.getMessage(e)); ServerLogger.getLogger().log( Level.WARNING, Tag.PRODUCT_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, CommonsConfigurator commonsConfigurator, SqlConfigurator sqlConfigurator, 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 = commonsConfigurator.getConnection(); transactionIsolation = connection.getTransactionIsolation(); } finally { // Release the connection ConnectionCloser.freeConnection(connection, sqlConfigurator); } } 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 commonsConfigurator * @param sqlConfigurator * @param out * @throws IOException * @throws SQLException * @throws IllegalArgumentException */ private void setCommitRollbackCloseExecute(HttpServletRequest request, CommonsConfigurator commonsConfigurator, SqlConfigurator sqlConfigurator, PrintWriter out, String action) throws IOException, SQLException, IllegalArgumentException { TransactionUtil.setCommitRollbackCloseExecute(request, commonsConfigurator, sqlConfigurator, out, action); } /** * Calls a setAutocommit, setReadOnly(), setHoldbility, * setTransactionIsolation * * @param request * @param commonsConfigurator * @param out * @throws IOException * @throws SQLException * @throws IllegalArgumentException */ private void setAutocommitReadOnlyHoldabilityTransactionInsolationExecute( HttpServletRequest request, CommonsConfigurator commonsConfigurator, PrintWriter out, String action) throws IOException, SQLException, IllegalArgumentException { TransactionUtil .setAutocommitReadOnlyHoldabilityTransactionInsolationExecute( request, commonsConfigurator, out, action); } /** * Calls a getAutocommit(), isReadOnly(), getHoldability(? * * @param request * @param commonsConfigurator * @param out * @param action */ private void getAutocommitReadOnlyHoldabilityExecute( HttpServletRequest request, CommonsConfigurator commonsConfigurator, PrintWriter out, String action) throws IOException, SQLException, IllegalArgumentException { TransactionUtil.getAutocommitReadOnlyHoldabilityExecute(request, commonsConfigurator, out, action); } /** * Calls a getAutocommit(), isReadOnly(), getHoldability(? * * @param request * @param commonsConfigurator * @param out * @param action */ private void setSavepointExecute(HttpServletRequest request, CommonsConfigurator commonsConfigurator, PrintWriter out, String action) throws IOException, SQLException, IllegalArgumentException { SavepointUtil.setSavepointExecute(request, commonsConfigurator, out, action); } private void connectionInfoExecute(HttpServletRequest request, CommonsConfigurator commonsConfigurator, PrintWriter out, String action) throws IOException, SQLException, IllegalArgumentException { ConnectionInfoUtil.connectionInfoExecute(request, commonsConfigurator, out, action); } /** * Execute a CallableStatement.executeQuery() * * @param request * @param commonsConfigurator * @param fileConfigurator * @param sqlConfigurator * @param out * @throws IOException * @throws SQLException * @throws IllegalArgumentExceptionn */ private void callableExecuteQuery(HttpServletRequest request, CommonsConfigurator commonsConfigurator, FileConfigurator fileConfigurator, SqlConfigurator sqlConfigurator, PrintWriter out) throws IOException, SQLException, IllegalArgumentException { // Actions that trigger a (Pre)Statement.executeQuery()/executeUppdate() ServerSqlExecutorCallable serverSqlExecutorCallable = new ServerSqlExecutorCallable( request, out, commonsConfigurator, fileConfigurator, sqlConfigurator); serverSqlExecutorCallable.executeQuery(); } /** * Executes a raw CallableStatement.execute() * * @param request * @param commonsConfigurator * @param fileConfigurator * @param sqlConfigurator * @param out * @throws IOException * @throws SQLException * @throws IllegalArgumentExceptionn */ private void callableExecute(HttpServletRequest request, CommonsConfigurator commonsConfigurator, FileConfigurator fileConfigurator, SqlConfigurator sqlConfigurator, PrintWriter out) throws IOException, SQLException, IllegalArgumentException { // Actions that trigger a (Pre)Statement.executeQuery()/executeUppdate() ServerSqlExecutorCallable serverSqlExecutorCallable = new ServerSqlExecutorCallable( request, out, commonsConfigurator, fileConfigurator, sqlConfigurator); serverSqlExecutorCallable.execute(); } /** * Executes a Statement or a PreparedStatement * * @param request * @param commonsConfigurator * @param fileConfigurator * @param sqlConfigurator * @param out * @throws IOException * @throws SQLException * @throws IllegalArgumentExceptionn */ private void executeStatement(HttpServletRequest request, CommonsConfigurator commonsConfigurator, FileConfigurator fileConfigurator, SqlConfigurator sqlConfigurator, PrintWriter out) throws IOException, SQLException, IllegalArgumentException { // Actions that trigger a (Pre)Statement.executeQuery()/executeUppdate() ServerSqlExecutorNew serverSqlExecutor = new ServerSqlExecutorNew( request, out, commonsConfigurator, fileConfigurator, sqlConfigurator); serverSqlExecutor.executeQueryOrUpdate(); } /** * Execute a Statement Batch * * @param request * @param commonsConfigurator * @param fileConfigurator * @param sqlConfigurator * @param out * @throws IOException * @throws SQLException * @throws IllegalArgumentException * @throws SecurityException */ private void executeStatementBatch(HttpServletRequest request, CommonsConfigurator commonsConfigurator, FileConfigurator fileConfigurator, SqlConfigurator sqlConfigurator, PrintWriter out) throws IOException, SQLException, IllegalArgumentException { // Actions that trigger a Statement batch ServerBatchStatementExecutorNew serverBatchStatementExecutor = new ServerBatchStatementExecutorNew( request, out, commonsConfigurator, fileConfigurator, sqlConfigurator); serverBatchStatementExecutor.execute(); } /** * Execute a PreparedStatement Batch * * @param request * @param commonsConfigurator * @param fileConfigurator * @param sqlConfigurator * @param out * @throws IOException * @throws SQLException * @throws IllegalArgumentException */ private void executePrepStatementBatch(HttpServletRequest request, CommonsConfigurator commonsConfigurator, FileConfigurator fileConfigurator, SqlConfigurator sqlConfigurator, PrintWriter out) throws IOException, SQLException, IllegalArgumentException { // Actions that trigger a PreparedStatement batch ServerBatchPrepStatementExecutorNew serverBatchPrepStatementExecutor = new ServerBatchPrepStatementExecutorNew( request, out, commonsConfigurator, fileConfigurator, sqlConfigurator); serverBatchPrepStatementExecutor.execute(); } /** * Execute a DatabaseMetaData call * * @param request * @param commonsConfigurator * @param sqlConfigurator * @param out * @throws Exception */ private void executeGetMetadata(HttpServletRequest request, CommonsConfigurator commonsConfigurator, SqlConfigurator sqlConfigurator, PrintWriter out) throws Exception { // Metadata retrieval DatabaseMetaDataExecutor databaseMetaDataExecutor = new DatabaseMetaDataExecutor( request, out, commonsConfigurator, sqlConfigurator); databaseMetaDataExecutor.execute(); } /** * Execute a raw (Prepared)Statement.execute() * * @param request * @param commonsConfigurator * @param fileConfigurator * @param sqlConfigurator * @param out */ private void executeRaw(HttpServletRequest request, CommonsConfigurator commonsConfigurator, FileConfigurator fileConfigurator, SqlConfigurator sqlConfigurator, PrintWriter out) throws IOException, SQLException, IllegalArgumentException { debug("Before ServerSqlExecutorNew.executeRaw()"); ServerSqlExecutorNew serverSqlExecutor = new ServerSqlExecutorNew( request, out, commonsConfigurator, fileConfigurator, sqlConfigurator); serverSqlExecutor.executeRaw(); debug("After ServerSqlExecutorNew.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 kawansoft-debug.ini */ public static void debug(String s) { if (DEBUG) { ServerLogger.getLogger().log(Level.WARNING, s); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy