RESOLVED - issue BATCH-581: Add filter capability to item oriented paradigm

http://jira.springframework.org/browse/BATCH-581

Added a new sample job: 'CustomerFilterJob' that represents a use case for the filtering of items in a processor.
This commit is contained in:
lucasward
2008-09-29 05:29:29 +00:00
parent 97773129eb
commit 2bc0c17140
17 changed files with 885 additions and 1 deletions

View File

@@ -0,0 +1,187 @@
/*
* 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.sample;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration()
public class CustomerFilterJobFunctionalTests extends AbstractValidatingBatchLauncherTests {
private static final String GET_CUSTOMERS = "select NAME, CREDIT from CUSTOMER order by NAME";
private List<Customer> customers;
private int activeRow = 0;
private SimpleJdbcTemplate simpleJdbcTemplate;
private Map<String, Double> credits = new HashMap<String, Double>();
@Autowired
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
@Before
public void onSetUp() throws Exception {
simpleJdbcTemplate.update("delete from TRADE");
List<Map<String, Object>> list = simpleJdbcTemplate.queryForList("select name, CREDIT from customer");
for (Map<String, Object> map : list) {
credits.put((String) map.get("NAME"), ((Number) map.get("CREDIT")).doubleValue());
}
}
@After
public void tearDown() throws Exception {
simpleJdbcTemplate.update("delete from TRADE");
}
@Test
public void testLaunchJob() throws Exception{
super.testLaunchJob();
}
protected void validatePostConditions() {
// assertTrue(((Resource)applicationContext.getBean("customerFileLocator")).exists());
customers = Arrays.asList(new Customer("customer1", (credits.get("customer1") )),
new Customer("customer2", (credits.get("customer2"))),
new Customer("customer3", 100500),
new Customer("customer4", credits.get("customer4")),
new Customer("customer5", 32345),
new Customer("customer6", 123456));
// check content of the customer table
activeRow = 0;
simpleJdbcTemplate.getJdbcOperations().query(GET_CUSTOMERS, new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
Customer customer = customers.get(activeRow++);
assertEquals(customer.getName(),rs.getString(1));
assertEquals(customer.getCredit(), rs.getDouble(2), .01);
}
});
assertEquals(customers.size(), activeRow);
// check content of the output file
}
protected void validatePreConditions() {
assertTrue(((Resource)applicationContext.getBean("customerFileResource")).exists());
}
private static class Customer {
private String name;
private double credit;
public Customer(String name, double credit) {
this.name = name;
this.credit = credit;
}
public Customer(){
}
/**
* @return the credit
*/
public double getCredit() {
return credit;
}
/**
* @param credit the credit to set
*/
public void setCredit(double credit) {
this.credit = credit;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
final int PRIME = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(credit);
result = PRIME * result + (int) (temp ^ (temp >>> 32));
result = PRIME * result + ((name == null) ? 0 : name.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Customer other = (Customer) obj;
if (Double.doubleToLongBits(credit) != Double.doubleToLongBits(other.credit))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
}

View File

@@ -0,0 +1,97 @@
/**
*
*/
package org.springframework.batch.sample.domain.trade;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.item.file.mapping.DefaultFieldSet;
import org.springframework.batch.item.file.mapping.FieldSet;
import org.springframework.batch.item.file.transform.LineTokenizer;
/**
* @author Lucas Ward
*
*/
public class CompositeCustomerUpdateLineTokenizerTests {
StubLineTokenizer customerTokenizer;
FieldSet customerFieldSet = new DefaultFieldSet(null);
StubLineTokenizer footerTokenizer;
FieldSet footerFieldSet = new DefaultFieldSet(null);
CompositeCustomerUpdateLineTokenizer compositeTokenizer;
@Before
public void init(){
customerTokenizer = new StubLineTokenizer(customerFieldSet);
footerTokenizer = new StubLineTokenizer(footerFieldSet);
compositeTokenizer = new CompositeCustomerUpdateLineTokenizer();
compositeTokenizer.setCustomerTokenizer(customerTokenizer);
compositeTokenizer.setFooterTokenizer(footerTokenizer);
}
@Test
public void testFooter(){
String footerLine = "Ffjkdalsfjdaskl;f";
FieldSet fs = compositeTokenizer.tokenize(footerLine);
assertEquals(footerFieldSet, fs);
assertEquals(footerLine, footerTokenizer.getTokenizedLine());
}
@Test
public void testCustomerAdd(){
String customerAddLine = "AFDASFDASFDFSA";
FieldSet fs = compositeTokenizer.tokenize(customerAddLine);
assertEquals(customerFieldSet, fs);
assertEquals(customerAddLine, customerTokenizer.getTokenizedLine());
}
@Test
public void testCustomerDelete(){
String customerAddLine = "DFDASFDASFDFSA";
FieldSet fs = compositeTokenizer.tokenize(customerAddLine);
assertEquals(customerFieldSet, fs);
assertEquals(customerAddLine, customerTokenizer.getTokenizedLine());
}
@Test
public void testCustomerUpdate(){
String customerAddLine = "UFDASFDASFDFSA";
FieldSet fs = compositeTokenizer.tokenize(customerAddLine);
assertEquals(customerFieldSet, fs);
assertEquals(customerAddLine, customerTokenizer.getTokenizedLine());
}
@Test(expected=IllegalArgumentException.class)
public void testInvalidLine(){
String invalidLine = "INVALID";
compositeTokenizer.tokenize(invalidLine);
}
private static class StubLineTokenizer implements LineTokenizer{
private final FieldSet fieldSetToReturn;
private String tokenizedLine;
public StubLineTokenizer(FieldSet fieldSetToReturn) {
this.fieldSetToReturn = fieldSetToReturn;
}
public FieldSet tokenize(String line) {
this.tokenizedLine = line;
return fieldSetToReturn;
}
public String getTokenizedLine() {
return tokenizedLine;
}
}
}

View File

@@ -0,0 +1,86 @@
/**
*
*/
package org.springframework.batch.sample.domain.trade;
import static org.easymock.EasyMock.*;
import static org.springframework.batch.sample.domain.trade.CustomerOperation.*;
import static org.junit.Assert.*;
import java.math.BigDecimal;
import org.junit.Before;
import org.junit.Test;
/**
* @author Lucas Ward
*
*/
public class CustomerUpdateProcessorTests {
CustomerDao customerDao;
InvalidCustomerLogger logger;
CustomerUpdateProcessor processor;
@Before
public void init(){
customerDao = createMock(CustomerDao.class);
logger = createMock(InvalidCustomerLogger.class);
processor = new CustomerUpdateProcessor();
processor.setCustomerDao(customerDao);
processor.setInvalidCustomerLogger(logger);
}
@Test
public void testSuccessfulAdd() throws Exception{
CustomerUpdate customerUpdate = new CustomerUpdate(ADD, "test customer", new BigDecimal(232.2));
expect(customerDao.getCustomerByName("test customer")).andReturn(null);
replay(customerDao);
assertEquals(customerUpdate, processor.process(customerUpdate));
verify(customerDao);
}
@Test
public void testInvalidAdd() throws Exception{
CustomerUpdate customerUpdate = new CustomerUpdate(ADD, "test customer", new BigDecimal(232.2));
expect(customerDao.getCustomerByName("test customer")).andReturn(new CustomerCredit());
logger.log(customerUpdate);
replay(customerDao, logger);
assertNull("Processor should return null", processor.process(customerUpdate));
verify(customerDao, logger);
}
@Test
public void testDelete() throws Exception{
//delete should never work, therefore, ensure it fails fast.
CustomerUpdate customerUpdate = new CustomerUpdate(DELETE, "test customer", new BigDecimal(232.2));
logger.log(customerUpdate);
replay(customerDao, logger);
assertNull("Processor should return null", processor.process(customerUpdate));
verify(customerDao, logger);
}
@Test
public void testSuccessfulUpdate() throws Exception{
CustomerUpdate customerUpdate = new CustomerUpdate(UPDATE, "test customer", new BigDecimal(232.2));
expect(customerDao.getCustomerByName("test customer")).andReturn(new CustomerCredit());
replay(customerDao, logger);
assertEquals(customerUpdate, processor.process(customerUpdate));
verify(customerDao, logger);
}
@Test
public void testInvalidUpdate() throws Exception{
CustomerUpdate customerUpdate = new CustomerUpdate(UPDATE, "test customer", new BigDecimal(232.2));
expect(customerDao.getCustomerByName("test customer")).andReturn(null);
logger.log(customerUpdate);
replay(customerDao, logger);
assertNull("Processor should return null", processor.process(customerUpdate));
verify(customerDao, logger);
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<import resource="classpath:/simple-job-launcher-context.xml" />
<import resource="classpath:/jobs/customerFilterJob.xml" />
</beans>