Skip to content

Commit e12071b

Browse files
jeanouiijbonofre
authored andcommitted
See if we can better fix the ConnectionPool
1 parent 4c034eb commit e12071b

File tree

2 files changed

+88
-142
lines changed

2 files changed

+88
-142
lines changed

activemq-jms-pool/src/main/java/org/apache/activemq/jms/pool/ConnectionPool.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ void setParentExceptionListener(ExceptionListener parentExceptionListener) {
378378

379379
@Override
380380
public void onException(JMSException exception) {
381+
setHasExpired(true);
381382
if (isReconnectOnException()) {
382383
close();
383384
}

activemq-jms-pool/src/test/java/org/apache/activemq/jms/pool/PooledConnectionSecurityExceptionTest.java

Lines changed: 87 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,11 @@
4444

4545
import java.util.ArrayList;
4646
import java.util.List;
47+
import java.util.concurrent.CountDownLatch;
4748

4849
import static org.junit.Assert.assertNotSame;
50+
import static org.junit.Assert.assertNull;
51+
import static org.junit.Assert.assertThrows;
4952
import static org.junit.Assert.assertTrue;
5053
import static org.junit.Assert.fail;
5154

@@ -65,47 +68,42 @@ public class PooledConnectionSecurityExceptionTest {
6568

6669
@Test
6770
public void testFailedConnectThenSucceeds() throws JMSException {
68-
Connection connection = pooledConnFact.createConnection("invalid", "credentials");
71+
try (final Connection connection1 = pooledConnFact.createConnection("invalid", "credentials")) {
72+
assertThrows(JMSSecurityException.class, connection1::start);
6973

70-
try {
71-
connection.start();
72-
fail("Should fail to connect");
73-
} catch (JMSSecurityException ex) {
74-
LOG.info("Caught expected security error");
75-
}
76-
77-
connection = pooledConnFact.createConnection("system", "manager");
78-
connection.start();
74+
try (final Connection connection2 = pooledConnFact.createConnection("system", "manager")) {
75+
connection2.start();
7976

80-
LOG.info("Successfully create new connection.");
77+
} catch (final JMSSecurityException ex) {
78+
fail("Should have succeeded to connect on 2nd attempt");
79+
}
8180

82-
connection.close();
81+
}
8382
}
8483

8584
@Test
86-
public void testFailedConnectThenSucceedsWithListener() throws JMSException {
87-
Connection connection = pooledConnFact.createConnection("invalid", "credentials");
88-
connection.setExceptionListener(new ExceptionListener() {
85+
public void testFailedConnectThenSucceedsWithListener() throws JMSException, InterruptedException {
86+
final CountDownLatch onExceptionCalled = new CountDownLatch(1);
87+
try (final Connection connection1 = pooledConnFact.createConnection("invalid", "credentials")) {
88+
connection1.setExceptionListener(new ExceptionListener() {
89+
90+
@Override
91+
public void onException(JMSException exception) {
92+
LOG.warn("Connection get error: {}", exception.getMessage());
93+
onExceptionCalled.countDown();
94+
}
95+
});
96+
assertThrows(JMSSecurityException.class, connection1::start);
97+
98+
try (final Connection connection2 = pooledConnFact.createConnection("system", "manager")) {
99+
connection2.start();
89100

90-
@Override
91-
public void onException(JMSException exception) {
92-
LOG.warn("Connection get error: {}", exception.getMessage());
101+
} catch (final JMSSecurityException ex) {
102+
fail("Should have succeeded to connect on 2nd attempt");
93103
}
94-
});
95104

96-
try {
97-
connection.start();
98-
fail("Should fail to connect");
99-
} catch (JMSSecurityException ex) {
100-
LOG.info("Caught expected security error");
101105
}
102-
103-
connection = pooledConnFact.createConnection("system", "manager");
104-
connection.start();
105-
106-
LOG.info("Successfully create new connection.");
107-
108-
connection.close();
106+
assertTrue("onException called", onExceptionCalled.await(10, java.util.concurrent.TimeUnit.SECONDS));
109107
}
110108

111109
@Test
@@ -119,67 +117,41 @@ public void testFailureGetsNewConnectionOnRetryLooped() throws Exception {
119117
public void testFailureGetsNewConnectionOnRetry() throws Exception {
120118
pooledConnFact.setMaxConnections(1);
121119

122-
final PooledConnection connection1 = (PooledConnection) pooledConnFact.createConnection("invalid", "credentials");
123-
124-
try {
125-
connection1.start();
126-
fail("Should fail to connect");
127-
} catch (JMSSecurityException ex) {
128-
LOG.info("Caught expected security error");
129-
}
130-
131-
// The pool should process the async error
132-
assertTrue("Should get new connection", Wait.waitFor(new Wait.Condition() {
133-
134-
@Override
135-
public boolean isSatisified() throws Exception {
136-
try (final PooledConnection newConnection = (PooledConnection) pooledConnFact.createConnection("invalid", "credentials")) {
137-
return connection1.pool != ((PooledConnection)newConnection).pool;
138-
} catch (Exception e) {
139-
return false;
120+
try (final Connection connection1 = pooledConnFact.createConnection("invalid", "credentials")) {
121+
assertThrows(JMSSecurityException.class, connection1::start);
122+
123+
// The pool should process the async error
124+
// we should eventually get a different connection instance from the pool regardless of the underlying connection
125+
assertTrue("Should get new connection", Wait.waitFor(new Wait.Condition() {
126+
@Override
127+
public boolean isSatisified() throws Exception {
128+
try (final PooledConnection newConnection = (PooledConnection) pooledConnFact.createConnection("invalid", "credentials")) {
129+
return connection1 != newConnection;
130+
} catch (Exception e) {
131+
return false;
132+
}
140133
}
134+
}));
135+
136+
try (final PooledConnection connection2 = (PooledConnection) pooledConnFact.createConnection("invalid", "credentials")) {
137+
assertNotSame(connection1, connection2);
141138
}
142-
}));
143-
144-
final PooledConnection connection2 = (PooledConnection) pooledConnFact.createConnection("invalid", "credentials");
145-
assertNotSame(connection1.pool, connection2.pool);
146-
147-
try {
148-
connection2.start();
149-
fail("Should fail to connect");
150-
} catch (JMSSecurityException ex) {
151-
LOG.info("Caught expected security error");
152-
} finally {
153-
connection2.close();
154-
}
155139

156-
connection1.close();
140+
assertNull(((PooledConnection)connection1).getConnection()); // underlying connection should have been closed
141+
}
157142
}
158143

159-
@Test
160144
public void testFailureGetsNewConnectionOnRetryBigPool() throws JMSException {
161145
pooledConnFact.setMaxConnections(10);
162146

163-
Connection connection1 = pooledConnFact.createConnection("invalid", "credentials");
164-
try {
165-
connection1.start();
166-
fail("Should fail to connect");
167-
} catch (JMSSecurityException ex) {
168-
LOG.info("Caught expected security error");
169-
}
170-
171-
Connection connection2 = pooledConnFact.createConnection("invalid", "credentials");
172-
try {
173-
connection2.start();
174-
fail("Should fail to connect");
175-
} catch (JMSSecurityException ex) {
176-
LOG.info("Caught expected security error");
147+
try (final Connection connection1 = pooledConnFact.createConnection("invalid", "credentials")) {
148+
assertThrows(JMSSecurityException.class, connection1::start);
149+
try (final Connection connection2 = pooledConnFact.createConnection("invalid", "credentials")) {
150+
assertThrows(JMSSecurityException.class, connection2::start);
151+
assertNotSame(connection1, connection2);
152+
}
177153
}
178154

179-
assertNotSame(connection1, connection2);
180-
181-
connection1.close();
182-
connection2.close();
183155
}
184156

185157
@Test
@@ -192,21 +164,14 @@ public void testFailoverWithInvalidCredentialsCanConnect() throws JMSException {
192164
pooledConnFact.setConnectionFactory(cf);
193165
pooledConnFact.setMaxConnections(1);
194166

195-
Connection connection = pooledConnFact.createConnection("invalid", "credentials");
167+
try (final Connection connection = pooledConnFact.createConnection("invalid", "credentials")) {
168+
assertThrows(JMSSecurityException.class, connection::start);
196169

197-
try {
198-
connection.start();
199-
fail("Should fail to connect");
200-
} catch (JMSSecurityException ex) {
201-
LOG.info("Caught expected security error");
170+
try (final Connection connection2 = pooledConnFact.createConnection("system", "manager")) {
171+
connection2.start();
172+
LOG.info("Successfully create new connection.");
173+
}
202174
}
203-
204-
connection = pooledConnFact.createConnection("system", "manager");
205-
connection.start();
206-
207-
LOG.info("Successfully create new connection.");
208-
209-
connection.close();
210175
}
211176

212177
@Test
@@ -219,66 +184,46 @@ public void testFailoverWithInvalidCredentials() throws Exception {
219184
pooledConnFact.setConnectionFactory(cf);
220185
pooledConnFact.setMaxConnections(1);
221186

222-
final PooledConnection connection1 = (PooledConnection) pooledConnFact.createConnection("invalid", "credentials");
187+
try (final PooledConnection connection1 = (PooledConnection) pooledConnFact.createConnection("invalid", "credentials")) {
188+
assertThrows(JMSSecurityException.class, connection1::start);
223189

224-
try {
225-
connection1.start();
226-
fail("Should fail to connect");
227-
} catch (JMSSecurityException ex) {
228-
LOG.info("Caught expected security error");
229-
// Intentionally don't close here to see that async pool reconnect takes place.
230-
}
190+
// The pool should process the async error
191+
assertTrue("Should get new connection", Wait.waitFor(new Wait.Condition() {
231192

232-
// The pool should process the async error
233-
assertTrue("Should get new connection", Wait.waitFor(new Wait.Condition() {
234-
235-
@Override
236-
public boolean isSatisified() throws Exception {
237-
try (final PooledConnection newConnection = (PooledConnection) pooledConnFact.createConnection("invalid", "credentials")) {
238-
return connection1.pool != ((PooledConnection)newConnection).pool;
239-
} catch (Exception e) {
240-
return false;
193+
@Override
194+
public boolean isSatisified() throws Exception {
195+
try (final PooledConnection newConnection = (PooledConnection) pooledConnFact.createConnection("invalid", "credentials")) {
196+
return connection1 != newConnection;
197+
} catch (Exception e) {
198+
return false;
199+
}
241200
}
201+
}));
202+
203+
try (final PooledConnection connection2 = (PooledConnection) pooledConnFact.createConnection("invalid", "credentials")) {
204+
assertNotSame(connection1.pool, connection2.pool);
205+
assertThrows(JMSSecurityException.class, connection2::start);
242206
}
243-
}));
244-
245-
final PooledConnection connection2 = (PooledConnection) pooledConnFact.createConnection("invalid", "credentials");
246-
assertNotSame(connection1.pool, connection2.pool);
247-
248-
try {
249-
connection2.start();
250-
fail("Should fail to connect");
251-
} catch (JMSSecurityException ex) {
252-
LOG.info("Caught expected security error");
253-
connection2.close();
254-
} finally {
255-
connection2.close();
256207
}
257-
258-
connection1.close();
259208
}
260209

261210
@Test
262211
public void testFailedCreateConsumerConnectionStillWorks() throws JMSException {
263-
Connection connection = pooledConnFact.createConnection("guest", "password");
264-
connection.start();
212+
try (final Connection connection = pooledConnFact.createConnection("guest", "password")) {
213+
connection.start();
265214

266-
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
267-
Queue queue = session.createQueue(name.getMethodName());
215+
try (final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)) {
216+
final Queue queue = session.createQueue(name.getMethodName());
268217

269-
try {
270-
session.createConsumer(queue);
271-
fail("Should fail to create consumer");
272-
} catch (JMSSecurityException ex) {
273-
LOG.info("Caught expected security error");
274-
}
218+
assertThrows(JMSSecurityException.class, () -> session.createConsumer(queue));
275219

276-
queue = session.createQueue("GUESTS." + name.getMethodName());
220+
final Queue guestsQueue = session.createQueue("GUESTS." + name.getMethodName());
277221

278-
MessageProducer producer = session.createProducer(queue);
279-
producer.close();
280-
281-
connection.close();
222+
try (final MessageProducer producer = session.createProducer(guestsQueue)) {
223+
// We can still produce to the GUESTS queue.
224+
}
225+
}
226+
}
282227
}
283228

284229
public String getName() {

0 commit comments

Comments
 (0)