Change prefetch on jms tests to 0 and add @DirtiesContext to tests

With the upgrade to ActiveMQ 5.9.0 as part of Spring IO, ActiveMQ's
prefetch behavior changed.  With each call to
JmsTemplate#receiveAndConvert, the template creates a new consumer.  In
these tests, the first call created a consumer which prefetched all the
test messages on the queue, leaving them unavailable for the second
consumer the JmsTemplate created.  By setting prefetch to 0, the
messages are now available for the subsequent
JmsTemplate#receiveAndConvert calls.  This addresses BATCH-2248.

Conflicts:
	spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/repeat/jms/SynchronousTests.java
This commit is contained in:
Michael Minella
2014-07-07 09:29:59 -05:00
committed by Michael Minella
parent d175f2d05a
commit 1b9b9621dd
5 changed files with 74 additions and 59 deletions

View File

@@ -15,11 +15,26 @@
*/
package org.springframework.batch.container.jms;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.retry.RecoveryCallback;
@@ -28,28 +43,17 @@ import org.springframework.retry.RetryContext;
import org.springframework.retry.policy.NeverRetryPolicy;
import org.springframework.retry.support.DefaultRetryState;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* @author Dave Syer
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/org/springframework/batch/jms/jms-context.xml")
@DirtiesContext
public class BatchMessageListenerContainerIntegrationTests {
@Autowired

View File

@@ -16,7 +16,9 @@
package org.springframework.batch.repeat.jms;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
@@ -27,22 +29,25 @@ import javax.jms.Session;
import javax.jms.TextMessage;
import javax.sql.DataSource;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.container.jms.BatchMessageListenerContainer;
import org.springframework.batch.jms.ExternalRetryInBatchTests;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.SessionAwareMessageListener;
import org.springframework.util.ClassUtils;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.junit.runner.RunWith;
import org.junit.Before;
import org.junit.After;
import org.junit.Test;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.ClassUtils;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/org/springframework/batch/jms/jms-context.xml")
@DirtiesContext
public class AsynchronousTests {
protected String[] getConfigLocations() {
@@ -117,7 +122,7 @@ public class AsynchronousTests {
});
container.initializeProxy();
container.start();
// Need to sleep for at least a second here...
@@ -139,7 +144,7 @@ public class AsynchronousTests {
public void testRollback() throws Exception {
assertInitialState();
// Prevent us from being overwhelmed after rollback
container.setRecoveryInterval(500);
@@ -155,7 +160,7 @@ public class AsynchronousTests {
}
}
});
container.initializeProxy();
container.start();

View File

@@ -23,6 +23,8 @@ import java.util.ArrayList;
import java.util.List;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Session;
import javax.sql.DataSource;
import org.junit.Test;
@@ -37,7 +39,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jms.connection.SessionProxy;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.SessionCallback;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.BeforeTransaction;
@@ -48,6 +53,7 @@ import org.springframework.transaction.support.TransactionTemplate;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/org/springframework/batch/jms/jms-context.xml")
@DirtiesContext
public class SynchronousTests implements ApplicationContextAware {
@Autowired
@@ -103,18 +109,18 @@ public class SynchronousTests implements ApplicationContextAware {
@Override
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
String text = (String) jmsTemplate.receiveAndConvert("queue");
System.out.println("text = " + text);
list.add(text);
jdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text);
return RepeatStatus.continueIf(text != null);
}
});
System.err.println(jdbcTemplate.queryForList("select * from T_BARS"));
int count = jdbcTemplate.queryForObject("select count(*) from T_BARS", Integer.class);
assertEquals(2, count);
assertTrue(list.contains("foo"));
assertTrue(list.contains("bar"));
String text = (String) jmsTemplate.receiveAndConvert("queue");
assertEquals(null, text);
@@ -123,6 +129,8 @@ public class SynchronousTests implements ApplicationContextAware {
@Test
public void testFullRollback() throws Exception {
onSetUpBeforeTransaction();
assertInitialState();
new TransactionTemplate(transactionManager).execute(new TransactionCallback<Void>() {
@@ -180,7 +188,6 @@ public class SynchronousTests implements ApplicationContextAware {
@Override
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
String text = (String) txJmsTemplate.receiveAndConvert("queue");
System.out.println("Receiving in transaction: " + text);
list.add(text);
jdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text);
return RepeatStatus.continueIf(text != null);
@@ -189,36 +196,32 @@ public class SynchronousTests implements ApplicationContextAware {
// Simulate a message system failure before the main transaction
// commits...
// txJmsTemplate.execute(new SessionCallback<Void>() {
// @Override
// public Void doInJms(Session session) throws JMSException {
// try {
// System.out.println("Session = " + session + " pass test? " + (session instanceof SessionProxy));
// assertTrue("Not a SessionProxy - wrong spring version?", session instanceof SessionProxy);
// ((SessionProxy) session).getTargetSession().rollback();
// }
// catch (JMSException e) {
// throw e;
// }
// catch (Exception e) {
// // swallow it
// e.printStackTrace();
// }
// return null;
// }
// });
txJmsTemplate.execute(new SessionCallback<Void>() {
@Override
public Void doInJms(Session session) throws JMSException {
try {
assertTrue("Not a SessionProxy - wrong spring version?", session instanceof SessionProxy);
((SessionProxy) session).getTargetSession().rollback();
}
catch (JMSException e) {
throw e;
}
catch (Exception e) {
// swallow it
e.printStackTrace();
}
return null;
}
});
return null;
}
});
System.err.println(jdbcTemplate.queryForList("select * from T_BARS"));
String text = "";
List<String> msgs = new ArrayList<String>();
while (text != null) {
text = (String) txJmsTemplate.receiveAndConvert("queue");
System.out.println("text = " + text);
msgs.add(text);
}
@@ -232,4 +235,4 @@ public class SynchronousTests implements ApplicationContextAware {
}
}
}

View File

@@ -1,3 +1,5 @@
DROP TABLE T_BARS;
create table T_BARS (
id integer not null primary key,
name varchar(80),

View File

@@ -17,10 +17,13 @@
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" depends-on="brokerService">
<property name="brokerURL">
<value>vm://localhost</value>
</property>
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
<property name="sessionCacheSize" value="5"/>
</bean>
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" depends-on="brokerService">
<property name="brokerURL" value="vm://localhost?jms.prefetchPolicy.all=0"/>
</bean>
<bean id="txAwareConnectionFactory"
@@ -70,11 +73,9 @@
<bean id="transactionalBatchTemplate"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager" />
<property name="proxyInterfaces">
<value>org.springframework.batch.repeat.RepeatOperations</value>
</property>
<property name="proxyInterfaces" value="org.springframework.batch.repeat.RepeatOperations"/>
<property name="proxyTargetClass" value="false" />
<property name="transactionAttributes" value="*=PROPAGATION_REQUIRED"></property>
<property name="transactionAttributes" value="*=PROPAGATION_REQUIRED"/>
<property name="target">
<bean class="org.springframework.batch.repeat.support.RepeatTemplate">
<property name="completionPolicy">
@@ -92,7 +93,7 @@
<property name="useJmx" value="false"/>
<property name="transportConnectorURIs">
<list>
<value>vm://localhost</value>
<value>vm://localhost?jms.prefetchPolicy.all=0</value>
</list>
</property>
<property name="persistenceAdapter">