SlideShare a Scribd company logo
1 of 27
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

What's hot

Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Rabble .
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09Michelangelo van Dam
 
Top 5 Magento Secure Coding Best Practices
Top 5 Magento Secure Coding Best PracticesTop 5 Magento Secure Coding Best Practices
Top 5 Magento Secure Coding Best PracticesOleksandr Zarichnyi
 
Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)Ivan Chepurnyi
 
Angular2 & ngrx/store: Game of States
Angular2 & ngrx/store: Game of StatesAngular2 & ngrx/store: Game of States
Angular2 & ngrx/store: Game of StatesOren Farhi
 
A Peek At The Future: Going Beyond JavaServer Faces 2.0 With RichFaces 4
A Peek At The Future: Going Beyond JavaServer Faces 2.0 With RichFaces 4A Peek At The Future: Going Beyond JavaServer Faces 2.0 With RichFaces 4
A Peek At The Future: Going Beyond JavaServer Faces 2.0 With RichFaces 4balunasj
 
Take Data Validation Seriously - Paul Milham, WildWorks
Take Data Validation Seriously - Paul Milham, WildWorksTake Data Validation Seriously - Paul Milham, WildWorks
Take Data Validation Seriously - Paul Milham, WildWorksNodejsFoundation
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Robert DeLuca
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gearsdion
 
Mastering Oracle ADF Bindings
Mastering Oracle ADF BindingsMastering Oracle ADF Bindings
Mastering Oracle ADF BindingsEuegene Fedorenko
 
Take Data Validation Seriously - Paul Milham, WildWorks
Take Data Validation Seriously - Paul Milham, WildWorksTake Data Validation Seriously - Paul Milham, WildWorks
Take Data Validation Seriously - Paul Milham, WildWorksNodejsFoundation
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Michelangelo van Dam
 
Owl: The New Odoo UI Framework
Owl: The New Odoo UI FrameworkOwl: The New Odoo UI Framework
Owl: The New Odoo UI FrameworkOdoo
 
Evan Schultz - Angular Camp - ng2-redux
Evan Schultz - Angular Camp - ng2-reduxEvan Schultz - Angular Camp - ng2-redux
Evan Schultz - Angular Camp - ng2-reduxEvan Schultz
 

What's hot (20)

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

Viewers also liked

Active Record Validations, Season 1
Active Record Validations, Season 1Active Record Validations, Season 1
Active Record Validations, Season 1RORLAB
 
Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2RORLAB
 
Asset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on RailsAsset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on RailsRORLAB
 
Spring Day | Behind the Scenes at Spring Batch | Dave Syer
Spring Day | Behind the Scenes at Spring Batch | Dave SyerSpring Day | Behind the Scenes at Spring Batch | Dave Syer
Spring Day | Behind the Scenes at Spring Batch | Dave SyerJAX London
 
Parallel batch processing with spring batch slideshare
Parallel batch processing with spring batch   slideshareParallel batch processing with spring batch   slideshare
Parallel batch processing with spring batch slideshareMorten Andersen-Gott
 
Spring Batch - Lessons Learned out of a real life banking system.
Spring Batch - Lessons Learned out of a real life banking system.Spring Batch - Lessons Learned out of a real life banking system.
Spring Batch - Lessons Learned out of a real life banking system.Raffael Schmid
 
Spring Batch Behind the Scenes
Spring Batch Behind the ScenesSpring Batch Behind the Scenes
Spring Batch Behind the ScenesJoshua Long
 
Spring Batch - Lessons Learned out of a real life banking system.
Spring Batch - Lessons Learned out of a real life banking system.Spring Batch - Lessons Learned out of a real life banking system.
Spring Batch - Lessons Learned out of a real life banking system.Raffael Schmid
 
S2GX 2012 - Introduction to Spring Integration and Spring Batch
S2GX 2012 - Introduction to Spring Integration and Spring BatchS2GX 2012 - Introduction to Spring Integration and Spring Batch
S2GX 2012 - Introduction to Spring Integration and Spring BatchGunnar Hillert
 
Spring Batch Performance Tuning
Spring Batch Performance TuningSpring Batch Performance Tuning
Spring Batch Performance TuningGunnar Hillert
 
Spring batch introduction
Spring batch introductionSpring batch introduction
Spring batch introductionAlex Fernandez
 

Viewers also liked (20)

Batch Processing - A&BP CC
Batch Processing - A&BP CCBatch Processing - A&BP CC
Batch Processing - A&BP CC
 
Spring batch-lightning-talk
Spring batch-lightning-talkSpring batch-lightning-talk
Spring batch-lightning-talk
 
Active Record Validations, Season 1
Active Record Validations, Season 1Active Record Validations, Season 1
Active Record Validations, Season 1
 
Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2
 
Asset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on RailsAsset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on Rails
 
Spring Batch Introduction
Spring Batch IntroductionSpring Batch Introduction
Spring Batch Introduction
 
Spring Day | Behind the Scenes at Spring Batch | Dave Syer
Spring Day | Behind the Scenes at Spring Batch | Dave SyerSpring Day | Behind the Scenes at Spring Batch | Dave Syer
Spring Day | Behind the Scenes at Spring Batch | Dave Syer
 
Spring Batch
Spring BatchSpring Batch
Spring Batch
 
Spring batch overivew
Spring batch overivewSpring batch overivew
Spring batch overivew
 
Spring batch
Spring batchSpring batch
Spring batch
 
Spring batch
Spring batch Spring batch
Spring batch
 
Parallel batch processing with spring batch slideshare
Parallel batch processing with spring batch   slideshareParallel batch processing with spring batch   slideshare
Parallel batch processing with spring batch slideshare
 
Spring Batch - Lessons Learned out of a real life banking system.
Spring Batch - Lessons Learned out of a real life banking system.Spring Batch - Lessons Learned out of a real life banking system.
Spring Batch - Lessons Learned out of a real life banking system.
 
Spring Batch Behind the Scenes
Spring Batch Behind the ScenesSpring Batch Behind the Scenes
Spring Batch Behind the Scenes
 
Spring Batch 2.0
Spring Batch 2.0Spring Batch 2.0
Spring Batch 2.0
 
Spring Batch - Lessons Learned out of a real life banking system.
Spring Batch - Lessons Learned out of a real life banking system.Spring Batch - Lessons Learned out of a real life banking system.
Spring Batch - Lessons Learned out of a real life banking system.
 
Spring batch
Spring batchSpring batch
Spring batch
 
S2GX 2012 - Introduction to Spring Integration and Spring Batch
S2GX 2012 - Introduction to Spring Integration and Spring BatchS2GX 2012 - Introduction to Spring Integration and Spring Batch
S2GX 2012 - Introduction to Spring Integration and Spring Batch
 
Spring Batch Performance Tuning
Spring Batch Performance TuningSpring Batch Performance Tuning
Spring Batch Performance Tuning
 
Spring batch introduction
Spring batch introductionSpring batch introduction
Spring batch introduction
 

Similar to Spring batch

Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
Harness SharePoint and jQuery to Make Dynamic Displays and Applications
 Harness SharePoint and jQuery to Make Dynamic Displays and Applications Harness SharePoint and jQuery to Make Dynamic Displays and Applications
Harness SharePoint and jQuery to Make Dynamic Displays and ApplicationsInnoTech
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
The Future of Plugin Dev
The Future of Plugin DevThe Future of Plugin Dev
The Future of Plugin DevBrandon Kelly
 
An ADF Special Report
An ADF Special Report An ADF Special Report
An ADF Special Report Luc Bors
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...
Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...
Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...Chester Chen
 
Simple blog wall creation on Java
Simple blog wall creation on JavaSimple blog wall creation on Java
Simple blog wall creation on JavaMax Titov
 
Salesforce Batch processing - Atlanta SFUG
Salesforce Batch processing - Atlanta SFUGSalesforce Batch processing - Atlanta SFUG
Salesforce Batch processing - Atlanta SFUGvraopolisetti
 
E2 appspresso hands on lab
E2 appspresso hands on labE2 appspresso hands on lab
E2 appspresso hands on labNAVER D2
 
E3 appspresso hands on lab
E3 appspresso hands on labE3 appspresso hands on lab
E3 appspresso hands on labNAVER D2
 
Unobtrusive JavaScript
Unobtrusive JavaScriptUnobtrusive JavaScript
Unobtrusive JavaScriptVitaly Baum
 
Spring Batch in Code - simple DB to DB batch applicaiton
Spring Batch in Code - simple DB to DB batch applicaitonSpring Batch in Code - simple DB to DB batch applicaiton
Spring Batch in Code - simple DB to DB batch applicaitontomi vanek
 

Similar to Spring batch (20)

Spring data requery
Spring data requerySpring data requery
Spring data requery
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Harness SharePoint and jQuery to Make Dynamic Displays and Applications
 Harness SharePoint and jQuery to Make Dynamic Displays and Applications Harness SharePoint and jQuery to Make Dynamic Displays and Applications
Harness SharePoint and jQuery to Make Dynamic Displays and Applications
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
实战Ecos
实战Ecos实战Ecos
实战Ecos
 
Reporting solutions for ADF Applications
Reporting solutions for ADF ApplicationsReporting solutions for ADF Applications
Reporting solutions for ADF Applications
 
The Future of Plugin Dev
The Future of Plugin DevThe Future of Plugin Dev
The Future of Plugin Dev
 
An ADF Special Report
An ADF Special Report An ADF Special Report
An ADF Special Report
 
Story ofcorespring infodeck
Story ofcorespring infodeckStory ofcorespring infodeck
Story ofcorespring infodeck
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...
Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...
Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...
 
Simple blog wall creation on Java
Simple blog wall creation on JavaSimple blog wall creation on Java
Simple blog wall creation on Java
 
Angularjs
AngularjsAngularjs
Angularjs
 
Salesforce Batch processing - Atlanta SFUG
Salesforce Batch processing - Atlanta SFUGSalesforce Batch processing - Atlanta SFUG
Salesforce Batch processing - Atlanta SFUG
 
ApacheCon 2005
ApacheCon 2005ApacheCon 2005
ApacheCon 2005
 
E2 appspresso hands on lab
E2 appspresso hands on labE2 appspresso hands on lab
E2 appspresso hands on lab
 
E3 appspresso hands on lab
E3 appspresso hands on labE3 appspresso hands on lab
E3 appspresso hands on lab
 
Unobtrusive JavaScript
Unobtrusive JavaScriptUnobtrusive JavaScript
Unobtrusive JavaScript
 
Spring Batch in Code - simple DB to DB batch applicaiton
Spring Batch in Code - simple DB to DB batch applicaitonSpring Batch in Code - simple DB to DB batch applicaiton
Spring Batch in Code - simple DB to DB batch applicaiton
 
Introduction to Angular JS
Introduction to Angular JSIntroduction to Angular JS
Introduction to Angular JS
 

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