SlideShare a Scribd company logo
Spring Batch
Domain
• Benefit Management Application
– Ledger information
Goal
• Input CSV
• The header  System ID,Account ID,Plan
Number,Payee ID,Check Type,Check Date,Transaction
Create Date,Check Number,Benefit Type,Pay Code,Pay
Source 1,Pay Source 2,Pay Source 3,Pay Source 4,Pay
Source 5,Pay Source 6,Pay Source 7,Pay Source 8,Pay
Source 9,Deduction 1,Deduction 2,Deduction
3,Deduction 4,Deduction 5,Deduction 6,Deduction
7,Deduction 8,Deduction 9,Deduction 10,Payable
ID,Customer ID,Category of Distribution,Customer Last
Name,Customer First Name,Customer Middle Initial,…
etc…
Output
• 600+ bytes to send to Paying Agent
• 'payCode' => '%-1.1s',
• 'paySource5' => '%011d',
• 'taxWithholdingElection' => '%-1.1s',
• 'taxableMaritalStatusElectionCode' => '%-1.1s',
• 'deduction10' => '%011d',
• 'systemID' => '%-1.1s',
• 'paySource1' => '%011d',
• 'checkType' => '%-1.1s',
• 'taxableAllowanceElection' => '%-2.2s',
• 'financialInstitutionCity' => '%-16.16s',
• 'checkCity' => '%-16.16s',
• 'paySource9' => '%011d',
• 'planNumber' => '%-6.6s',
• 'payeeDateofDeath' => '%-8.8s',
• 'aCHRoutingNumber' => '%-9.9s',
• 'check3rdStreetAddress' => '%-32.32s',
• 'deduction1' => '%011d',
• 'transactionCreateDate' => '%-8.8s',
• 'deduction2' => '%011d',
• 'deduction5' => '%011d',
• 'checkNumber' => '%-10.10s',
• 'checkDate' => '%-8.8s',
• 'financialInstitutionPostalCode' => '%-9.9s',
• 'deduction8' => '%011d',
• 'categoryofDistribution' => '%-2.2s',
• 'customerFirstName' => '%-12.12s',
• 'check1stStreetAddress' => '%-32.32s',
Tools
• Spring Source Tools IDE /Eclipse
• Apache Maven
• Perl
• Bash  Cygwin (Windows)
• Spring Batch legacy code that currently
supports 1.6 spec but needs to upgrade to 1.9
spec
Spring Batch Project
• Start with the simplest hello-world project
• Build more complexity on top
Spring Batch Application Context
• <?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.5.xsd">
• <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
• <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
• <property name="transactionManager" ref="transactionManager"/>
• </bean>
• <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
• <property name="jobRepository" ref="jobRepository" />
• </bean>
•
• <!--
• <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
• -->
• </beans>
Maven POM• <name>Spring Batch Hello World</name>
• <properties>
• <spring.version>2.5.4</spring.version>
• <spring-batch.version>2.0.3.RELEASE</spring-batch.version>
• </properties>
• <dependencies>
• <dependency>
• <groupId>org.springframework.batch</groupId>
• <artifactId>spring-batch-core</artifactId>
• <version>${spring-batch.version}</version>
• </dependency>
• <dependency>
• <groupId>org.springframework</groupId>
• <artifactId>spring-aop</artifactId>
• <version>${spring.version}</version>
• </dependency>
• <dependency>
• <groupId>org.springframework</groupId>
• <artifactId>spring-tx</artifactId>
• <version>${spring.version}</version>
• </dependency>
• <dependency>
• <groupId>org.springframework</groupId>
• <artifactId>spring-core</artifactId>
• <version>${spring.version}</version>
• </dependency>
• <dependency>
• <groupId>org.springframework</groupId>
• <artifactId>spring-beans</artifactId>
• <version>${spring.version}</version>
• </dependency>
• <dependency>
• <groupId>org.springframework</groupId>
• <artifactId>spring-context</artifactId>
• <version>${spring.version}</version>
• </dependency>
• <dependency>
• <groupId>org.springframework</groupId>
• <artifactId>org.springframework.test</artifactId>
• <version>3.0.4.RELEASE</version>
• </dependency>
Domain Class
Getter and setter(s)…
Tokenizer
• <!-- Tokenizer - Converts a delimited string
into a Set of Fields -->
• <bean name="defaultTokenizer"
class="org.springframework.batch.item.file.tr
ansform.DelimitedLineTokenizer"/>
Field Set Mapper
• <bean name="pbtItemFieldSetMapper"
class="aspire.mapper.PBTItemFieldSetMapper
" />
Line Mapper
• <bean name="pbtItemLineMapper"
class="org.springframework.batch.item.file.m
apping.DefaultLineMapper">
• <property name="lineTokenizer"
ref="defaultTokenizer"/>
• <property name="fieldSetMapper"
ref="pbtItemFieldSetMapper"/>
• </bean>
Flat File Item Reader
• <bean name="pbtItemReader"
class="org.springframework.batch.item.file.FlatFileIte
mReader">
• <property name="lineMapper"
ref="pbtItemLineMapper"/>
• <!-- use spring integrations for the following, but for
now filename is hard coded -->
• <property name="resource" value="classpath:pbt-
input-4.txt"/>
• </bean>
Input File(s)
Item Processor
• <bean name="pbtItemProcessor"
class="aspire.processor.PBTItemProcessor">
• </bean>
Item Writer
• <bean id="pbtItemWriter"
• class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
• <property name="resource" value="file:target/output-pbt-4.det"/>
• <property name="lineAggregator">
• <bean
• class="org.springframework.batch.item.file.transform.FormatterLineAggregator">
• <property name="fieldExtractor">
• <bean
• class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
• <property name="names"
• value="systemID,accountID,planNumber,payeeID,checkType,checkDate,transactionCreateDate,checkNumber,benefitType,payCode,paySource1,paySource2,paySource3,paySource4,paySo
urce5,paySource6,paySource7,paySource8,paySource9,deduction1,deduction2,deduction3,deduction4,deduction5,deduction6,deduction7,deduction8,
……,financialInstitutionfinancialInstitutionAccountNumber,financialInstitutionAccountType,financialInstitutionStreet1,financialInstitutionCity,financialInstitutionStateCode,financialInstitutio
nProvince,financialInstitutionPostalCode,financialInstitutionIRSCountryCode,taxWithholdingElection,taxableMaritalStatusElectionCode,taxableAllowanceElection" />
• </bean>
• </property>
• <!--
• %[argument_index$][flags][width][.precision]conversion
• -->
• <property name="format" value="%-1.1s%-5.5s%-6.6s%-9.9s%-1.1s%-8.8s%-8.8s%-10.10s%-3.3s%-1.1s%011d%011d%011d%011d%011d%011d%011d%011d%011d%011d%011d%011d
%011d%011d%011d%011d%011d%011d%011d%-10.10s%-30.30s%-2.2s%-20.20s%-12.12s%-1.1s%-8.8s%-8.8s%-32.32s%-32.32s%-32.32s%-16.16s%-2.2s%-9.9s%-2.2s%-16.16s%-1.1s%-
9.9s%-17.17s%-32.32s%-32.32s%-2.2s%-32.32s%-16.16s%-2.2s%-16.16s%-9.9s%-2.2s%-1.1s%-1.1s%-2.2s" />
• </bean>
• </property>
• <property name="footerCallback" ref="pbtfootercallback" />
• </bean>
• <bean id="pbtfootercallback" class="aspire.core.PBTFooterCallback">
• <property name="delegate" ref="pbtItemWriter"></property>
• </bean>
Field Set Mapper…
Batch Job
• <batch:job id="pbgcPBTIncomingJob">
• <!-- batch:step id="step1" next="step2">
• <batch:tasklet ref="helloWorldTasklet" />
• </batch:step-->
• <batch:step id="step4">
• <batch:tasklet>
• <batch:chunk reader="pbtItemReader" processor="pbtItemProcessor"
writer="pbtfootercallback" commit-interval="1">
• <batch:streams>
• <batch:stream ref="pbtItemReader" />
• <batch:stream ref="pbtItemWriter"/>
• </batch:streams>
• </batch:chunk>
• <batch:listeners>
• <batch:listener ref="pbtfootercallback"/>
• </batch:listeners>
• </batch:tasklet>
• </batch:step>
• </batch:job>
Footer Callback
Footer callback …(2)
How to test/run
• Command line
– mvn exec….
– jUnit test case
Junit Test Case
• import org.springframework.batch.core.repository.JobRestartException;
• 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;
• import org.springframework.util.StopWatch;
• @ContextConfiguration("classpath:simpleJob.xml")
• @RunWith(SpringJUnit4ClassRunner.class)
• public class HelloTestCase {
• private static Log logger = LogFactory.getLog(HelloTestCase.class);
• @Autowired
• @Qualifier("pbgcPBTIncomingJob")
• private Job job;
• @Autowired
• private JobLauncher jobLauncher;
• @Test
• public void test() {
• //fail("Not yet implemented");
• JobExecution execution = null;
• try {
• logger.debug("hello world");
• logger.debug("Job name: " + job.getName());
• execution = jobLauncher.run(job, new JobParameters());
• //execution = jobLauncher.run(job,
• //new JobParametersBuilder()
• //.addString("inputFile", "ack-test-new.xlsx")
• //.addString("outputFile", "1002").toJobParameters());
• } catch (JobExecutionAlreadyRunningException e)
jUnit Eclipse Plug-in
Sample output…
• Abbreviated Input
• 12:47:43,019 DEBUG main PBTItemFieldSetMapper:19 - [1, AGENCY1, ….., …….., 61, RA3, R, 45677,
7, 6, 5, 4, 3, 2, 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,…….., 7, SMITH, JOE, F, 123456, *, 742 ANY STREET,, *,
*, ANY CITY, OH, ……, US, *, A, ………….., *, *, *, *, *, *, *, *, *, N, *, 0]
• Abbreviated Output
• 12:47:43,019 DEBUG main PBTItemProcessor:21 - after processing [SystemID = 1 AccountID =
AGENCY1 PlanNumber ……… BenefitType = RA3 PayCode = R PaySource1 = 45677 PaySource2 = 7
PaySource3 = 6 PaySource4 = 5 PaySource5 = 4 PaySource6 = 3 PaySource7 = 2 PaySource8 = 1
PaySource9 = 0 Deduction1 = 10 Deduction2 = 9 Deduction3 = 8 Deduction4 = 7 Deduction5 = 6
Deduction6 = 5 Deduction7 = 4 Deduction8 = 3 Deduction9 = 2 Deduction10 = 1
……….Check2ndStreetAddress = * Check3rdStreetAddress = ……CheckIRSCountryCode = US
CheckProvince = * PaymentDestinationType = A ………… FinancialInstitutionPostalCode = *
FinancialInstitutionIRSCountryCode = * TaxWithholdingElection = N
TaxableMaritalStatusElectionCode = * TaxableAllowanceElection = 0]
• 12:47:43,019 DEBUG main PBTFooterCallback:44 - write...callback...
• 12:47:43,019 DEBUG main PBTFooterCallback:65 - 8
• ….
• 12:47:43,035 DEBUG main PBTFooterCallback:31 - FooterCallback....
• 12:47:43,035 INFO main SimpleJobLauncher:111 - Job: [FlowJob: [name=pbgcPBTIncomingJob]]
completed with the following parameters: [{}] and the following status: [COMPLETED]
Counting the bytes
• Fires up cygwin
• user@PC123456> /cygdrive/c/dev/spring-
batch/batch-dir/Spring-Batch-Hello-Wor
ld/target
– $ head -n1 output-pbt-4.det | wc -c
– 669
Be aware of newlines char
• Bash/gnu wc utility
• userID@PC123456 /cygdrive/c/dev/spring-
batch/batch-dir/Spring-Batch-Hello-World/target
– $ head -n1 output-pbt-4.det | perl -ne 'print
substr($_,667,2);' | od -c
– 0000000 r n
– 0000002
• So technically we only 667 bytes instead of 669
as reported by wc

More Related Content

PDF
Breaking the limits_of_page_objects
PDF
Contagion的Ruby/Rails投影片
 
PDF
My Top 5 APEX JavaScript API's
PPTX
Oracle APEX Performance
PDF
Advanced Django
PPTX
Escape from the automation hell
PDF
Hidden Treasures in Project Wonder
PDF
Scala ActiveRecord
Breaking the limits_of_page_objects
Contagion的Ruby/Rails投影片
 
My Top 5 APEX JavaScript API's
Oracle APEX Performance
Advanced Django
Escape from the automation hell
Hidden Treasures in Project Wonder
Scala ActiveRecord

What's hot (20)

PDF
Introduction to Active Record at MySQL Conference 2007
PPT
Presentation
KEY
Php Unit With Zend Framework Zendcon09
PDF
Frontin like-a-backer
PPTX
Top 5 Magento Secure Coding Best Practices
PDF
Rails Best Practices
PPTX
Making Magento flying like a rocket! (A set of valuable tips for developers)
PDF
Angular2 & ngrx/store: Game of States
PDF
A Peek At The Future: Going Beyond JavaServer Faces 2.0 With RichFaces 4
PDF
Take Data Validation Seriously - Paul Milham, WildWorks
PDF
Crossing platforms with JavaScript & React
PDF
Future of Web Apps: Google Gears
PDF
Mastering Oracle ADF Bindings
PPT
PPTX
Basics of AngularJS
PDF
Take Data Validation Seriously - Paul Milham, WildWorks
PDF
Unit testing after Zend Framework 1.8
PDF
Practical Object Oriented Models In Sql
PPTX
Owl: The New Odoo UI Framework
PDF
Evan Schultz - Angular Camp - ng2-redux
Introduction to Active Record at MySQL Conference 2007
Presentation
Php Unit With Zend Framework Zendcon09
Frontin like-a-backer
Top 5 Magento Secure Coding Best Practices
Rails Best Practices
Making Magento flying like a rocket! (A set of valuable tips for developers)
Angular2 & ngrx/store: Game of States
A Peek At The Future: Going Beyond JavaServer Faces 2.0 With RichFaces 4
Take Data Validation Seriously - Paul Milham, WildWorks
Crossing platforms with JavaScript & React
Future of Web Apps: Google Gears
Mastering Oracle ADF Bindings
Basics of AngularJS
Take Data Validation Seriously - Paul Milham, WildWorks
Unit testing after Zend Framework 1.8
Practical Object Oriented Models In Sql
Owl: The New Odoo UI Framework
Evan Schultz - Angular Camp - ng2-redux
Ad

Viewers also liked (20)

PDF
Batch Processing - A&BP CC
PDF
Spring batch-lightning-talk
KEY
Active Record Validations, Season 1
KEY
Getting started with Rails (2), Season 2
PDF
Asset Pipeline in Ruby on Rails
PPT
Spring Batch Introduction
PDF
Spring Day | Behind the Scenes at Spring Batch | Dave Syer
PPS
Spring Batch
PDF
Spring batch overivew
PPTX
Spring batch
PPTX
Spring batch
PPTX
Parallel batch processing with spring batch slideshare
PDF
Spring Batch - Lessons Learned out of a real life banking system.
KEY
Spring Batch Behind the Scenes
PPT
Spring Batch 2.0
PDF
Spring Batch - Lessons Learned out of a real life banking system.
PPTX
Spring batch
KEY
S2GX 2012 - Introduction to Spring Integration and Spring Batch
PDF
Spring Batch Performance Tuning
PPTX
Spring batch introduction
Batch Processing - A&BP CC
Spring batch-lightning-talk
Active Record Validations, Season 1
Getting started with Rails (2), Season 2
Asset Pipeline in Ruby on Rails
Spring Batch Introduction
Spring Day | Behind the Scenes at Spring Batch | Dave Syer
Spring Batch
Spring batch overivew
Spring batch
Spring batch
Parallel batch processing with spring batch slideshare
Spring Batch - Lessons Learned out of a real life banking system.
Spring Batch Behind the Scenes
Spring Batch 2.0
Spring Batch - Lessons Learned out of a real life banking system.
Spring batch
S2GX 2012 - Introduction to Spring Integration and Spring Batch
Spring Batch Performance Tuning
Spring batch introduction
Ad

Similar to Spring batch (16)

PPTX
Spring Batch
PDF
Spring Batch in Code - simple DB to DB batch applicaiton
PDF
知っておきたいSpring Batch Tips
PDF
Gain Proficiency in Batch Processing with Spring Batch
PPTX
Spring & SpringBatch EN
PPTX
Spring batch for large enterprises operations
DOCX
springn batch tutorial
PPTX
Mule batch
PPTX
Mule batch processing
PDF
Spring Batch Workshop
PDF
Spring Batch Workshop (advanced)
PPTX
Spring batch
PPTX
M batching
PDF
Batch Applications for the Java Platform
DOCX
MVest Spring Job Execution
PDF
Design & Develop Batch Applications in Java/JEE
Spring Batch
Spring Batch in Code - simple DB to DB batch applicaiton
知っておきたいSpring Batch Tips
Gain Proficiency in Batch Processing with Spring Batch
Spring & SpringBatch EN
Spring batch for large enterprises operations
springn batch tutorial
Mule batch
Mule batch processing
Spring Batch Workshop
Spring Batch Workshop (advanced)
Spring batch
M batching
Batch Applications for the Java Platform
MVest Spring Job Execution
Design & Develop Batch Applications in Java/JEE

Spring batch

  • 2. Domain • Benefit Management Application – Ledger information
  • 3. Goal • Input CSV • The header  System ID,Account ID,Plan Number,Payee ID,Check Type,Check Date,Transaction Create Date,Check Number,Benefit Type,Pay Code,Pay Source 1,Pay Source 2,Pay Source 3,Pay Source 4,Pay Source 5,Pay Source 6,Pay Source 7,Pay Source 8,Pay Source 9,Deduction 1,Deduction 2,Deduction 3,Deduction 4,Deduction 5,Deduction 6,Deduction 7,Deduction 8,Deduction 9,Deduction 10,Payable ID,Customer ID,Category of Distribution,Customer Last Name,Customer First Name,Customer Middle Initial,… etc…
  • 4. Output • 600+ bytes to send to Paying Agent • 'payCode' => '%-1.1s', • 'paySource5' => '%011d', • 'taxWithholdingElection' => '%-1.1s', • 'taxableMaritalStatusElectionCode' => '%-1.1s', • 'deduction10' => '%011d', • 'systemID' => '%-1.1s', • 'paySource1' => '%011d', • 'checkType' => '%-1.1s', • 'taxableAllowanceElection' => '%-2.2s', • 'financialInstitutionCity' => '%-16.16s', • 'checkCity' => '%-16.16s', • 'paySource9' => '%011d', • 'planNumber' => '%-6.6s', • 'payeeDateofDeath' => '%-8.8s', • 'aCHRoutingNumber' => '%-9.9s', • 'check3rdStreetAddress' => '%-32.32s', • 'deduction1' => '%011d', • 'transactionCreateDate' => '%-8.8s', • 'deduction2' => '%011d', • 'deduction5' => '%011d', • 'checkNumber' => '%-10.10s', • 'checkDate' => '%-8.8s', • 'financialInstitutionPostalCode' => '%-9.9s', • 'deduction8' => '%011d', • 'categoryofDistribution' => '%-2.2s', • 'customerFirstName' => '%-12.12s', • 'check1stStreetAddress' => '%-32.32s',
  • 5. Tools • Spring Source Tools IDE /Eclipse • Apache Maven • Perl • Bash  Cygwin (Windows) • Spring Batch legacy code that currently supports 1.6 spec but needs to upgrade to 1.9 spec
  • 6. Spring Batch Project • Start with the simplest hello-world project • Build more complexity on top
  • 7. Spring Batch Application Context • <?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.5.xsd"> • <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" /> • <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"> • <property name="transactionManager" ref="transactionManager"/> • </bean> • <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> • <property name="jobRepository" ref="jobRepository" /> • </bean> • • <!-- • <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/> • --> • </beans>
  • 8. Maven POM• <name>Spring Batch Hello World</name> • <properties> • <spring.version>2.5.4</spring.version> • <spring-batch.version>2.0.3.RELEASE</spring-batch.version> • </properties> • <dependencies> • <dependency> • <groupId>org.springframework.batch</groupId> • <artifactId>spring-batch-core</artifactId> • <version>${spring-batch.version}</version> • </dependency> • <dependency> • <groupId>org.springframework</groupId> • <artifactId>spring-aop</artifactId> • <version>${spring.version}</version> • </dependency> • <dependency> • <groupId>org.springframework</groupId> • <artifactId>spring-tx</artifactId> • <version>${spring.version}</version> • </dependency> • <dependency> • <groupId>org.springframework</groupId> • <artifactId>spring-core</artifactId> • <version>${spring.version}</version> • </dependency> • <dependency> • <groupId>org.springframework</groupId> • <artifactId>spring-beans</artifactId> • <version>${spring.version}</version> • </dependency> • <dependency> • <groupId>org.springframework</groupId> • <artifactId>spring-context</artifactId> • <version>${spring.version}</version> • </dependency> • <dependency> • <groupId>org.springframework</groupId> • <artifactId>org.springframework.test</artifactId> • <version>3.0.4.RELEASE</version> • </dependency>
  • 11. Tokenizer • <!-- Tokenizer - Converts a delimited string into a Set of Fields --> • <bean name="defaultTokenizer" class="org.springframework.batch.item.file.tr ansform.DelimitedLineTokenizer"/>
  • 12. Field Set Mapper • <bean name="pbtItemFieldSetMapper" class="aspire.mapper.PBTItemFieldSetMapper " />
  • 13. Line Mapper • <bean name="pbtItemLineMapper" class="org.springframework.batch.item.file.m apping.DefaultLineMapper"> • <property name="lineTokenizer" ref="defaultTokenizer"/> • <property name="fieldSetMapper" ref="pbtItemFieldSetMapper"/> • </bean>
  • 14. Flat File Item Reader • <bean name="pbtItemReader" class="org.springframework.batch.item.file.FlatFileIte mReader"> • <property name="lineMapper" ref="pbtItemLineMapper"/> • <!-- use spring integrations for the following, but for now filename is hard coded --> • <property name="resource" value="classpath:pbt- input-4.txt"/> • </bean>
  • 16. Item Processor • <bean name="pbtItemProcessor" class="aspire.processor.PBTItemProcessor"> • </bean>
  • 17. Item Writer • <bean id="pbtItemWriter" • class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step"> • <property name="resource" value="file:target/output-pbt-4.det"/> • <property name="lineAggregator"> • <bean • class="org.springframework.batch.item.file.transform.FormatterLineAggregator"> • <property name="fieldExtractor"> • <bean • class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor"> • <property name="names" • value="systemID,accountID,planNumber,payeeID,checkType,checkDate,transactionCreateDate,checkNumber,benefitType,payCode,paySource1,paySource2,paySource3,paySource4,paySo urce5,paySource6,paySource7,paySource8,paySource9,deduction1,deduction2,deduction3,deduction4,deduction5,deduction6,deduction7,deduction8, ……,financialInstitutionfinancialInstitutionAccountNumber,financialInstitutionAccountType,financialInstitutionStreet1,financialInstitutionCity,financialInstitutionStateCode,financialInstitutio nProvince,financialInstitutionPostalCode,financialInstitutionIRSCountryCode,taxWithholdingElection,taxableMaritalStatusElectionCode,taxableAllowanceElection" /> • </bean> • </property> • <!-- • %[argument_index$][flags][width][.precision]conversion • --> • <property name="format" value="%-1.1s%-5.5s%-6.6s%-9.9s%-1.1s%-8.8s%-8.8s%-10.10s%-3.3s%-1.1s%011d%011d%011d%011d%011d%011d%011d%011d%011d%011d%011d%011d %011d%011d%011d%011d%011d%011d%011d%-10.10s%-30.30s%-2.2s%-20.20s%-12.12s%-1.1s%-8.8s%-8.8s%-32.32s%-32.32s%-32.32s%-16.16s%-2.2s%-9.9s%-2.2s%-16.16s%-1.1s%- 9.9s%-17.17s%-32.32s%-32.32s%-2.2s%-32.32s%-16.16s%-2.2s%-16.16s%-9.9s%-2.2s%-1.1s%-1.1s%-2.2s" /> • </bean> • </property> • <property name="footerCallback" ref="pbtfootercallback" /> • </bean> • <bean id="pbtfootercallback" class="aspire.core.PBTFooterCallback"> • <property name="delegate" ref="pbtItemWriter"></property> • </bean>
  • 19. Batch Job • <batch:job id="pbgcPBTIncomingJob"> • <!-- batch:step id="step1" next="step2"> • <batch:tasklet ref="helloWorldTasklet" /> • </batch:step--> • <batch:step id="step4"> • <batch:tasklet> • <batch:chunk reader="pbtItemReader" processor="pbtItemProcessor" writer="pbtfootercallback" commit-interval="1"> • <batch:streams> • <batch:stream ref="pbtItemReader" /> • <batch:stream ref="pbtItemWriter"/> • </batch:streams> • </batch:chunk> • <batch:listeners> • <batch:listener ref="pbtfootercallback"/> • </batch:listeners> • </batch:tasklet> • </batch:step> • </batch:job>
  • 22. How to test/run • Command line – mvn exec…. – jUnit test case
  • 23. Junit Test Case • import org.springframework.batch.core.repository.JobRestartException; • 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; • import org.springframework.util.StopWatch; • @ContextConfiguration("classpath:simpleJob.xml") • @RunWith(SpringJUnit4ClassRunner.class) • public class HelloTestCase { • private static Log logger = LogFactory.getLog(HelloTestCase.class); • @Autowired • @Qualifier("pbgcPBTIncomingJob") • private Job job; • @Autowired • private JobLauncher jobLauncher; • @Test • public void test() { • //fail("Not yet implemented"); • JobExecution execution = null; • try { • logger.debug("hello world"); • logger.debug("Job name: " + job.getName()); • execution = jobLauncher.run(job, new JobParameters()); • //execution = jobLauncher.run(job, • //new JobParametersBuilder() • //.addString("inputFile", "ack-test-new.xlsx") • //.addString("outputFile", "1002").toJobParameters()); • } catch (JobExecutionAlreadyRunningException e)
  • 25. Sample output… • Abbreviated Input • 12:47:43,019 DEBUG main PBTItemFieldSetMapper:19 - [1, AGENCY1, ….., …….., 61, RA3, R, 45677, 7, 6, 5, 4, 3, 2, 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,…….., 7, SMITH, JOE, F, 123456, *, 742 ANY STREET,, *, *, ANY CITY, OH, ……, US, *, A, ………….., *, *, *, *, *, *, *, *, *, N, *, 0] • Abbreviated Output • 12:47:43,019 DEBUG main PBTItemProcessor:21 - after processing [SystemID = 1 AccountID = AGENCY1 PlanNumber ……… BenefitType = RA3 PayCode = R PaySource1 = 45677 PaySource2 = 7 PaySource3 = 6 PaySource4 = 5 PaySource5 = 4 PaySource6 = 3 PaySource7 = 2 PaySource8 = 1 PaySource9 = 0 Deduction1 = 10 Deduction2 = 9 Deduction3 = 8 Deduction4 = 7 Deduction5 = 6 Deduction6 = 5 Deduction7 = 4 Deduction8 = 3 Deduction9 = 2 Deduction10 = 1 ……….Check2ndStreetAddress = * Check3rdStreetAddress = ……CheckIRSCountryCode = US CheckProvince = * PaymentDestinationType = A ………… FinancialInstitutionPostalCode = * FinancialInstitutionIRSCountryCode = * TaxWithholdingElection = N TaxableMaritalStatusElectionCode = * TaxableAllowanceElection = 0] • 12:47:43,019 DEBUG main PBTFooterCallback:44 - write...callback... • 12:47:43,019 DEBUG main PBTFooterCallback:65 - 8 • …. • 12:47:43,035 DEBUG main PBTFooterCallback:31 - FooterCallback.... • 12:47:43,035 INFO main SimpleJobLauncher:111 - Job: [FlowJob: [name=pbgcPBTIncomingJob]] completed with the following parameters: [{}] and the following status: [COMPLETED]
  • 26. Counting the bytes • Fires up cygwin • user@PC123456> /cygdrive/c/dev/spring- batch/batch-dir/Spring-Batch-Hello-Wor ld/target – $ head -n1 output-pbt-4.det | wc -c – 669
  • 27. Be aware of newlines char • Bash/gnu wc utility • userID@PC123456 /cygdrive/c/dev/spring- batch/batch-dir/Spring-Batch-Hello-World/target – $ head -n1 output-pbt-4.det | perl -ne 'print substr($_,667,2);' | od -c – 0000000 r n – 0000002 • So technically we only 667 bytes instead of 669 as reported by wc