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   *     http://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.assertNull;
24  import static org.junit.jupiter.api.Assertions.fail;
25  
26  import java.sql.Connection;
27  import java.sql.SQLException;
28  import java.time.Duration;
29  import java.util.Properties;
30  
31  import javax.transaction.TransactionManager;
32  
33  import org.apache.commons.dbcp2.ConnectionFactory;
34  import org.apache.commons.dbcp2.Constants;
35  import org.apache.commons.dbcp2.DriverConnectionFactory;
36  import org.apache.commons.dbcp2.PoolableConnection;
37  import org.apache.commons.dbcp2.PoolableConnectionFactory;
38  import org.apache.commons.dbcp2.TesterDriver;
39  import org.apache.commons.pool2.impl.GenericObjectPool;
40  import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
41  import org.junit.jupiter.api.AfterEach;
42  import org.junit.jupiter.api.BeforeEach;
43  import org.junit.jupiter.api.Test;
44  
45  /**
46   * Tests for PoolableManagedConnection.
47   */
48  public class TestPoolableManagedConnection {
49  
50      private TransactionManager transactionManager;
51      private TransactionRegistry transactionRegistry;
52      private GenericObjectPool<PoolableConnection> pool;
53      private Connection conn;
54      private PoolableManagedConnection poolableManagedConnection;
55  
56      @BeforeEach
57      public void setUp() throws Exception {
58          // create a GeronimoTransactionManager for testing
59          transactionManager = new TransactionManagerImpl();
60  
61          // create a driver connection factory
62          final Properties properties = new Properties();
63          properties.setProperty(Constants.KEY_USER, "userName");
64          properties.setProperty(Constants.KEY_PASSWORD, "password");
65          final ConnectionFactory connectionFactory = new DriverConnectionFactory(new TesterDriver(), "jdbc:apache:commons:testdriver", properties);
66  
67          // wrap it with a LocalXAConnectionFactory
68          final XAConnectionFactory xaConnectionFactory = new LocalXAConnectionFactory(transactionManager, connectionFactory);
69  
70          // create transaction registry
71          transactionRegistry = xaConnectionFactory.getTransactionRegistry();
72  
73          // create the pool object factory
74          final PoolableConnectionFactory factory = new PoolableConnectionFactory(xaConnectionFactory, null);
75          factory.setValidationQuery("SELECT DUMMY FROM DUAL");
76          factory.setDefaultReadOnly(Boolean.TRUE);
77          factory.setDefaultAutoCommit(Boolean.TRUE);
78  
79          // create the pool
80          pool = new GenericObjectPool<>(factory);
81          factory.setPool(pool);
82          pool.setMaxTotal(10);
83          pool.setMaxWait(Duration.ofMillis(100));
84      }
85  
86      @AfterEach
87      public void tearDown() throws SQLException {
88          if (conn != null && !conn.isClosed()) {
89              conn.close();
90          }
91          if (pool != null && !pool.isClosed()) {
92              pool.close();
93          }
94      }
95  
96      @Test
97      public void testManagedConnection() throws Exception {
98          assertEquals(0, pool.getNumActive());
99          // create a connection
100         conn = pool.borrowObject();
101         assertEquals(1, pool.getNumActive());
102         // create the poolable managed connection
103         poolableManagedConnection = new PoolableManagedConnection(transactionRegistry, conn, pool);
104         poolableManagedConnection.close();
105         // closing a poolable managed connection won't close it, but simply return to the pool
106         assertEquals(1, pool.getNumActive());
107         // but closing the underlying connection really closes it
108         conn.close();
109         assertEquals(0, pool.getNumActive());
110     }
111 
112     @Test
113     public void testPoolableConnection() throws Exception {
114         // create a connection
115         // pool uses LocalXAConnectionFactory, which register the connection with the TransactionRegistry
116         conn = pool.borrowObject();
117         assertNotNull(transactionRegistry.getXAResource(conn));
118         // create the poolable managed connection
119         poolableManagedConnection = new PoolableManagedConnection(transactionRegistry, conn, pool);
120         poolableManagedConnection.close();
121         assertNotNull(transactionRegistry.getXAResource(conn));
122     }
123 
124     @Test
125     public void testReallyClose() throws Exception {
126         assertEquals(0, pool.getNumActive());
127         // create a connection
128         // pool uses LocalXAConnectionFactory, which register the connection with the 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 registry
138         poolableManagedConnection.reallyClose();
139         try {
140             assertNull(transactionRegistry.getXAResource(conn));
141             fail("Transaction registry was supposed to be empty now");
142         } catch (final SQLException ignore) {
143             // ignore
144         }
145         assertEquals(0, pool.getNumActive());
146     }
147 }