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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org