View Javadoc
1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one or more
4    * contributor license agreements.  See the NOTICE file distributed with
5    * this work for additional information regarding copyright ownership.
6    * The ASF licenses this file to You under the Apache License, Version 2.0
7    * (the "License"); you may not use this file except in compliance with
8    * the License.  You may obtain a copy of the License at
9    *
10   *     https://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing, software
13   *  distributed under the License is distributed on an "AS IS" BASIS,
14   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *  See the License for the specific language governing permissions and
16   *  limitations under the License.
17   */
18  
19  package org.apache.commons.dbcp2.managed;
20  
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertNotNull;
23  import static org.junit.jupiter.api.Assertions.assertThrows;
24  
25  import java.sql.Connection;
26  import java.sql.SQLException;
27  import java.time.Duration;
28  import java.util.Properties;
29  
30  import javax.transaction.TransactionManager;
31  
32  import org.apache.commons.dbcp2.ConnectionFactory;
33  import org.apache.commons.dbcp2.Constants;
34  import org.apache.commons.dbcp2.DriverConnectionFactory;
35  import org.apache.commons.dbcp2.PoolableConnection;
36  import org.apache.commons.dbcp2.PoolableConnectionFactory;
37  import org.apache.commons.dbcp2.TesterDriver;
38  import org.apache.commons.pool2.impl.GenericObjectPool;
39  import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
40  import org.junit.jupiter.api.AfterEach;
41  import org.junit.jupiter.api.BeforeEach;
42  import org.junit.jupiter.api.Test;
43  
44  /**
45   * Tests for PoolableManagedConnection.
46   */
47  public class TestPoolableManagedConnection {
48  
49      private TransactionManager transactionManager;
50      private TransactionRegistry transactionRegistry;
51      private GenericObjectPool<PoolableConnection> pool;
52      private Connection conn;
53      private PoolableManagedConnection poolableManagedConnection;
54  
55      @BeforeEach
56      public void setUp() throws Exception {
57          // create a GeronimoTransactionManager for testing
58          transactionManager = new TransactionManagerImpl();
59  
60          // create a driver connection factory
61          final Properties properties = new Properties();
62          properties.setProperty(Constants.KEY_USER, "userName");
63          properties.setProperty(Constants.KEY_PASSWORD, "password");
64          final ConnectionFactory connectionFactory = new DriverConnectionFactory(new TesterDriver(), "jdbc:apache:commons:testdriver", properties);
65  
66          // wrap it with a LocalXAConnectionFactory
67          final XAConnectionFactory xaConnectionFactory = new LocalXAConnectionFactory(transactionManager, connectionFactory);
68  
69          // create transaction registry
70          transactionRegistry = xaConnectionFactory.getTransactionRegistry();
71  
72          // create the pool object factory
73          final PoolableConnectionFactory factory = new PoolableConnectionFactory(xaConnectionFactory, null);
74          factory.setValidationQuery("SELECT DUMMY FROM DUAL");
75          factory.setDefaultReadOnly(Boolean.TRUE);
76          factory.setDefaultAutoCommit(Boolean.TRUE);
77  
78          // create the pool
79          pool = new GenericObjectPool<>(factory);
80          factory.setPool(pool);
81          pool.setMaxTotal(10);
82          pool.setMaxWait(Duration.ofMillis(100));
83      }
84  
85      @AfterEach
86      public void tearDown() throws SQLException {
87          if (conn != null && !conn.isClosed()) {
88              conn.close();
89          }
90          if (pool != null && !pool.isClosed()) {
91              pool.close();
92          }
93      }
94  
95      @Test
96      void testManagedConnection() throws Exception {
97          assertEquals(0, pool.getNumActive());
98          // create a connection
99          conn = pool.borrowObject();
100         assertEquals(1, pool.getNumActive());
101         // create the poolable managed connection
102         poolableManagedConnection = new PoolableManagedConnection(transactionRegistry, conn, pool);
103         poolableManagedConnection.close();
104         // closing a poolable managed connection won't close it, but simply return to the pool
105         assertEquals(1, pool.getNumActive());
106         // but closing the underlying connection really closes it
107         conn.close();
108         assertEquals(0, pool.getNumActive());
109     }
110 
111     @Test
112     void testPoolableConnection() throws Exception {
113         // create a connection
114         // pool uses LocalXAConnectionFactory, which register the connection with the TransactionRegistry
115         conn = pool.borrowObject();
116         assertNotNull(transactionRegistry.getXAResource(conn));
117         // create the poolable managed connection
118         poolableManagedConnection = new PoolableManagedConnection(transactionRegistry, conn, pool);
119         poolableManagedConnection.close();
120         assertNotNull(transactionRegistry.getXAResource(conn));
121     }
122 
123     @Test
124     void testReallyClose() throws Exception {
125         assertEquals(0, pool.getNumActive());
126         // create a connection
127         // pool uses LocalXAConnectionFactory, which register the connection with the
128         // TransactionRegistry
129         conn = pool.borrowObject();
130         assertEquals(1, pool.getNumActive());
131         assertNotNull(transactionRegistry.getXAResource(conn));
132         // create the poolable managed connection
133         poolableManagedConnection = new PoolableManagedConnection(transactionRegistry, conn, pool);
134         poolableManagedConnection.close();
135         assertNotNull(transactionRegistry.getXAResource(conn));
136         assertEquals(1, pool.getNumActive());
137         // this must close the managed connection, removing it from the transaction
138         // registry
139         poolableManagedConnection.reallyClose();
140         assertThrows(SQLException.class, () -> transactionRegistry.getXAResource(conn), "Transaction registry was supposed to be empty now");
141         assertEquals(0, pool.getNumActive());
142     }
143 }