You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2008/12/19 18:55:46 UTC
svn commit: r728081 - in /tomcat/trunk/modules/jdbc-pool: ./ doc/
java/org/apache/tomcat/jdbc/pool/
java/org/apache/tomcat/jdbc/pool/interceptor/
test/org/apache/tomcat/jdbc/pool/
test/org/apache/tomcat/jdbc/pool/interceptor/ test/org/apache/tomcat/jdb...
Author: fhanik
Date: Fri Dec 19 09:55:46 2008
New Revision: 728081
URL: http://svn.apache.org/viewvc?rev=728081&view=rev
Log:
Documented interceptors a bit better, implemented setters for interceptor properties
Added:
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/pool/
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/pool/interceptor/
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/pool/interceptor/TestInterceptor.java
tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestInterceptorShortName.java
Modified:
tomcat/trunk/modules/jdbc-pool/build.xml
tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java
tomcat/trunk/modules/jdbc-pool/sign.sh
Modified: tomcat/trunk/modules/jdbc-pool/build.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/build.xml?rev=728081&r1=728080&r2=728081&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/build.xml (original)
+++ tomcat/trunk/modules/jdbc-pool/build.xml Fri Dec 19 09:55:46 2008
@@ -23,7 +23,7 @@
<!-- See "build.properties.sample" in the top level directory for all -->
<property name="version.major" value="1" />
<property name="version.minor" value="0" />
- <property name="version.build" value="7" />
+ <property name="version.build" value="8" />
<property name="version.patch" value="-beta" />
<property name="version" value="${version.major}.${version.minor}.${version.build}${version.patch}" />
<!-- property values you must customize for successful building!!! -->
Modified: tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml?rev=728081&r1=728080&r2=728081&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml (original)
+++ tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml Fri Dec 19 09:55:46 2008
@@ -350,6 +350,75 @@
of the results from a method invokation as well. You could build query performance analyzer that provides JMX notifications when a
query is running longer than the expected time.</p>
</subsection>
+ <subsection name="JDBC interceptors">
+ <p>Configuring JDBC interceptors is done using the <b>jdbcInterceptors</b> property.
+ The property contains a list of semi colon separated class names. If the classname if not fully qualified it will be prefixed with the
+ <code>org.apache.tomcat.jdbc.pool.interceptor.</code> prefix.<br/>
+ Example:<br/>
+ <code>
+ jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
+ <br/>
+ is the same as
+ <br/>
+ jdbcInterceptors="ConnectionState;StatementFinalizer"
+ </code><br/>
+ Interceptors can have properties as well. These would be configured within the paranthesis of the class names.
+ Example:<br/>
+ <code>
+ jdbcInterceptors="ConnectionState;StatementFinalizer(useWeakReferences=true,useEquals=true)"
+ </code><br/>
+ </p>
+ </subsection>
+ <subsection name="org.apache.tomcat.jdbc.pool.JdbcInterceptor">
+ <p>Abstract base class for all interceptors, can not be instantiated.</p>
+ <attributes>
+ <attribute name="useEquals" required="false">
+ <p>(String as boolean) A custom query to be run when a connection is first created.
+ The default value is <code>false</code>.
+ </p>
+ </attribute>
+ </attributes>
+ </subsection>
+ <subsection name="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState">
+ <p>Caches the connection for the following attributes <code>autoCommit</code>, <code>readOnly</code>,
+ <code>transactionIsolation</code> and <code>catalog</code>.
+ It is a performance enhancement to avoid roundtrip to the database when getters are called or setters are called with an already set value.
+ </p>
+ <attributes>
+ </attributes>
+ </subsection>
+ <subsection name="org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer">
+ <p>Keeps track of all statements created using <code>createStatement</code>, <code>prepareStatement</code> or <code>prepareCall</code>
+ and closes these statements when the connection is returned to the pool.
+ </p>
+ <attributes>
+ </attributes>
+ </subsection>
+ <subsection name="org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport">
+ <p>Keeps track of query performance and issues log entries when queries exceed a time threshold of fail.
+ The log level used is <code>WARN</code>
+ </p>
+ <attributes>
+ <attribute name="threshold" required="false">
+ <p>(int as String) The number of milliseconds a query has to exceed before issuing a log alert.
+ The default value is <code>1000</code> milliseconds.
+ </p>
+ </attribute>
+ <attribute name="maxQueries" required="false">
+ <p>(int as String) The maximum number of queries to keep track of in order to preserve memory space
+ The default value is <code>1000</code>.
+ </p>
+ </attribute>
+ </attributes>
+ </subsection>
+ <subsection name="org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx">
+ <p>Extends the <code>SlowQueryReport</code> and in addition to log entries it issues JMX notification
+ for monitoring tools to react to. Inherits all the attributes from its parent class.
+ This class uses Tomcat's JMX engine so it wont work outside of the Tomcat container.
+ </p>
+ <attributes>
+ </attributes>
+ </subsection>
</section>
<section name="Code Example">
@@ -519,15 +588,41 @@
</source>
The <code>compare(String,Method)</code> will use the <code>useEquals</code> flag on an interceptor and do either reference comparison or
a string value comparison when the <code>useEquals=true</code> flag is set.
- </p>
+ </p>
+ <p>Pool start/stop<br/>
+ When the connection pool is started or closed, you can be notifed. You will only be notified once per interceptor class
+ even though it is an instance method. and you will be notified using an interceptor currently not attached to a pool.
+ <source>
+ public void poolStarted(ConnectionPool pool) {
+ }
+
+ public void poolClosed(ConnectionPool pool) {
+ }
+ </source>
+ When overriding these methods, don't forget to call super if you are extending a class other than <code>JdbcInterceptor</code>
+ </p>
<p>Configuring interceptors<br/>
Interceptors are configured using the <code>jdbcInterceptors</code> property or the <code>setJdbcInterceptors</code> method.
An interceptor can have properties, and would be configured like this
<source>
-
String jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState(useEquals=true,fast=yes)"
</source>
</p>
+ <p>Interceptor properties<br/>
+ Since interceptors can have properties, you need to be able to read the values of these properties within your
+ interceptor. Taking an example like the one above, you can override the <code>setProperties</code> method.
+ <source>
+ @Override
+ public void setProperties(Map<String, InterceptorProperty> properties) {
+ super.setProperties(properties);
+ final String myprop = "myprop";
+ InterceptorProperty p1 = properties.get(myprop);
+ if (p1!=null) {
+ setMyprop(Long.parseLong(p1.getValue()));
+ }
+ }
+ </source>
+ </p>
</subsection>
Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java?rev=728081&r1=728080&r2=728081&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java Fri Dec 19 09:55:46 2008
@@ -355,7 +355,7 @@
try {
proxies[i].getInterceptorClass().newInstance().poolStarted(this);
}catch (Exception x) {
- log.warn("Unable to inform interceptor of pool start.",x);
+ log.error("Unable to inform interceptor of pool start.",x);
if (jmxPool!=null) jmxPool.notify(jmxPool.NOTIFY_INIT, getStackTrace(x));
close(true);
SQLException ex = new SQLException();
@@ -745,7 +745,7 @@
return getStackTrace(x);
}
- protected static String getStackTrace(Exception x) {
+ public static String getStackTrace(Throwable x) {
if (x == null) {
return null;
} else {
Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java?rev=728081&r1=728080&r2=728081&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java Fri Dec 19 09:55:46 2008
@@ -20,6 +20,7 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorProperty;
@@ -32,7 +33,7 @@
public static final String TOSTRING_VAL = "toString";
public static final String ISCLOSED_VAL = "isClosed";
- protected List<InterceptorProperty> properties = null;
+ protected Map<String,InterceptorProperty> properties = null;
private JdbcInterceptor next = null;
private boolean useEquals = false;
@@ -75,12 +76,17 @@
*/
public abstract void reset(ConnectionPool parent, PooledConnection con);
- public List<InterceptorProperty> getProperties() {
+ public Map<String,InterceptorProperty> getProperties() {
return properties;
}
- public void setProperties(List<InterceptorProperty> properties) {
+ public void setProperties(Map<String,InterceptorProperty> properties) {
this.properties = properties;
+ final String useEquals = "useEquals";
+ InterceptorProperty p = properties.get(useEquals);
+ if (p!=null) {
+ setUseEquals(Boolean.parseBoolean(p.getValue()));
+ }
}
public boolean isUseEquals() {
Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java?rev=728081&r1=728080&r2=728081&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java Fri Dec 19 09:55:46 2008
@@ -19,7 +19,9 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
@@ -28,6 +30,8 @@
*
*/
public class PoolProperties {
+ public static final String PKG_PREFIX = "org.apache.tomcat.jdbc.pool.interceptor.";
+
protected static AtomicInteger poolCounter = new AtomicInteger(0);
protected Properties dbProperties = new Properties();
protected String url = null;
@@ -430,7 +434,7 @@
public static class InterceptorDefinition {
protected String className;
- protected List<InterceptorProperty> properties = new ArrayList<InterceptorProperty>();
+ protected Map<String,InterceptorProperty> properties = new HashMap<String,InterceptorProperty>();
protected volatile Class clazz = null;
public InterceptorDefinition(String className) {
this.className = className;
@@ -445,16 +449,20 @@
}
public void addProperty(InterceptorProperty p) {
- properties.add(p);
+ properties.put(p.getName(), p);
}
- public List<InterceptorProperty> getProperties() {
+ public Map<String,InterceptorProperty> getProperties() {
return properties;
}
public Class<? extends JdbcInterceptor> getInterceptorClass() throws ClassNotFoundException {
if (clazz==null) {
- clazz = Class.forName(getClassName(), true, this.getClass().getClassLoader());
+ if (getClassName().indexOf(".")<0) {
+ clazz = Class.forName(PoolProperties.PKG_PREFIX+getClassName(), true, this.getClass().getClassLoader());
+ } else {
+ clazz = Class.forName(getClassName(), true, this.getClass().getClassLoader());
+ }
}
return (Class<? extends JdbcInterceptor>)clazz;
}
@@ -464,6 +472,7 @@
String name;
String value;
public InterceptorProperty(String name, String value) {
+ assert(name!=null);
this.name = name;
this.value = value;
}
@@ -473,6 +482,17 @@
public String getValue() {
return value;
}
+ public int hashCode() {
+ return name.hashCode();
+ }
+ public boolean equals(Object o) {
+ if (o==this) return true;
+ if (o instanceof InterceptorProperty) {
+ InterceptorProperty other = (InterceptorProperty)o;
+ return other.name.equals(this.name);
+ }
+ return false;
+ }
}
public boolean isUseEquals() {
Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java?rev=728081&r1=728080&r2=728081&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java Fri Dec 19 09:55:46 2008
@@ -25,6 +25,7 @@
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.management.openmbean.CompositeDataSupport;
@@ -38,6 +39,7 @@
import org.apache.tomcat.jdbc.pool.ConnectionPool;
import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
import org.apache.tomcat.jdbc.pool.PooledConnection;
+import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorProperty;
/**
* Slow query report interceptor. Tracks timing of query executions.
@@ -65,7 +67,7 @@
/**
* The threshold in milliseconds. If the query is faster than this, we don't measure it
*/
- protected long threshold = 100; //don't report queries less than this
+ protected long threshold = 1000; //don't report queries less than this
/**
* Maximum number of queries we will be storing
*/
@@ -104,6 +106,10 @@
public void setThreshold(long threshold) {
this.threshold = threshold;
}
+
+ public void setMaxQueries(int maxQueries) {
+ this.maxQueries = maxQueries;
+ }
/**
* invoked when the connection receives the close request
@@ -214,6 +220,8 @@
if (sql!=null) {
QueryStats qs = getQueryStats(sql);
if (qs!=null) qs.failure(System.currentTimeMillis()-start,start);
+ if (log.isWarnEnabled()) log.warn("Failed query["+sql+"] Stacktrace:"+ConnectionPool.getStackTrace(t));
+
}
return sql;
}
@@ -229,6 +237,7 @@
if (sql!=null) {
QueryStats qs = getQueryStats(sql);
if (qs!=null) qs.add(delta,start);
+ if (log.isWarnEnabled()) log.warn("Slow query["+sql+"] Time to execute:"+delta+" ms.");
}
return sql;
}
@@ -273,6 +282,26 @@
queries = SlowQueryReport.perPoolStats.get(parent.getName());
}
+
+
+
+
+ @Override
+ public void setProperties(Map<String, InterceptorProperty> properties) {
+ super.setProperties(properties);
+ final String threshold = "threshold";
+ final String maxqueries= "maxQueries";
+ InterceptorProperty p1 = properties.get(threshold);
+ InterceptorProperty p2 = properties.get(maxqueries);
+ if (p1!=null) {
+ setThreshold(Long.parseLong(p1.getValue()));
+ }
+ if (p2!=null) {
+ setMaxQueries(Integer.parseInt(p2.getValue()));
+ }
+ }
+
+
Modified: tomcat/trunk/modules/jdbc-pool/sign.sh
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/sign.sh?rev=728081&r1=728080&r2=728081&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/sign.sh (original)
+++ tomcat/trunk/modules/jdbc-pool/sign.sh Fri Dec 19 09:55:46 2008
@@ -1,4 +1,4 @@
-VERSION=v1.0.7-beta
+VERSION=v1.0.8-beta
for i in $(find output/release/$VERSION -name "*.zip" -o -name "*.tar.gz"); do
echo Signing $i
echo $1|gpg --passphrase-fd 0 -a -b $i
Added: tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/pool/interceptor/TestInterceptor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/pool/interceptor/TestInterceptor.java?rev=728081&view=auto
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/pool/interceptor/TestInterceptor.java (added)
+++ tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/pool/interceptor/TestInterceptor.java Fri Dec 19 09:55:46 2008
@@ -0,0 +1,43 @@
+package org.apache.tomcat.jdbc.pool.interceptor;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.tomcat.jdbc.pool.ConnectionPool;
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+import org.apache.tomcat.jdbc.pool.PoolProperties.InterceptorProperty;
+
+public class TestInterceptor extends JdbcInterceptor {
+ public static boolean poolstarted = false;
+ public static boolean poolclosed = false;
+ public static AtomicInteger instancecount = new AtomicInteger(0);
+
+ @Override
+ public void poolClosed(ConnectionPool pool) {
+ // TODO Auto-generated method stub
+ super.poolClosed(pool);
+ poolclosed = true;
+ }
+
+ @Override
+ public void poolStarted(ConnectionPool pool) {
+ super.poolStarted(pool);
+ poolstarted = true;
+ }
+
+ @Override
+ public void reset(ConnectionPool parent, PooledConnection con) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setProperties(Map<String, InterceptorProperty> properties) {
+ instancecount.incrementAndGet();
+ super.setProperties(properties);
+ }
+
+
+
+}
Added: tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestInterceptorShortName.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestInterceptorShortName.java?rev=728081&view=auto
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestInterceptorShortName.java (added)
+++ tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestInterceptorShortName.java Fri Dec 19 09:55:46 2008
@@ -0,0 +1,31 @@
+package org.apache.tomcat.jdbc.test;
+
+import java.sql.Connection;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.tomcat.jdbc.pool.ConnectionPool;
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+import org.apache.tomcat.jdbc.pool.interceptor.TestInterceptor;
+
+public class TestInterceptorShortName extends DefaultTestCase {
+
+ public TestInterceptorShortName(String name) {
+ super(name);
+ }
+
+ public void testShortInterceptor() throws Exception {
+ this.datasource = this.createDefaultDataSource();
+ this.datasource.setJdbcInterceptors("TestInterceptor");
+ this.datasource.setMaxActive(1);
+ Connection con = this.datasource.getConnection();
+ assertTrue("Pool should have been started.",TestInterceptor.poolstarted);
+ assertEquals("Only one interceptor should have been called setProperties",1,TestInterceptor.instancecount.get());
+ con.close();
+ this.datasource.close();
+ assertTrue("Pool should have been closed.",TestInterceptor.poolclosed);
+ }
+
+
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org