OPEN - issue BATCH-911: Consolidate Samples

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

Consolidated non sequential and incrementer jobs into skipSample.
This commit is contained in:
lucasward
2008-11-18 20:23:49 +00:00
parent 43b5edba71
commit 6e39c1a572
51 changed files with 588 additions and 1364 deletions

View File

@@ -19,7 +19,6 @@ package org.springframework.batch.sample.domain.trade;
import java.io.Serializable;
import java.math.BigDecimal;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
@@ -81,7 +80,18 @@ public class Trade implements Serializable {
}
public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
if(!(o instanceof Trade)){
return false;
}
if(o == this){
return true;
}
Trade t = (Trade)o;
return isin.equals(t.getIsin()) && quantity == t.getQuantity() &&
price.equals(t.getPrice()) && customer.equals(t.getCustomer()) ;
}
public int hashCode() {

View File

@@ -1,43 +0,0 @@
package org.springframework.batch.sample.support;
import java.util.ArrayList;
import java.util.List;
import org.springframework.batch.item.ItemWriter;
/**
* Remembers all items written - useful for testing.
*/
public class ItemTrackingItemWriter<T> implements ItemWriter<T> {
private List<T> items = new ArrayList<T>();
private T failed = null;
private int failure = -1;
private int counter = 0;
public void write(List<? extends T> items) throws Exception {
if (failed!=null && items.contains(failed)) {
throw new RuntimeException("write failed again");
}
this.items.addAll(items);
int current = counter;
counter += items.size();
if (current < failure && counter >= failure) {
failed = items.get(failure-current-1);
this.items.remove(failed);
throw new RuntimeException("write failed");
}
}
public List<T> getItems() {
return items;
}
public void setWriteFailure(int failure) {
this.failure = failure;
}
}

View File

@@ -1,36 +0,0 @@
package org.springframework.batch.sample.tasklet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.listener.StepExecutionListenerSupport;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.core.AttributeAccessor;
/**
* Dummy tasklet that retrieves message from the job execution context.
*/
public class DummyMessageReceivingTasklet extends StepExecutionListenerSupport implements Tasklet {
private static final Log logger = LogFactory.getLog(DummyMessageReceivingTasklet.class);
private String receivedMessage = null;
public void beforeStep(StepExecution stepExecution) {
ExecutionContext ctx = stepExecution.getJobExecution().getExecutionContext();
receivedMessage = ctx.getString(DummyMessageSendingTasklet.MESSAGE_KEY);
logger.info("Got message from context: " + receivedMessage);
}
public RepeatStatus execute(StepContribution contribution, AttributeAccessor attributes) throws Exception {
return RepeatStatus.FINISHED;
}
public String getReceivedMessage() {
return receivedMessage;
}
}

View File

@@ -1,44 +0,0 @@
package org.springframework.batch.sample.tasklet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.listener.StepExecutionListenerSupport;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.core.AttributeAccessor;
/**
* Dummy tasklet that stores a message in the job execution context.
*/
public class DummyMessageSendingTasklet extends StepExecutionListenerSupport implements Tasklet {
private static final Log logger = LogFactory.getLog(DummyMessageSendingTasklet.class);
public static final String MESSAGE_KEY = DummyMessageSendingTasklet.class.getSimpleName()+".MESSAGE";
private String message = "Hello!";
public ExitStatus afterStep(StepExecution stepExecution) {
ExecutionContext ctx = stepExecution.getJobExecution().getExecutionContext();
ctx.putString(MESSAGE_KEY, message);
logger.info("Put message into context: " + message);
return null;
}
public RepeatStatus execute(StepContribution contribution, AttributeAccessor attributes) throws Exception {
return RepeatStatus.FINISHED;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@@ -1,40 +0,0 @@
package org.springframework.batch.sample.tasklet;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.UnexpectedJobExecutionException;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.AttributeAccessor;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
/**
* Deletes files from an array of resources, so a pattern can be used in
* configuration, e.g. <code>resources="/home/batch/job/**"</code>
*
* @author Robert Kasanicky
*/
public class FileDeletingTasklet implements Tasklet, InitializingBean {
private Resource[] resources;
public RepeatStatus execute(StepContribution contribution, AttributeAccessor attributes) throws Exception {
for (Resource resource : resources) {
boolean deleted = resource.getFile().delete();
if (!deleted) {
throw new UnexpectedJobExecutionException("Could not delete file " + resource);
}
}
return RepeatStatus.FINISHED;
}
public void setResources(Resource[] resources) {
this.resources = resources;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(resources, "Resources must be set");
}
}

View File

@@ -87,5 +87,7 @@ CREATE TABLE PLAYER_SUMMARY (
) ;
CREATE TABLE ERROR_LOG (
MESSAGE CHAR(300) NOT NULL
JOB_NAME CHAR(20) ,
STEP_NAME CHAR(20) ,
MESSAGE CHAR(300) NOT NULL
) ;

View File

@@ -87,5 +87,7 @@ CREATE TABLE PLAYER_SUMMARY (
) ;
CREATE TABLE ERROR_LOG (
MESSAGE CHAR(300) NOT NULL
JOB_NAME CHAR(20) ,
STEP_NAME CHAR(20) ,
MESSAGE CHAR(300) NOT NULL
) ;

View File

@@ -93,5 +93,7 @@ CREATE TABLE PLAYER_SUMMARY (
) ;
CREATE TABLE ERROR_LOG (
MESSAGE CHAR(300) NOT NULL
JOB_NAME CHAR(20) ,
STEP_NAME CHAR(20) ,
MESSAGE CHAR(300) NOT NULL
) ;

View File

@@ -90,5 +90,7 @@ CREATE TABLE PLAYER_SUMMARY (
) type=InnoDB;
CREATE TABLE ERROR_LOG (
MESSAGE CHAR(300) NOT NULL
JOB_NAME CHAR(20) ,
STEP_NAME CHAR(20) ,
MESSAGE CHAR(300) NOT NULL
) type=InnoDB;

View File

@@ -87,5 +87,7 @@ CREATE TABLE PLAYER_SUMMARY (
) ;
CREATE TABLE ERROR_LOG (
MESSAGE CHAR(300) NOT NULL
JOB_NAME CHAR(20) ,
STEP_NAME CHAR(20) ,
MESSAGE CHAR(300) NOT NULL
) ;

View File

@@ -87,5 +87,7 @@ CREATE TABLE PLAYER_SUMMARY (
) ;
CREATE TABLE ERROR_LOG (
MESSAGE CHAR(300) NOT NULL
JOB_NAME CHAR(20) ,
STEP_NAME CHAR(20) ,
MESSAGE CHAR(300) NOT NULL
) ;

View File

@@ -87,5 +87,7 @@ CREATE TABLE PLAYER_SUMMARY (
) ;
CREATE TABLE ERROR_LOG (
MESSAGE CHAR(300) NOT NULL
JOB_NAME CHAR(20) ,
STEP_NAME CHAR(20) ,
MESSAGE CHAR(300) NOT NULL
) ;

View File

@@ -87,5 +87,7 @@ CREATE TABLE PLAYER_SUMMARY (
) ;
CREATE TABLE ERROR_LOG (
MESSAGE CHAR(300) NOT NULL
JOB_NAME CHAR(20) NULL,
STEP_NAME CHAR(20) NULL,
MESSAGE CHAR(300) NOT NULL
) ;

View File

@@ -0,0 +1,5 @@
UK21341EAH4121131.11customer1
UK21341EAH4221232.11customer2
UK21341EAH4321333.11customer3
UK21341EAH4421434.11customer4
UK21341EAH4521535.11customer5

View File

@@ -1,79 +0,0 @@
AbduKa00,1998,mia,6,jax,0,0,0,0,0,21,43,0,0,1
AbduKa00,1998,mia,7,ram,0,0,0,0,0,17,59,2,12,0
AbduKa00,1998,mia,8,nwe,0,0,0,0,0,21,56,3,12,0
AbduKa00,1998,mia,9,buf,0,0,0,0,0,22,97,2,9,1
AbduKa00,1999,cle,10,pit,0,0,0,0,0,18,56,1,7,0
AbduKa00,1999,cle,11,car,0,0,0,0,0,7,11,2,2,0
AbduKa00,1999,cle,12,oti,0,0,0,0,0,15,35,1,1,0
AbduKa00,1999,cle,13,sdg,0,0,0,0,0,10,29,1,21,0
AbduKa00,1999,cle,14,cin,0,0,0,0,0,5,10,2,7,1
AbduKa00,1999,cle,15,jax,0,0,0,0,0,13,36,1,4,0
AbduKa00,1999,cle,16,clt,0,0,0,0,0,19,84,2,7,0
AbduKa00,1999,cle,1,den,0,0,0,0,0,16,60,1,7,1
AbduKa00,1999,cle,2,crd,0,0,0,0,0,9,33,3,18,0
AbduKa00,1999,cle,4,buf,0,0,0,0,0,3,2,0,0,0
AbduKa00,1999,cle,7,ram,0,0,0,0,0,6,27,2,8,0
AbduKa00,1999,cle,8,nor,0,0,0,0,0,13,39,0,0,0
AbduKa00,1999,cle,9,rav,0,0,0,0,0,9,23,1,2,0
AbduKa00,2000,clt,1,kan,0,0,0,0,0,1,-2,0,0,0
AbduRa00,1999,tam,13,min,0,0,0,0,0,0,0,1,3,0
AbduRa00,1999,tam,15,rai,0,0,0,0,0,4,12,0,0,0
AbduRa00,1999,tam,1,nyg,0,0,0,0,0,1,0,0,0,0
AbduRa00,1999,tam,8,det,0,0,0,0,0,0,0,1,8,0
AbduRa00,2000,tam,12,chi,0,0,0,0,0,2,18,0,0,0
AbduRa00,2000,tam,14,dal,0,0,0,0,0,10,38,1,11,0
AbduRa00,2000,tam,15,mia,0,0,0,0,0,4,14,0,0,0
AbduRa00,2000,tam,1,nwe,0,0,0,0,0,0,0,1,3,0
AbduRa00,2001,tam,15,nor,0,0,0,0,0,3,6,0,0,0
AbduRa00,2001,tam,17,phi,0,0,0,0,0,8,34,2,26,0
AbduRa00,2003,chi,10,det,0,0,0,0,0,2,3,1,7,0
AbduRa00,2003,chi,11,ram,0,0,0,0,0,1,1,0,0,0
AbduRa00,2003,chi,13,crd,0,0,0,0,0,1,0,0,0,0
AbduRa00,2003,chi,14,gnb,0,0,0,0,0,2,3,1,5,0
AbduRa00,2003,chi,15,min,0,0,0,0,0,1,3,0,0,0
AbduRa00,2003,chi,17,kan,0,0,0,0,0,2,8,2,19,0
AbduRa00,2003,chi,2,min,0,0,0,0,0,1,2,2,10,0
AbduRa00,2003,chi,4,gnb,0,0,0,0,0,1,-4,2,14,0
AbduRa00,2003,chi,5,rai,0,0,0,0,0,2,8,0,0,0
AbduRa00,2003,chi,7,sea,0,0,0,0,0,3,4,0,0,0
AbduRa00,2003,chi,8,det,0,0,0,0,0,1,6,0,0,0
AbduRa00,2003,chi,9,sdg,0,0,0,0,0,1,3,0,0,0
AbduRa00,2004,nwe,10,buf,0,0,0,0,0,4,-5,0,0,0
AbduRa00,2004,nwe,16,nyj,0,0,0,0,0,1,5,0,0,0
AbduRa00,2004,nwe,17,sfo,0,0,0,0,0,2,5,0,0,0
AbduRa00,2004,nwe,2,crd,0,0,0,0,0,1,4,0,0,0
AbduRa00,2004,nwe,5,mia,0,0,0,0,0,5,4,0,0,1
AbduRa00,2004,nwe,6,sea,0,0,0,0,0,0,0,1,9,0
AdamCh00,2005,den,10,rai,0,0,0,0,0,2,5,0,0,0
AdamCh00,2005,den,11,nyj,0,0,0,0,0,1,3,2,21,0
AdamCh00,2005,den,12,dal,0,0,0,0,0,0,0,1,7,0
AdamCh00,2005,den,13,kan,0,0,0,0,0,0,0,0,0,0
AdamCh00,2005,den,14,rav,0,0,0,0,0,0,0,3,35,0
AdamCh00,2005,den,15,buf,0,0,0,0,0,0,0,0,0,0
AdamCh00,2005,den,16,rai,0,0,0,0,0,1,-7,0,0,0
AdamCh00,2005,den,17,sdg,0,0,0,0,0,0,0,2,6,0
AdamCh00,2005,den,1,mia,0,0,0,0,0,0,0,2,35,0
AdamCh00,2005,den,2,sdg,0,0,0,0,0,0,0,3,31,0
AdamCh00,2005,den,3,kan,0,0,0,0,0,0,0,2,23,0
AdamCh00,2005,den,4,jax,0,0,0,0,0,1,13,1,9,0
AdamCh00,2005,den,5,was,0,0,0,0,0,0,0,2,11,0
AdamCh00,2005,den,6,nwe,0,0,0,0,0,0,0,0,0,0
AdamCh00,2005,den,7,nyg,0,0,0,0,0,0,0,0,0,0
AdamCh00,2005,den,8,phi,0,0,0,0,0,0,0,3,25,0
AdamMi00,1997,pit,5,oti,0,0,0,0,0,0,0,1,39,0
AddaJo00,2006,clt,10,buf,0,0,0,0,0,13,78,7,46,1
AddaJo00,2006,clt,11,dal,0,0,0,0,0,13,50,1,7,0
AddaJo00,2006,clt,12,phi,0,0,0,0,0,24,171,2,37,4
AddaJo00,2006,clt,13,oti,0,0,0,0,0,16,56,1,11,0
AddaJo00,2006,clt,14,jax,0,0,0,0,0,11,22,1,14,0
AddaJo00,2006,clt,15,cin,0,0,0,0,0,8,50,2,29,0
AddaJo00,2006,clt,16,htx,0,0,0,0,0,15,100,4,8,0
AddaJo00,2006,clt,17,mia,0,0,0,0,0,21,64,3,29,0
AddaJo00,2006,clt,1,nyg,0,0,0,0,0,7,26,3,22,0
AddaJo00,2006,clt,2,htx,0,0,0,0,0,16,82,2,22,1
AddaJo00,2006,clt,3,jax,0,0,0,0,0,3,15,3,13,0
AddaJo00,2006,clt,4,nyj,0,0,0,0,0,20,84,3,15,1
AddaJo00,2006,clt,5,oti,0,0,0,0,0,13,62,2,15,0
AddaJo00,2006,clt,7,was,0,0,0,0,0,11,85,1,20,0
AddaJo00,2006,clt,8,den,0,0,0,0,0,17,93,5,37,0
AddaJo00,2006,clt,9,nwe,0,0,0,0,0,18,43,0,0,1
1 AbduKa00 1998 mia 6 jax 0 0 0 0 0 21 43 0 0 1
2 AbduKa00 1998 mia 7 ram 0 0 0 0 0 17 59 2 12 0
3 AbduKa00 1998 mia 8 nwe 0 0 0 0 0 21 56 3 12 0
4 AbduKa00 1998 mia 9 buf 0 0 0 0 0 22 97 2 9 1
5 AbduKa00 1999 cle 10 pit 0 0 0 0 0 18 56 1 7 0
6 AbduKa00 1999 cle 11 car 0 0 0 0 0 7 11 2 2 0
7 AbduKa00 1999 cle 12 oti 0 0 0 0 0 15 35 1 1 0
8 AbduKa00 1999 cle 13 sdg 0 0 0 0 0 10 29 1 21 0
9 AbduKa00 1999 cle 14 cin 0 0 0 0 0 5 10 2 7 1
10 AbduKa00 1999 cle 15 jax 0 0 0 0 0 13 36 1 4 0
11 AbduKa00 1999 cle 16 clt 0 0 0 0 0 19 84 2 7 0
12 AbduKa00 1999 cle 1 den 0 0 0 0 0 16 60 1 7 1
13 AbduKa00 1999 cle 2 crd 0 0 0 0 0 9 33 3 18 0
14 AbduKa00 1999 cle 4 buf 0 0 0 0 0 3 2 0 0 0
15 AbduKa00 1999 cle 7 ram 0 0 0 0 0 6 27 2 8 0
16 AbduKa00 1999 cle 8 nor 0 0 0 0 0 13 39 0 0 0
17 AbduKa00 1999 cle 9 rav 0 0 0 0 0 9 23 1 2 0
18 AbduKa00 2000 clt 1 kan 0 0 0 0 0 1 -2 0 0 0
19 AbduRa00 1999 tam 13 min 0 0 0 0 0 0 0 1 3 0
20 AbduRa00 1999 tam 15 rai 0 0 0 0 0 4 12 0 0 0
21 AbduRa00 1999 tam 1 nyg 0 0 0 0 0 1 0 0 0 0
22 AbduRa00 1999 tam 8 det 0 0 0 0 0 0 0 1 8 0
23 AbduRa00 2000 tam 12 chi 0 0 0 0 0 2 18 0 0 0
24 AbduRa00 2000 tam 14 dal 0 0 0 0 0 10 38 1 11 0
25 AbduRa00 2000 tam 15 mia 0 0 0 0 0 4 14 0 0 0
26 AbduRa00 2000 tam 1 nwe 0 0 0 0 0 0 0 1 3 0
27 AbduRa00 2001 tam 15 nor 0 0 0 0 0 3 6 0 0 0
28 AbduRa00 2001 tam 17 phi 0 0 0 0 0 8 34 2 26 0
29 AbduRa00 2003 chi 10 det 0 0 0 0 0 2 3 1 7 0
30 AbduRa00 2003 chi 11 ram 0 0 0 0 0 1 1 0 0 0
31 AbduRa00 2003 chi 13 crd 0 0 0 0 0 1 0 0 0 0
32 AbduRa00 2003 chi 14 gnb 0 0 0 0 0 2 3 1 5 0
33 AbduRa00 2003 chi 15 min 0 0 0 0 0 1 3 0 0 0
34 AbduRa00 2003 chi 17 kan 0 0 0 0 0 2 8 2 19 0
35 AbduRa00 2003 chi 2 min 0 0 0 0 0 1 2 2 10 0
36 AbduRa00 2003 chi 4 gnb 0 0 0 0 0 1 -4 2 14 0
37 AbduRa00 2003 chi 5 rai 0 0 0 0 0 2 8 0 0 0
38 AbduRa00 2003 chi 7 sea 0 0 0 0 0 3 4 0 0 0
39 AbduRa00 2003 chi 8 det 0 0 0 0 0 1 6 0 0 0
40 AbduRa00 2003 chi 9 sdg 0 0 0 0 0 1 3 0 0 0
41 AbduRa00 2004 nwe 10 buf 0 0 0 0 0 4 -5 0 0 0
42 AbduRa00 2004 nwe 16 nyj 0 0 0 0 0 1 5 0 0 0
43 AbduRa00 2004 nwe 17 sfo 0 0 0 0 0 2 5 0 0 0
44 AbduRa00 2004 nwe 2 crd 0 0 0 0 0 1 4 0 0 0
45 AbduRa00 2004 nwe 5 mia 0 0 0 0 0 5 4 0 0 1
46 AbduRa00 2004 nwe 6 sea 0 0 0 0 0 0 0 1 9 0
47 AdamCh00 2005 den 10 rai 0 0 0 0 0 2 5 0 0 0
48 AdamCh00 2005 den 11 nyj 0 0 0 0 0 1 3 2 21 0
49 AdamCh00 2005 den 12 dal 0 0 0 0 0 0 0 1 7 0
50 AdamCh00 2005 den 13 kan 0 0 0 0 0 0 0 0 0 0
51 AdamCh00 2005 den 14 rav 0 0 0 0 0 0 0 3 35 0
52 AdamCh00 2005 den 15 buf 0 0 0 0 0 0 0 0 0 0
53 AdamCh00 2005 den 16 rai 0 0 0 0 0 1 -7 0 0 0
54 AdamCh00 2005 den 17 sdg 0 0 0 0 0 0 0 2 6 0
55 AdamCh00 2005 den 1 mia 0 0 0 0 0 0 0 2 35 0
56 AdamCh00 2005 den 2 sdg 0 0 0 0 0 0 0 3 31 0
57 AdamCh00 2005 den 3 kan 0 0 0 0 0 0 0 2 23 0
58 AdamCh00 2005 den 4 jax 0 0 0 0 0 1 13 1 9 0
59 AdamCh00 2005 den 5 was 0 0 0 0 0 0 0 2 11 0
60 AdamCh00 2005 den 6 nwe 0 0 0 0 0 0 0 0 0 0
61 AdamCh00 2005 den 7 nyg 0 0 0 0 0 0 0 0 0 0
62 AdamCh00 2005 den 8 phi 0 0 0 0 0 0 0 3 25 0
63 AdamMi00 1997 pit 5 oti 0 0 0 0 0 0 0 1 39 0
64 AddaJo00 2006 clt 10 buf 0 0 0 0 0 13 78 7 46 1
65 AddaJo00 2006 clt 11 dal 0 0 0 0 0 13 50 1 7 0
66 AddaJo00 2006 clt 12 phi 0 0 0 0 0 24 171 2 37 4
67 AddaJo00 2006 clt 13 oti 0 0 0 0 0 16 56 1 11 0
68 AddaJo00 2006 clt 14 jax 0 0 0 0 0 11 22 1 14 0
69 AddaJo00 2006 clt 15 cin 0 0 0 0 0 8 50 2 29 0
70 AddaJo00 2006 clt 16 htx 0 0 0 0 0 15 100 4 8 0
71 AddaJo00 2006 clt 17 mia 0 0 0 0 0 21 64 3 29 0
72 AddaJo00 2006 clt 1 nyg 0 0 0 0 0 7 26 3 22 0
73 AddaJo00 2006 clt 2 htx 0 0 0 0 0 16 82 2 22 1
74 AddaJo00 2006 clt 3 jax 0 0 0 0 0 3 15 3 13 0
75 AddaJo00 2006 clt 4 nyj 0 0 0 0 0 20 84 3 15 1
76 AddaJo00 2006 clt 5 oti 0 0 0 0 0 13 62 2 15 0
77 AddaJo00 2006 clt 7 was 0 0 0 0 0 11 85 1 20 0
78 AddaJo00 2006 clt 8 den 0 0 0 0 0 17 93 5 37 0
79 AddaJo00 2006 clt 9 nwe 0 0 0 0 0 18 43 0 0 1

View File

@@ -1,20 +0,0 @@
AbduKa00,Abdul-Jabbar,Karim,rb,1974,1996
AbduRa00,Abdullah,Rabih,rb,1975,1999
AberWa00,Abercrombie,Walter,rb,1959,1982
AbraDa00,Abramowicz,Danny,wr,1945,1967
AdamBo00,Adams,Bob,te,1946,1969
AdamCh00,Adams,Charlie,wr,1979,2003
AdamCu00,Adams,Curtis,rb,1962
AdamGe00,Adams,George,rb,1962,1985
AdamGr00,Adams,Grant,2000,2005
AdamJo00,Adams,John,rb,1937,1959
Adams,Michael,wr,1974,1997
AdamMi01,Adamle,Mike,rb,1949,1971
AdamTo00,Adams,Tony,qb,1950,1975
AdamTo01,Adams,Tom,wr,1940,1962
AdamTo02,Adamle,Tony,rb,,1950
AdamWi00,Adams,Willie,wr,1956,1979
AddaJo00,Addai,Joseph,1983,2006,rb
AdkiJa00,Adkisson,James,te,1980,2005
AdkiMa00,Adkins,Margene,wr,1947,1970
AdkiSa00,Adkins,Sam,qb,1955,1977
1 AbduKa00,Abdul-Jabbar,Karim,rb,1974,1996
2 AbduRa00,Abdullah,Rabih,rb,1975,1999
3 AberWa00,Abercrombie,Walter,rb,1959,1982
4 AbraDa00,Abramowicz,Danny,wr,1945,1967
5 AdamBo00,Adams,Bob,te,1946,1969
6 AdamCh00,Adams,Charlie,wr,1979,2003
7 AdamCu00,Adams,Curtis,rb,1962
8 AdamGe00,Adams,George,rb,1962,1985
9 AdamGr00,Adams,Grant,2000,2005
10 AdamJo00,Adams,John,rb,1937,1959
11 Adams,Michael,wr,1974,1997
12 AdamMi01,Adamle,Mike,rb,1949,1971
13 AdamTo00,Adams,Tony,qb,1950,1975
14 AdamTo01,Adams,Tom,wr,1940,1962
15 AdamTo02,Adamle,Tony,rb,,1950
16 AdamWi00,Adams,Willie,wr,1956,1979
17 AddaJo00,Addai,Joseph,1983,2006,rb
18 AdkiJa00,Adkisson,James,te,1980,2005
19 AdkiMa00,Adkins,Margene,wr,1947,1970
20 AdkiSa00,Adkins,Sam,qb,1955,1977

View File

@@ -1,20 +0,0 @@
AbduKa00,Abdul-Jabbar,Karim,rb,1974,1996
AbduRa00,Abdullah,Rabih,rb,1975,1999
AberWa00,Abercrombie,Walter,rb,1959,1982
AbraDa00,Abramowicz,Danny,wr,1945,1967
AdamBo00,Adams,Bob,te,1946,1969
AdamCh00,Adams,Charlie,wr,1979,2003
AdamCu00,Adams,Curtis,rb,1962,1985
AdamGe00,Adams,George,rb,1962,1985
AdamGr00,Adams,Grant,wr,2000,2005
AdamJo00,Adams,John,rb,1937,1959
AdamMi00,Adams,Michael,wr,1974,1997
AdamMi01,Adamle,Mike,rb,1949,1971
AdamTo00,Adams,Tony,qb,1950,1975
AdamTo01,Adams,Tom,wr,1940,1962
AdamTo02,Adamle,Tony,rb,1924,1950
AdamWi00,Adams,Willie,wr,1956,1979
AddaJo00,Addai,Joseph,rb,1983,2006
AdkiJa00,Adkisson,James,te,1980,2005
AdkiMa00,Adkins,Margene,wr,1947,1970
AdkiSa00,Adkins,Sam,qb,1955,1977
1 AbduKa00 Abdul-Jabbar Karim rb 1974 1996
2 AbduRa00 Abdullah Rabih rb 1975 1999
3 AberWa00 Abercrombie Walter rb 1959 1982
4 AbraDa00 Abramowicz Danny wr 1945 1967
5 AdamBo00 Adams Bob te 1946 1969
6 AdamCh00 Adams Charlie wr 1979 2003
7 AdamCu00 Adams Curtis rb 1962 1985
8 AdamGe00 Adams George rb 1962 1985
9 AdamGr00 Adams Grant wr 2000 2005
10 AdamJo00 Adams John rb 1937 1959
11 AdamMi00 Adams Michael wr 1974 1997
12 AdamMi01 Adamle Mike rb 1949 1971
13 AdamTo00 Adams Tony qb 1950 1975
14 AdamTo01 Adams Tom wr 1940 1962
15 AdamTo02 Adamle Tony rb 1924 1950
16 AdamWi00 Adams Willie wr 1956 1979
17 AddaJo00 Addai Joseph rb 1983 2006
18 AdkiJa00 Adkisson James te 1980 2005
19 AdkiMa00 Adkins Margene wr 1947 1970
20 AdkiSa00 Adkins Sam qb 1955 1977

View File

@@ -0,0 +1,5 @@
UK21341EAH45,978,98.34,customer1
UK21341EAH46,112,18.12,customer2
UK21341EAH47,245,12.78,customer2
UK21341EAH48,ERR,ERR,customer3
UK21341EAH49,854,123.39,customer4

View File

@@ -0,0 +1,5 @@
UK21341EAH50,323,38.24,customer5
UK21341EAH51,654,69.32,customer6
UK21341EAH52,723,96.53,customer7
UK21341EAH53,754,17.43,customer8
UK21341EAH54,934,49.23,customer9

View File

@@ -1,75 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
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
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="fixedLengthImportJob" parent="simpleJob">
<property name="steps">
<bean id="step1" parent="simpleStep" p:commitInterval="3">
<property name="itemReader" ref="fileItemReader" />
<property name="itemProcessor">
<bean class="org.springframework.batch.item.validator.ValidatingItemProcessor">
<constructor-arg ref="fixedValidator" />
</bean>
</property>
<property name="itemWriter">
<bean class="org.springframework.batch.sample.domain.trade.internal.TradeWriter">
<property name="dao" ref="tradeDao" />
</bean>
</property>
</bean>
</property>
</bean>
<!-- INFRASTRUCTURE SETUP -->
<!-- This input source is injected into the test case to verify the output - not used by the job at all -->
<bean id="testItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource"
value="classpath:data/fixedLengthImportJob/input/20070122.teststream.ImportTradeDataStep.txt" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer" ref="fixedFileTokenizer" />
<property name="fieldSetMapper" ref="fieldSetMapper" />
</bean>
</property>
</bean>
<bean id="fileItemReader" parent="testItemReader" autowire-candidate="false" />
<bean id="fixedFileTokenizer" class="org.springframework.batch.item.file.transform.FixedLengthTokenizer">
<property name="names" value="ISIN, Quantity, Price, Customer" />
<property name="columns" value="1-12, 13-15, 16-20, 21-29" />
</bean>
<bean id="fixedValidator" class="org.springframework.batch.item.validator.SpringValidator">
<property name="validator">
<bean id="tradeValidator" class="org.springmodules.validation.valang.ValangValidator">
<property name="valang">
<value>
<![CDATA[
{ isin : length(?) < 13 : 'ISIN too long' : 'isin_length' : 12}
]]>
</value>
</property>
</bean>
</property>
</bean>
<bean id="tradeDao" class="org.springframework.batch.sample.domain.trade.internal.JdbcTradeDao">
<property name="dataSource" ref="dataSource" />
<property name="incrementer">
<bean parent="incrementerParent">
<property name="incrementerName" value="TRADE_SEQ" />
</bean>
</property>
</bean>
<bean id="fieldSetMapper" class="org.springframework.batch.sample.domain.trade.internal.TradeFieldSetMapper" />
</beans>

View File

@@ -1,62 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="incrementerJob" parent="simpleJob">
<property name="steps">
<bean id="step1" parent="skipLimitStep">
<property name="transactionManager" ref="transactionManager" />
<property name="jobRepository" ref="jobRepository" />
<property name="commitInterval" value="1" />
<property name="startLimit" value="100" />
<property name="skipLimit" value="3" />
<property name="itemReader">
<bean id="playerFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" ref="playerInputResource"/>
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="ID,lastName,firstName,position,birthYear,debutYear" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="org.springframework.batch.sample.domain.football.internal.PlayerFieldSetMapper" />
</property>
</bean>
</property>
</bean>
</property>
<property name="itemWriter">
<bean class="org.springframework.batch.sample.domain.football.internal.PlayerItemWriter">
<property name="playerDao">
<bean class="org.springframework.batch.sample.domain.football.internal.JdbcPlayerDao">
<property name="dataSource" ref="dataSource" />
</bean>
</property>
</bean>
</property>
<property name="listeners">
<list>
<ref bean="playerInputResource"/>
</list>
</property>
</bean>
</property>
<property name="jobParametersIncrementer">
<bean class="org.springframework.batch.sample.common.InfiniteLoopIncrementer"/>
</property>
</bean>
<bean id="playerInputResource" class="org.springframework.batch.core.resource.StepExecutionResourceProxy">
<property name="filePattern" value="classpath:data/footballjob/input/player-small%run.id(long)%.csv"/>
</bean>
</beans>

View File

@@ -1,32 +0,0 @@
<?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.xsd">
<description>
Simple example of inter-step communication using persistent job
execution context.
</description>
<bean id="jobExecutionContextSample" parent="simpleJob">
<property name="steps">
<list>
<bean id="step1" parent="taskletStep">
<property name="tasklet" ref="sender" />
</bean>
<bean id="step2" parent="taskletStep">
<property name="tasklet" ref="receiver" />
</bean>
</list>
</property>
</bean>
<bean id="sender"
class="org.springframework.batch.sample.tasklet.DummyMessageSendingTasklet">
<property name="message" value="Hey!" />
</bean>
<bean id="receiver"
class="org.springframework.batch.sample.tasklet.DummyMessageReceivingTasklet" />
</beans>

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<import resource="nonSequentialJob-base.xml" />
<bean id="skipCheckingDecider" class="org.springframework.batch.sample.domain.football.internal.SkipCheckingDecider"/>
<batch:job id="nonSequentialDecisionJob">
<batch:step name="playerload">
<batch:next on="*" to="skipCheckingDecision" />
</batch:step>
<batch:decision id="skipCheckingDecision" decider="skipCheckingDecider">
<batch:end on="FAILED" status="FAILED"/>
<batch:next on="COMPLETED WITH SKIPS" to="errorPrint" />
<batch:next on="*" to="gameLoad" />
</batch:decision>
<batch:step name="errorPrint">
<batch:next on="*" to="gameLoad" />
</batch:step>
<batch:step name="gameLoad">
<batch:next on="*" to="playerSummarization" />
</batch:step>
<batch:step name="playerSummarization"/>
</batch:job>
</beans>

View File

@@ -1,127 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="playerload" class="org.springframework.batch.core.step.item.FaultTolerantStepFactoryBean">
<property name="transactionManager" ref="transactionManager" />
<property name="jobRepository" ref="jobRepository" />
<property name="commitInterval" value="${job.commit.interval}" />
<property name="startLimit" value="100" />
<property name="skipLimit" value="100" />
<property name="itemReader" ref="playerFileItemReader" />
<property name="itemWriter">
<bean class="org.springframework.batch.sample.domain.football.internal.PlayerItemWriter">
<property name="playerDao">
<bean class="org.springframework.batch.sample.domain.football.internal.JdbcPlayerDao">
<property name="dataSource" ref="dataSource" />
</bean>
</property>
</bean>
</property>
<property name="listeners">
<list>
<bean class="org.springframework.batch.sample.domain.football.internal.SkipCheckingListener"/>
<ref bean="playerInputResource"/>
</list>
</property>
</bean>
<bean id="errorPrint" parent="taskletStep">
<property name="tasklet">
<bean class="org.springframework.batch.sample.domain.football.internal.ErrorLogTasklet">
<property name="dataSource" ref="dataSource"/>
</bean>
</property>
</bean>
<bean id="gameLoad" parent="simpleStep">
<property name="itemReader" ref="gameFileItemReader" />
<property name="itemWriter">
<bean class="org.springframework.batch.sample.domain.football.internal.JdbcGameDao">
<property name="dataSource" ref="dataSource" />
</bean>
</property>
<property name="commitInterval" value="${job.commit.interval}" />
</bean>
<bean id="playerSummarization" parent="simpleStep">
<property name="commitInterval" value="${job.commit.interval}" />
<property name="itemReader" ref="playerSummarizationSource" />
<property name="itemWriter">
<bean class="org.springframework.batch.sample.domain.football.internal.JdbcPlayerSummaryDao">
<property name="dataSource" ref="dataSource" />
</bean>
</property>
</bean>
<bean id="playerInputResource" class="org.springframework.batch.core.resource.StepExecutionResourceProxy">
<property name="filePattern" value="classpath:data/footballjob/input/%player.file.name%"/>
</bean>
<bean id="playerFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" ref="playerInputResource"/>
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="ID,lastName,firstName,position,birthYear,debutYear" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="org.springframework.batch.sample.domain.football.internal.PlayerFieldSetMapper" />
</property>
</bean>
</property>
</bean>
<bean id="gameFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="classpath:data/footballJob/input/${games.file.name}" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="id,year,team,week,opponent,completes,attempts,passingYards,passingTd,interceptions,rushes,rushYards,receptions,receptionYards,totalTd" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="org.springframework.batch.sample.domain.football.internal.GameFieldSetMapper" />
</property>
</bean>
</property>
</bean>
<bean id="playerSummarizationSource" class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="dataSource" />
<property name="mapper">
<bean class="org.springframework.batch.sample.domain.football.internal.PlayerSummaryMapper" />
</property>
<property name="sql">
<value>
SELECT games.player_id, games.year_no, SUM(COMPLETES),
SUM(ATTEMPTS), SUM(PASSING_YARDS), SUM(PASSING_TD),
SUM(INTERCEPTIONS), SUM(RUSHES), SUM(RUSH_YARDS),
SUM(RECEPTIONS), SUM(RECEPTIONS_YARDS), SUM(TOTAL_TD)
from games, players where players.player_id =
games.player_id group by games.player_id, games.year_no
</value>
</property>
</bean>
<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties">
<value>
games.file.name=games-small.csv
job.commit.interval=2
</value>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="order" value="1" />
</bean>
</beans>

View File

@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<import resource="nonSequentialJob-base.xml" />
<batch:job id="nonSequentialJob">
<batch:step name="playerload">
<batch:end on="FAILED" status="FAILED"/>
<batch:next on="COMPLETED WITH SKIPS" to="errorPrint" />
<batch:next on="*" to="gameLoad" />
</batch:step>
<batch:step name="errorPrint">
<batch:next on="*" to="gameLoad" />
</batch:step>
<batch:step name="gameLoad">
<batch:next on="*" to="playerSummarization" />
</batch:step>
<batch:step name="playerSummarization"/>
</batch:job>
</beans>

View File

@@ -43,14 +43,14 @@
value="classpath:data/fixedLengthImportJob/input/20070122.teststream.ImportTradeDataStep.txt" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer" ref="fixedFileDescriptor" />
<property name="lineTokenizer" ref="fixedFileTokenizer" />
<property name="fieldSetMapper" ref="fieldSetMapper" />
</bean>
</property>
<property name="saveState" value="true" />
</bean>
<bean id="fixedFileDescriptor"
<bean id="fixedFileTokenizer"
class="org.springframework.batch.item.file.transform.FixedLengthTokenizer">
<property name="names" value="ISIN, Quantity, Price, Customer" />
<property name="columns" value="1-12, 13-15, 16-20, 21-29" />

View File

@@ -1,90 +1,116 @@
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<import resource="tradeJobIo.xml" />
<bean id="skipJob" parent="simpleJob">
<property name="steps">
<list>
<bean id="step1" parent="skipLimitStep">
<property name="skipLimit" value="1" />
<property name="itemReader" ref="fileItemReader" />
<property name="itemProcessor">
<bean
class="org.springframework.batch.sample.domain.trade.internal.TradeProcessor"
p:validationFailure="3" />
</property>
<property name="itemWriter">
<bean
class="org.springframework.batch.sample.domain.trade.internal.TradeWriter"
p:dao-ref="tradeDao" />
</property>
</bean>
<bean id="step2" parent="skipLimitStep">
<property name="commitInterval" value="2" />
<property name="skipLimit" value="1" />
<!-- No rollback for exceptions that are marked with "+" in the tx attributes -->
<property name="skippableExceptionClasses">
<list>
<value>org.springframework.batch.item.validator.ValidationException</value>
</list>
</property>
<property name="itemReader"
ref="tradeSqlItemReader" />
<property name="itemProcessor">
<bean
class="org.springframework.batch.sample.domain.trade.internal.TradeProcessor"
p:validationFailure="2" />
</property>
<property name="itemWriter"
ref="itemTrackingWriter" />
</bean>
</list>
</property>
</bean>
<bean id="itemTrackingWriter"
class="org.springframework.batch.sample.support.ItemTrackingItemWriter" />
<bean id="tradeSqlItemReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="dataSource" />
<property name="sql"
value="SELECT isin, quantity, price, customer from TRADE" />
<property name="mapper">
<bean
class="org.springframework.batch.sample.domain.trade.internal.TradeRowMapper" />
</property>
</bean>
<bean id="customerSqlItemReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="dataSource" />
<property name="sql"
value="SELECT id, name, credit FROM customer " />
<property name="mapper">
<bean
class="org.springframework.batch.sample.domain.trade.internal.CustomerCreditRowMapper" />
</property>
</bean>
<bean id="fileLocator"
class="org.springframework.core.io.ClassPathResource">
<constructor-arg type="java.lang.String"
value="data/tradeJob/input/20070122.teststream.ImportTradeDataStep.txt" />
</bean>
<bean id="customerFileLocator"
class="org.springframework.core.io.FileSystemResource">
<constructor-arg type="java.lang.String"
value="target/test-outputs/20070122.testStream.CustomerReportStep.TEMP.txt" />
</bean>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<import resource="tradeJobIo.xml" />
<batch:job id="skipJob" incrementer="incrementer">
<batch:step name="step1">
<batch:end on="FAILED" status="FAILED"/>
<batch:next on="COMPLETED WITH SKIPS" to="errorPrint1" />
<batch:next on="*" to="step2" />
</batch:step>
<batch:step name="errorPrint1">
<batch:next on="*" to="step2" />
</batch:step>
<batch:step name="step2">
<batch:next on="*" to="skipCheckingDecision" />
</batch:step>
<batch:decision id="skipCheckingDecision" decider="skipCheckingDecider">
<batch:next on="COMPLETED WITH SKIPS" to="errorPrint2" />
<batch:end on="*"/>
</batch:decision>
<batch:step name="errorPrint2" />
</batch:job>
<bean id="step1" parent="skipLimitStep">
<property name="skipLimit" value="1" />
<property name="itemReader" ref="fileItemReader" />
<property name="itemProcessor">
<bean class="org.springframework.batch.sample.domain.trade.internal.TradeProcessor"/>
</property>
<property name="itemWriter">
<bean class="org.springframework.batch.sample.domain.trade.internal.TradeWriter"
p:dao-ref="tradeDao" />
</property>
<property name="listeners">
<list>
<bean class="org.springframework.batch.sample.common.SkipCheckingListener"/>
<ref bean="fileLocator"/>
</list>
</property>
</bean>
<bean id="step2" parent="skipLimitStep">
<property name="commitInterval" value="2" />
<property name="skipLimit" value="1" />
<!-- No rollback for exceptions that are marked with "+" in the tx attributes -->
<property name="skippableExceptionClasses">
<list>
<value>org.springframework.batch.item.validator.ValidationException</value>
<value>java.lang.RuntimeException</value>
</list>
</property>
<property name="itemReader" ref="tradeSqlItemReader" />
<property name="itemProcessor">
<bean class="org.springframework.batch.sample.domain.trade.internal.TradeProcessor"/>
</property>
<property name="itemWriter" ref="itemTrackingWriter" />
<property name="listeners">
<list>
<bean class="org.springframework.batch.sample.common.SkipCheckingListener"/>
</list>
</property>
</bean>
<bean id="tradeSqlItemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="dataSource" />
<property name="sql"
value="SELECT isin, quantity, price, customer from TRADE" />
<property name="mapper">
<bean
class="org.springframework.batch.sample.domain.trade.internal.TradeRowMapper" />
</property>
</bean>
<bean id="customerSqlItemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="dataSource" />
<property name="sql"
value="SELECT id, name, credit FROM customer " />
<property name="mapper">
<bean class="org.springframework.batch.sample.domain.trade.internal.CustomerCreditRowMapper" />
</property>
</bean>
<bean id="fileLocator" class="org.springframework.batch.core.resource.StepExecutionResourceProxy">
<property name="filePattern" value="classpath:data/skipJob/input/input%run.id(long)%.txt"/>
</bean>
<bean id="customerFileLocator" class="org.springframework.core.io.FileSystemResource">
<constructor-arg type="java.lang.String"
value="target/test-outputs/20070122.testStream.CustomerReportStep.TEMP.txt" />
</bean>
<bean id="errorPrint" parent="taskletStep">
<property name="tasklet">
<bean class="org.springframework.batch.sample.common.ErrorLogTasklet">
<property name="dataSource" ref="dataSource"/>
</bean>
</property>
</bean>
<bean id="errorPrint1" parent="errorPrint"/>
<bean id="errorPrint2" parent="errorPrint"/>
<bean id="skipCheckingDecider" class="org.springframework.batch.sample.common.SkipCheckingDecider"/>
<bean id="incrementer" class="org.springframework.batch.sample.common.InfiniteLoopIncrementer"/>
</beans>

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" 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
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<description>
Deletes files in given directory - TaskletStep is used as this
is the kind of task that is not natural to split into read and
write. In this case the step is wrapped in a standalone job,
however typically it would be a setup step in a multi-step job.
The second step illustrates executing a system command.
</description>
<bean id="taskletJob" parent="simpleJob">
<property name="steps">
<list>
<bean id="deleteFilesInDir" parent="taskletStep">
<property name="tasklet">
<bean class="org.springframework.batch.sample.tasklet.FileDeletingTasklet">
<property name="resources" value="file:target/test-outputs/test-dir/*" />
</bean>
</property>
</bean>
<bean id="executeSystemCommand" parent="taskletStep">
<property name="tasklet">
<bean class="org.springframework.batch.core.step.tasklet.SystemCommandTasklet">
<property name="command" value="java -version" />
<!-- 5 second timeout for the command to complete -->
<property name="timeout" value="5000" />
</bean>
</property>
</bean>
</list>
</property>
</bean>
</beans>

View File

@@ -32,7 +32,7 @@
p:databaseType="${environment}" p:dataSource-ref="dataSource" />
<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.ClassPathXmlJobRegistry" >
<constructor-arg value="jobs/incrementerJob.xml" />
<constructor-arg value="jobs/skipSampleJob.xml" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
@@ -40,4 +40,7 @@
</bean>
<bean id="logAdvice" class="org.springframework.batch.sample.common.LogAdvice" />
<bean id="itemTrackingWriter" class="org.springframework.batch.sample.domain.trade.internal.ItemTrackingTradeItemWriter" />
</beans>

View File

@@ -75,5 +75,7 @@ CREATE TABLE PLAYER_SUMMARY (
) $!{VOODOO};
CREATE TABLE ERROR_LOG (
MESSAGE CHAR(300) NOT NULL
JOB_NAME CHAR(20) $!{NULL},
STEP_NAME CHAR(20) $!{NULL},
MESSAGE CHAR(300) NOT NULL
) $!{VOODOO};

View File

@@ -1,129 +0,0 @@
/*
* 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.assertNull;
import java.io.BufferedReader;
import java.io.FileReader;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.LineTokenizer;
import org.springframework.batch.sample.domain.trade.Trade;
import org.springframework.batch.sample.domain.trade.internal.TradeFieldSetMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
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 FixedLengthImportJobFunctionalTests extends AbstractValidatingBatchLauncherTests {
//expected line length in input file (sum of pattern lengths + 2, because the counter is appended twice)
private static final int LINE_LENGTH = 29;
//auto-injected attributes
private SimpleJdbcTemplate simpleJdbcTemplate;
private Resource fileLocator;
protected FlatFileItemReader<Trade> itemReader;
private LineTokenizer lineTokenizer;
@Autowired
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
@Autowired
public void setLineTokenizer(LineTokenizer lineTokenizer) {
this.lineTokenizer = lineTokenizer;
}
@Before
public void onSetUp() throws Exception {
simpleJdbcTemplate.update("delete from TRADE");
fileLocator = new ClassPathResource("data/fixedLengthImportJob/input/20070122.teststream.ImportTradeDataStep.txt");
itemReader = new FlatFileItemReader<Trade>();
FieldSetMapper<Trade> mapper = new TradeFieldSetMapper();
DefaultLineMapper<Trade> lineMapper = new DefaultLineMapper<Trade>();
lineMapper.setLineTokenizer(lineTokenizer);
lineMapper.setFieldSetMapper(mapper);
itemReader.setLineMapper(lineMapper);
itemReader.setResource(fileLocator);
itemReader.open(new ExecutionContext());
}
/**
* Check that records have been correctly written to database
* @throws Exception
*/
protected void validatePostConditions() throws Exception {
simpleJdbcTemplate.getJdbcOperations().query(
"SELECT ID, ISIN, QUANTITY, PRICE, CUSTOMER FROM trade ORDER BY id",
new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
Trade trade;
try {
trade = itemReader.read();
}
catch (Exception e) {
throw new IllegalStateException(e.getMessage());
}
assertEquals(trade.getIsin(), rs.getString(2));
assertEquals(trade.getQuantity(),rs.getLong(3));
assertEquals(trade.getPrice(), rs.getBigDecimal(4));
assertEquals(trade.getCustomer(), rs.getString(5));
}
});
assertNull(itemReader.read());
}
/*
* fixed-length file is expected on input
*/
protected void validatePreConditions() throws Exception{
BufferedReader reader;
reader = new BufferedReader(new FileReader(fileLocator.getFile()));
String line;
while ((line = reader.readLine()) != null) {
assertEquals (LINE_LENGTH, line.length());
}
}
}

View File

@@ -47,8 +47,6 @@ public class HibernateFailureJobFunctionalTests extends AbstractCustomerCreditIn
setJobParameters(params);
writer.setFailOnFlush(2);
int before = simpleJdbcTemplate.queryForInt("SELECT COUNT(*) from CUSTOMER");
assertTrue(before > 0);
try {
super.testLaunchJob();
} catch (HibernateJdbcException e) {
@@ -62,7 +60,7 @@ public class HibernateFailureJobFunctionalTests extends AbstractCustomerCreditIn
throw e;
}
int after = simpleJdbcTemplate.queryForInt("SELECT COUNT(*) from CUSTOMER");
assertEquals(before, after);
assertEquals(4, after);
}
/*

View File

@@ -1,105 +0,0 @@
package org.springframework.batch.sample;
import static org.junit.Assert.*;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.launch.JobOperator;
import org.springframework.batch.core.launch.JobParametersNotFoundException;
import org.springframework.batch.core.launch.NoSuchJobException;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
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 = { "/incrementer-job-launcher-context.xml" })
public class IncrementerJobFunctionalTests {
private SimpleJdbcTemplate simpleJdbcTemplate;
@Autowired
private JobOperator jobOperator;
/**
* This test calls the same job twice. However, using a job incrementer, the
* second launching is a separate job instance.<br>
* <br>
* Conditions:
* <ul>
* <li>Two flat files, each containing 20 player records
* <li>Job is started twice, using the job incrementer to chose the input
* file.
* </ul>
* Expected Results:
* <ul>
* <li>First run completes with 20 players in the database
* <li>Second run completes with 40 players in the database.
* </ul>
*/
@Test
public void testWithSkips() throws Exception {
simpleJdbcTemplate.update("DELETE from PLAYERS");
long id1 = this.launchJob();
Map<String, Object> execution1 = this.getJobExecution(id1);
assertEquals("COMPLETED", execution1.get("STATUS"));
assertEquals(20, this.countPlayers());
long id2 = this.launchJob();
Map<String, Object> execution2 = this.getJobExecution(id2);
assertEquals("COMPLETED", execution2.get("STATUS"));
assertEquals(40, this.countPlayers());
assertTrue(id1 != id2);
assertTrue(!execution1.get("JOB_INSTANCE_ID").equals(execution2.get("JOB_INSTANCE_ID")));
}
private Map<String, Object> getJobExecution(long jobExecutionId) {
return simpleJdbcTemplate.queryForMap("SELECT * from BATCH_JOB_EXECUTION where JOB_EXECUTION_ID = ?",
jobExecutionId);
}
private int countPlayers() {
return SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "PLAYERS");
}
/**
* Launch the entire job, including all steps, in order.
*
* @return JobExecution, so that the test may validate the exit status
*/
public long launchJob() {
try {
return this.jobOperator.startNextInstance("incrementerJob");
}
catch (NoSuchJobException e) {
throw new RuntimeException(e);
}
catch (JobExecutionAlreadyRunningException e) {
throw new RuntimeException(e);
}
catch (JobParametersNotFoundException e) {
throw new RuntimeException(e);
}
catch (JobRestartException e) {
throw new RuntimeException(e);
}
catch (JobInstanceAlreadyCompleteException e) {
throw new RuntimeException(e);
}
}
@Autowired
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
}

View File

@@ -1,26 +0,0 @@
package org.springframework.batch.sample;
import static org.junit.Assert.assertEquals;
import org.junit.runner.RunWith;
import org.springframework.batch.sample.tasklet.DummyMessageReceivingTasklet;
import org.springframework.batch.sample.tasklet.DummyMessageSendingTasklet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration()
public class JobExecutionContextSampleFunctionalTests extends AbstractValidatingBatchLauncherTests {
@Autowired
private DummyMessageSendingTasklet sender;
@Autowired
private DummyMessageReceivingTasklet receiver;
protected void validatePostConditions() throws Exception {
assertEquals(sender.getMessage(), receiver.getReceivedMessage());
}
}

View File

@@ -1,50 +1,113 @@
package org.springframework.batch.sample;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import static org.junit.Assert.*;
import org.junit.runner.RunWith;
import org.springframework.batch.core.Job;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration()
public class MultiResourceJobFunctionalTests extends FixedLengthImportJobFunctionalTests {
/**
* Context: 5 items overall, min. 2 items per output file, commitInterval=3,
* => two files created, with 3 items in the first and two in second.
*/
@Override
protected void validatePostConditions() throws Exception {
File file1 = new File("target/test-outputs/multiResourceOutput.txt.1");
File file2 = new File("target/test-outputs/multiResourceOutput.txt.2");
assertTrue(file1.exists());
assertTrue(file2.exists());
BufferedReader reader1 = new BufferedReader(new FileReader(file1));
for (int i = 1; i <= 3; i++) {
assertEquals(itemReader.read().toString(), reader1.readLine());
}
assertNull(reader1.readLine());
BufferedReader reader2 = new BufferedReader(new FileReader(file2));
for (int i = 1; i <= 2; i++) {
assertEquals(itemReader.read().toString(), reader2.readLine());
}
assertNull(reader2.readLine());
}
@Autowired
public void setJob(@Qualifier("multiResourceJob") Job job) {
super.setJob(job);
}
}
package org.springframework.batch.sample;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import javax.sql.DataSource;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.batch.core.Job;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.LineTokenizer;
import org.springframework.batch.sample.domain.trade.Trade;
import org.springframework.batch.sample.domain.trade.internal.TradeFieldSetMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
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 MultiResourceJobFunctionalTests extends AbstractValidatingBatchLauncherTests {
// expected line length in input file (sum of pattern lengths + 2, because
// the counter is appended twice)
private static final int LINE_LENGTH = 29;
// auto-injected attributes
private SimpleJdbcTemplate simpleJdbcTemplate;
private Resource fileLocator;
protected FlatFileItemReader<Trade> itemReader;
private LineTokenizer lineTokenizer;
@Autowired
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
@Autowired
public void setLineTokenizer(LineTokenizer lineTokenizer) {
this.lineTokenizer = lineTokenizer;
}
@Before
public void onSetUp() throws Exception {
simpleJdbcTemplate.update("delete from TRADE");
fileLocator = new ClassPathResource(
"data/multiResourceJob/input/20070122.teststream.ImportTradeDataStep.txt");
itemReader = new FlatFileItemReader<Trade>();
FieldSetMapper<Trade> mapper = new TradeFieldSetMapper();
DefaultLineMapper<Trade> lineMapper = new DefaultLineMapper<Trade>();
lineMapper.setLineTokenizer(lineTokenizer);
lineMapper.setFieldSetMapper(mapper);
itemReader.setLineMapper(lineMapper);
itemReader.setResource(fileLocator);
itemReader.open(new ExecutionContext());
}
/*
* fixed-length file is expected on input
*/
protected void validatePreConditions() throws Exception {
BufferedReader reader;
reader = new BufferedReader(new FileReader(fileLocator.getFile()));
String line;
while ((line = reader.readLine()) != null) {
assertEquals(LINE_LENGTH, line.length());
}
}
/**
* Context: 5 items overall, min. 2 items per output file, commitInterval=3, =>
* two files created, with 3 items in the first and two in second.
*/
@Override
protected void validatePostConditions() throws Exception {
File file1 = new File("target/test-outputs/multiResourceOutput.txt.1");
File file2 = new File("target/test-outputs/multiResourceOutput.txt.2");
assertTrue(file1.exists());
assertTrue(file2.exists());
BufferedReader reader1 = new BufferedReader(new FileReader(file1));
for (int i = 1; i <= 3; i++) {
assertEquals(itemReader.read().toString(), reader1.readLine());
}
assertNull(reader1.readLine());
BufferedReader reader2 = new BufferedReader(new FileReader(file2));
for (int i = 1; i <= 2; i++) {
assertEquals(itemReader.read().toString(), reader2.readLine());
}
assertNull(reader2.readLine());
}
@Autowired
public void setJob(@Qualifier("multiResourceJob")
Job job) {
super.setJob(job);
}
}

View File

@@ -1,10 +0,0 @@
package org.springframework.batch.sample;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/simple-job-launcher-context.xml", "/jobs/nonSequentialDecisionJob.xml" })
public class NonSequentialDecisionJobFunctionalTests extends NonSequentialJobFunctionalTestsBase {
}

View File

@@ -1,10 +0,0 @@
package org.springframework.batch.sample;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/simple-job-launcher-context.xml", "/jobs/nonSequentialJob.xml" })
public class NonSequentialJobFunctionalTests extends NonSequentialJobFunctionalTestsBase {
}

View File

@@ -1,97 +0,0 @@
package org.springframework.batch.sample;
import static org.junit.Assert.assertEquals;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.test.AbstractJobTests;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
public abstract class NonSequentialJobFunctionalTestsBase extends AbstractJobTests {
private SimpleJdbcTemplate simpleJdbcTemplate;
@Before
public void removeOldData() throws Exception {
simpleJdbcTemplate.update("DELETE FROM PLAYERS");
simpleJdbcTemplate.update("DELETE FROM GAMES");
simpleJdbcTemplate.update("DELETE FROM PLAYER_SUMMARY");
}
/**
* This test processes a file that contains bad records. Those records will
* skip. The step execution listener will detect that skips have occurred,
* and return an exit status that directs the flow job to the error logging
* step. The error logging step will log an error. <br>
* <br>
* Conditions:
* <ul>
* <li>Flat file containing 20 player records, 5 are invalid
* <li>Skipping is allowed
* </ul>
* Expected Results:
* <ul>
* <li>15 player records written to the database
* <li>1 error logged to the database
* </ul>
*/
@Test
public void testWithSkips() throws Exception {
launchTest("player-containsBadRecords.csv");
assertEquals(1, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "ERROR_LOG"));
assertEquals(15, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "PLAYERS"));
}
/**
* This test processes a file that contains all valid record. The step
* execution listener will detect that NO skips have occurred, and return an
* exit status that direct the flow job to bypass the error logging step.<br>
* <br>
* Conditions:
* <ul>
* <li>Flat file containing 20 player records, all are valid
* <li>Skipping is allowed
* </ul>
* Expected Results:
* <ul>
* <li>20 player records written to the database
* <li>NO errors logged to the database
* </ul>
*/
@Test
public void testWithoutSkips() throws Exception {
launchTest("player-small1.csv");
assertEquals(0, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "ERROR_LOG"));
assertEquals(20, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "PLAYERS"));
}
private void launchTest(String playerInputfile) throws Exception {
simpleJdbcTemplate.update("DELETE from ERROR_LOG");
simpleJdbcTemplate.update("DELETE from PLAYER_SUMMARY");
simpleJdbcTemplate.update("DELETE from PLAYERS");
simpleJdbcTemplate.update("DELETE from GAMES");
Map<String, JobParameter> parameters = new HashMap<String, JobParameter>();
parameters.put("timestamp", new JobParameter(new Date().getTime()));
parameters.put("player.file.name", new JobParameter(playerInputfile));
JobParameters jobParameters = new JobParameters(parameters);
assertEquals(BatchStatus.COMPLETED, this.launchJob(jobParameters).getStatus());
}
@Autowired
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
}

View File

@@ -1,33 +1,46 @@
package org.springframework.batch.sample;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.sample.support.ItemTrackingItemWriter;
import org.springframework.batch.core.launch.JobOperator;
import org.springframework.batch.core.launch.JobParametersNotFoundException;
import org.springframework.batch.core.launch.NoSuchJobException;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.batch.sample.domain.trade.internal.ItemTrackingTradeItemWriter;
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;
/**
* Error is encountered during writing - transaction is rolled back and the
* error item is skipped on second attempt to process the chunk.
*
* @author Robert Kasanicky
* @author Dan Garrette
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration()
public class SkipSampleFunctionalTests extends AbstractValidatingBatchLauncherTests {
@ContextConfiguration(locations = { "/skipSample-job-launcher-context.xml" })
public class SkipSampleFunctionalTests {
int before = -1;
SimpleJdbcTemplate simpleJdbcTemplate;
private SimpleJdbcTemplate simpleJdbcTemplate;
@Autowired
ItemTrackingItemWriter<?> writer;
private JobOperator jobOperator;
@Autowired
private ItemTrackingTradeItemWriter itemTrackingWriter;
@Autowired
public void setDataSource(DataSource dataSource) {
@@ -35,18 +48,177 @@ public class SkipSampleFunctionalTests extends AbstractValidatingBatchLauncherTe
}
@Before
public void onSetUp() throws Exception {
before = simpleJdbcTemplate.queryForInt("SELECT COUNT(*) from TRADE");
public void setUp() {
simpleJdbcTemplate.update("DELETE from TRADE");
simpleJdbcTemplate.update("DELETE from CUSTOMER");
for (int i = 1; i < 10; i++) {
simpleJdbcTemplate.update("INSERT INTO CUSTOMER VALUES (" + i + ", 0, 'customer" + i + "', 100000)");
}
simpleJdbcTemplate.update("DELETE from ERROR_LOG");
itemTrackingWriter.clearItems();
itemTrackingWriter.setWriteFailureISIN("UK21341EAH47");
}
protected void validatePostConditions() throws Exception {
/**
* LAUNCH 1 <br>
* <br>
* step1
* <ul>
* <li>The step name is saved to the job execution context.
* <li>Read five records from flat file and insert them into the TRADE
* table.
* <li>One record will be invalid, and it will be skipped. Four records
* will be written to the database.
* <li>The skip will result in an exit status that directs the job to run
* the error logging step.
* </ul>
* errorPrint1
* <ul>
* <li>The error logging step will log one record using the step name from
* the job execution context.
* </ul>
* step2
* <ul>
* <li>The step name is saved to the job execution context.
* <li>Read four records from the TRADE table and processes them.
* <li>One record will be invalid, and it will be skipped. Three records
* will be stored in the writer's "items" property.
* <li>The skip will result in an exit status that directs the job to run
* the error logging step.
* </ul>
* errorPrint2
* <ul>
* <li>The error logging step will log one record using the step name from
* the job execution context.
* </ul>
* <br>
* <br>
* LAUNCH 2 <br>
* <br>
* step1
* <ul>
* <li>The step name is saved to the job execution context.
* <li>Read five records from flat file and insert them into the TRADE
* table.
* <li>No skips will occur.
* <li>The exist status of SUCCESS will direct the job to step2.
* </ul>
* errorPrint1
* <ul>
* <li>This step does not occur. No error records are logged.
* </ul>
* step2
* <ul>
* <li>The step name is saved to the job execution context.
* <li>Read five records from the TRADE table and processes them.
* <li>No skips will occur.
* <li>The exist status of SUCCESS will direct the job to end.
* </ul>
* errorPrint2
* <ul>
* <li>This step does not occur. No error records are logged.
* </ul>
*/
@Test
public void testJobIncrementing() {
//
// Launch 1
//
long id1 = this.launchJobWithIncrementer();
Map<String, Object> execution1 = this.getJobExecution(id1);
assertEquals("COMPLETED", execution1.get("STATUS"));
int after = simpleJdbcTemplate.queryForInt("SELECT COUNT(*) from TRADE");
// 5 input records, 1 skipped => 4 written to output
assertEquals(before + 4, after);
this.validateLaunchWithSkips();
//
// Clear the data
//
setUp();
//
// Launch 2
//
long id2 = this.launchJobWithIncrementer();
Map<String, Object> execution2 = this.getJobExecution(id2);
assertEquals("COMPLETED", execution2.get("STATUS"));
this.validateLaunchWithoutSkips();
//
// Make sure that the launches were separate executions and separate
// instances
//
assertTrue(id1 != id2);
assertTrue(!execution1.get("JOB_INSTANCE_ID").equals(execution2.get("JOB_INSTANCE_ID")));
}
/**
*
*/
private void validateLaunchWithSkips() {
// Step1: 5 input records, 1 skipped => 4 written to output
assertEquals(4, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "TRADE"));
// Step2: 4 input records, 1 skipped => 3 written to output
assertEquals(3, itemTrackingWriter.getItems().size());
for(Object o : simpleJdbcTemplate.queryForList(
"SELECT * from ERROR_LOG"))
{
System.err.println("DHG > "+o);
}
// no item was processed twice (one rollback occurred due to validation error)
assertEquals(after - 1, writer.getItems().size());
// Both steps contained skips
assertEquals(2, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "ERROR_LOG"));
assertEquals(1, simpleJdbcTemplate.queryForInt(
"SELECT Count(*) from ERROR_LOG where JOB_NAME = ? and STEP_NAME = ?", "skipJob", "step1"));
assertEquals(1, simpleJdbcTemplate.queryForInt(
"SELECT Count(*) from ERROR_LOG where JOB_NAME = ? and STEP_NAME = ?", "skipJob", "step2"));
}
/**
*
*/
private void validateLaunchWithoutSkips() {
// Step1: 5 input records => 5 written to output
assertEquals(5, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "TRADE"));
// Step2: 5 input records => 5 written to output
assertEquals(5, itemTrackingWriter.getItems().size());
// Neither step contained skips
assertEquals(0, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "ERROR_LOG"));
}
private Map<String, Object> getJobExecution(long jobExecutionId) {
return simpleJdbcTemplate.queryForMap("SELECT * from BATCH_JOB_EXECUTION where JOB_EXECUTION_ID = ?",
jobExecutionId);
}
/**
* Launch the entire job, including all steps, in order.
*
* @return JobExecution, so that the test may validate the exit status
*/
public long launchJobWithIncrementer() {
try {
return this.jobOperator.startNextInstance("skipJob");
}
catch (NoSuchJobException e) {
throw new RuntimeException(e);
}
catch (JobExecutionAlreadyRunningException e) {
throw new RuntimeException(e);
}
catch (JobParametersNotFoundException e) {
throw new RuntimeException(e);
}
catch (JobRestartException e) {
throw new RuntimeException(e);
}
catch (JobInstanceAlreadyCompleteException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -1,55 +0,0 @@
package org.springframework.batch.sample;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Deletes files in the given directory.
*
* @author Robert Kasanicky
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration()
public class TaskletJobFunctionalTests extends AbstractValidatingBatchLauncherTests {
private static Resource directory = new FileSystemResource("target/test-outputs/test-dir");
/*
* Create the directory and some files in it.
*/
@BeforeClass
public static void onSetUp() throws Exception {
File dir = directory.getFile();
dir.mkdirs();
new File(dir, "file1").createNewFile();
new File(dir, "file2").createNewFile();
}
/**
* We have directory with some files in it.
*/
@Override
protected void validatePreConditions() throws Exception {
assertTrue(directory.getFile().isDirectory());
assertTrue(directory.getFile().listFiles().length > 0);
}
/**
* Directory still exists but contains no files.
*/
@Override
protected void validatePostConditions() throws Exception {
assertTrue(directory.getFile().isDirectory());
assertEquals(0, directory.getFile().listFiles().length);
}
}

View File

@@ -1,26 +1,43 @@
package org.springframework.batch.sample.domain.football.internal;
package org.springframework.batch.sample.common;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.core.AttributeAccessor;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
public class ErrorLogTasklet implements Tasklet {
public class ErrorLogTasklet implements Tasklet, StepExecutionListener {
protected final Log logger = LogFactory.getLog(getClass());
private SimpleJdbcTemplate simpleJdbcTemplate;
private String jobName;
private String stepName;
public RepeatStatus execute(StepContribution contribution, AttributeAccessor attributes) throws Exception {
this.simpleJdbcTemplate.update("insert into ERROR_LOG values ('Some records were skipped!')");
this.simpleJdbcTemplate.update("insert into ERROR_LOG values ('"+jobName+"', '"+stepName+"', 'Some records were skipped!')");
return RepeatStatus.FINISHED;
}
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
public ExitStatus afterStep(StepExecution stepExecution) {
// TODO Auto-generated method stub
return null;
}
public void beforeStep(StepExecution stepExecution) {
this.jobName = stepExecution.getJobExecution().getJobInstance().getJobName().trim();
this.stepName = (String)stepExecution.getJobExecution().getExecutionContext().get("stepName");
}
}

View File

@@ -1,4 +1,4 @@
package org.springframework.batch.sample.domain.football.internal;
package org.springframework.batch.sample.common;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution;
@@ -8,11 +8,12 @@ import org.springframework.batch.core.job.flow.support.state.JobExecutionDecider
public class SkipCheckingDecider implements JobExecutionDecider {
public String decide(JobExecution jobExecution, StepExecution stepExecution) {
if (!stepExecution.getExitStatus().getExitCode().equals(ExitStatus.FAILED.getExitCode())
if (!stepExecution.getExitStatus().getExitCode().equals(
ExitStatus.FAILED.getExitCode())
&& stepExecution.getSkipCount() > 0) {
return "COMPLETED WITH SKIPS";
} else {
return ExitStatus.FINISHED.getExitCode();
}
}
}
}

View File

@@ -1,4 +1,4 @@
package org.springframework.batch.sample.domain.football.internal;
package org.springframework.batch.sample.common;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepExecution;
@@ -16,5 +16,6 @@ public class SkipCheckingListener implements StepExecutionListener {
}
public void beforeStep(StepExecution stepExecution) {
stepExecution.getJobExecution().getExecutionContext().put("stepName", stepExecution.getStepName());
}
}

View File

@@ -0,0 +1,21 @@
package org.springframework.batch.sample.domain.trade;
import static org.junit.Assert.*;
import java.math.BigDecimal;
import org.junit.Test;
public class TradeTests {
@Test
public void testEquality(){
Trade trade1 = new Trade("isin", 1, new BigDecimal(1.1), "customer1");
Trade trade1Clone = new Trade("isin", 1, new BigDecimal(1.1), "customer1");
Trade trade2 = new Trade("isin", 1, new BigDecimal(2.3), "customer2");
assertEquals(trade1, trade1Clone);
assertFalse(trade1.equals(trade2));
}
}

View File

@@ -0,0 +1,39 @@
package org.springframework.batch.sample.domain.trade.internal;
import java.util.ArrayList;
import java.util.List;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.sample.domain.trade.Trade;
public class ItemTrackingTradeItemWriter implements ItemWriter<Trade> {
private List<Trade> items = new ArrayList<Trade>();
private String writeFailureISIN;
public void setWriteFailureISIN(String writeFailureISIN) {
this.writeFailureISIN = writeFailureISIN;
}
public void setItems(List<Trade> items) {
this.items = items;
}
public List<Trade> getItems() {
return items;
}
public void clearItems(){
this.items.clear();
}
public void write(List<? extends Trade> items) throws Exception {
List<Trade> newItems = new ArrayList<Trade>();
for(Trade t : items){
if (t.getIsin().equals(this.writeFailureISIN)){
throw new RuntimeException("write failed");
}
newItems.add(t);
}
this.items.addAll(newItems);
}
}

View File

@@ -21,49 +21,53 @@ import static org.junit.Assert.fail;
import java.util.Arrays;
import org.junit.Test;
import org.springframework.batch.sample.domain.trade.Trade;
import org.springframework.batch.sample.domain.trade.internal.ItemTrackingTradeItemWriter;
/**
* @author Dave Syer
*
*
*/
public class ItemTrackingItemWriterTests {
private ItemTrackingItemWriter<String> writer = new ItemTrackingItemWriter<String>();
private ItemTrackingTradeItemWriter writer = new ItemTrackingTradeItemWriter();
/**
* Test method for {@link org.springframework.batch.sample.support.ItemTrackingItemWriter#write(java.util.List)}.
* @throws Exception
* Test method for
* {@link org.springframework.batch.sample.domain.trade.internal.ItemTrackingTradeItemWriter#write(java.util.List)}.
*
* @throws Exception
*/
@Test
public void testWrite() throws Exception {
assertEquals(0, writer.getItems().size());
writer.write(Arrays.asList("a", "b", "c"));
Trade a = new Trade("a", 0, null, null);
Trade b = new Trade("b", 0, null, null);
Trade c = new Trade("c", 0, null, null);
writer.write(Arrays.asList(a, b, c));
assertEquals(3, writer.getItems().size());
}
@Test
public void testWriteFailure() throws Exception {
writer.setWriteFailure(2);
writer.setWriteFailureISIN("c");
try {
writer.write(Arrays.asList("a", "b", "c"));
Trade a = new Trade("a", 0, null, null);
Trade b = new Trade("b", 0, null, null);
Trade c = new Trade("c", 0, null, null);
writer.write(Arrays.asList(a, b, c));
fail("Expected Write Failure Exception");
}
catch (RuntimeException e) {
// expected
}
// the failed item is removed
assertEquals(2, writer.getItems().size());
writer.write(Arrays.asList("a", "e", "c"));
assertEquals(5, writer.getItems().size());
try {
writer.write(Arrays.asList("f", "b", "g"));
fail("Expected RuntimeException");
}
catch (RuntimeException e) {
// expected
}
// barf immediately if a failure is detected
assertEquals(5, writer.getItems().size());
}
assertEquals(0, writer.getItems().size());
Trade e = new Trade("e", 0, null, null);
Trade f = new Trade("f", 0, null, null);
Trade g = new Trade("g", 0, null, null);
writer.write(Arrays.asList(e, f, g));
assertEquals(3, writer.getItems().size());
}
}

View File

@@ -1,10 +0,0 @@
<?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/fixedLengthImportJob.xml" />
</beans>

View File

@@ -1,10 +0,0 @@
<?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/jobExecutionContextSample.xml" />
</beans>

View File

@@ -1,10 +0,0 @@
<?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/skipSampleJob.xml" />
</beans>

View File

@@ -1,10 +0,0 @@
<?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/taskletJob.xml" />
</beans>