View | Details | Raw Unified | Return to bug 54693
Collapse All | Expand All

(-)src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java (+13 lines)
Lines 524-529 Link Here
524
    public void setValidationQuery(String validationQuery);
524
    public void setValidationQuery(String validationQuery);
525
525
526
    /**
526
    /**
527
     * The timeout in seconds before a connection validation queries fail.
528
     * A value less than or equal to zero will disable this feature.  Defaults to -1. 
529
     * @return the timeout value in seconds 
530
     */
531
    public int getValidationQueryTimeout();
532
    
533
    /**
534
     * The timeout in seconds before a connection validation queries fail.
535
     * A value less than or equal to zero will disable this feature.  Defaults to -1. 
536
     */
537
    public void setValidationQueryTimeout(int validationQueryTimeout);
538
    
539
    /**
527
     * Return the name of the optional validator class - may be null.
540
     * Return the name of the optional validator class - may be null.
528
     *
541
     *
529
     * @return the name of the optional validator class - may be null
542
     * @return the name of the optional validator class - may be null
(-)src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java (+6 lines)
Lines 451-456 Link Here
451
        Statement stmt = null;
451
        Statement stmt = null;
452
        try {
452
        try {
453
            stmt = connection.createStatement();
453
            stmt = connection.createStatement();
454
            
455
            int validationQueryTimeout = poolProperties.getValidationQueryTimeout();
456
            if (validationQueryTimeout > 0) {
457
            	stmt.setQueryTimeout(validationQueryTimeout);
458
            }
459
            
454
            stmt.execute(query);
460
            stmt.execute(query);
455
            stmt.close();
461
            stmt.close();
456
            this.lastValidated = now;
462
            this.lastValidated = now;
(-)src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java (+10 lines)
Lines 310-315 Link Here
310
    public String getValidationQuery() {
310
    public String getValidationQuery() {
311
        return getPoolProperties().getValidationQuery();
311
        return getPoolProperties().getValidationQuery();
312
    }
312
    }
313
    
314
    @Override
315
    public int getValidationQueryTimeout() {
316
    	return getPoolProperties().getValidationQueryTimeout();
317
    }
313
318
314
    /**
319
    /**
315
     * {@inheritDoc}
320
     * {@inheritDoc}
Lines 664-669 Link Here
664
        getPoolProperties().setValidationQuery(validationQuery);
669
        getPoolProperties().setValidationQuery(validationQuery);
665
    }
670
    }
666
671
672
    @Override
673
    public void setValidationQueryTimeout(int validationQueryTimeout) {
674
    	getPoolProperties().setValidationQueryTimeout(validationQueryTimeout);
675
    }
676
    
667
    /**
677
    /**
668
     * {@inheritDoc}
678
     * {@inheritDoc}
669
     */
679
     */
(-)src/main/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java (+7 lines)
Lines 80-85 Link Here
80
    protected static final String PROP_TESTWHILEIDLE = "testWhileIdle";
80
    protected static final String PROP_TESTWHILEIDLE = "testWhileIdle";
81
    protected static final String PROP_TESTONCONNECT = "testOnConnect";
81
    protected static final String PROP_TESTONCONNECT = "testOnConnect";
82
    protected static final String PROP_VALIDATIONQUERY = "validationQuery";
82
    protected static final String PROP_VALIDATIONQUERY = "validationQuery";
83
    protected static final String PROP_VALIDATIONQUERY_TIMEOUT = "validationQueryTimeout";
83
    protected static final String PROP_VALIDATOR_CLASS_NAME = "validatorClassName";
84
    protected static final String PROP_VALIDATOR_CLASS_NAME = "validatorClassName";
84
85
85
    protected static final String PROP_NUMTESTSPEREVICTIONRUN = "numTestsPerEvictionRun";
86
    protected static final String PROP_NUMTESTSPEREVICTIONRUN = "numTestsPerEvictionRun";
Lines 149-154 Link Here
149
        PROP_URL,
150
        PROP_URL,
150
        PROP_USERNAME,
151
        PROP_USERNAME,
151
        PROP_VALIDATIONQUERY,
152
        PROP_VALIDATIONQUERY,
153
        PROP_VALIDATIONQUERY_TIMEOUT,
152
        PROP_VALIDATOR_CLASS_NAME,
154
        PROP_VALIDATOR_CLASS_NAME,
153
        PROP_VALIDATIONINTERVAL,
155
        PROP_VALIDATIONINTERVAL,
154
        PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED,
156
        PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED,
Lines 366-371 Link Here
366
        if (value != null) {
368
        if (value != null) {
367
            poolProperties.setValidationQuery(value);
369
            poolProperties.setValidationQuery(value);
368
        }
370
        }
371
        
372
        value = properties.getProperty(PROP_VALIDATIONQUERY_TIMEOUT);
373
        if (value != null) {
374
        	poolProperties.setValidationQueryTimeout(Integer.parseInt(value));
375
        }
369
376
370
        value = properties.getProperty(PROP_VALIDATOR_CLASS_NAME);
377
        value = properties.getProperty(PROP_VALIDATOR_CLASS_NAME);
371
        if (value != null) {
378
        if (value != null) {
(-)src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java (+17 lines)
Lines 57-62 Link Here
57
    private volatile int minIdle = initialSize;
57
    private volatile int minIdle = initialSize;
58
    private volatile int maxWait = 30000;
58
    private volatile int maxWait = 30000;
59
    private volatile String validationQuery;
59
    private volatile String validationQuery;
60
    private volatile int validationQueryTimeout = -1;
60
    private volatile String validatorClassName;
61
    private volatile String validatorClassName;
61
    private volatile Validator validator;
62
    private volatile Validator validator;
62
    private volatile boolean testOnBorrow = false;
63
    private volatile boolean testOnBorrow = false;
Lines 382-387 Link Here
382
    /**
383
    /**
383
     * {@inheritDoc}
384
     * {@inheritDoc}
384
     */
385
     */
386
    @Override
387
    public int getValidationQueryTimeout() {
388
    	return validationQueryTimeout;
389
    }
390
    
391
    /**
392
     * {@inheritDoc}
393
     */
394
    @Override
395
    public void setValidationQueryTimeout(int validationQueryTimeout) {
396
    	this.validationQueryTimeout = validationQueryTimeout;
397
    }
398
    
399
    /**
400
     * {@inheritDoc}
401
     */
385
402
386
    @Override
403
    @Override
387
    public String getValidatorClassName() {
404
    public String getValidatorClassName() {
(-)src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java (+18 lines)
Lines 452-457 Link Here
452
    public void setValidatorClassName(String className) {
452
    public void setValidatorClassName(String className) {
453
        this.poolProperties.setValidatorClassName(className);
453
        this.poolProperties.setValidatorClassName(className);
454
    }
454
    }
455
    
456
    /**
457
     * {@inheritDoc}
458
     */
459
    
460
    @Override
461
    public void setValidationQueryTimeout(int validationQueryTimeout) {
462
    	this.poolProperties.setValidationQueryTimeout(validationQueryTimeout);
463
    }
455
464
456
    /**
465
    /**
457
     * {@inheritDoc}
466
     * {@inheritDoc}
Lines 928-933 Link Here
928
    /**
937
    /**
929
     * {@inheritDoc}
938
     * {@inheritDoc}
930
     */
939
     */
940
    
941
    @Override
942
    public int getValidationQueryTimeout() {
943
    	return getPoolProperties().getValidationQueryTimeout();
944
    }
945
    
946
    /**
947
     * {@inheritDoc}
948
     */
931
949
932
    @Override
950
    @Override
933
    public String getValidatorClassName() {
951
    public String getValidatorClassName() {
(-)src/main/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml (+5 lines)
Lines 125-130 Link Here
125
           description="The query to run during validation"
125
           description="The query to run during validation"
126
                  type="java.lang.String"
126
                  type="java.lang.String"
127
             writeable="false"/>
127
             writeable="false"/>
128
             
129
    <attribute    name="validationQueryTimeout"
130
           description="The timeout in seconds before a connection validation queries fail"
131
                  type="java.lang.Integer"
132
             writeable="false" />
128
133
129
    <attribute    name="testOnBorrow"
134
    <attribute    name="testOnBorrow"
130
           description="True if validation happens when a connection is requested"
135
           description="True if validation happens when a connection is requested"
(-)doc/jdbc-pool.xml (+9 lines)
Lines 277-282 Link Here
277
         Example values are <code>SELECT 1</code>(mysql), <code>select 1 from dual</code>(oracle), <code>SELECT 1</code>(MS Sql Server)
277
         Example values are <code>SELECT 1</code>(mysql), <code>select 1 from dual</code>(oracle), <code>SELECT 1</code>(MS Sql Server)
278
      </p>
278
      </p>
279
    </attribute>
279
    </attribute>
280
    
281
    <attribute name="validationQueryTimeout" required="false">
282
      <p>(int) The timeout in seconds before a connection validation queries fail.  This works by calling 
283
         <code>java.sql.Statement.setQueryTimeout(seconds)</code> on the statement that executes the <code>validationQuery</code>.
284
         The pool itself doesn't timeout the query, it is still up to the JDBC driver to enforce query timeouts. 
285
         A value less than or equal to zero will disable this feature. 
286
         The default value is <code>-1</code>.
287
      </p>
288
    </attribute>
280
289
281
    <attribute name="validatorClassName" required="false">
290
    <attribute name="validatorClassName" required="false">
282
      <p>(String) The name of a class which implements the
291
      <p>(String) The name of a class which implements the
(-)src/test/java/org/apache/tomcat/jdbc/test/TestValidationQueryTimeout.java (+133 lines)
Line 0 Link Here
1
package org.apache.tomcat.jdbc.test;
2
3
import java.sql.Connection;
4
import java.sql.DriverManager;
5
import java.sql.DriverPropertyInfo;
6
import java.sql.SQLException;
7
import java.sql.SQLFeatureNotSupportedException;
8
import java.sql.Statement;
9
import java.util.Properties;
10
import java.util.logging.Logger;
11
12
import junit.framework.Assert;
13
14
import org.junit.After;
15
import org.junit.Before;
16
import org.junit.Test;
17
18
public class TestValidationQueryTimeout extends DefaultTestCase {
19
	
20
	private static final int TIMEOUT = 10;
21
	private static boolean isTimeoutSet;
22
	
23
	@Before
24
	public void setUp() throws SQLException {
25
		DriverManager.registerDriver(new MockDriver());
26
		isTimeoutSet = false;
27
	}
28
	
29
	@After
30
	public void tearDown() throws SQLException {
31
		DriverManager.deregisterDriver(new MockDriver());
32
	}
33
	
34
	@Test
35
	public void testValidationQueryTimeoutEnabled() throws Exception {
36
		// use our mock driver
37
		this.datasource.setDriverClassName(MockDriver.class.getName());
38
        this.datasource.setUrl(MockDriver.url);
39
        
40
        // Required to trigger validation query's execution 
41
        this.datasource.setTestOnBorrow(true);
42
        this.datasource.setValidationInterval(-1);
43
        this.datasource.setValidationQuery("SELECT 1");
44
        this.datasource.setValidationQueryTimeout(TIMEOUT);
45
        
46
    	// because testOnBorrow is true, this triggers the validation query
47
    	this.datasource.getConnection();
48
    	Assert.assertTrue(isTimeoutSet);
49
	}
50
	
51
	@Test
52
	public void testValidationQueryTimeoutDisabled() throws Exception {
53
		// use our mock driver
54
		this.datasource.setDriverClassName(MockDriver.class.getName());
55
        this.datasource.setUrl(MockDriver.url);
56
        
57
        // Required to trigger validation query's execution 
58
        this.datasource.setTestOnBorrow(true);
59
        this.datasource.setValidationInterval(-1);
60
        this.datasource.setValidationQuery("SELECT 1");
61
        this.datasource.setValidationQueryTimeout(-1);
62
        
63
    	// because testOnBorrow is true, this triggers the validation query
64
    	this.datasource.getConnection();
65
    	Assert.assertFalse(isTimeoutSet);
66
	}
67
	
68
	/**
69
	 * Mock Driver, Connection and Statement implementations use to verify setQueryTimeout was called.
70
	 */
71
    public static class MockDriver implements java.sql.Driver {
72
    	public static final String url = "jdbc:tomcat:mock";
73
74
        public MockDriver() {
75
        }
76
77
        @Override
78
        public boolean acceptsURL(String url) throws SQLException {
79
            return url!=null && url.equals(MockDriver.url);
80
        }
81
82
        @Override
83
        public Connection connect(String url, Properties info) throws SQLException {
84
            return new MockConnection(info);
85
        }
86
87
        @Override
88
        public int getMajorVersion() {
89
            return 0;
90
        }
91
92
        @Override
93
        public int getMinorVersion() {
94
            return 0;
95
        }
96
97
        @Override
98
        public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
99
            return null;
100
        }
101
102
        @Override
103
        public boolean jdbcCompliant() {
104
            return false;
105
        }
106
107
        @Override
108
        public Logger getParentLogger() throws SQLFeatureNotSupportedException {
109
            return null;
110
        }
111
    }
112
    
113
    public static class MockConnection extends org.apache.tomcat.jdbc.test.driver.Connection {
114
        public MockConnection(Properties info) {
115
			super(info);
116
		}
117
118
		@Override
119
        public Statement createStatement() throws SQLException {
120
            return new MockStatement();
121
        }
122
    }
123
    
124
    public static class MockStatement extends org.apache.tomcat.jdbc.test.driver.Statement {
125
    	@Override
126
    	public void setQueryTimeout(int seconds) throws SQLException {
127
    		super.setQueryTimeout(seconds);
128
    		Assert.assertEquals(TIMEOUT, seconds);
129
    		isTimeoutSet = true;
130
    	}
131
    }
132
    
133
}

Return to bug 54693