Moved bulk async reader tests to integration test project
This commit is contained in:
@@ -100,6 +100,11 @@
|
||||
<version>1.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
@@ -121,6 +126,36 @@
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.ibatis</groupId>
|
||||
<artifactId>ibatis-sqlmap</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.persistence</groupId>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-annotations</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-jta_1.1_spec</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ws</groupId>
|
||||
<artifactId>spring-oxm-tiger</artifactId>
|
||||
@@ -131,6 +166,11 @@
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jms</artifactId>
|
||||
|
||||
@@ -42,10 +42,10 @@ public class DatasourceTests {
|
||||
@Transactional @Test
|
||||
public void testTemplate() throws Exception {
|
||||
System.err.println(System.getProperty("java.class.path"));
|
||||
simpleJdbcTemplate.getJdbcOperations().execute("delete from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
simpleJdbcTemplate.getJdbcOperations().execute("delete from T_BARS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(0, count);
|
||||
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", 0, "foo");
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", 0, "foo");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletionService;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.orm.ibatis.SqlMapClientFactoryBean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
|
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "JdbcPagingItemReaderCommonTests-context.xml")
|
||||
public class IbatisPagingItemReaderAsyncTests {
|
||||
|
||||
/**
|
||||
* The number of items to read
|
||||
*/
|
||||
private static final int ITEM_COUNT = 100;
|
||||
|
||||
/**
|
||||
* The number of threads to create
|
||||
*/
|
||||
private static final int THREAD_COUNT = 5;
|
||||
|
||||
private static Log logger = LogFactory.getLog(IbatisPagingItemReaderAsyncTests.class);
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
private int maxId;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||
maxId = jdbcTemplate.queryForInt("SELECT MAX(ID) from T_FOOS");
|
||||
for (int i = maxId + 1; i <= ITEM_COUNT; i++) {
|
||||
jdbcTemplate.update("INSERT into T_FOOS (ID,NAME,VALUE) values (?, ?, ?)", i, "foo" + i, i);
|
||||
}
|
||||
assertEquals(ITEM_COUNT, SimpleJdbcTestUtils.countRowsInTable(jdbcTemplate, "T_FOOS"));
|
||||
}
|
||||
|
||||
@After
|
||||
public void destroy() {
|
||||
SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||
jdbcTemplate.update("DELETE from T_FOOS where ID>?", maxId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncReader() throws Throwable {
|
||||
List<Throwable> throwables = new ArrayList<Throwable>();
|
||||
int max = 10;
|
||||
for (int i = 0; i < max; i++) {
|
||||
try {
|
||||
doTest();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throwables.add(e);
|
||||
}
|
||||
}
|
||||
if (!throwables.isEmpty()) {
|
||||
throw new IllegalStateException(String.format("Failed %d out of %d", throwables.size(), max), throwables
|
||||
.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* @throws InterruptedException
|
||||
* @throws ExecutionException
|
||||
*/
|
||||
private void doTest() throws Exception, InterruptedException, ExecutionException {
|
||||
final IbatisPagingItemReader<Foo> reader = getItemReader();
|
||||
CompletionService<List<Foo>> completionService = new ExecutorCompletionService<List<Foo>>(Executors
|
||||
.newFixedThreadPool(THREAD_COUNT));
|
||||
for (int i = 0; i < THREAD_COUNT; i++) {
|
||||
completionService.submit(new Callable<List<Foo>>() {
|
||||
public List<Foo> call() throws Exception {
|
||||
List<Foo> list = new ArrayList<Foo>();
|
||||
Foo next = null;
|
||||
do {
|
||||
next = reader.read();
|
||||
Thread.sleep(10L); // try to make it fairer
|
||||
logger.debug("Reading item: " + next);
|
||||
if (next != null) {
|
||||
list.add(next);
|
||||
}
|
||||
} while (next != null);
|
||||
return list;
|
||||
}
|
||||
});
|
||||
}
|
||||
int count = 0;
|
||||
Set<Foo> results = new HashSet<Foo>();
|
||||
for (int i = 0; i < THREAD_COUNT; i++) {
|
||||
List<Foo> items = completionService.take().get();
|
||||
count += items.size();
|
||||
logger.debug("Finished items count: " + items.size());
|
||||
logger.debug("Finished items: " + items);
|
||||
assertNotNull(items);
|
||||
results.addAll(items);
|
||||
}
|
||||
assertEquals(ITEM_COUNT, count);
|
||||
assertEquals(ITEM_COUNT, results.size());
|
||||
reader.close();
|
||||
}
|
||||
|
||||
private IbatisPagingItemReader<Foo> getItemReader() throws Exception {
|
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
|
||||
factory.setConfigLocation(new ClassPathResource("ibatis-config.xml", getClass()));
|
||||
factory.setDataSource(dataSource);
|
||||
factory.afterPropertiesSet();
|
||||
SqlMapClient sqlMapClient = createSqlMapClient();
|
||||
|
||||
IbatisPagingItemReader<Foo> reader = new IbatisPagingItemReader<Foo>();
|
||||
reader.setQueryId("getPagedFoos");
|
||||
reader.setPageSize(2);
|
||||
reader.setSqlMapClient(sqlMapClient);
|
||||
reader.setSaveState(true);
|
||||
|
||||
reader.afterPropertiesSet();
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
private SqlMapClient createSqlMapClient() throws Exception {
|
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
|
||||
factory.setConfigLocation(new ClassPathResource("ibatis-config.xml", getClass()));
|
||||
factory.setDataSource(dataSource);
|
||||
factory.afterPropertiesSet();
|
||||
return (SqlMapClient) factory.getObject();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletionService;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.database.support.HsqlPagingQueryProvider;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "JdbcPagingItemReaderCommonTests-context.xml")
|
||||
public class JdbcPagingItemReaderAsyncTests {
|
||||
|
||||
/**
|
||||
* The page size
|
||||
*/
|
||||
private static final int PAGE_SIZE = 2;
|
||||
|
||||
/**
|
||||
* The number of items to read
|
||||
*/
|
||||
private static final int ITEM_COUNT = 10;
|
||||
|
||||
/**
|
||||
* The number of threads to create
|
||||
*/
|
||||
private static final int THREAD_COUNT = 3;
|
||||
|
||||
private static Log logger = LogFactory.getLog(JdbcPagingItemReaderAsyncTests.class);
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
private int maxId;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||
maxId = jdbcTemplate.queryForInt("SELECT MAX(ID) from T_FOOS");
|
||||
for (int i = maxId + 1; i <= ITEM_COUNT; i++) {
|
||||
jdbcTemplate.update("INSERT into T_FOOS (ID,NAME,VALUE) values (?, ?, ?)", i, "foo" + i, i);
|
||||
}
|
||||
assertEquals(ITEM_COUNT, SimpleJdbcTestUtils.countRowsInTable(jdbcTemplate, "T_FOOS"));
|
||||
}
|
||||
|
||||
@After
|
||||
public void destroy() {
|
||||
SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||
jdbcTemplate.update("DELETE from T_FOOS where ID>?", maxId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncReader() throws Throwable {
|
||||
List<Throwable> throwables = new ArrayList<Throwable>();
|
||||
int max = 10;
|
||||
for (int i = 0; i < max; i++) {
|
||||
try {
|
||||
doTest();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throwables.add(e);
|
||||
}
|
||||
}
|
||||
if (!throwables.isEmpty()) {
|
||||
throw new IllegalStateException(String.format("Failed %d out of %d", throwables.size(), max), throwables
|
||||
.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* @throws InterruptedException
|
||||
* @throws ExecutionException
|
||||
*/
|
||||
private void doTest() throws Exception, InterruptedException, ExecutionException {
|
||||
final ItemReader<Foo> reader = getItemReader();
|
||||
CompletionService<List<Foo>> completionService = new ExecutorCompletionService<List<Foo>>(Executors
|
||||
.newFixedThreadPool(THREAD_COUNT));
|
||||
for (int i = 0; i < THREAD_COUNT; i++) {
|
||||
completionService.submit(new Callable<List<Foo>>() {
|
||||
public List<Foo> call() throws Exception {
|
||||
List<Foo> list = new ArrayList<Foo>();
|
||||
Foo next = null;
|
||||
do {
|
||||
next = reader.read();
|
||||
Thread.sleep(10L);
|
||||
logger.debug("Reading item: " + next);
|
||||
if (next != null) {
|
||||
list.add(next);
|
||||
}
|
||||
} while (next != null);
|
||||
return list;
|
||||
}
|
||||
});
|
||||
}
|
||||
int count = 0;
|
||||
Set<Foo> results = new HashSet<Foo>();
|
||||
for (int i = 0; i < THREAD_COUNT; i++) {
|
||||
List<Foo> items = completionService.take().get();
|
||||
count += items.size();
|
||||
logger.debug("Finished items count: " + items.size());
|
||||
logger.debug("Finished items: " + items);
|
||||
assertNotNull(items);
|
||||
results.addAll(items);
|
||||
}
|
||||
assertEquals(ITEM_COUNT, count);
|
||||
assertEquals(ITEM_COUNT, results.size());
|
||||
}
|
||||
|
||||
protected ItemReader<Foo> getItemReader() throws Exception {
|
||||
|
||||
JdbcPagingItemReader<Foo> reader = new JdbcPagingItemReader<Foo>();
|
||||
reader.setDataSource(dataSource);
|
||||
HsqlPagingQueryProvider queryProvider = new HsqlPagingQueryProvider();
|
||||
queryProvider.setSelectClause("select ID, NAME, VALUE");
|
||||
queryProvider.setFromClause("from T_FOOS");
|
||||
queryProvider.setSortKey("ID");
|
||||
reader.setQueryProvider(queryProvider);
|
||||
reader.setRowMapper(new ParameterizedRowMapper<Foo>() {
|
||||
public Foo mapRow(ResultSet rs, int i) throws SQLException {
|
||||
Foo foo = new Foo();
|
||||
foo.setId(rs.getInt(1));
|
||||
foo.setName(rs.getString(2));
|
||||
foo.setValue(rs.getInt(3));
|
||||
return foo;
|
||||
}
|
||||
});
|
||||
reader.setPageSize(PAGE_SIZE);
|
||||
reader.afterPropertiesSet();
|
||||
reader.setSaveState(false);
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletionService;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "JpaPagingItemReaderCommonTests-context.xml")
|
||||
public class JpaPagingItemReaderAsyncTests {
|
||||
|
||||
/**
|
||||
* The number of items to read
|
||||
*/
|
||||
private static final int ITEM_COUNT = 10;
|
||||
|
||||
/**
|
||||
* The number of threads to create
|
||||
*/
|
||||
private static final int THREAD_COUNT = 3;
|
||||
|
||||
private static Log logger = LogFactory.getLog(JpaPagingItemReaderAsyncTests.class);
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
@Autowired
|
||||
private EntityManagerFactory entityManagerFactory;
|
||||
|
||||
private int maxId;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||
maxId = jdbcTemplate.queryForInt("SELECT MAX(ID) from T_FOOS");
|
||||
for (int i = maxId + 1; i <= ITEM_COUNT; i++) {
|
||||
jdbcTemplate.update("INSERT into T_FOOS (ID,NAME,VALUE) values (?, ?, ?)", i, "foo" + i, i);
|
||||
}
|
||||
assertEquals(ITEM_COUNT, SimpleJdbcTestUtils.countRowsInTable(jdbcTemplate, "T_FOOS"));
|
||||
}
|
||||
|
||||
@After
|
||||
public void destroy() {
|
||||
SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||
jdbcTemplate.update("DELETE from T_FOOS where ID>?", maxId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncReader() throws Throwable {
|
||||
List<Throwable> throwables = new ArrayList<Throwable>();
|
||||
int max = 10;
|
||||
for (int i = 0; i < max; i++) {
|
||||
try {
|
||||
doTest();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throwables.add(e);
|
||||
}
|
||||
}
|
||||
if (!throwables.isEmpty()) {
|
||||
throw new IllegalStateException(String.format("Failed %d out of %d", throwables.size(), max), throwables
|
||||
.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* @throws InterruptedException
|
||||
* @throws ExecutionException
|
||||
*/
|
||||
private void doTest() throws Exception, InterruptedException, ExecutionException {
|
||||
final JpaPagingItemReader<Foo> reader = getItemReader();
|
||||
CompletionService<List<Foo>> completionService = new ExecutorCompletionService<List<Foo>>(Executors
|
||||
.newFixedThreadPool(THREAD_COUNT));
|
||||
for (int i = 0; i < THREAD_COUNT; i++) {
|
||||
completionService.submit(new Callable<List<Foo>>() {
|
||||
public List<Foo> call() throws Exception {
|
||||
List<Foo> list = new ArrayList<Foo>();
|
||||
Foo next = null;
|
||||
do {
|
||||
next = reader.read();
|
||||
Thread.sleep(10L);
|
||||
logger.debug("Reading item: " + next);
|
||||
if (next != null) {
|
||||
list.add(next);
|
||||
}
|
||||
} while (next != null);
|
||||
return list;
|
||||
}
|
||||
});
|
||||
}
|
||||
int count = 0;
|
||||
Set<Foo> results = new HashSet<Foo>();
|
||||
for (int i = 0; i < THREAD_COUNT; i++) {
|
||||
List<Foo> items = completionService.take().get();
|
||||
count += items.size();
|
||||
logger.debug("Finished items count: " + items.size());
|
||||
logger.debug("Finished items: " + items);
|
||||
assertNotNull(items);
|
||||
results.addAll(items);
|
||||
}
|
||||
assertEquals(ITEM_COUNT, count);
|
||||
assertEquals(ITEM_COUNT, results.size());
|
||||
reader.close();
|
||||
}
|
||||
|
||||
private JpaPagingItemReader<Foo> getItemReader() throws Exception {
|
||||
|
||||
String jpqlQuery = "select f from Foo f";
|
||||
|
||||
JpaPagingItemReader<Foo> reader = new JpaPagingItemReader<Foo>();
|
||||
reader.setQueryString(jpqlQuery);
|
||||
reader.setEntityManagerFactory(entityManagerFactory);
|
||||
reader.setPageSize(3);
|
||||
reader.afterPropertiesSet();
|
||||
reader.setSaveState(false);
|
||||
reader.open(new ExecutionContext());
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package org.springframework.batch.item.sample;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* Simple domain object for testing purposes.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "T_FOOS")
|
||||
public class Foo {
|
||||
|
||||
public static final String FAILURE_MESSAGE = "Foo Failure!";
|
||||
|
||||
public static final String UGLY_FAILURE_MESSAGE = "Ugly Foo Failure!";
|
||||
|
||||
@Id
|
||||
private int id;
|
||||
private String name;
|
||||
private int value;
|
||||
|
||||
public Foo(){}
|
||||
|
||||
public Foo(int id, String name, int value) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
public void setValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Foo[id=" +id +",name=" + name + ",value=" + value + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + id;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + value;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Foo other = (Foo) obj;
|
||||
if (id != other.id)
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
}
|
||||
else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (value != other.value)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void fail() throws Exception {
|
||||
throw new Exception(FAILURE_MESSAGE);
|
||||
}
|
||||
|
||||
public void failUgly() throws Throwable {
|
||||
throw new Throwable(UGLY_FAILURE_MESSAGE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.springframework.batch.io.oxm;
|
||||
package org.springframework.batch.item.xml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@@ -9,18 +9,20 @@ import java.util.List;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.io.oxm.domain.Trade;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.xml.StaxEventItemReader;
|
||||
import org.springframework.batch.item.xml.domain.Trade;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
public abstract class AbstractStaxEventReaderItemReaderTests {
|
||||
|
||||
protected StaxEventItemReader<Trade> reader = new StaxEventItemReader<Trade>();
|
||||
|
||||
protected Resource resource = new ClassPathResource("org/springframework/batch/io/oxm/input.xml");
|
||||
protected Resource resource = new ClassPathResource(ClassUtils
|
||||
.addResourcePathToPackagePath(getClass(), "input.xml"));
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@@ -28,7 +30,7 @@ public abstract class AbstractStaxEventReaderItemReaderTests {
|
||||
reader.setResource(resource);
|
||||
|
||||
reader.setFragmentRootElementName("trade");
|
||||
|
||||
|
||||
reader.setUnmarshaller(getUnmarshaller());
|
||||
|
||||
reader.afterPropertiesSet();
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.springframework.batch.io.oxm;
|
||||
package org.springframework.batch.item.xml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
@@ -13,9 +13,9 @@ import org.custommonkey.xmlunit.XMLUnit;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.io.oxm.domain.Trade;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.xml.StaxEventItemWriter;
|
||||
import org.springframework.batch.item.xml.domain.Trade;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.springframework.batch.io.oxm;
|
||||
package org.springframework.batch.item.xml;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.springframework.batch.io.oxm;
|
||||
package org.springframework.batch.item.xml;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.springframework.batch.io.oxm;
|
||||
package org.springframework.batch.item.xml;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@@ -11,7 +11,7 @@ import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import org.springframework.batch.io.oxm.domain.Trade;
|
||||
import org.springframework.batch.item.xml.domain.Trade;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.springframework.batch.io.oxm;
|
||||
package org.springframework.batch.item.xml;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@@ -18,9 +18,9 @@ import org.custommonkey.xmlunit.XMLUnit;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.io.oxm.domain.QualifiedTrade;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.xml.StaxEventItemWriter;
|
||||
import org.springframework.batch.item.xml.domain.QualifiedTrade;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.springframework.batch.io.oxm;
|
||||
package org.springframework.batch.item.xml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@@ -12,20 +12,22 @@ import javax.xml.transform.stream.StreamSource;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.io.oxm.domain.QualifiedTrade;
|
||||
import org.springframework.batch.io.oxm.domain.Trade;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.xml.StaxEventItemReader;
|
||||
import org.springframework.batch.item.xml.domain.QualifiedTrade;
|
||||
import org.springframework.batch.item.xml.domain.Trade;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
public class Jaxb2NamespaceUnmarshallingTests {
|
||||
|
||||
private StaxEventItemReader<QualifiedTrade> reader = new StaxEventItemReader<QualifiedTrade>();
|
||||
|
||||
private Resource resource = new ClassPathResource("org/springframework/batch/io/oxm/domain/trades.xml");
|
||||
private Resource resource = new ClassPathResource(ClassUtils.addResourcePathToPackagePath(getClass(),
|
||||
"domain/trades.xml"));
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@@ -44,7 +46,8 @@ public class Jaxb2NamespaceUnmarshallingTests {
|
||||
|
||||
@Test
|
||||
public void testUnmarshal() throws Exception {
|
||||
QualifiedTrade trade = (QualifiedTrade) getUnmarshaller().unmarshal(new StreamSource(new StringReader(TRADE_XML)));
|
||||
QualifiedTrade trade = (QualifiedTrade) getUnmarshaller().unmarshal(
|
||||
new StreamSource(new StringReader(TRADE_XML)));
|
||||
assertEquals("XYZ0001", trade.getIsin());
|
||||
assertEquals(5, trade.getQuantity());
|
||||
assertEquals(new BigDecimal("11.39"), trade.getPrice());
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.springframework.batch.io.oxm;
|
||||
package org.springframework.batch.item.xml;
|
||||
|
||||
import org.springframework.batch.io.oxm.domain.Trade;
|
||||
import org.springframework.batch.item.xml.domain.Trade;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.springframework.batch.io.oxm;
|
||||
package org.springframework.batch.item.xml;
|
||||
|
||||
import org.springframework.batch.io.oxm.domain.Trade;
|
||||
import org.springframework.batch.item.xml.domain.Trade;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.xstream.XStreamMarshaller;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.springframework.batch.io.oxm;
|
||||
package org.springframework.batch.item.xml;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.springframework.batch.io.oxm.domain.Trade;
|
||||
import org.springframework.batch.item.xml.domain.Trade;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.oxm.xstream.XStreamMarshaller;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.springframework.batch.io.oxm.domain;
|
||||
package org.springframework.batch.item.xml.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.springframework.batch.io.oxm.domain;
|
||||
package org.springframework.batch.item.xml.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@@ -78,7 +78,7 @@ public class ExternalRetryInBatchTests {
|
||||
@Before
|
||||
public void onSetUp() throws Exception {
|
||||
getMessages(); // drain queue
|
||||
jdbcTemplate.getJdbcOperations().execute("delete from T_FOOS");
|
||||
jdbcTemplate.getJdbcOperations().execute("delete from T_BARS");
|
||||
jmsTemplate.convertAndSend("queue", "foo");
|
||||
jmsTemplate.convertAndSend("queue", "bar");
|
||||
provider = new ItemReader<String>() {
|
||||
@@ -94,11 +94,11 @@ public class ExternalRetryInBatchTests {
|
||||
@After
|
||||
public void onTearDown() throws Exception {
|
||||
getMessages(); // drain queue
|
||||
jdbcTemplate.getJdbcOperations().execute("delete from T_FOOS");
|
||||
jdbcTemplate.getJdbcOperations().execute("delete from T_BARS");
|
||||
}
|
||||
|
||||
private void assertInitialState() {
|
||||
int count = jdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = jdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(0, count);
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ public class ExternalRetryInBatchTests {
|
||||
// back. When it comes back for recovery this code is not
|
||||
// executed...
|
||||
jdbcTemplate.update(
|
||||
"INSERT into T_FOOS (id,name,foo_date) values (?,?,null)",
|
||||
"INSERT into T_BARS (id,name,foo_date) values (?,?,null)",
|
||||
list.size(), item);
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
@@ -188,7 +188,7 @@ public class ExternalRetryInBatchTests {
|
||||
assertEquals(2, recovered.size());
|
||||
|
||||
// The database portion committed once...
|
||||
int count = jdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = jdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(0, count);
|
||||
|
||||
// ... and so did the message session.
|
||||
|
||||
@@ -71,7 +71,7 @@ public class AsynchronousTests {
|
||||
foo = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
count++;
|
||||
}
|
||||
simpleJdbcTemplate.getJdbcOperations().execute("delete from T_FOOS");
|
||||
simpleJdbcTemplate.getJdbcOperations().execute("delete from T_BARS");
|
||||
|
||||
// Queue is now drained...
|
||||
assertNull(foo);
|
||||
@@ -98,7 +98,7 @@ public class AsynchronousTests {
|
||||
private volatile List<String> list = new ArrayList<String>();
|
||||
|
||||
private void assertInitialState() {
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(0, count);
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ public class AsynchronousTests {
|
||||
public void onMessage(Message message, Session session) throws JMSException {
|
||||
list.add(message.toString());
|
||||
String text = ((TextMessage) message).getText();
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -122,14 +122,14 @@ public class AsynchronousTests {
|
||||
// Need to sleep for at least a second here...
|
||||
waitFor(list,2,2000);
|
||||
|
||||
System.err.println(simpleJdbcTemplate.queryForList("select * from T_FOOS"));
|
||||
System.err.println(simpleJdbcTemplate.queryForList("select * from T_BARS"));
|
||||
|
||||
assertEquals(2, list.size());
|
||||
|
||||
String foo = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
assertEquals(null, foo);
|
||||
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(2, count);
|
||||
|
||||
}
|
||||
@@ -146,7 +146,7 @@ public class AsynchronousTests {
|
||||
public void onMessage(Message message, Session session) throws JMSException {
|
||||
list.add(message.toString());
|
||||
final String text = ((TextMessage) message).getText();
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
// This causes the DB to rollback but not the message
|
||||
if (text.equals("bar")) {
|
||||
throw new RuntimeException("Rollback!");
|
||||
@@ -175,7 +175,7 @@ public class AsynchronousTests {
|
||||
msgs.add(text);
|
||||
}
|
||||
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(0, count);
|
||||
|
||||
assertTrue("Foo not on queue", msgs.contains("foo"));
|
||||
|
||||
@@ -83,13 +83,13 @@ public class SynchronousTests implements ApplicationContextAware {
|
||||
foo = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
count++;
|
||||
}
|
||||
simpleJdbcTemplate.getJdbcOperations().execute("delete from T_FOOS");
|
||||
simpleJdbcTemplate.getJdbcOperations().execute("delete from T_BARS");
|
||||
jmsTemplate.convertAndSend("queue", "foo");
|
||||
jmsTemplate.convertAndSend("queue", "bar");
|
||||
}
|
||||
|
||||
private void assertInitialState() {
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(0, count);
|
||||
}
|
||||
|
||||
@@ -105,12 +105,12 @@ public class SynchronousTests implements ApplicationContextAware {
|
||||
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
|
||||
String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
list.add(text);
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
return RepeatStatus.continueIf(text != null);
|
||||
}
|
||||
});
|
||||
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(2, count);
|
||||
|
||||
String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
@@ -129,7 +129,7 @@ public class SynchronousTests implements ApplicationContextAware {
|
||||
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
|
||||
String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
list.add(text);
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
return RepeatStatus.continueIf(text != null);
|
||||
}
|
||||
});
|
||||
@@ -147,7 +147,7 @@ public class SynchronousTests implements ApplicationContextAware {
|
||||
}
|
||||
|
||||
// The database portion rolled back...
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(0, count);
|
||||
|
||||
// ... and so did the message session. The rollback should have restored
|
||||
@@ -174,7 +174,7 @@ public class SynchronousTests implements ApplicationContextAware {
|
||||
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
|
||||
String text = (String) txJmsTemplate.receiveAndConvert("queue");
|
||||
list.add(text);
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
return RepeatStatus.continueIf(text != null);
|
||||
}
|
||||
});
|
||||
@@ -210,7 +210,7 @@ public class SynchronousTests implements ApplicationContextAware {
|
||||
}
|
||||
|
||||
// The database portion committed...
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(2, count);
|
||||
|
||||
// ...but the JMS session rolled back, so the message is still there
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.repeat.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.repeat.RepeatCallback;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.RepeatStatus;
|
||||
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
/**
|
||||
* Simple tests for concurrent behaviour in repeat template, in particular the
|
||||
* barrier at the end of the iteration. N.B. these tests may fail if
|
||||
* insufficient threads are available (e.g. on a single-core machine, or under
|
||||
* load). They shouldn't deadlock though.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class TaskExecutorRepeatTemplateBulkAsynchronousTests {
|
||||
|
||||
static Log logger = LogFactory.getLog(TaskExecutorRepeatTemplateBulkAsynchronousTests.class);
|
||||
|
||||
private int total = 1000;
|
||||
|
||||
private int throttleLimit = 30;
|
||||
|
||||
private volatile int early = Integer.MAX_VALUE;
|
||||
|
||||
private TaskExecutorRepeatTemplate template;
|
||||
|
||||
private RepeatCallback callback;
|
||||
|
||||
private List<String> items;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
template = new TaskExecutorRepeatTemplate();
|
||||
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
|
||||
taskExecutor.setMaxPoolSize(300);
|
||||
taskExecutor.setCorePoolSize(10);
|
||||
taskExecutor.setQueueCapacity(0);
|
||||
taskExecutor.afterPropertiesSet();
|
||||
template.setTaskExecutor(taskExecutor);
|
||||
template.setThrottleLimit(throttleLimit);
|
||||
|
||||
items = Collections.synchronizedList(new ArrayList<String>());
|
||||
|
||||
callback = new RepeatCallback() {
|
||||
|
||||
private volatile AtomicInteger count = new AtomicInteger(0);
|
||||
|
||||
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
|
||||
int position = count.incrementAndGet();
|
||||
String item = position <= total ? "" + position : null;
|
||||
items.add("" + item);
|
||||
if (item != null) {
|
||||
beBusy();
|
||||
}
|
||||
/*
|
||||
* In a multi-threaded task, one of the callbacks can call
|
||||
* FINISHED early, while other threads are still working, and
|
||||
* would do more work if the callback was called again. (This
|
||||
* happens for instance if there is a failure and you want to
|
||||
* retry the work.)
|
||||
*/
|
||||
RepeatStatus result = RepeatStatus.continueIf(position != early && item != null);
|
||||
if (!result.isContinuable()) {
|
||||
logger.debug("Returning " + result + " for count=" + position);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThrottleLimit() throws Exception {
|
||||
|
||||
template.iterate(callback);
|
||||
int frequency = Collections.frequency(items, "null");
|
||||
// System.err.println(items);
|
||||
// System.err.println("Frequency: " + frequency);
|
||||
assertEquals(total, items.size() - frequency);
|
||||
assertTrue(frequency > 1);
|
||||
assertTrue(frequency <= throttleLimit + 1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThrottleLimitEarlyFinish() throws Exception {
|
||||
|
||||
early = 2;
|
||||
|
||||
template.iterate(callback);
|
||||
int frequency = Collections.frequency(items, "null");
|
||||
// System.err.println("Frequency: " + frequency);
|
||||
// System.err.println("Items: " + items);
|
||||
assertEquals(total, items.size() - frequency);
|
||||
assertTrue(frequency > 1);
|
||||
assertTrue(frequency <= throttleLimit + 1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThrottleLimitEarlyFinishThreadStarvation() throws Exception {
|
||||
|
||||
early = 2;
|
||||
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
|
||||
// Set the concurrency limit below the throttle limit for possible
|
||||
// starvation condition
|
||||
taskExecutor.setMaxPoolSize(20);
|
||||
taskExecutor.setCorePoolSize(10);
|
||||
taskExecutor.setQueueCapacity(0);
|
||||
// This is the most sensible setting, otherwise the bookkeeping in
|
||||
// ResultHolderResultQueue gets out of whack when tasks are aborted.
|
||||
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
taskExecutor.afterPropertiesSet();
|
||||
template.setTaskExecutor(taskExecutor);
|
||||
|
||||
template.iterate(callback);
|
||||
int frequency = Collections.frequency(items, "null");
|
||||
// System.err.println("Frequency: " + frequency);
|
||||
// System.err.println("Items: " + items);
|
||||
// Extra tasks will be submitted before the termination is detected
|
||||
assertEquals(total, items.size() - frequency);
|
||||
assertTrue(frequency <= throttleLimit + 1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThrottleLimitEarlyFinishOneThread() throws Exception {
|
||||
|
||||
early = 4;
|
||||
SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
|
||||
taskExecutor.setConcurrencyLimit(1);
|
||||
|
||||
// This is kind of slow with only one thread, so reduce size:
|
||||
throttleLimit = 10;
|
||||
total = 20;
|
||||
|
||||
template.setThrottleLimit(throttleLimit);
|
||||
template.setTaskExecutor(taskExecutor);
|
||||
|
||||
template.iterate(callback);
|
||||
int frequency = Collections.frequency(items, "null");
|
||||
// System.err.println("Frequency: " + frequency);
|
||||
// System.err.println("Items: " + items);
|
||||
assertEquals(total, items.size() - frequency);
|
||||
assertTrue(frequency <= throttleLimit + 1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThrottleLimitWithEarlyCompletion() throws Exception {
|
||||
|
||||
early = 2;
|
||||
template.setCompletionPolicy(new SimpleCompletionPolicy(10));
|
||||
|
||||
template.iterate(callback);
|
||||
int frequency = Collections.frequency(items, "null");
|
||||
assertEquals(10, items.size() - frequency);
|
||||
// System.err.println("Frequency: " + frequency);
|
||||
assertEquals(0, frequency);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Slightly flakey convenience method. If this doesn't do something that
|
||||
* lasts sufficiently long for another worker to be launched while it is
|
||||
* busy, the early completion tests will fail. "Sufficiently long" is the
|
||||
* problem so we try and block until we know someone else is busy?
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private void beBusy() throws Exception {
|
||||
synchronized (this) {
|
||||
wait(100L);
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -69,7 +69,7 @@ public class ExternalRetryTests {
|
||||
@Before
|
||||
public void onSetUp() throws Exception {
|
||||
getMessages(); // drain queue
|
||||
simpleJdbcTemplate.getJdbcOperations().execute("delete from T_FOOS");
|
||||
simpleJdbcTemplate.getJdbcOperations().execute("delete from T_BARS");
|
||||
jmsTemplate.convertAndSend("queue", "foo");
|
||||
provider = new ItemReader<String>() {
|
||||
public String read() {
|
||||
@@ -82,7 +82,7 @@ public class ExternalRetryTests {
|
||||
}
|
||||
|
||||
private void assertInitialState() {
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(0, count);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class ExternalRetryTests {
|
||||
|
||||
for (Object text : texts) {
|
||||
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(),
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(),
|
||||
text);
|
||||
if (list.size() == 1) {
|
||||
throw new RuntimeException("Rollback!");
|
||||
@@ -165,7 +165,7 @@ public class ExternalRetryTests {
|
||||
List<String> msgs = getMessages();
|
||||
|
||||
// The database portion committed once...
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(1, count);
|
||||
|
||||
// ... and so did the message session.
|
||||
@@ -183,7 +183,7 @@ public class ExternalRetryTests {
|
||||
final String item = provider.read();
|
||||
final RetryCallback<String> callback = new RetryCallback<String>() {
|
||||
public String doWithRetry(RetryContext context) throws Exception {
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), item);
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), item);
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
};
|
||||
@@ -230,7 +230,7 @@ public class ExternalRetryTests {
|
||||
assertEquals(1, recovered.size());
|
||||
|
||||
// The database portion committed once...
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(0, count);
|
||||
|
||||
// ... and so did the message session.
|
||||
|
||||
@@ -74,7 +74,7 @@ public class SynchronousTests {
|
||||
|
||||
@BeforeTransaction
|
||||
public void onSetUpBeforeTransaction() throws Exception {
|
||||
simpleJdbcTemplate.getJdbcOperations().execute("delete from T_FOOS");
|
||||
simpleJdbcTemplate.getJdbcOperations().execute("delete from T_BARS");
|
||||
jmsTemplate.convertAndSend("queue", "foo");
|
||||
jmsTemplate.convertAndSend("queue", "foo");
|
||||
final String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
@@ -94,11 +94,11 @@ public class SynchronousTests {
|
||||
foo = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
count++;
|
||||
}
|
||||
simpleJdbcTemplate.getJdbcOperations().execute("delete from T_FOOS");
|
||||
simpleJdbcTemplate.getJdbcOperations().execute("delete from T_BARS");
|
||||
}
|
||||
|
||||
private void assertInitialState() {
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(0, count);
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ public class SynchronousTests {
|
||||
|
||||
list.add(text);
|
||||
System.err.println("Inserting: [" + list.size() + "," + text + "]");
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
if (list.size() == 1) {
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
@@ -151,7 +151,7 @@ public class SynchronousTests {
|
||||
List<String> msgs = getMessages();
|
||||
|
||||
// The database portion committed once...
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(1, count);
|
||||
|
||||
// ... and so did the message session.
|
||||
@@ -184,7 +184,7 @@ public class SynchronousTests {
|
||||
|
||||
list.add(item);
|
||||
System.err.println("Inserting: [" + list.size() + "," + item + "]");
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), item);
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), item);
|
||||
if (list.size() == 1) {
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
@@ -202,7 +202,7 @@ public class SynchronousTests {
|
||||
List<String> msgs = getMessages();
|
||||
|
||||
// The database portion committed once...
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(1, count);
|
||||
|
||||
// ... and so did the message session.
|
||||
@@ -245,7 +245,7 @@ public class SynchronousTests {
|
||||
|
||||
list.add(text);
|
||||
System.err.println("Inserting: [" + list.size() + "," + text + "]");
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
return text;
|
||||
|
||||
}
|
||||
@@ -258,7 +258,7 @@ public class SynchronousTests {
|
||||
}
|
||||
|
||||
// The nested database transaction has committed...
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(1, count);
|
||||
|
||||
// force rollback...
|
||||
@@ -273,7 +273,7 @@ public class SynchronousTests {
|
||||
List<String> msgs = getMessages();
|
||||
|
||||
// The database portion rolled back...
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(0, count);
|
||||
|
||||
// ... and so did the message session.
|
||||
@@ -303,7 +303,7 @@ public class SynchronousTests {
|
||||
// transaction...
|
||||
final String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
list.add(text);
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
if (list.size() == 1) {
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
@@ -320,7 +320,7 @@ public class SynchronousTests {
|
||||
List<String> msgs = getMessages();
|
||||
|
||||
// The database portion committed once...
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(1, count);
|
||||
|
||||
// ... and so did the message session.
|
||||
@@ -351,7 +351,7 @@ public class SynchronousTests {
|
||||
// transaction...
|
||||
final String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
list.add(text);
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
simpleJdbcTemplate.update("INSERT into T_BARS (id,name,foo_date) values (?,?,null)", list.size(), text);
|
||||
throw new RuntimeException("Rollback!");
|
||||
|
||||
}
|
||||
@@ -377,7 +377,7 @@ public class SynchronousTests {
|
||||
List<String> msgs = getMessages();
|
||||
|
||||
// The database portion rolled back...
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
int count = simpleJdbcTemplate.queryForInt("select count(*) from T_BARS");
|
||||
assertEquals(0, count);
|
||||
|
||||
// ... and so did the message session.
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -52,7 +51,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class DataSourceInitializer implements InitializingBean, DisposableBean {
|
||||
public class DataSourceInitializer implements InitializingBean {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(DataSourceInitializer.class);
|
||||
|
||||
@@ -64,7 +63,7 @@ public class DataSourceInitializer implements InitializingBean, DisposableBean {
|
||||
|
||||
private boolean ignoreFailedDrop = true;
|
||||
|
||||
private static boolean initialized = false;
|
||||
private boolean initialized = false;
|
||||
|
||||
/**
|
||||
* Main method as convenient entry point.
|
||||
@@ -76,34 +75,6 @@ public class DataSourceInitializer implements InitializingBean, DisposableBean {
|
||||
DataSourceInitializer.class.getSimpleName() + "-context.xml"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
* @see java.lang.Object#finalize()
|
||||
*/
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
initialized = false;
|
||||
logger.debug("finalize called");
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (destroyScripts==null) return;
|
||||
for (int i = 0; i < destroyScripts.length; i++) {
|
||||
Resource destroyScript = initScripts[i];
|
||||
try {
|
||||
doExecuteScript(destroyScript);
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
|
||||
}
|
||||
else {
|
||||
logger.warn("Could not execute destroy script [" + destroyScript + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(dataSource);
|
||||
initialize();
|
||||
@@ -111,7 +82,12 @@ public class DataSourceInitializer implements InitializingBean, DisposableBean {
|
||||
|
||||
private void initialize() {
|
||||
if (!initialized) {
|
||||
destroy();
|
||||
if (destroyScripts != null) {
|
||||
for (int i = 0; i < destroyScripts.length; i++) {
|
||||
Resource initScript = initScripts[i];
|
||||
doExecuteScript(initScript);
|
||||
}
|
||||
}
|
||||
if (initScripts != null) {
|
||||
for (int i = 0; i < initScripts.length; i++) {
|
||||
Resource initScript = initScripts[i];
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit name="bar" transaction-type="RESOURCE_LOCAL">
|
||||
|
||||
<class>org.springframework.batch.item.sample.Foo</class>
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC
|
||||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping>
|
||||
<class name="org.springframework.batch.item.sample.Foo" table="T_WRITE_FOOS">
|
||||
<id name="id" column="ID">
|
||||
<generator class="increment"/>
|
||||
</id>
|
||||
<property name="name" />
|
||||
<property name="value" />
|
||||
</class>
|
||||
|
||||
</hibernate-mapping>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC
|
||||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping>
|
||||
<class name="org.springframework.batch.item.sample.Foo" table="T_FOOS">
|
||||
<id name="id" column="ID">
|
||||
<generator class="increment" />
|
||||
</id>
|
||||
<property name="name" />
|
||||
<property name="value" />
|
||||
</class>
|
||||
|
||||
<query name="allFoos">
|
||||
from Foo
|
||||
</query>
|
||||
</hibernate-mapping>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
|
||||
|
||||
<bean class="test.jdbc.datasource.DataSourceInitializer">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="initScripts" value="org/springframework/batch/item/database/init-foo-schema-hsqldb.sql" />
|
||||
</bean>
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
|
||||
<property name="url" value="jdbc:hsqldb:mem:testdb" />
|
||||
</bean>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
|
||||
<bean id="xincrementerParent" class="org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer"
|
||||
abstract="true">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="columnName" value="ID" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
|
||||
|
||||
<bean class="test.jdbc.datasource.DataSourceInitializer">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="initScripts" value="org/springframework/batch/item/database/init-foo-schema-hsqldb.sql" />
|
||||
</bean>
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
|
||||
<property name="url" value="jdbc:hsqldb:mem:testdb" />
|
||||
</bean>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="persistenceUnitName" value="bar"/>
|
||||
<property name="jpaVendorAdapter">
|
||||
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
|
||||
<property name="showSql" value="false"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="incrementerParent" class="org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer"
|
||||
abstract="true">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="columnName" value="ID" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
|
||||
<bean class="test.jdbc.datasource.DataSourceInitializer">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="initScripts" value="org/springframework/batch/item/database/init-foo-schema-hsqldb.sql" />
|
||||
</bean>
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
|
||||
<property name="url" value="jdbc:hsqldb:mem:testdb" />
|
||||
</bean>
|
||||
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
<bean id="incrementerParent" class="org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer"
|
||||
abstract="true">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="columnName" value="ID" />
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
|
||||
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
|
||||
|
||||
<sqlMapConfig>
|
||||
<!-- lazy loading is enabled by default, but it is emphasized here - if it was set
|
||||
to false, input source would load all data into memory! -->
|
||||
<settings lazyLoadingEnabled="true"/>
|
||||
|
||||
<sqlMap resource="org/springframework/batch/item/database/ibatis-foo.xml" />
|
||||
|
||||
</sqlMapConfig>
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
|
||||
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
|
||||
|
||||
<sqlMap namespace="Foo">
|
||||
|
||||
<resultMap id="fooResult" class="org.springframework.batch.item.sample.Foo">
|
||||
<result property="id" column="ID" />
|
||||
<result property="name" column="NAME" />
|
||||
<result property="value" column="VALUE" />
|
||||
</resultMap>
|
||||
|
||||
<select id="getAllFooIds" resultClass="int">
|
||||
select ID from T_FOOS
|
||||
</select>
|
||||
|
||||
<select id="getFooById" parameterClass="int" resultMap="fooResult">
|
||||
select ID, NAME, VALUE from T_FOOS where ID = #value#
|
||||
</select>
|
||||
|
||||
<select id="getAllFoos" resultMap="fooResult">
|
||||
select ID, NAME, VALUE from T_FOOS
|
||||
</select>
|
||||
|
||||
<select id="getPagedFoos" resultMap="fooResult">
|
||||
select LIMIT #_skiprows# #_pagesize# ID, NAME, VALUE from T_FOOS order by ID
|
||||
</select>
|
||||
|
||||
<select id="getPagedFoos3AndUp" resultMap="fooResult">
|
||||
select LIMIT #_skiprows# #_pagesize# ID, NAME, VALUE from T_FOOS where VALUE >= #limit# order by ID
|
||||
</select>
|
||||
|
||||
<select id="getFoos3AndUp" resultMap="fooResult">
|
||||
select ID, NAME, VALUE from T_FOOS where VALUE >= #limit#
|
||||
</select>
|
||||
|
||||
<select id="getAllFooIdsRestart" resultClass="int">
|
||||
select ID from T_FOOS where ID > #id#
|
||||
</select>
|
||||
|
||||
<select id="getNoFoos" resultMap="fooResult">
|
||||
select ID, NAME, VALUE from T_FOOS where ID = -1
|
||||
</select>
|
||||
|
||||
<insert id="insertFoo" parameterClass="org.springframework.batch.item.sample.Foo">
|
||||
insert INTO T_WRITE_FOOS (ID, NAME, VALUE) VALUES (#id#, #name#, #value#)
|
||||
</insert>
|
||||
|
||||
<update id="updateFoo" parameterClass="org.springframework.batch.item.sample.Foo">
|
||||
update T_WRITE_FOOS set NAME = #name#, VALUE = #value# where ID = #id#
|
||||
</update>
|
||||
|
||||
<delete id="deleteFoo" parameterClass="org.springframework.batch.item.sample.Foo">
|
||||
delete from T_WRITE_FOOS where ID = #id#
|
||||
</delete>
|
||||
|
||||
</sqlMap>
|
||||
@@ -0,0 +1,24 @@
|
||||
DROP TABLE T_FOOS if exists;
|
||||
DROP TABLE T_WRITE_FOOS if exists;
|
||||
|
||||
CREATE TABLE T_FOOS (
|
||||
ID BIGINT NOT NULL,
|
||||
NAME VARCHAR(45),
|
||||
VALUE INTEGER
|
||||
);
|
||||
|
||||
ALTER TABLE T_FOOS ADD PRIMARY KEY (ID);
|
||||
|
||||
INSERT INTO t_foos (id, name, value) VALUES (1, 'bar1', 1);
|
||||
INSERT INTO t_foos (id, name, value) VALUES (2, 'bar2', 2);
|
||||
INSERT INTO t_foos (id, name, value) VALUES (3, 'bar3', 3);
|
||||
INSERT INTO t_foos (id, name, value) VALUES (4, 'bar4', 4);
|
||||
INSERT INTO t_foos (id, name, value) VALUES (5, 'bar5', 5);
|
||||
|
||||
CREATE TABLE T_WRITE_FOOS (
|
||||
ID BIGINT NOT NULL,
|
||||
NAME VARCHAR(45),
|
||||
VALUE INTEGER
|
||||
);
|
||||
|
||||
ALTER TABLE T_WRITE_FOOS ADD PRIMARY KEY (ID);
|
||||
@@ -1,5 +1,5 @@
|
||||
<mapping>
|
||||
<class name="org.springframework.batch.io.oxm.domain.Trade">
|
||||
<class name="org.springframework.batch.item.xml.domain.Trade">
|
||||
|
||||
<map-to xml="trade" />
|
||||
|
||||
@@ -1 +1 @@
|
||||
DROP TABLE T_FOOS;
|
||||
DROP TABLE T_BARS;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
DROP TABLE T_FOOS;
|
||||
create table T_FOOS (
|
||||
DROP TABLE T_BARS;
|
||||
create table T_BARS (
|
||||
id integer not null primary key,
|
||||
name varchar(80),
|
||||
foo_date timestamp
|
||||
|
||||
@@ -39,12 +39,12 @@ public class IbatisPagingItemReaderAsyncTests {
|
||||
/**
|
||||
* The number of items to read
|
||||
*/
|
||||
private static final int ITEM_COUNT = 100;
|
||||
private static final int ITEM_COUNT = 10;
|
||||
|
||||
/**
|
||||
* The number of threads to create
|
||||
*/
|
||||
private static final int THREAD_COUNT = 5;
|
||||
private static final int THREAD_COUNT = 3;
|
||||
|
||||
private static Log logger = LogFactory.getLog(IbatisPagingItemReaderAsyncTests.class);
|
||||
|
||||
|
||||
@@ -40,17 +40,17 @@ public class JdbcPagingItemReaderAsyncTests {
|
||||
/**
|
||||
* The page size
|
||||
*/
|
||||
private static final int PAGE_SIZE = 5;
|
||||
private static final int PAGE_SIZE = 2;
|
||||
|
||||
/**
|
||||
* The number of items to read
|
||||
*/
|
||||
private static final int ITEM_COUNT = 100;
|
||||
private static final int ITEM_COUNT = 10;
|
||||
|
||||
/**
|
||||
* The number of threads to create
|
||||
*/
|
||||
private static final int THREAD_COUNT = 5;
|
||||
private static final int THREAD_COUNT = 3;
|
||||
|
||||
private static Log logger = LogFactory.getLog(JdbcPagingItemReaderAsyncTests.class);
|
||||
|
||||
|
||||
@@ -37,12 +37,12 @@ public class JpaPagingItemReaderAsyncTests {
|
||||
/**
|
||||
* The number of items to read
|
||||
*/
|
||||
private static final int ITEM_COUNT = 100;
|
||||
private static final int ITEM_COUNT = 10;
|
||||
|
||||
/**
|
||||
* The number of threads to create
|
||||
*/
|
||||
private static final int THREAD_COUNT = 5;
|
||||
private static final int THREAD_COUNT = 3;
|
||||
|
||||
private static Log logger = LogFactory.getLog(JpaPagingItemReaderAsyncTests.class);
|
||||
|
||||
|
||||
@@ -47,9 +47,9 @@ public class TaskExecutorRepeatTemplateBulkAsynchronousTests {
|
||||
|
||||
static Log logger = LogFactory.getLog(TaskExecutorRepeatTemplateBulkAsynchronousTests.class);
|
||||
|
||||
private int total = 100;
|
||||
private int total = 20;
|
||||
|
||||
private int throttleLimit = 30;
|
||||
private int throttleLimit = 8;
|
||||
|
||||
private volatile int early = Integer.MAX_VALUE;
|
||||
|
||||
@@ -154,8 +154,8 @@ public class TaskExecutorRepeatTemplateBulkAsynchronousTests {
|
||||
taskExecutor.setConcurrencyLimit(1);
|
||||
|
||||
// This is kind of slow with only one thread, so reduce size:
|
||||
throttleLimit = 10;
|
||||
total = 20;
|
||||
throttleLimit = 4;
|
||||
total = 10;
|
||||
|
||||
template.setThrottleLimit(throttleLimit);
|
||||
template.setTaskExecutor(taskExecutor);
|
||||
|
||||
Reference in New Issue
Block a user