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:
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
) ;
|
||||
|
||||
@@ -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
|
||||
) ;
|
||||
|
||||
@@ -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
|
||||
) ;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
) ;
|
||||
|
||||
@@ -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
|
||||
) ;
|
||||
|
||||
@@ -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
|
||||
) ;
|
||||
|
||||
@@ -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
|
||||
) ;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
UK21341EAH4121131.11customer1
|
||||
UK21341EAH4221232.11customer2
|
||||
UK21341EAH4321333.11customer3
|
||||
UK21341EAH4421434.11customer4
|
||||
UK21341EAH4521535.11customer5
|
||||
@@ -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,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,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
|
||||
|
@@ -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
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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};
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user