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

org.kawanfw.sql.api.server.DefaultPoolsInfo Maven / Gradle / Ivy

Go to download

AceQL HTTP is a framework of REST like http APIs that allow to access to remote SQL databases over http from any device that supports http. AceQL HTTP is provided with four client SDK: - The AceQL C# Client SDK allows to wrap the HTTP APIs using Microsoft SQL Server like calls in their code, just like they would for a local database. - The AceQL Java Client SDK allows to wrap the HTTP APIs using JDBC calls in their code, just like they would for a local database. - The AceQL Python Client SDK allows SQL calls to be encoded with standard unmodified DB-API 2.0 syntax

There is a newer version: 12.2
Show newest version
/*
 * Copyright (c)2022 KawanSoft S.A.S. All rights reserved.
 * 
 * Use of this software is governed by the Business Source License included
 * in the LICENSE.TXT file in the project's root directory.
 *
 * Change Date: 2026-11-01
 *
 * On the date above, in accordance with the Business Source License, use
 * of this software will be governed by version 2.0 of the Apache License.
 */
package org.kawanfw.sql.api.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.sql.SQLException;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.json.stream.JsonGenerator;
import javax.json.stream.JsonGeneratorFactory;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.apache.tomcat.jdbc.pool.DataSourceProxy;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.kawanfw.sql.servlet.ServerSqlManager;
import org.kawanfw.sql.servlet.sql.json_return.ExceptionReturner;
import org.kawanfw.sql.servlet.sql.json_return.JsonErrorReturn;
import org.kawanfw.sql.servlet.sql.json_return.JsonUtil;
import org.kawanfw.sql.util.FrameworkDebug;

/**
 *
 * Allows to display current JDBC pool status and info for each database.
* Includes 3 methods to modify the JDBC pools.
*
* Values are accessed using methods in * {@code org.apache.tomcat.jdbc.pool.DataSource} class.
* The {@code DataSource} instances are retrieved in this servlet using * {@link DataSourceStore#getDataSources()} static method.
*
* See Tomcat JDBC Pool DataSourceProxy for the meaning of the displayed values.
*
* * It is also possible to interact with the pool and call three * {@code DataSource} set methods: *
    *
  • {@code DataSource.setMinIdle(int)}.
  • *
  • {@code DataSource.setMaxIdle(int)}.
  • *
  • {@code DataSource.setMaxActive(int)}.
  • *
*
* To call the servlet from a browser, cURL or a program:
* * {@code http(s)://host:port/default_pools_info?password=}
*
* Where:
* password_value = value of "password" property stored in * user.home/.kawansoft/default_pools_info.properties
*
* * To modify the pool for a database:
* {@code http(s)://host:port/default_pools_info?password=&database=database_name&set_method=int_value} *
*
* Where: *
    *
  • database_name=the database as defined in aceql-server.properties. If not * specified, set_method will be applied to all databases.
  • *
  • set_method = setMinIdle or setMaxIdle or setMaxActive.
  • *
  • int_value= the number to pass to the set_method.
  • *
* *
* Note that You can create your own servlet if you want to develop you own * interaction with the JDBC pools.
* Just add you servlet name, class and url-pattern in the Servlets Section of * your aceql-server.properties file.
*
* * @author Nicolas de Pomereu * @since 1.0 * @see DataSourceProxy */ public class DefaultPoolsInfo extends HttpServlet { private static final long serialVersionUID = 6129302507495768396L; private static boolean DEBUG = FrameworkDebug.isSet(DefaultPoolsInfo.class); /* * (non-Javadoc) * * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http. * HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { executeRequest(request, response); } /** * Execute the client sent SQL request. Exception are trapped, cleanly returned * to client side and logged on DatabaseConfigurator.getLogger() Logger. * * @param request the http request * @param response the http response * @throws IOException if any IOException occurs */ private void executeRequest(HttpServletRequest request, HttpServletResponse response) throws IOException { OutputStream out = null; try { out = response.getOutputStream(); executeRequestInTryCatch(request, response, out); } catch (Exception e) { ExceptionReturner.logAndReturnException(request, response, out, e); } } /** * Execute the client request * * @param request the http request * @param response the http response * @param out * @throws IOException if any IOException occurs * @throws SQLException * @throws FileUploadException */ private void executeRequestInTryCatch(HttpServletRequest request, HttpServletResponse response, OutputStream out) throws IOException, SQLException, FileUploadException { debug("Starting..."); request.setCharacterEncoding("UTF-8"); // Prepare the response response.setContentType("text/plain; charset=UTF-8"); String password = request.getParameter("password"); if (password == null || password.isEmpty()) { JsonErrorReturn errorReturn = new JsonErrorReturn(response, HttpServletResponse.SC_FORBIDDEN, JsonErrorReturn.ERROR_ACEQL_UNAUTHORIZED, JsonErrorReturn.INVALID_USERNAME_OR_PASSWORD); ServerSqlManager.writeLine(out, errorReturn.build()); return; } String storedPassword = null; try { File file = new File(SystemUtils.USER_HOME + File.separator + ".kawansoft" + File.separator + "default_pools_info.properties"); Properties properties = new Properties(); try (InputStream in = new FileInputStream(file);) { properties.load(in); } storedPassword = properties.getProperty("password"); // Support previous version if (storedPassword == null || storedPassword.isEmpty()) { storedPassword = FileUtils.readFileToString(new File(SystemUtils.USER_HOME + File.separator + ".kawansoft" + File.separator + "default_pools_info_password.txt"), "UTF-8"); } debug("stored_password: " + storedPassword + ":"); if (storedPassword == null || !storedPassword.trim().equals(password)) { throw new IllegalArgumentException(JsonErrorReturn.INVALID_USERNAME_OR_PASSWORD); } } catch (Exception e) { JsonErrorReturn errorReturn = new JsonErrorReturn(response, HttpServletResponse.SC_FORBIDDEN, JsonErrorReturn.ERROR_ACEQL_UNAUTHORIZED, JsonErrorReturn.INVALID_USERNAME_OR_PASSWORD); ServerSqlManager.writeLine(out, errorReturn.build()); return; } String setDatabase = request.getParameter("database"); Map dataSources = DataSourceStore.getDataSources(); if (dataSources == null || dataSources.isEmpty()) { JsonErrorReturn errorReturn = new JsonErrorReturn(response, HttpServletResponse.SC_BAD_REQUEST, JsonErrorReturn.ERROR_ACEQL_ERROR, JsonErrorReturn.NO_DATASOURCES_DEFINED); ServerSqlManager.writeLine(out, errorReturn.build()); return; } writeOutpuMain(request, out, setDatabase, dataSources); } /** * @param request * @param setDatabase * @param dataSources * @throws NumberFormatException * @throws IOException */ private void writeOutpuMain(HttpServletRequest request, OutputStream out, String setDatabase, Map dataSources) throws NumberFormatException, IOException { StringWriter writer = new StringWriter(); JsonGeneratorFactory jf = JsonUtil.getJsonGeneratorFactory(true); JsonGenerator gen = jf.createGenerator(writer); Set databases = dataSources.keySet(); gen.writeStartObject(); gen.write("status", "OK"); gen.write("see", "https://tomcat.apache.org/tomcat-9.0-doc/api/org/apache/tomcat/jdbc/pool/DataSourceProxy.html"); gen.writeStartArray("databases"); for (String database : databases) { writeOutputElementInLoop(request, setDatabase, dataSources, gen, database); } gen.writeEnd(); gen.writeEnd(); gen.close(); String outString = writer.toString(); ServerSqlManager.writeLine(out, outString); } /** * @param request * @param setDatabase * @param dataSources * @param gen * @param database * @throws NumberFormatException */ private void writeOutputElementInLoop(HttpServletRequest request, String setDatabase, Map dataSources, JsonGenerator gen, String database) throws NumberFormatException { DataSource datasource = dataSources.get(database); DataSourceProxy dataSourceProxy = (org.apache.tomcat.jdbc.pool.DataSource) datasource; if (setDatabase == null || setDatabase.equals(database)) { String doSet = request.getParameter("setMinIdle"); if (doSet != null && !doSet.isEmpty() && StringUtils.isNumeric(doSet) && StringUtils.isNumeric(doSet)) { dataSourceProxy.setMinIdle(Integer.parseInt(doSet)); } doSet = request.getParameter("setMaxIdle"); if (doSet != null && !doSet.isEmpty() && StringUtils.isNumeric(doSet) && StringUtils.isNumeric(doSet)) { dataSourceProxy.setMaxIdle(Integer.parseInt(doSet)); } doSet = request.getParameter("setMaxActive"); if (doSet != null && !doSet.isEmpty() && StringUtils.isNumeric(doSet) && StringUtils.isNumeric(doSet)) { dataSourceProxy.setMaxActive(Integer.parseInt(doSet)); } } gen.writeStartObject().write("database", database).writeEnd(); gen.writeStartObject().write("getBorrowedCount()", dataSourceProxy.getBorrowedCount()).writeEnd(); gen.writeStartObject().write("getMaxActive()", dataSourceProxy.getMaxActive()).writeEnd(); gen.writeStartObject().write("getMaxIdle()", dataSourceProxy.getMaxIdle()).writeEnd(); gen.writeStartObject().write("getMinIdle()", dataSourceProxy.getMinIdle()).writeEnd(); gen.writeStartObject().write("getNumActive()", dataSourceProxy.getNumActive()).writeEnd(); gen.writeStartObject().write("getNumIdle()", dataSourceProxy.getNumIdle()).writeEnd(); gen.writeStartObject().write("getReconnectedCount()", dataSourceProxy.getReconnectedCount()).writeEnd(); gen.writeStartObject().write("getReleasedCount()", dataSourceProxy.getReleasedCount()).writeEnd(); gen.writeStartObject().write("getReleasedIdleCount()", dataSourceProxy.getReleasedIdleCount()).writeEnd(); gen.writeStartObject().write("getRemoveAbandonedCount()", dataSourceProxy.getRemoveAbandonedCount()).writeEnd(); gen.writeStartObject().write("getReturnedCount()", dataSourceProxy.getReturnedCount()).writeEnd(); gen.writeStartObject().write("getSize()", dataSourceProxy.getSize()).writeEnd(); gen.writeStartObject().write("getWaitCount()", dataSourceProxy.getWaitCount()).writeEnd(); } /** * Method called by children Servlet for debug purpose Println is done only if * class name name is in kawansoft-debug.ini */ private static void debug(String s) { if (DEBUG) { System.out.println(new Date() + " " + s); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy