├── .gitignore ├── README.md ├── atomic-processing-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── atomic-processing-job.xml │ │ ├── contacts-nok.txt │ │ ├── contacts-ok.txt │ │ └── create-tables.sql │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── AtomicProcessingJobTest.java │ └── resources │ └── logback-test.xml ├── atomic-processing-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── atomic-processing-job.xml │ │ ├── contacts-nok.txt │ │ ├── contacts-ok.txt │ │ └── create-tables.sql │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── AtomicProcessingJobTest.java │ └── resources │ └── logback-test.xml ├── chunk-processing-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── StringItemProcessor.java │ │ │ ├── StringItemReader.java │ │ │ └── StringItemWriter.java │ └── resources │ │ └── chunk-processing-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── ChunkProcessingJobTest.java │ └── resources │ └── logback-test.xml ├── chunk-processing-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── StringItemProcessor.java │ │ │ ├── StringItemReader.java │ │ │ └── StringItemWriter.java │ └── resources │ │ └── chunk-processing-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── ChunkProcessingJobTest.java │ └── resources │ └── logback-test.xml ├── complex-flow-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ ├── DigestListener.java │ │ │ ├── DigestTasklet.java │ │ │ ├── JdbcContactItemWriter.java │ │ │ ├── SkipsListener.java │ │ │ └── TrackingService.java │ └── resources │ │ ├── complex-flow-job.xml │ │ ├── contacts-correct-file.txt │ │ ├── contacts-correct-file.txt.md5 │ │ ├── contacts-incorrect-file.txt │ │ ├── contacts-incorrect-file.txt.md5 │ │ ├── contacts-with-skips.txt │ │ ├── contacts-with-skips.txt.md5 │ │ └── create-tables.sql │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── ComplexFlowJobTest.java │ └── resources │ └── logback-test.xml ├── complex-flow-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ ├── DigestListener.java │ │ │ ├── DigestTasklet.java │ │ │ ├── JdbcContactItemWriter.java │ │ │ ├── SkipsListener.java │ │ │ └── TrackingService.java │ └── resources │ │ ├── complex-flow-job.xml │ │ ├── contacts-correct-file.txt │ │ ├── contacts-correct-file.txt.md5 │ │ ├── contacts-incorrect-file.txt │ │ ├── contacts-incorrect-file.txt.md5 │ │ ├── contacts-with-skips.txt │ │ ├── contacts-with-skips.txt.md5 │ │ └── create-tables.sql │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── ComplexFlowJobTest.java │ └── resources │ └── logback-test.xml ├── database-reading-partitioning-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Product.java │ │ │ ├── ProductCategoryPartitioner.java │ │ │ └── ProductRowMapper.java │ └── resources │ │ ├── create-tables.sql │ │ └── database-reading-partitioning-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── DatabaseReadingPartitioningJobTest.java │ └── resources │ └── logback-test.xml ├── database-reading-partitioning-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Product.java │ │ │ ├── ProductCategoryPartitioner.java │ │ │ └── ProductRowMapper.java │ └── resources │ │ ├── create-tables.sql │ │ └── database-reading-partitioning-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── DatabaseReadingPartitioningJobTest.java │ └── resources │ └── logback-test.xml ├── dynamic-job-parameters-solution ├── input │ ├── contacts-01.txt │ └── contacts-02.txt ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── create-tables.sql │ │ └── dynamic-job-parameters-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── DynamicJobParametersJobTest.java │ └── resources │ └── logback-test.xml ├── dynamic-job-parameters-start ├── input │ ├── contacts-01.txt │ └── contacts-02.txt ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── create-tables.sql │ │ └── dynamic-job-parameters-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── DynamicJobParametersJobTest.java │ └── resources │ └── logback-test.xml ├── execution-metadata-solution ├── input │ ├── contacts-01.txt │ └── contacts-02.txt ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ ├── resources │ │ ├── META-INF │ │ │ └── spring │ │ │ │ └── batch │ │ │ │ └── jobs │ │ │ │ └── flat-file-reading-job.xml │ │ ├── batch-default.properties │ │ ├── create-tables.sql │ │ └── drop-tables.sql │ └── webapp │ │ └── WEB-INF │ │ └── web.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ ├── ExecutionMetadataTest.java │ │ ├── H2Server.java │ │ ├── JettyServer.java │ │ └── LaunchExecutionMetadata.java │ └── resources │ └── logback-test.xml ├── execution-metadata-start ├── input │ ├── contacts-01.txt │ └── contacts-02.txt ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ ├── resources │ │ ├── META-INF │ │ │ └── spring │ │ │ │ └── batch │ │ │ │ └── jobs │ │ │ │ └── flat-file-reading-job.xml │ │ ├── batch-default.properties │ │ ├── create-tables.sql │ │ └── drop-tables.sql │ └── webapp │ │ └── WEB-INF │ │ └── web.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ ├── ExecutionMetadataTest.java │ │ └── LaunchExecutionMetadata.java │ └── resources │ └── logback-test.xml ├── file-dropping-launching-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ ├── JdbcContactItemWriter.java │ │ │ └── integration │ │ │ └── FileContactJobLauncher.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ ├── file-dropping-launching-job.xml │ │ └── integration-file.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ ├── EmbeddedFtpServer.java │ │ ├── FileDroppingLaunchingJobTest.java │ │ ├── StartClient.java │ │ ├── StartDbConsole.java │ │ └── StartFtpServer.java │ └── resources │ └── logback-test.xml ├── file-dropping-launching-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ ├── JdbcContactItemWriter.java │ │ │ └── integration │ │ │ └── FileContactJobLauncher.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ ├── file-dropping-launching-job.xml │ │ └── integration-file.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ ├── EmbeddedFtpServer.java │ │ ├── StartClient.java │ │ ├── StartDbConsole.java │ │ └── StartFtpServer.java │ └── resources │ └── logback-test.xml ├── file-reading-partitioning-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── create-tables.sql │ │ ├── file-reading-partitioning-job.xml │ │ └── input │ │ ├── contacts-01.txt │ │ ├── contacts-02.txt │ │ ├── contacts-03.txt │ │ └── contacts-04.txt │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── FileReadingPartitioningJobTest.java │ └── resources │ └── logback-test.xml ├── file-reading-partitioning-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── create-tables.sql │ │ ├── file-reading-partitioning-job.xml │ │ └── input │ │ ├── contacts-01.txt │ │ ├── contacts-02.txt │ │ ├── contacts-03.txt │ │ └── contacts-04.txt │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── FileReadingPartitioningJobTest.java │ └── resources │ └── logback-test.xml ├── flat-file-reading-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ └── flat-file-reading-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── FlatFileReadingJobTest.java │ └── resources │ └── logback-test.xml ├── flat-file-reading-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ └── flat-file-reading-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── FlatFileReadingJobTest.java │ └── resources │ └── logback-test.xml ├── hello-world-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ └── HelloWorldTasklet.java │ └── resources │ │ └── hello-world-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── HelloWorldJobTest.java │ └── resources │ └── logback-test.xml ├── hello-world-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ └── HelloWorldTasklet.java │ └── resources │ │ └── hello-world-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── HelloWorldJobTest.java │ └── resources │ └── logback-test.xml ├── item-enrichment-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ ├── JdbcContactItemWriter.java │ │ │ └── SsnWebServiceItemProcessor.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ └── item-enrichment-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ ├── ItemEnrichmentJobTest.java │ │ └── WebServiceHandler.java │ └── resources │ └── logback-test.xml ├── item-enrichment-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ ├── JdbcContactItemWriter.java │ │ │ └── SsnWebServiceItemProcessor.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ └── item-enrichment-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ ├── ItemEnrichmentJobTest.java │ │ └── WebServiceHandler.java │ └── resources │ └── logback-test.xml ├── item-processor-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ ├── ContactItemProcessor.java │ │ │ ├── JdbcRegistrationConfirmationItemWriter.java │ │ │ ├── RegistrationConfirmation.java │ │ │ └── RegistrationService.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ └── item-processor-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── ItemProcessorJobTest.java │ └── resources │ └── logback-test.xml ├── item-processor-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ ├── ContactItemProcessor.java │ │ │ ├── JdbcRegistrationConfirmationItemWriter.java │ │ │ ├── RegistrationConfirmation.java │ │ │ └── RegistrationService.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ └── item-processor-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── ItemProcessorJobTest.java │ └── resources │ └── logback-test.xml ├── jdbc-paging-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ └── ContactRowMapper.java │ └── resources │ │ ├── create-tables.sql │ │ ├── insert-data.sql │ │ └── jdbc-paging-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── JdbcPagingJobTest.java │ └── resources │ └── logback-test.xml ├── jdbc-paging-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ └── ContactRowMapper.java │ └── resources │ │ ├── create-tables.sql │ │ ├── insert-data.sql │ │ └── jdbc-paging-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── JdbcPagingJobTest.java │ └── resources │ └── logback-test.xml ├── logging-skipped-items-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ ├── JdbcContactItemWriter.java │ │ │ └── Slf4jSkipListener.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ └── logging-skipped-items-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── LoggingSkippedItemsTest.java │ └── resources │ └── logback-test.xml ├── logging-skipped-items-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ ├── JdbcContactItemWriter.java │ │ │ └── Slf4jSkipListener.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ └── logging-skipped-items-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── LoggingSkippedItemsTest.java │ └── resources │ └── logback-test.xml ├── pom.xml ├── presentation ├── atomic-processing.tex ├── chunk-processing.tex ├── complex-flow.tex ├── database-reading-partitioning.tex ├── dynamic-job-parameters.tex ├── execution-metadata.tex ├── figures │ ├── after-cc.png │ ├── before-cc.png │ ├── code-completion.png │ ├── configure-content.png │ ├── content.png │ ├── enable-task-tags.png │ ├── input-files-partitioning.pdf │ ├── input-files-partitioning.svg │ ├── input-files-serial.pdf │ ├── input-files-serial.svg │ ├── jobinstance.pdf │ ├── jobinstance.svg │ ├── logo_zenika.png │ ├── spring-integration-ftp-poller.pdf │ ├── spring-integration-ftp-poller.svg │ └── tasks.png ├── file-dropping-launching.tex ├── file-reading-partitioning.tex ├── flat-file-reading.tex ├── hello-world.tex ├── ide-set-up.tex ├── ide-spring-support.tex ├── item-enrichment.tex ├── item-processor.tex ├── jdbc-paging.tex ├── logging-skipped-items.tex ├── overview-advanced.tex ├── overview.tex ├── scheduling.tex ├── skip.tex ├── spring-batch-overview.tex ├── spring-batch-workshop-advanced.pdf ├── spring-batch-workshop-advanced.tex ├── spring-batch-workshop.pdf ├── spring-batch-workshop.tex └── xml-file-reading.tex ├── scheduling-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ ├── ImportLauncher.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ └── scheduling-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── SchedulingTest.java │ └── resources │ └── logback-test.xml ├── scheduling-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ ├── ImportLauncher.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ └── scheduling-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── SchedulingTest.java │ └── resources │ └── logback-test.xml ├── skip-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ └── skip-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── SkipJobTest.java │ └── resources │ └── logback-test.xml ├── skip-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── contacts.txt │ │ ├── create-tables.sql │ │ └── skip-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── SkipJobTest.java │ └── resources │ └── logback-test.xml ├── xml-file-reading-solution ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── zenika │ │ │ └── workshop │ │ │ └── springbatch │ │ │ ├── Contact.java │ │ │ ├── ContactFieldSetMapper.java │ │ │ └── JdbcContactItemWriter.java │ └── resources │ │ ├── contacts.xml │ │ ├── create-tables.sql │ │ └── xml-file-reading-job.xml │ └── test │ ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ └── XmlFileReadingJobTest.java │ └── resources │ └── logback-test.xml └── xml-file-reading-start ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── zenika │ │ └── workshop │ │ └── springbatch │ │ ├── Contact.java │ │ ├── ContactFieldSetMapper.java │ │ └── JdbcContactItemWriter.java └── resources │ ├── contacts.xml │ ├── create-tables.sql │ └── xml-file-reading-job.xml └── test ├── java └── com │ └── zenika │ └── workshop │ └── springbatch │ └── XmlFileReadingJobTest.java └── resources └── logback-test.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .classpath 3 | .springBeans 4 | **/target/* 5 | **/.settings/* 6 | .settings/* 7 | *.snm 8 | *.log 9 | *.tex~ 10 | *.*.backup 11 | *.aux 12 | *.bbl 13 | *.blg 14 | *.nav 15 | *.out 16 | *.toc 17 | *.vrb 18 | *.vrb~ 19 | *.iml 20 | 21 | -------------------------------------------------------------------------------- /atomic-processing-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | atomic-processing-solution 12 | 13 | 14 | -------------------------------------------------------------------------------- /atomic-processing-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /atomic-processing-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /atomic-processing-solution/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | jdbcTemplate.update( 32 | "insert into contact (firstname,lastname,birth) values (?,?,?)", 33 | item.getFirstname(),item.getLastname(),item.getBirth() 34 | ); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /atomic-processing-solution/src/main/resources/contacts-nok.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senecal,2010-03-04 6 | De-Anna,Raghunath,2010-03-04 7 | Susy,Hauerstock,2010-03-04 8 | Kiam,Whitehurst,2010-03-04 9 | Alecia,Van Holst,2010-03-04 10 | Hing,Senecal,2010-03-04 11 | De-Anna,Raghunath,2010-03-04 12 | Susy,Hauerstock,2010-03-04 13 | Kiam,Whitehurst,2010-03-04 14 | Alecia,Van Holst,2010-03-04 15 | Hing,Senecal,2010-03-04 16 | De-Anna,Raghunath,2010-03-04 17 | Susy,Hauerstock,2010-03-04 18 | Kiam,Whitehurst,2010-03-04 19 | Alecia,Van Holst,2010-03-04 20 | Hing,Senecal,2010-03-04 21 | De-Anna,Raghunath,2010-03-04 22 | Susy,Hauerstock,2010-03-04 23 | Kiam,Whitehurst,2010-03-04 24 | Alecia,Van Holst,2010-03-04 25 | Hing,Senecal,03/03/2010 -------------------------------------------------------------------------------- /atomic-processing-solution/src/main/resources/contacts-ok.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senecal,2010-03-04 6 | De-Anna,Raghunath,2010-03-04 7 | Susy,Hauerstock,2010-03-04 8 | Kiam,Whitehurst,2010-03-04 9 | Alecia,Van Holst,2010-03-04 10 | Hing,Senecal,2010-03-04 11 | De-Anna,Raghunath,2010-03-04 12 | Susy,Hauerstock,2010-03-04 13 | Kiam,Whitehurst,2010-03-04 14 | Alecia,Van Holst,2010-03-04 15 | Hing,Senecal,2010-03-04 16 | De-Anna,Raghunath,2010-03-04 17 | Susy,Hauerstock,2010-03-04 18 | Kiam,Whitehurst,2010-03-04 19 | Alecia,Van Holst,2010-03-04 20 | Hing,Senecal,2010-03-04 21 | De-Anna,Raghunath,2010-03-04 22 | Susy,Hauerstock,2010-03-04 23 | Kiam,Whitehurst,2010-03-04 24 | Alecia,Van Holst,2010-03-04 25 | Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /atomic-processing-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int auto_increment primary key, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | -------------------------------------------------------------------------------- /atomic-processing-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /atomic-processing-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | atomic-processing-start 12 | 13 | 14 | -------------------------------------------------------------------------------- /atomic-processing-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /atomic-processing-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /atomic-processing-start/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | jdbcTemplate.update( 32 | "insert into contact (firstname,lastname,birth) values (?,?,?)", 33 | item.getFirstname(),item.getLastname(),item.getBirth() 34 | ); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /atomic-processing-start/src/main/resources/contacts-nok.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senecal,2010-03-04 6 | De-Anna,Raghunath,2010-03-04 7 | Susy,Hauerstock,2010-03-04 8 | Kiam,Whitehurst,2010-03-04 9 | Alecia,Van Holst,2010-03-04 10 | Hing,Senecal,2010-03-04 11 | De-Anna,Raghunath,2010-03-04 12 | Susy,Hauerstock,2010-03-04 13 | Kiam,Whitehurst,2010-03-04 14 | Alecia,Van Holst,2010-03-04 15 | Hing,Senecal,2010-03-04 16 | De-Anna,Raghunath,2010-03-04 17 | Susy,Hauerstock,2010-03-04 18 | Kiam,Whitehurst,2010-03-04 19 | Alecia,Van Holst,2010-03-04 20 | Hing,Senecal,2010-03-04 21 | De-Anna,Raghunath,2010-03-04 22 | Susy,Hauerstock,2010-03-04 23 | Kiam,Whitehurst,2010-03-04 24 | Alecia,Van Holst,2010-03-04 25 | Hing,Senecal,03/03/2010 -------------------------------------------------------------------------------- /atomic-processing-start/src/main/resources/contacts-ok.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senecal,2010-03-04 6 | De-Anna,Raghunath,2010-03-04 7 | Susy,Hauerstock,2010-03-04 8 | Kiam,Whitehurst,2010-03-04 9 | Alecia,Van Holst,2010-03-04 10 | Hing,Senecal,2010-03-04 11 | De-Anna,Raghunath,2010-03-04 12 | Susy,Hauerstock,2010-03-04 13 | Kiam,Whitehurst,2010-03-04 14 | Alecia,Van Holst,2010-03-04 15 | Hing,Senecal,2010-03-04 16 | De-Anna,Raghunath,2010-03-04 17 | Susy,Hauerstock,2010-03-04 18 | Kiam,Whitehurst,2010-03-04 19 | Alecia,Van Holst,2010-03-04 20 | Hing,Senecal,2010-03-04 21 | De-Anna,Raghunath,2010-03-04 22 | Susy,Hauerstock,2010-03-04 23 | Kiam,Whitehurst,2010-03-04 24 | Alecia,Van Holst,2010-03-04 25 | Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /atomic-processing-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int auto_increment primary key, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | -------------------------------------------------------------------------------- /atomic-processing-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /chunk-processing-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | chunk-processing-solution 12 | 13 | 14 | -------------------------------------------------------------------------------- /chunk-processing-solution/src/main/java/com/zenika/workshop/springbatch/StringItemProcessor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.ItemProcessor; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class StringItemProcessor implements ItemProcessor { 13 | 14 | /* (non-Javadoc) 15 | * @see org.springframework.batch.item.ItemProcessor#process(java.lang.Object) 16 | */ 17 | @Override 18 | public String process(String item) throws Exception { 19 | return "*** "+item+" ***"; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /chunk-processing-solution/src/main/java/com/zenika/workshop/springbatch/StringItemReader.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | import org.springframework.batch.item.ItemReader; 11 | import org.springframework.batch.item.NonTransientResourceException; 12 | import org.springframework.batch.item.ParseException; 13 | import org.springframework.batch.item.UnexpectedInputException; 14 | 15 | /** 16 | * @author acogoluegnes 17 | * 18 | */ 19 | public class StringItemReader implements ItemReader { 20 | 21 | private List list; 22 | 23 | public StringItemReader() { 24 | this.list = new ArrayList(Arrays.asList("1","2","3","4","5","6","7")); 25 | } 26 | 27 | /* (non-Javadoc) 28 | * @see org.springframework.batch.item.ItemReader#read() 29 | */ 30 | @Override 31 | public String read() throws Exception, UnexpectedInputException, 32 | ParseException, NonTransientResourceException { 33 | return !list.isEmpty() ? list.remove(0) : null; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /chunk-processing-solution/src/main/java/com/zenika/workshop/springbatch/StringItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.batch.item.ItemWriter; 11 | 12 | /** 13 | * @author acogoluegnes 14 | * 15 | */ 16 | public class StringItemWriter implements ItemWriter { 17 | 18 | private static final Logger LOGGER = LoggerFactory.getLogger(StringItemWriter.class); 19 | 20 | /* (non-Javadoc) 21 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 22 | */ 23 | @Override 24 | public void write(List items) throws Exception { 25 | for(String item : items) { 26 | LOGGER.info("writing "+item); 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /chunk-processing-solution/src/test/java/com/zenika/workshop/springbatch/ChunkProcessingJobTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.batch.core.ExitStatus; 9 | import org.springframework.batch.core.Job; 10 | import org.springframework.batch.core.JobExecution; 11 | import org.springframework.batch.core.JobParameters; 12 | import org.springframework.batch.core.launch.JobLauncher; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.test.context.ContextConfiguration; 15 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 16 | 17 | import static org.junit.Assert.assertEquals; 18 | 19 | /** 20 | * @author acogoluegnes 21 | * 22 | */ 23 | @RunWith(SpringJUnit4ClassRunner.class) 24 | @ContextConfiguration("/chunk-processing-job.xml") 25 | public class ChunkProcessingJobTest { 26 | 27 | @Autowired 28 | private Job job; 29 | 30 | @Autowired 31 | private JobLauncher jobLauncher; 32 | 33 | @Test public void chunkProcessing() throws Exception { 34 | JobExecution execution = jobLauncher.run(job, new JobParameters()); 35 | assertEquals(ExitStatus.COMPLETED, execution.getExitStatus()); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /chunk-processing-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /chunk-processing-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | chunk-processing-start 12 | 13 | 14 | -------------------------------------------------------------------------------- /chunk-processing-start/src/main/java/com/zenika/workshop/springbatch/StringItemProcessor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.batch.item.ItemProcessor; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class StringItemProcessor implements ItemProcessor { 15 | 16 | private static final Logger LOGGER = LoggerFactory.getLogger(StringItemProcessor.class); 17 | 18 | /* (non-Javadoc) 19 | * @see org.springframework.batch.item.ItemProcessor#process(java.lang.Object) 20 | */ 21 | @Override 22 | public String process(String item) throws Exception { 23 | // TODO 03 decorate the incoming item with stars and return it 24 | return null; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /chunk-processing-start/src/main/java/com/zenika/workshop/springbatch/StringItemReader.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.batch.item.ItemReader; 11 | import org.springframework.batch.item.NonTransientResourceException; 12 | import org.springframework.batch.item.ParseException; 13 | import org.springframework.batch.item.UnexpectedInputException; 14 | 15 | /** 16 | * @author acogoluegnes 17 | * 18 | */ 19 | public class StringItemReader implements ItemReader { 20 | 21 | private static final Logger LOGGER = LoggerFactory.getLogger(StringItemReader.class); 22 | 23 | private List list; 24 | 25 | public StringItemReader() { 26 | // TODO 01 fill in the list with String objects 27 | this.list = null; 28 | } 29 | 30 | /* (non-Javadoc) 31 | * @see org.springframework.batch.item.ItemReader#read() 32 | */ 33 | @Override 34 | public String read() throws Exception, UnexpectedInputException, 35 | ParseException, NonTransientResourceException { 36 | // TODO 02 remove items from the list until it's empty 37 | return null; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /chunk-processing-start/src/main/java/com/zenika/workshop/springbatch/StringItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.batch.item.ItemWriter; 11 | 12 | /** 13 | * @author acogoluegnes 14 | * 15 | */ 16 | public class StringItemWriter implements ItemWriter { 17 | 18 | private static final Logger LOGGER = LoggerFactory.getLogger(StringItemWriter.class); 19 | 20 | /* (non-Javadoc) 21 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 22 | */ 23 | @Override 24 | public void write(List items) throws Exception { 25 | // TODO 04 output items one after the other with the LOGGER 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /chunk-processing-start/src/main/resources/chunk-processing-job.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /chunk-processing-start/src/test/java/com/zenika/workshop/springbatch/ChunkProcessingJobTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.junit.Ignore; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.springframework.batch.core.Job; 10 | import org.springframework.batch.core.launch.JobLauncher; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.test.context.ContextConfiguration; 13 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 14 | 15 | /** 16 | * @author acogoluegnes 17 | * 18 | */ 19 | @RunWith(SpringJUnit4ClassRunner.class) 20 | @ContextConfiguration("/chunk-processing-job.xml") 21 | // TODO 07 remove the @Ignore annotation on the test 22 | @Ignore 23 | public class ChunkProcessingJobTest { 24 | 25 | @Autowired 26 | private Job job; 27 | 28 | @Autowired 29 | private JobLauncher jobLauncher; 30 | 31 | @Test public void chunkProcessing() throws Exception { 32 | // TODO 08 run the job with the job launcher. Use empty job parameters 33 | 34 | // TODO 09 check the returned JobExecution 35 | // it should have an ExitStatus.COMPLETED exit status 36 | 37 | // TODO 10 run the test! you should see the decorated Strings on the console 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /chunk-processing-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /complex-flow-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | complex-flow-solution 12 | 13 | 14 | -------------------------------------------------------------------------------- /complex-flow-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /complex-flow-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /complex-flow-solution/src/main/java/com/zenika/workshop/springbatch/DigestListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.core.ExitStatus; 7 | import org.springframework.batch.core.StepExecution; 8 | import org.springframework.batch.core.StepExecutionListener; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class DigestListener implements StepExecutionListener { 15 | 16 | /* (non-Javadoc) 17 | * @see org.springframework.batch.core.StepExecutionListener#beforeStep(org.springframework.batch.core.StepExecution) 18 | */ 19 | @Override 20 | public void beforeStep(StepExecution stepExecution) { } 21 | 22 | /* (non-Javadoc) 23 | * @see org.springframework.batch.core.StepExecutionListener#afterStep(org.springframework.batch.core.StepExecution) 24 | */ 25 | @Override 26 | public ExitStatus afterStep(StepExecution stepExecution) { 27 | if(hasStepExecutionFailed(stepExecution)) { 28 | return new ExitStatus("INCORRECT FILE", "digest comparison failed"); 29 | } else { 30 | return stepExecution.getExitStatus(); 31 | } 32 | } 33 | 34 | private boolean hasStepExecutionFailed(StepExecution stepExecution) { 35 | return ExitStatus.FAILED.getExitCode().equals(stepExecution.getExitStatus().getExitCode()); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /complex-flow-solution/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | jdbcTemplate.update( 32 | "insert into contact (firstname,lastname,birth) values (?,?,?)", 33 | item.getFirstname(),item.getLastname(),item.getBirth() 34 | ); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /complex-flow-solution/src/main/java/com/zenika/workshop/springbatch/SkipsListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.core.ExitStatus; 7 | import org.springframework.batch.core.StepExecution; 8 | import org.springframework.batch.core.StepExecutionListener; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class SkipsListener implements StepExecutionListener { 15 | 16 | /* (non-Javadoc) 17 | * @see org.springframework.batch.core.StepExecutionListener#beforeStep(org.springframework.batch.core.StepExecution) 18 | */ 19 | @Override 20 | public void beforeStep(StepExecution stepExecution) { } 21 | 22 | /* (non-Javadoc) 23 | * @see org.springframework.batch.core.StepExecutionListener#afterStep(org.springframework.batch.core.StepExecution) 24 | */ 25 | @Override 26 | public ExitStatus afterStep(StepExecution stepExecution) { 27 | String exitCode = stepExecution.getExitStatus().getExitCode(); 28 | if (!exitCode.equals(ExitStatus.FAILED.getExitCode()) && 29 | stepExecution.getSkipCount() > 0) { 30 | return new ExitStatus("COMPLETED WITH SKIPS"); 31 | } 32 | else { 33 | return null; 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /complex-flow-solution/src/main/java/com/zenika/workshop/springbatch/TrackingService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import javax.sql.DataSource; 7 | 8 | import org.springframework.jdbc.core.JdbcTemplate; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class TrackingService { 15 | 16 | private JdbcTemplate jdbcTemplate; 17 | 18 | public TrackingService(DataSource dataSource) { 19 | this.jdbcTemplate = new JdbcTemplate(dataSource); 20 | } 21 | 22 | public void trackIncorrectFile(String name) { 23 | jdbcTemplate.update("insert into tracking (filename,reason) values (?,?)", 24 | name,"INCORRECT" 25 | ); 26 | } 27 | 28 | public void trackFileWithSkips(String name) { 29 | jdbcTemplate.update("insert into tracking (filename,reason) values (?,?)", 30 | name,"SKIPS" 31 | ); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /complex-flow-solution/src/main/resources/contacts-correct-file.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /complex-flow-solution/src/main/resources/contacts-correct-file.txt.md5: -------------------------------------------------------------------------------- 1 | 398b4d4e524535d4ea2e608504ebd3db -------------------------------------------------------------------------------- /complex-flow-solution/src/main/resources/contacts-incorrect-file.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senec -------------------------------------------------------------------------------- /complex-flow-solution/src/main/resources/contacts-incorrect-file.txt.md5: -------------------------------------------------------------------------------- 1 | 398b4d4e524535d4ea2e608504ebd3db -------------------------------------------------------------------------------- /complex-flow-solution/src/main/resources/contacts-with-skips.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,03/29/2010 5 | Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /complex-flow-solution/src/main/resources/contacts-with-skips.txt.md5: -------------------------------------------------------------------------------- 1 | c8f9b86132aad63364da94a345e28002 -------------------------------------------------------------------------------- /complex-flow-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int auto_increment primary key, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create table tracking( 9 | filename varchar(1024), 10 | reason varchar(255) 11 | ); 12 | -------------------------------------------------------------------------------- /complex-flow-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /complex-flow-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | complex-flow-start 12 | 13 | 14 | -------------------------------------------------------------------------------- /complex-flow-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /complex-flow-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /complex-flow-start/src/main/java/com/zenika/workshop/springbatch/DigestListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.core.ExitStatus; 7 | import org.springframework.batch.core.StepExecution; 8 | import org.springframework.batch.core.StepExecutionListener; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class DigestListener implements StepExecutionListener { 15 | 16 | /* (non-Javadoc) 17 | * @see org.springframework.batch.core.StepExecutionListener#beforeStep(org.springframework.batch.core.StepExecution) 18 | */ 19 | @Override 20 | public void beforeStep(StepExecution stepExecution) { } 21 | 22 | /* (non-Javadoc) 23 | * @see org.springframework.batch.core.StepExecutionListener#afterStep(org.springframework.batch.core.StepExecution) 24 | */ 25 | @Override 26 | public ExitStatus afterStep(StepExecution stepExecution) { 27 | if(hasStepExecutionFailed(stepExecution)) { 28 | return new ExitStatus("INCORRECT FILE", "digest comparison failed"); 29 | } else { 30 | return stepExecution.getExitStatus(); 31 | } 32 | } 33 | 34 | private boolean hasStepExecutionFailed(StepExecution stepExecution) { 35 | return ExitStatus.FAILED.getExitCode().equals(stepExecution.getExitStatus().getExitCode()); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /complex-flow-start/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | jdbcTemplate.update( 32 | "insert into contact (firstname,lastname,birth) values (?,?,?)", 33 | item.getFirstname(),item.getLastname(),item.getBirth() 34 | ); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /complex-flow-start/src/main/java/com/zenika/workshop/springbatch/SkipsListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.core.ExitStatus; 7 | import org.springframework.batch.core.StepExecution; 8 | import org.springframework.batch.core.StepExecutionListener; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class SkipsListener implements StepExecutionListener { 15 | 16 | /* (non-Javadoc) 17 | * @see org.springframework.batch.core.StepExecutionListener#beforeStep(org.springframework.batch.core.StepExecution) 18 | */ 19 | @Override 20 | public void beforeStep(StepExecution stepExecution) { } 21 | 22 | /* (non-Javadoc) 23 | * @see org.springframework.batch.core.StepExecutionListener#afterStep(org.springframework.batch.core.StepExecution) 24 | */ 25 | @Override 26 | public ExitStatus afterStep(StepExecution stepExecution) { 27 | // TODO 01 write SkipsListener 28 | // it checks if the exit code isn't FAILED and the number of skips 29 | // in this case, it returns a "COMPLETED WITH SKIPS" exit 30 | // it leaves the ExitStatus unchanged otherwise 31 | return null; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /complex-flow-start/src/main/java/com/zenika/workshop/springbatch/TrackingService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import javax.sql.DataSource; 7 | 8 | import org.springframework.jdbc.core.JdbcTemplate; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class TrackingService { 15 | 16 | private JdbcTemplate jdbcTemplate; 17 | 18 | public TrackingService(DataSource dataSource) { 19 | this.jdbcTemplate = new JdbcTemplate(dataSource); 20 | } 21 | 22 | public void trackIncorrectFile(String name) { 23 | jdbcTemplate.update("insert into tracking (filename,reason) values (?,?)", 24 | name,"INCORRECT" 25 | ); 26 | } 27 | 28 | public void trackFileWithSkips(String name) { 29 | jdbcTemplate.update("insert into tracking (filename,reason) values (?,?)", 30 | name,"SKIPS" 31 | ); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /complex-flow-start/src/main/resources/contacts-correct-file.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /complex-flow-start/src/main/resources/contacts-correct-file.txt.md5: -------------------------------------------------------------------------------- 1 | 398b4d4e524535d4ea2e608504ebd3db -------------------------------------------------------------------------------- /complex-flow-start/src/main/resources/contacts-incorrect-file.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senec -------------------------------------------------------------------------------- /complex-flow-start/src/main/resources/contacts-incorrect-file.txt.md5: -------------------------------------------------------------------------------- 1 | 398b4d4e524535d4ea2e608504ebd3db -------------------------------------------------------------------------------- /complex-flow-start/src/main/resources/contacts-with-skips.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,03/29/2010 5 | Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /complex-flow-start/src/main/resources/contacts-with-skips.txt.md5: -------------------------------------------------------------------------------- 1 | c8f9b86132aad63364da94a345e28002 -------------------------------------------------------------------------------- /complex-flow-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int auto_increment primary key, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create table tracking( 9 | filename varchar(1024), 10 | reason varchar(255) 11 | ); 12 | -------------------------------------------------------------------------------- /complex-flow-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /database-reading-partitioning-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | database-reading-partitioning-solution 12 | 13 | 14 | 15 | commons-dbcp 16 | commons-dbcp 17 | 1.4 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /database-reading-partitioning-solution/src/main/java/com/zenika/workshop/springbatch/Product.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | 7 | /** 8 | * @author acogoluegnes 9 | * 10 | */ 11 | public class Product { 12 | 13 | private final Long id; 14 | 15 | private final String name; 16 | 17 | private final String category; 18 | 19 | public Product(Long id, String name, String category) { 20 | super(); 21 | this.id = id; 22 | this.name = name; 23 | this.category = category; 24 | } 25 | 26 | public Long getId() { 27 | return id; 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public String getCategory() { 35 | return category; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /database-reading-partitioning-solution/src/main/java/com/zenika/workshop/springbatch/ProductRowMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.sql.ResultSet; 7 | import java.sql.SQLException; 8 | 9 | import org.springframework.jdbc.core.RowMapper; 10 | 11 | /** 12 | * @author acogoluegnes 13 | * 14 | */ 15 | public class ProductRowMapper implements RowMapper { 16 | 17 | /* 18 | * (non-Javadoc) 19 | * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int) 20 | */ 21 | @Override 22 | public Product mapRow(ResultSet rs, int rowNum) throws SQLException { 23 | return new Product( 24 | rs.getLong("id"), 25 | rs.getString("name"), 26 | rs.getString("category") 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /database-reading-partitioning-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table product( 2 | id int primary key, 3 | name varchar(255), 4 | category varchar(255), 5 | ); -------------------------------------------------------------------------------- /database-reading-partitioning-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /database-reading-partitioning-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | database-reading-partitioning-start 12 | 13 | 14 | 15 | commons-dbcp 16 | commons-dbcp 17 | 1.4 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /database-reading-partitioning-start/src/main/java/com/zenika/workshop/springbatch/Product.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | 7 | /** 8 | * @author acogoluegnes 9 | * 10 | */ 11 | public class Product { 12 | 13 | private final Long id; 14 | 15 | private final String name; 16 | 17 | private final String category; 18 | 19 | public Product(Long id, String name, String category) { 20 | super(); 21 | this.id = id; 22 | this.name = name; 23 | this.category = category; 24 | } 25 | 26 | public Long getId() { 27 | return id; 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public String getCategory() { 35 | return category; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /database-reading-partitioning-start/src/main/java/com/zenika/workshop/springbatch/ProductRowMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.sql.ResultSet; 7 | import java.sql.SQLException; 8 | 9 | import org.springframework.jdbc.core.RowMapper; 10 | 11 | /** 12 | * @author acogoluegnes 13 | * 14 | */ 15 | public class ProductRowMapper implements RowMapper { 16 | 17 | /* 18 | * (non-Javadoc) 19 | * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int) 20 | */ 21 | @Override 22 | public Product mapRow(ResultSet rs, int rowNum) throws SQLException { 23 | return new Product( 24 | rs.getLong("id"), 25 | rs.getString("name"), 26 | rs.getString("category") 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /database-reading-partitioning-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table product( 2 | id int primary key, 3 | name varchar(255), 4 | category varchar(255), 5 | ); -------------------------------------------------------------------------------- /database-reading-partitioning-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /dynamic-job-parameters-solution/input/contacts-01.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Unreg,Kleynenberg,2010-03-04 5 | Belvia,Hazelton,2010-03-04 6 | Sadie,Selchow,2010-03-04 7 | Elayne,Chinnery,2010-03-04 -------------------------------------------------------------------------------- /dynamic-job-parameters-solution/input/contacts-02.txt: -------------------------------------------------------------------------------- 1 | Alecia,Van Holst,2010-03-04 2 | Hing,Senecal,2010-03-04 3 | Rachael,Schiefer,2010-03-04 4 | Dorri,Hutchings,2010-03-04 5 | Allis,Cifelli,2010-03-04 6 | Lashonda,Fetzko,2010-03-04 -------------------------------------------------------------------------------- /dynamic-job-parameters-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | dynamic-job-parameters-solution 12 | 13 | 14 | -------------------------------------------------------------------------------- /dynamic-job-parameters-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /dynamic-job-parameters-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dynamic-job-parameters-solution/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /dynamic-job-parameters-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /dynamic-job-parameters-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /dynamic-job-parameters-start/input/contacts-01.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Unreg,Kleynenberg,2010-03-04 5 | Belvia,Hazelton,2010-03-04 6 | Sadie,Selchow,2010-03-04 7 | Elayne,Chinnery,2010-03-04 -------------------------------------------------------------------------------- /dynamic-job-parameters-start/input/contacts-02.txt: -------------------------------------------------------------------------------- 1 | Alecia,Van Holst,2010-03-04 2 | Hing,Senecal,2010-03-04 3 | Rachael,Schiefer,2010-03-04 4 | Dorri,Hutchings,2010-03-04 5 | Allis,Cifelli,2010-03-04 6 | Lashonda,Fetzko,2010-03-04 -------------------------------------------------------------------------------- /dynamic-job-parameters-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | dynamic-job-parameters-start 12 | 13 | 14 | -------------------------------------------------------------------------------- /dynamic-job-parameters-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /dynamic-job-parameters-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dynamic-job-parameters-start/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /dynamic-job-parameters-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /dynamic-job-parameters-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /execution-metadata-solution/input/contacts-01.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Unreg,Kleynenberg,2010-03-04 5 | Belvia,Hazelton,2010-03-04 6 | Sadie,Selchow,2010-03-04 7 | Elayne,Chinnery,2010-03-04 -------------------------------------------------------------------------------- /execution-metadata-solution/input/contacts-02.txt: -------------------------------------------------------------------------------- 1 | Alecia,Van Holst,2010-03-04 2 | Hing,Senecal,2010-03-04 3 | Rachael,Schiefer,2010-03-04 4 | Dorri,Hutchings,09/23/2011 5 | Allis,Cifelli,2010-03-04 6 | Lashonda,Fetzko,2010-03-04 -------------------------------------------------------------------------------- /execution-metadata-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /execution-metadata-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /execution-metadata-solution/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /execution-metadata-solution/src/main/resources/batch-default.properties: -------------------------------------------------------------------------------- 1 | batch.jdbc.driver=org.h2.Driver 2 | batch.jdbc.url=jdbc:h2:tcp://localhost/mem:execution_metadata 3 | batch.jdbc.user=sa 4 | batch.jdbc.password= 5 | batch.database.incrementer.class=org.springframework.jdbc.support.incrementer.H2SequenceMaxValueIncrementer 6 | 7 | batch.data.source.init=true 8 | batch.business.schema.script=classpath:/create-tables.sql 9 | batch.schema.script=classpath:/org/springframework/batch/core/schema-h2.sql 10 | batch.drop.script=classpath:/drop-tables.sql 11 | batch.remote.base.url= -------------------------------------------------------------------------------- /execution-metadata-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /execution-metadata-solution/src/main/resources/drop-tables.sql: -------------------------------------------------------------------------------- 1 | drop table contact if exists; 2 | drop sequence contact_seq if exists; -------------------------------------------------------------------------------- /execution-metadata-solution/src/test/java/com/zenika/workshop/springbatch/ExecutionMetadataTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import static org.junit.Assert.assertTrue; 7 | 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | import org.junit.rules.RuleChain; 11 | import org.springframework.web.client.RestTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class ExecutionMetadataTest { 18 | 19 | private static final int PORT = 8081; 20 | 21 | private static final String CONTEXT_PATH = "/springbatchadmin"; 22 | 23 | private static final String BASE_URL = String.format("http://localhost:%d%s/",PORT,CONTEXT_PATH); 24 | 25 | private static final String JOB = "flatFileReadingJob"; 26 | 27 | private RestTemplate restTemplate = new RestTemplate(); 28 | 29 | @Rule public RuleChain servers = RuleChain 30 | .outerRule(new H2Server()) 31 | .around(new JettyServer(PORT,CONTEXT_PATH,"./src/main/webapp")); 32 | 33 | @Test public void submitJob() throws Exception { 34 | assertTrue(restTemplate.getForObject(BASE_URL+"jobs.json", String.class).contains(JOB)); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /execution-metadata-solution/src/test/java/com/zenika/workshop/springbatch/H2Server.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.junit.rules.ExternalResource; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class H2Server extends ExternalResource { 13 | 14 | private org.h2.tools.Server h2; 15 | 16 | @Override 17 | protected void before() throws Throwable { 18 | h2 = org.h2.tools.Server.createTcpServer(); 19 | h2.start(); 20 | } 21 | 22 | @Override 23 | protected void after() { 24 | h2.stop(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /execution-metadata-solution/src/test/java/com/zenika/workshop/springbatch/LaunchExecutionMetadata.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.h2.tools.Console; 7 | import org.mortbay.jetty.Connector; 8 | import org.mortbay.jetty.Server; 9 | import org.mortbay.jetty.nio.SelectChannelConnector; 10 | import org.mortbay.jetty.webapp.WebAppContext; 11 | 12 | import java.io.File; 13 | 14 | 15 | /** 16 | * @author acogoluegnes 17 | * 18 | */ 19 | public class LaunchExecutionMetadata { 20 | 21 | public static void main(String [] args) throws Exception { 22 | Console.main(args); 23 | 24 | Server server = new Server(); 25 | Connector connector = new SelectChannelConnector(); 26 | connector.setPort(8080); 27 | connector.setHost("127.0.0.1"); 28 | server.addConnector(connector); 29 | 30 | WebAppContext wac = new WebAppContext(); 31 | wac.setContextPath("/springbatchadmin"); 32 | wac.setWar("./src/main/webapp"); 33 | server.setHandler(wac); 34 | server.setStopAtShutdown(true); 35 | 36 | server.start(); 37 | 38 | System.out.println("**** Spring Batch Admin launched"); 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /execution-metadata-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /execution-metadata-start/input/contacts-01.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Unreg,Kleynenberg,2010-03-04 5 | Belvia,Hazelton,2010-03-04 6 | Sadie,Selchow,2010-03-04 7 | Elayne,Chinnery,2010-03-04 -------------------------------------------------------------------------------- /execution-metadata-start/input/contacts-02.txt: -------------------------------------------------------------------------------- 1 | Alecia,Van Holst,2010-03-04 2 | Hing,Senecal,2010-03-04 3 | Rachael,Schiefer,2010-03-04 4 | Dorri,Hutchings,09/23/2011 5 | Allis,Cifelli,2010-03-04 6 | Lashonda,Fetzko,2010-03-04 -------------------------------------------------------------------------------- /execution-metadata-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /execution-metadata-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /execution-metadata-start/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /execution-metadata-start/src/main/resources/batch-default.properties: -------------------------------------------------------------------------------- 1 | batch.jdbc.driver=org.h2.Driver 2 | batch.jdbc.url=jdbc:h2:tcp://localhost/mem:execution_metadata 3 | batch.jdbc.user=sa 4 | batch.jdbc.password= 5 | batch.database.incrementer.class=org.springframework.jdbc.support.incrementer.H2SequenceMaxValueIncrementer 6 | 7 | batch.data.source.init=true 8 | batch.business.schema.script=classpath:/create-tables.sql 9 | batch.schema.script=classpath:/org/springframework/batch/core/schema-h2.sql 10 | batch.drop.script=classpath:/drop-tables.sql 11 | batch.remote.base.url= -------------------------------------------------------------------------------- /execution-metadata-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /execution-metadata-start/src/main/resources/drop-tables.sql: -------------------------------------------------------------------------------- 1 | drop table contact if exists; 2 | drop sequence contact_seq if exists; -------------------------------------------------------------------------------- /execution-metadata-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /file-dropping-launching-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /file-dropping-launching-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /file-dropping-launching-solution/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForLong("select contact_seq.nextval from dual"); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /file-dropping-launching-solution/src/main/java/com/zenika/workshop/springbatch/integration/FileContactJobLauncher.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch.integration; 5 | 6 | import java.io.File; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.batch.core.Job; 11 | import org.springframework.batch.core.JobExecution; 12 | import org.springframework.batch.core.JobParametersBuilder; 13 | import org.springframework.batch.core.launch.JobLauncher; 14 | 15 | /** 16 | * @author acogoluegnes 17 | * 18 | */ 19 | public class FileContactJobLauncher { 20 | 21 | private static final Logger LOG = LoggerFactory.getLogger(FileContactJobLauncher.class); 22 | 23 | private JobLauncher jobLauncher; 24 | 25 | private Job job; 26 | 27 | public void launch(File file) throws Exception { 28 | LOG.info("starting import for file {}",file); 29 | JobExecution exec = jobLauncher.run( 30 | job, 31 | new JobParametersBuilder() 32 | .addString("input.file", "file:"+file.getAbsolutePath()) 33 | .addLong("time",System.currentTimeMillis()) 34 | .toJobParameters() 35 | ); 36 | LOG.info("job ended with status {}",exec); 37 | } 38 | 39 | public void setJob(Job job) { 40 | this.job = job; 41 | } 42 | 43 | public void setJobLauncher(JobLauncher jobLauncher) { 44 | this.jobLauncher = jobLauncher; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /file-dropping-launching-solution/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /file-dropping-launching-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /file-dropping-launching-solution/src/test/java/com/zenika/workshop/springbatch/StartClient.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.io.File; 7 | 8 | import org.apache.commons.io.FileUtils; 9 | import org.h2.tools.Server; 10 | import org.springframework.context.support.ClassPathXmlApplicationContext; 11 | 12 | /** 13 | * @author acogoluegnes 14 | * 15 | */ 16 | public class StartClient { 17 | 18 | public static final String CLIENT_INPUT_DIRECTORY = "./input"; 19 | 20 | /** 21 | * @param args 22 | */ 23 | public static void main(String[] args) throws Exception { 24 | Server.createTcpServer().start(); 25 | File input = new File(CLIENT_INPUT_DIRECTORY); 26 | if(input.exists()) { 27 | FileUtils.cleanDirectory(new File(CLIENT_INPUT_DIRECTORY)); 28 | } 29 | new ClassPathXmlApplicationContext("file-dropping-launching-job.xml","integration-file.xml"); 30 | System.out.println("Client started."); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /file-dropping-launching-solution/src/test/java/com/zenika/workshop/springbatch/StartDbConsole.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.sql.SQLException; 7 | 8 | import org.h2.tools.Console; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class StartDbConsole { 15 | 16 | /** 17 | * @param args 18 | * @throws SQLException 19 | */ 20 | public static void main(String[] args) throws SQLException { 21 | Console.main("-web","-browser"); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /file-dropping-launching-solution/src/test/java/com/zenika/workshop/springbatch/StartFtpServer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | /** 7 | * @author acogoluegnes 8 | * 9 | */ 10 | public class StartFtpServer { 11 | 12 | public static void main(String [] args) throws Exception { 13 | EmbeddedFtpServer.start(); 14 | System.out.println("FTP started, press Enter to stop it..."); 15 | System.in.read(); 16 | EmbeddedFtpServer.stop(); 17 | System.out.println("FTP stopped."); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /file-dropping-launching-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /file-dropping-launching-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /file-dropping-launching-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /file-dropping-launching-start/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForLong("select contact_seq.nextval from dual"); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /file-dropping-launching-start/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /file-dropping-launching-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /file-dropping-launching-start/src/test/java/com/zenika/workshop/springbatch/StartClient.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.io.File; 7 | 8 | import org.apache.commons.io.FileUtils; 9 | import org.h2.tools.Server; 10 | import org.springframework.context.support.ClassPathXmlApplicationContext; 11 | 12 | /** 13 | * @author acogoluegnes 14 | * 15 | */ 16 | public class StartClient { 17 | 18 | public static final String CLIENT_INPUT_DIRECTORY = "./input"; 19 | 20 | /** 21 | * @param args 22 | */ 23 | public static void main(String[] args) throws Exception { 24 | // TODO 06 start the client 25 | Server.createTcpServer().start(); 26 | File input = new File(CLIENT_INPUT_DIRECTORY); 27 | if(input.exists()) { 28 | FileUtils.cleanDirectory(new File(CLIENT_INPUT_DIRECTORY)); 29 | } 30 | new ClassPathXmlApplicationContext("file-dropping-launching-job.xml","integration-file.xml"); 31 | System.out.println("Client started."); 32 | // TODO 07 copy the contacts.txt file in src/main/resources to the ./ftphome directory 33 | // (the directory has just been created, refresh your project directory if you use Eclipse) 34 | // the file will be detected, downloaded from the FTP in the ./input, and processed by Spring Batch 35 | // (you should see some logs in the console) 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /file-dropping-launching-start/src/test/java/com/zenika/workshop/springbatch/StartDbConsole.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.sql.SQLException; 7 | 8 | import org.h2.tools.Console; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class StartDbConsole { 15 | 16 | /** 17 | * @param args 18 | * @throws SQLException 19 | */ 20 | public static void main(String[] args) throws SQLException { 21 | // TODO 08 launch the database console to check the content of the database 22 | Console.main("-web","-browser"); 23 | // TODO 09 in the database console, enter "jdbc:h2:tcp://localhost/mem:file-dropping-launching" for the URL 24 | // "sa" for the user, and nothing in the password. Check the content of the contact table. 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /file-dropping-launching-start/src/test/java/com/zenika/workshop/springbatch/StartFtpServer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | /** 7 | * @author acogoluegnes 8 | * 9 | */ 10 | public class StartFtpServer { 11 | 12 | public static void main(String [] args) throws Exception { 13 | // TODO 05 start the FTP server 14 | EmbeddedFtpServer.start(); 15 | System.out.println("FTP started, press Enter to stop it..."); 16 | System.in.read(); 17 | EmbeddedFtpServer.stop(); 18 | System.out.println("FTP stopped."); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /file-dropping-launching-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /file-reading-partitioning-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | file-reading-partitioning-solution 12 | 13 | 14 | 15 | commons-dbcp 16 | commons-dbcp 17 | 1.4 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /file-reading-partitioning-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /file-reading-partitioning-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /file-reading-partitioning-solution/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | Thread.sleep(10); 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /file-reading-partitioning-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int primary key, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /file-reading-partitioning-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /file-reading-partitioning-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | file-reading-partitioning-start 12 | 13 | 14 | 15 | commons-dbcp 16 | commons-dbcp 17 | 1.4 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /file-reading-partitioning-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /file-reading-partitioning-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /file-reading-partitioning-start/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | Thread.sleep(10); 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /file-reading-partitioning-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int primary key, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /file-reading-partitioning-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /flat-file-reading-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | flat-file-reading-solution 12 | 13 | 14 | -------------------------------------------------------------------------------- /flat-file-reading-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /flat-file-reading-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /flat-file-reading-solution/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /flat-file-reading-solution/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /flat-file-reading-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /flat-file-reading-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /flat-file-reading-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | flat-file-reading-start 12 | 13 | 14 | -------------------------------------------------------------------------------- /flat-file-reading-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /flat-file-reading-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | // TODO 02 create a Contact from the FieldSet 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /flat-file-reading-start/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /flat-file-reading-start/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /flat-file-reading-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /flat-file-reading-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /hello-world-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | hello-world-solution 12 | 13 | 14 | -------------------------------------------------------------------------------- /hello-world-solution/src/main/java/com/zenika/workshop/springbatch/HelloWorldTasklet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.core.StepContribution; 7 | import org.springframework.batch.core.scope.context.ChunkContext; 8 | import org.springframework.batch.core.step.tasklet.Tasklet; 9 | import org.springframework.batch.repeat.RepeatStatus; 10 | 11 | /** 12 | * @author acogoluegnes 13 | * 14 | */ 15 | public class HelloWorldTasklet implements Tasklet { 16 | 17 | @Override 18 | public RepeatStatus execute(StepContribution contribution, 19 | ChunkContext chunkContext) throws Exception { 20 | System.out.println("Hello world!"); 21 | return RepeatStatus.FINISHED; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /hello-world-solution/src/main/resources/hello-world-job.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /hello-world-solution/src/test/java/com/zenika/workshop/springbatch/HelloWorldJobTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.batch.core.ExitStatus; 9 | import org.springframework.batch.core.Job; 10 | import org.springframework.batch.core.JobExecution; 11 | import org.springframework.batch.core.JobParameters; 12 | import org.springframework.batch.core.launch.JobLauncher; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.test.context.ContextConfiguration; 15 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 16 | 17 | import static org.junit.Assert.assertEquals; 18 | 19 | /** 20 | * @author acogoluegnes 21 | * 22 | */ 23 | @RunWith(SpringJUnit4ClassRunner.class) 24 | @ContextConfiguration("/hello-world-job.xml") 25 | public class HelloWorldJobTest { 26 | 27 | @Autowired 28 | private Job job; 29 | 30 | @Autowired 31 | private JobLauncher jobLauncher; 32 | 33 | @Test public void helloWorld() throws Exception { 34 | JobExecution execution = jobLauncher.run(job, new JobParameters()); 35 | assertEquals(ExitStatus.COMPLETED, execution.getExitStatus()); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /hello-world-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /hello-world-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | hello-world-start 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /hello-world-start/src/main/java/com/zenika/workshop/springbatch/HelloWorldTasklet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.core.StepContribution; 7 | import org.springframework.batch.core.scope.context.ChunkContext; 8 | import org.springframework.batch.core.step.tasklet.Tasklet; 9 | import org.springframework.batch.repeat.RepeatStatus; 10 | 11 | /** 12 | * @author acogoluegnes 13 | * 14 | */ 15 | public class HelloWorldTasklet implements Tasklet { 16 | 17 | @Override 18 | public RepeatStatus execute(StepContribution contribution, 19 | ChunkContext chunkContext) throws Exception { 20 | // TODO 01 print "Hello World!" on the console 21 | 22 | // TODO 02 return RepeatStatus.FINISHED 23 | // Spring Batch will execute the method once then 24 | return null; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /hello-world-start/src/main/resources/hello-world-job.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /hello-world-start/src/test/java/com/zenika/workshop/springbatch/HelloWorldJobTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.junit.Ignore; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.springframework.batch.core.Job; 10 | import org.springframework.batch.core.launch.JobLauncher; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.test.context.ContextConfiguration; 13 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 14 | 15 | /** 16 | * @author acogoluegnes 17 | * 18 | */ 19 | @RunWith(SpringJUnit4ClassRunner.class) 20 | @ContextConfiguration("/hello-world-job.xml") 21 | // TODO 04 remove the @Ignore annotation on the test 22 | @Ignore 23 | public class HelloWorldJobTest { 24 | 25 | @Autowired 26 | private Job job; 27 | 28 | @Autowired 29 | private JobLauncher jobLauncher; 30 | 31 | @Test public void helloWorld() throws Exception { 32 | // TODO 05 run the job with the job launcher. Use empty job parameters 33 | 34 | // TODO 06 check the returned JobExecution 35 | // it should have an ExitStatus.COMPLETED exit status 36 | 37 | // TODO 07 run the test! 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /hello-world-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /item-enrichment-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | item-enrichment-solution 12 | 13 | 14 | 15 | org.springframework 16 | spring-webmvc 17 | ${spring.version} 18 | 19 | 20 | org.springframework.batch 21 | spring-batch-integration 22 | ${spring.batch.integration.version} 23 | 24 | 25 | org.springframework 26 | spring-aop 27 | 28 | 29 | org.slf4j 30 | slf4j-log4j12 31 | 32 | 33 | 34 | 35 | org.mortbay.jetty 36 | jetty 37 | ${jetty.version} 38 | test 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /item-enrichment-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | private String ssn; 21 | 22 | public Contact(Long id,String firstname, String lastname, Date birth) { 23 | super(); 24 | this.id = id; 25 | this.firstname = firstname; 26 | this.lastname = lastname; 27 | this.birth = birth; 28 | } 29 | 30 | public Long getId() { 31 | return id; 32 | } 33 | 34 | public String getFirstname() { 35 | return firstname; 36 | } 37 | 38 | public String getLastname() { 39 | return lastname; 40 | } 41 | 42 | public Date getBirth() { 43 | return birth; 44 | } 45 | 46 | public String getSsn() { 47 | return ssn; 48 | } 49 | 50 | public void setSsn(String ssn) { 51 | this.ssn = ssn; 52 | } 53 | 54 | @Override 55 | public String toString() { 56 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 57 | + lastname + ", birth=" + birth + ", ssn=" + ssn + "]"; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /item-enrichment-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readLong("id"), 27 | fieldSet.readString("firstname"), 28 | fieldSet.readString("lastname"), 29 | fieldSet.readDate("birth","yyyy-MM-dd") 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /item-enrichment-solution/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | jdbcTemplate.update( 32 | "insert into contact (id,firstname,lastname,birth,ssn) values (?,?,?,?,?)", 33 | item.getId(),item.getFirstname(),item.getLastname(),item.getBirth(),item.getSsn() 34 | ); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /item-enrichment-solution/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | 1,De-Anna,Raghunath,2010-03-04 2 | 2,Susy,Hauerstock,2010-03-04 3 | 3,Kiam,Whitehurst,2010-03-04 4 | 4,Alecia,Van Holst,2010-03-04 5 | 5,Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /item-enrichment-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date, 6 | ssn varchar(11) 7 | ); -------------------------------------------------------------------------------- /item-enrichment-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /item-enrichment-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | item-enrichment-start 12 | 13 | 14 | 15 | org.springframework 16 | spring-webmvc 17 | ${spring.version} 18 | 19 | 20 | org.springframework.batch 21 | spring-batch-integration 22 | ${spring.batch.integration.version} 23 | 24 | 25 | org.springframework 26 | spring-aop 27 | 28 | 29 | org.slf4j 30 | slf4j-log4j12 31 | 32 | 33 | 34 | 35 | org.mortbay.jetty 36 | jetty 37 | ${jetty.version} 38 | test 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /item-enrichment-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | private String ssn; 21 | 22 | public Contact(Long id,String firstname, String lastname, Date birth) { 23 | super(); 24 | this.id = id; 25 | this.firstname = firstname; 26 | this.lastname = lastname; 27 | this.birth = birth; 28 | } 29 | 30 | public Long getId() { 31 | return id; 32 | } 33 | 34 | public String getFirstname() { 35 | return firstname; 36 | } 37 | 38 | public String getLastname() { 39 | return lastname; 40 | } 41 | 42 | public Date getBirth() { 43 | return birth; 44 | } 45 | 46 | public String getSsn() { 47 | return ssn; 48 | } 49 | 50 | public void setSsn(String ssn) { 51 | this.ssn = ssn; 52 | } 53 | 54 | @Override 55 | public String toString() { 56 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 57 | + lastname + ", birth=" + birth + ", ssn=" + ssn + "]"; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /item-enrichment-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readLong("id"), 27 | fieldSet.readString("firstname"), 28 | fieldSet.readString("lastname"), 29 | fieldSet.readDate("birth","yyyy-MM-dd") 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /item-enrichment-start/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | jdbcTemplate.update( 32 | "insert into contact (id,firstname,lastname,birth,ssn) values (?,?,?,?,?)", 33 | item.getId(),item.getFirstname(),item.getLastname(),item.getBirth(),item.getSsn() 34 | ); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /item-enrichment-start/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | 1,De-Anna,Raghunath,2010-03-04 2 | 2,Susy,Hauerstock,2010-03-04 3 | 3,Kiam,Whitehurst,2010-03-04 4 | 4,Alecia,Van Holst,2010-03-04 5 | 5,Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /item-enrichment-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date, 6 | ssn varchar(11) 7 | ); -------------------------------------------------------------------------------- /item-enrichment-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /item-processor-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | item-processor-solution 12 | 13 | 14 | -------------------------------------------------------------------------------- /item-processor-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(Long id,String firstname, String lastname, Date birth) { 21 | super(); 22 | this.id = id; 23 | this.firstname = firstname; 24 | this.lastname = lastname; 25 | this.birth = birth; 26 | } 27 | 28 | public Long getId() { 29 | return id; 30 | } 31 | 32 | public String getFirstname() { 33 | return firstname; 34 | } 35 | 36 | public String getLastname() { 37 | return lastname; 38 | } 39 | 40 | public Date getBirth() { 41 | return birth; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 47 | + lastname + ", birth=" + birth + "]"; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /item-processor-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readLong("id"), 27 | fieldSet.readString("firstname"), 28 | fieldSet.readString("lastname"), 29 | fieldSet.readDate("birth","yyyy-MM-dd") 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /item-processor-solution/src/main/java/com/zenika/workshop/springbatch/ContactItemProcessor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.ItemProcessor; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class ContactItemProcessor implements 13 | ItemProcessor { 14 | 15 | private RegistrationService registrationService; 16 | 17 | /* (non-Javadoc) 18 | * @see org.springframework.batch.item.ItemProcessor#process(java.lang.Object) 19 | */ 20 | @Override 21 | public RegistrationConfirmation process(Contact item) throws Exception { 22 | return registrationService.process(item); 23 | } 24 | 25 | public void setRegistrationService(RegistrationService registrationService) { 26 | this.registrationService = registrationService; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /item-processor-solution/src/main/java/com/zenika/workshop/springbatch/JdbcRegistrationConfirmationItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcRegistrationConfirmationItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcRegistrationConfirmationItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(RegistrationConfirmation item : items) { 31 | jdbcTemplate.update( 32 | "insert into registration_confirmation (number,contact_id,accepted) values (?,?,?)", 33 | item.getNumber(),item.getContact().getId(),item.isAccepted() 34 | ); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /item-processor-solution/src/main/java/com/zenika/workshop/springbatch/RegistrationConfirmation.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | /** 7 | * @author acogoluegnes 8 | * 9 | */ 10 | public class RegistrationConfirmation { 11 | 12 | private String number; 13 | 14 | private boolean accepted; 15 | 16 | private Contact contact; 17 | 18 | public RegistrationConfirmation(String number, Contact contact,boolean accepted) { 19 | super(); 20 | this.number = number; 21 | this.contact = contact; 22 | this.accepted = accepted; 23 | } 24 | 25 | public String getNumber() { 26 | return number; 27 | } 28 | 29 | public Contact getContact() { 30 | return contact; 31 | } 32 | 33 | public boolean isAccepted() { 34 | return accepted; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /item-processor-solution/src/main/java/com/zenika/workshop/springbatch/RegistrationService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.UUID; 7 | 8 | import org.apache.commons.lang.math.RandomUtils; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class RegistrationService { 15 | 16 | public RegistrationConfirmation process(Contact contact) { 17 | return new RegistrationConfirmation( 18 | UUID.randomUUID().toString(), 19 | contact, 20 | RandomUtils.nextBoolean() 21 | ); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /item-processor-solution/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | 1,De-Anna,Raghunath,2010-03-04 2 | 2,Susy,Hauerstock,2010-03-04 3 | 3,Kiam,Whitehurst,2010-03-04 4 | 4,Alecia,Van Holst,2010-03-04 5 | 5,Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /item-processor-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table registration_confirmation( 2 | number varchar(255), 3 | contact_id int, 4 | accepted boolean 5 | ); -------------------------------------------------------------------------------- /item-processor-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /item-processor-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | item-processor-start 12 | 13 | 14 | -------------------------------------------------------------------------------- /item-processor-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(Long id,String firstname, String lastname, Date birth) { 21 | super(); 22 | this.id = id; 23 | this.firstname = firstname; 24 | this.lastname = lastname; 25 | this.birth = birth; 26 | } 27 | 28 | public Long getId() { 29 | return id; 30 | } 31 | 32 | public String getFirstname() { 33 | return firstname; 34 | } 35 | 36 | public String getLastname() { 37 | return lastname; 38 | } 39 | 40 | public Date getBirth() { 41 | return birth; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 47 | + lastname + ", birth=" + birth + "]"; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /item-processor-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readLong("id"), 27 | fieldSet.readString("firstname"), 28 | fieldSet.readString("lastname"), 29 | fieldSet.readDate("birth","yyyy-MM-dd") 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /item-processor-start/src/main/java/com/zenika/workshop/springbatch/ContactItemProcessor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.ItemProcessor; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class ContactItemProcessor implements 13 | ItemProcessor { 14 | 15 | private RegistrationService registrationService; 16 | 17 | /* (non-Javadoc) 18 | * @see org.springframework.batch.item.ItemProcessor#process(java.lang.Object) 19 | */ 20 | @Override 21 | public RegistrationConfirmation process(Contact item) throws Exception { 22 | // TODO 02 call the registrationService to process the item and return the confirmation 23 | return null; 24 | } 25 | 26 | public void setRegistrationService(RegistrationService registrationService) { 27 | this.registrationService = registrationService; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /item-processor-start/src/main/java/com/zenika/workshop/springbatch/JdbcRegistrationConfirmationItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcRegistrationConfirmationItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcRegistrationConfirmationItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | // TODO 03 take a look at the writer: it inserts the confirmations inside the database 31 | for(RegistrationConfirmation item : items) { 32 | jdbcTemplate.update( 33 | "insert into registration_confirmation (number,contact_id,accepted) values (?,?,?)", 34 | item.getNumber(),item.getContact().getId(),item.isAccepted() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /item-processor-start/src/main/java/com/zenika/workshop/springbatch/RegistrationConfirmation.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | /** 7 | * @author acogoluegnes 8 | * 9 | */ 10 | public class RegistrationConfirmation { 11 | 12 | private String number; 13 | 14 | private boolean accepted; 15 | 16 | private Contact contact; 17 | 18 | public RegistrationConfirmation(String number, Contact contact,boolean accepted) { 19 | super(); 20 | this.number = number; 21 | this.contact = contact; 22 | this.accepted = accepted; 23 | } 24 | 25 | public String getNumber() { 26 | return number; 27 | } 28 | 29 | public Contact getContact() { 30 | return contact; 31 | } 32 | 33 | public boolean isAccepted() { 34 | return accepted; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /item-processor-start/src/main/java/com/zenika/workshop/springbatch/RegistrationService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.UUID; 7 | 8 | import org.apache.commons.lang.math.RandomUtils; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class RegistrationService { 15 | 16 | public RegistrationConfirmation process(Contact contact) { 17 | // TODO 01 take a look at the (dummy) business logic 18 | // it's about confirming the contact is registered 19 | return new RegistrationConfirmation( 20 | UUID.randomUUID().toString(), 21 | contact, 22 | RandomUtils.nextBoolean() 23 | ); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /item-processor-start/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | 1,De-Anna,Raghunath,2010-03-04 2 | 2,Susy,Hauerstock,2010-03-04 3 | 3,Kiam,Whitehurst,2010-03-04 4 | 4,Alecia,Van Holst,2010-03-04 5 | 5,Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /item-processor-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table registration_confirmation( 2 | number varchar(255), 3 | contact_id int, 4 | accepted boolean 5 | ); -------------------------------------------------------------------------------- /item-processor-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /jdbc-paging-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | jdbc-paging-solution 12 | 13 | 14 | -------------------------------------------------------------------------------- /jdbc-paging-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(Long id,String firstname, String lastname, Date birth) { 21 | super(); 22 | this.id = id; 23 | this.firstname = firstname; 24 | this.lastname = lastname; 25 | this.birth = birth; 26 | } 27 | 28 | public Long getId() { 29 | return id; 30 | } 31 | 32 | public String getFirstname() { 33 | return firstname; 34 | } 35 | 36 | public String getLastname() { 37 | return lastname; 38 | } 39 | 40 | public Date getBirth() { 41 | return birth; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 47 | + lastname + ", birth=" + birth + "]"; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /jdbc-paging-solution/src/main/java/com/zenika/workshop/springbatch/ContactRowMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.sql.ResultSet; 7 | import java.sql.SQLException; 8 | 9 | import org.springframework.jdbc.core.RowMapper; 10 | 11 | /** 12 | * @author acogoluegnes 13 | * 14 | */ 15 | public class ContactRowMapper implements RowMapper { 16 | 17 | /* 18 | * (non-Javadoc) 19 | * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int) 20 | */ 21 | @Override 22 | public Contact mapRow(ResultSet rs, int rowNum) throws SQLException { 23 | return new Contact( 24 | rs.getLong("id"), 25 | rs.getString("firstname"), 26 | rs.getString("lastname"), 27 | rs.getDate("birth") 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /jdbc-paging-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /jdbc-paging-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /jdbc-paging-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | jdbc-paging-start 12 | 13 | 14 | -------------------------------------------------------------------------------- /jdbc-paging-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(Long id,String firstname, String lastname, Date birth) { 21 | super(); 22 | this.id = id; 23 | this.firstname = firstname; 24 | this.lastname = lastname; 25 | this.birth = birth; 26 | } 27 | 28 | public Long getId() { 29 | return id; 30 | } 31 | 32 | public String getFirstname() { 33 | return firstname; 34 | } 35 | 36 | public String getLastname() { 37 | return lastname; 38 | } 39 | 40 | public Date getBirth() { 41 | return birth; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 47 | + lastname + ", birth=" + birth + "]"; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /jdbc-paging-start/src/main/java/com/zenika/workshop/springbatch/ContactRowMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.sql.ResultSet; 7 | import java.sql.SQLException; 8 | 9 | import org.springframework.jdbc.core.RowMapper; 10 | 11 | /** 12 | * @author acogoluegnes 13 | * 14 | */ 15 | public class ContactRowMapper implements RowMapper { 16 | 17 | /* 18 | * (non-Javadoc) 19 | * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int) 20 | */ 21 | @Override 22 | public Contact mapRow(ResultSet rs, int rowNum) throws SQLException { 23 | // TODO 02 take a look at the ContactRowMapper 24 | // it implements the logic to convert the JDBC ResultSet into a domain object 25 | // the item reader will use it 26 | return new Contact( 27 | rs.getLong("id"), 28 | rs.getString("firstname"), 29 | rs.getString("lastname"), 30 | rs.getDate("birth") 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jdbc-paging-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /jdbc-paging-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /logging-skipped-items-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | logging-skipped-items-solution 12 | 13 | 14 | -------------------------------------------------------------------------------- /logging-skipped-items-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /logging-skipped-items-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /logging-skipped-items-solution/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /logging-skipped-items-solution/src/main/java/com/zenika/workshop/springbatch/Slf4jSkipListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.batch.core.listener.SkipListenerSupport; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class Slf4jSkipListener extends SkipListenerSupport { 15 | 16 | private static final Logger LOG = LoggerFactory.getLogger(Slf4jSkipListener.class); 17 | 18 | @Override 19 | public void onSkipInRead(Throwable t) { 20 | LOG.warn("skipped item: {}",t.toString()); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /logging-skipped-items-solution/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,09-23-2010 5 | Hing,Senecal,2010-03-04 6 | Kannan,Pirkle,2010-03-04 7 | Row,Maudrie,2010-03-04,extra column 8 | Voort,Philbeck,2010-03-04 -------------------------------------------------------------------------------- /logging-skipped-items-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /logging-skipped-items-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /logging-skipped-items-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | logging-skipped-items-start 12 | 13 | 14 | -------------------------------------------------------------------------------- /logging-skipped-items-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /logging-skipped-items-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /logging-skipped-items-start/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /logging-skipped-items-start/src/main/java/com/zenika/workshop/springbatch/Slf4jSkipListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | /** 10 | * @author acogoluegnes 11 | * 12 | */ 13 | // TODO 01 make the listener extend the SkipListenerSupport class 14 | public class Slf4jSkipListener { 15 | 16 | private static final Logger LOG = LoggerFactory.getLogger(Slf4jSkipListener.class); 17 | 18 | // TODO 02 override the onSkipInRead method and log the exception message 19 | // use the warn level 20 | 21 | } 22 | -------------------------------------------------------------------------------- /logging-skipped-items-start/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,09-23-2010 5 | Hing,Senecal,2010-03-04 6 | Kannan,Pirkle,2010-03-04 7 | Row,Maudrie,2010-03-04,extra column 8 | Voort,Philbeck,2010-03-04 -------------------------------------------------------------------------------- /logging-skipped-items-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /logging-skipped-items-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /presentation/dynamic-job-parameters.tex: -------------------------------------------------------------------------------- 1 | \section{Dynamic job parameters} 2 | 3 | \begin{frame} 4 | \begin{itemize} 5 | \item Problem: passing values to the configuration when launching a job 6 | \item Solution: using job parameters and late binding 7 | \end{itemize} 8 | \end{frame} 9 | 10 | \begin{frame}[fragile] 11 | \frametitle{Dynamically providing an input file to the item reader} 12 | 13 | \begin{itemize} 14 | \item Launching the job with an \code{input.file} parameter: 15 | \end{itemize} 16 | \begin{javacode} 17 | JobParameters jobParameters = new JobParametersBuilder() 18 | .addString("input.file", "file:./input/contacts-01.txt") 19 | .toJobParameters(); 20 | JobExecution execution = jobLauncher.run(job, jobParameters); 21 | \end{javacode} 22 | \begin{itemize} 23 | \item Referring to the \code{input.file} parameter in the configuration: 24 | \end{itemize} 25 | \begin{xmlcode} 26 | 29 | 30 | (...) 31 | 32 | \end{xmlcode} 33 | \end{frame} 34 | 35 | \begin{frame} 36 | \frametitle{Going further...} 37 | \begin{itemize} 38 | \item Spring Expression Language (SpEL) 39 | \item Step scope for partitioning 40 | \end{itemize} 41 | \end{frame} 42 | 43 | -------------------------------------------------------------------------------- /presentation/figures/after-cc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/figures/after-cc.png -------------------------------------------------------------------------------- /presentation/figures/before-cc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/figures/before-cc.png -------------------------------------------------------------------------------- /presentation/figures/code-completion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/figures/code-completion.png -------------------------------------------------------------------------------- /presentation/figures/configure-content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/figures/configure-content.png -------------------------------------------------------------------------------- /presentation/figures/content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/figures/content.png -------------------------------------------------------------------------------- /presentation/figures/enable-task-tags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/figures/enable-task-tags.png -------------------------------------------------------------------------------- /presentation/figures/input-files-partitioning.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/figures/input-files-partitioning.pdf -------------------------------------------------------------------------------- /presentation/figures/input-files-serial.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/figures/input-files-serial.pdf -------------------------------------------------------------------------------- /presentation/figures/jobinstance.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/figures/jobinstance.pdf -------------------------------------------------------------------------------- /presentation/figures/logo_zenika.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/figures/logo_zenika.png -------------------------------------------------------------------------------- /presentation/figures/spring-integration-ftp-poller.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/figures/spring-integration-ftp-poller.pdf -------------------------------------------------------------------------------- /presentation/figures/tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/figures/tasks.png -------------------------------------------------------------------------------- /presentation/ide-spring-support.tex: -------------------------------------------------------------------------------- 1 | \section{Spring support in IDE} 2 | 3 | \begin{frame} 4 | \frametitle{Spring support in IDE is a +} 5 | 6 | \begin{itemize} 7 | \item e.g. code completion in SpringSource Tool Suite 8 | \end{itemize} 9 | 10 | \begin{figure} 11 | \begin{center} 12 | \includegraphics[width=10cm]{figures/before-cc.png} 13 | \end{center} 14 | \end{figure} 15 | 16 | \begin{center} 17 | \begin{picture}(0,0) 18 | \put(0,15){\vector(0,-1){15}} 19 | \end{picture} 20 | \end{center} 21 | 22 | \begin{figure} 23 | \begin{center} 24 | \includegraphics[width=10cm]{figures/after-cc.png} 25 | \title{Code completion in SpringSource Tool Suite} 26 | \end{center} 27 | \end{figure} 28 | 29 | \end{frame} 30 | 31 | \begin{frame}[fragile] 32 | \frametitle{Shortened package names} 33 | \begin{itemize} 34 | \item{Be careful, a package name can sometimes be shortened} 35 | \end{itemize} 36 | \begin{xmlcode} 37 | 38 | \end{xmlcode} 39 | \begin{itemize} 40 | \item{Type the name of the class, code completion will do the rest...} 41 | \end{itemize} 42 | \begin{xmlcode} 43 | 44 | \end{xmlcode} 45 | \end{frame} 46 | 47 | -------------------------------------------------------------------------------- /presentation/overview-advanced.tex: -------------------------------------------------------------------------------- 1 | \section{Overview} 2 | 3 | \begin{frame} 4 | \frametitle{Overview} 5 | \begin{itemize} 6 | \item This workshop highlights advanced Spring Batch features 7 | \item Problem/solution approach 8 | \begin{itemize} 9 | \item A few slides to cover the feature 10 | \item A project to start from, just follow the TODOs 11 | \end{itemize} 12 | \item Prerequisites 13 | \begin{itemize} 14 | \item Basics about Java and Java EE 15 | \item Spring: dependency injection, enterprise support 16 | \item Spring Batch: what the first workshop covers 17 | \end{itemize} 18 | \item https://github.com/acogoluegnes/Spring-Batch-Workshop 19 | \end{itemize} 20 | 21 | \end{frame} 22 | 23 | \begin{frame} 24 | \frametitle{License} 25 | 26 | This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 27 | Unported License. 28 | 29 | To view a copy of this license, 30 | visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or 31 | send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, 32 | California, 94041, USA. 33 | 34 | \end{frame} 35 | -------------------------------------------------------------------------------- /presentation/overview.tex: -------------------------------------------------------------------------------- 1 | \section{Overview} 2 | 3 | \begin{frame} 4 | \frametitle{Overview} 5 | \begin{itemize} 6 | \item This workshop highlights Spring Batch features 7 | \item Problem/solution approach 8 | \begin{itemize} 9 | \item A few slides to cover the feature 10 | \item A project to start from, just follow the TODOs 11 | \end{itemize} 12 | \item Prerequisites 13 | \begin{itemize} 14 | \item Basics about Java and Java EE 15 | \item Spring: dependency injection, enterprise support 16 | \end{itemize} 17 | \item https://github.com/acogoluegnes/Spring-Batch-Workshop 18 | \end{itemize} 19 | 20 | \end{frame} 21 | 22 | \begin{frame} 23 | \frametitle{License} 24 | 25 | This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 26 | Unported License. 27 | 28 | To view a copy of this license, 29 | visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or 30 | send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, 31 | California, 94041, USA. 32 | 33 | \end{frame} 34 | -------------------------------------------------------------------------------- /presentation/scheduling.tex: -------------------------------------------------------------------------------- 1 | \section{Scheduling} 2 | 3 | \begin{frame} 4 | \begin{itemize} 5 | \item Problem: scheduling a job to execute periodically 6 | \item Solution: using the scheduling support in Spring 7 | \end{itemize} 8 | \end{frame} 9 | 10 | \begin{frame}[fragile] 11 | \frametitle{A class to launch the job} 12 | \begin{javacode} 13 | public class ImportLauncher { 14 | 15 | public void launch() throws Exception { 16 | JobExecution exec = jobLauncher.run( 17 | job, 18 | new JobParametersBuilder() 19 | .addLong("time", System.currentTimeMillis()) 20 | .toJobParameters() 21 | ); 22 | } 23 | } 24 | \end{javacode} 25 | \end{frame} 26 | 27 | \begin{frame}[fragile] 28 | \frametitle{Spring scheduling configuration} 29 | \begin{xmlcode} 30 | 32 | 33 | 34 | 36 | 37 | \end{xmlcode} 38 | \begin{itemize} 39 | \item \code{cron} attribute available 40 | \end{itemize} 41 | 42 | \end{frame} 43 | 44 | \begin{frame} 45 | \frametitle{Going further...} 46 | \begin{itemize} 47 | \item Threading settings in Spring Scheduler 48 | \item Spring support for Quartz 49 | \end{itemize} 50 | \end{frame} 51 | 52 | -------------------------------------------------------------------------------- /presentation/spring-batch-overview.tex: -------------------------------------------------------------------------------- 1 | \section{Spring Batch overview} 2 | 3 | \begin{frame} 4 | \frametitle{Basic features for batch applications} 5 | \begin{itemize} 6 | \item Read – process – write large amounts of data, efficiently 7 | \item Ready-to-use components to read from/write to 8 | \begin{itemize} 9 | \item Flat/XML files 10 | \item Databases (JDBC, Hibernate, JPA, iBatis) 11 | \item JMS queues 12 | \item Emails 13 | \end{itemize} 14 | \item Numerous extension points/hooks 15 | \end{itemize} 16 | 17 | \end{frame} 18 | 19 | \begin{frame} 20 | \frametitle{Advanced features for batch applications} 21 | \begin{itemize} 22 | \item Configuration to skip/retry items 23 | \item Execution metadata 24 | \begin{itemize} 25 | \item Monitoring 26 | \item Restart after failure 27 | \end{itemize} 28 | \item Scaling strategies 29 | \begin{itemize} 30 | \item Local/remote 31 | \item Partitioning, remote processing 32 | \end{itemize} 33 | \end{itemize} 34 | \end{frame} 35 | 36 | -------------------------------------------------------------------------------- /presentation/spring-batch-workshop-advanced.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/spring-batch-workshop-advanced.pdf -------------------------------------------------------------------------------- /presentation/spring-batch-workshop.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acogoluegnes/Spring-Batch-Workshop/5f07095e873cb7b0a17031456e115b9d2c11d5a9/presentation/spring-batch-workshop.pdf -------------------------------------------------------------------------------- /scheduling-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | scheduling-solution 12 | 13 | 14 | 15 | 16 | com.jayway.awaitility 17 | awaitility 18 | 1.3.1 19 | test 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /scheduling-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /scheduling-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * @see org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet(org.springframework.batch.item.file.transform.FieldSet) 19 | */ 20 | @Override 21 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 22 | return new Contact( 23 | fieldSet.readString("firstname"), 24 | fieldSet.readString("lastname"), 25 | fieldSet.readDate("birth","yyyy-MM-dd") 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /scheduling-solution/src/main/java/com/zenika/workshop/springbatch/ImportLauncher.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.batch.core.Job; 9 | import org.springframework.batch.core.JobExecution; 10 | import org.springframework.batch.core.JobParametersBuilder; 11 | import org.springframework.batch.core.launch.JobLauncher; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | 14 | /** 15 | * @author acogoluegnes 16 | * 17 | */ 18 | public class ImportLauncher { 19 | 20 | private static final Logger LOG = LoggerFactory.getLogger(ImportLauncher.class); 21 | 22 | @Autowired 23 | private Job job; 24 | 25 | @Autowired 26 | private JobLauncher jobLauncher; 27 | 28 | public void launch() throws Exception { 29 | JobExecution exec = jobLauncher.run( 30 | job, 31 | new JobParametersBuilder() 32 | .addLong("time", System.currentTimeMillis()) 33 | .toJobParameters() 34 | ); 35 | LOG.info("job ended with status {}",exec); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /scheduling-solution/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /scheduling-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /scheduling-solution/src/test/java/com/zenika/workshop/springbatch/SchedulingTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import static com.jayway.awaitility.Awaitility.await; 7 | import static com.jayway.awaitility.Awaitility.to; 8 | import static org.hamcrest.Matchers.equalTo; 9 | 10 | import org.junit.Test; 11 | import org.junit.runner.RunWith; 12 | import org.springframework.batch.core.Job; 13 | import org.springframework.batch.core.explore.JobExplorer; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.test.context.ContextConfiguration; 16 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 17 | 18 | /** 19 | * @author acogoluegnes 20 | * 21 | */ 22 | @RunWith(SpringJUnit4ClassRunner.class) 23 | @ContextConfiguration("/scheduling-job.xml") 24 | public class SchedulingTest { 25 | 26 | @Autowired 27 | private JobExplorer jobExplorer; 28 | 29 | @Autowired 30 | private Job job; 31 | 32 | @Test public void scheduling() throws Exception { 33 | final int expectedJobInstances = 5; 34 | // default timeout is 10 s 35 | await().untilCall(to(this).getJobInstancesNumber(),equalTo(expectedJobInstances)); 36 | } 37 | 38 | public int getJobInstancesNumber() { 39 | return jobExplorer.getJobInstances(job.getName(), 0, Integer.MAX_VALUE).size(); 40 | } 41 | 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /scheduling-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /scheduling-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | scheduling-start 12 | 13 | 14 | 15 | 16 | com.jayway.awaitility 17 | awaitility 18 | 1.3.1 19 | test 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /scheduling-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /scheduling-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * @see org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet(org.springframework.batch.item.file.transform.FieldSet) 19 | */ 20 | @Override 21 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 22 | return new Contact( 23 | fieldSet.readString("firstname"), 24 | fieldSet.readString("lastname"), 25 | fieldSet.readDate("birth","yyyy-MM-dd") 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /scheduling-start/src/main/java/com/zenika/workshop/springbatch/ImportLauncher.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.batch.core.Job; 9 | import org.springframework.batch.core.JobExecution; 10 | import org.springframework.batch.core.launch.JobLauncher; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class ImportLauncher { 18 | 19 | private static final Logger LOG = LoggerFactory.getLogger(ImportLauncher.class); 20 | 21 | @Autowired 22 | private Job job; 23 | 24 | @Autowired 25 | private JobLauncher jobLauncher; 26 | 27 | public void launch() throws Exception { 28 | // TODO 01 launch the job with a Long parameter = System.currentTimeMillis()) 29 | // hint: use the JobParametersBuilder class and the addLong method to create the job parameters 30 | JobExecution exec = null; 31 | LOG.info("job ended with status {}",exec); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /scheduling-start/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,2010-03-04 5 | Hing,Senecal,2010-03-04 -------------------------------------------------------------------------------- /scheduling-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /scheduling-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /skip-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | skip-solution 12 | 13 | 14 | -------------------------------------------------------------------------------- /skip-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /skip-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /skip-solution/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /skip-solution/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,09-23-2010 5 | Hing,Senecal,2010-03-04 6 | Kannan,Pirkle,2010-03-04 7 | Row,Maudrie,2010-03-04 8 | Voort,Philbeck,2010-03-04 -------------------------------------------------------------------------------- /skip-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /skip-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /skip-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | skip-start 12 | 13 | 14 | -------------------------------------------------------------------------------- /skip-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /skip-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /skip-start/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /skip-start/src/main/resources/contacts.txt: -------------------------------------------------------------------------------- 1 | De-Anna,Raghunath,2010-03-04 2 | Susy,Hauerstock,2010-03-04 3 | Kiam,Whitehurst,2010-03-04 4 | Alecia,Van Holst,09-23-2010 5 | Hing,Senecal,2010-03-04 6 | Kannan,Pirkle,2010-03-04 7 | Row,Maudrie,2010-03-04 8 | Voort,Philbeck,2010-03-04 -------------------------------------------------------------------------------- /skip-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /skip-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /xml-file-reading-solution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | xml-file-reading-solution 12 | 13 | 14 | 15 | org.springframework 16 | spring-oxm 17 | ${spring.version} 18 | 19 | 20 | com.thoughtworks.xstream 21 | xstream 22 | ${xstream.version} 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /xml-file-reading-solution/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Contact() { } 28 | 29 | public Long getId() { 30 | return id; 31 | } 32 | 33 | public String getFirstname() { 34 | return firstname; 35 | } 36 | 37 | public String getLastname() { 38 | return lastname; 39 | } 40 | 41 | public Date getBirth() { 42 | return birth; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 48 | + lastname + ", birth=" + birth + "]"; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /xml-file-reading-solution/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /xml-file-reading-solution/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /xml-file-reading-solution/src/main/resources/contacts.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | De-Anna 5 | Raghunath 6 | 2010-03-04 7 | 8 | 9 | Susy 10 | Hauerstock 11 | 2010-03-04 12 | 13 | 14 | Kiam 15 | Whitehusrt 16 | 2010-03-04 17 | 18 | 19 | Alecia 20 | Van Holst 21 | 2010-03-04 22 | 23 | 24 | Hing 25 | Senecal 26 | 2010-03-04 27 | 28 | -------------------------------------------------------------------------------- /xml-file-reading-solution/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /xml-file-reading-solution/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /xml-file-reading-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springbatch 8 | com.zenika.workshop 9 | 1.0.0 10 | 11 | xml-file-reading-start 12 | 13 | 14 | 15 | org.springframework 16 | spring-oxm 17 | ${spring.version} 18 | 19 | 20 | com.thoughtworks.xstream 21 | xstream 22 | ${xstream.version} 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /xml-file-reading-start/src/main/java/com/zenika/workshop/springbatch/Contact.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author acogoluegnes 10 | * 11 | */ 12 | public class Contact { 13 | 14 | private Long id; 15 | 16 | private String firstname,lastname; 17 | 18 | private Date birth; 19 | 20 | public Contact(String firstname, String lastname, Date birth) { 21 | super(); 22 | this.firstname = firstname; 23 | this.lastname = lastname; 24 | this.birth = birth; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public String getFirstname() { 32 | return firstname; 33 | } 34 | 35 | public String getLastname() { 36 | return lastname; 37 | } 38 | 39 | public Date getBirth() { 40 | return birth; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Contact [id=" + id + ", firstname=" + firstname + ", lastname=" 46 | + lastname + ", birth=" + birth + "]"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /xml-file-reading-start/src/main/java/com/zenika/workshop/springbatch/ContactFieldSetMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import org.springframework.batch.item.file.mapping.FieldSetMapper; 7 | import org.springframework.batch.item.file.transform.FieldSet; 8 | import org.springframework.validation.BindException; 9 | 10 | /** 11 | * @author acogoluegnes 12 | * 13 | */ 14 | public class ContactFieldSetMapper implements FieldSetMapper { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @see 20 | * org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet 21 | * (org.springframework.batch.item.file.transform.FieldSet) 22 | */ 23 | @Override 24 | public Contact mapFieldSet(FieldSet fieldSet) throws BindException { 25 | return new Contact( 26 | fieldSet.readString("firstname"), 27 | fieldSet.readString("lastname"), 28 | fieldSet.readDate("birth","yyyy-MM-dd") 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /xml-file-reading-start/src/main/java/com/zenika/workshop/springbatch/JdbcContactItemWriter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.zenika.workshop.springbatch; 5 | 6 | import java.util.List; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.springframework.batch.item.ItemWriter; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | 13 | /** 14 | * @author acogoluegnes 15 | * 16 | */ 17 | public class JdbcContactItemWriter implements ItemWriter { 18 | 19 | private JdbcTemplate jdbcTemplate; 20 | 21 | public JdbcContactItemWriter(DataSource dataSource) { 22 | this.jdbcTemplate = new JdbcTemplate(dataSource); 23 | } 24 | 25 | /* (non-Javadoc) 26 | * @see org.springframework.batch.item.ItemWriter#write(java.util.List) 27 | */ 28 | @Override 29 | public void write(List items) throws Exception { 30 | for(Contact item : items) { 31 | Long id = jdbcTemplate.queryForObject("select contact_seq.nextval from dual",Long.class).longValue(); 32 | jdbcTemplate.update( 33 | "insert into contact (id,firstname,lastname,birth) values (?,?,?,?)", 34 | id,item.getFirstname(),item.getLastname(),item.getBirth() 35 | ); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /xml-file-reading-start/src/main/resources/contacts.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | De-Anna 5 | Raghunath 6 | 2010-03-04 7 | 8 | 9 | Susy 10 | Hauerstock 11 | 2010-03-04 12 | 13 | 14 | Kiam 15 | Whitehusrt 16 | 2010-03-04 17 | 18 | 19 | Alecia 20 | Van Holst 21 | 2010-03-04 22 | 23 | 24 | Hing 25 | Senecal 26 | 2010-03-04 27 | 28 | -------------------------------------------------------------------------------- /xml-file-reading-start/src/main/resources/create-tables.sql: -------------------------------------------------------------------------------- 1 | create table contact( 2 | id int, 3 | firstname varchar(255), 4 | lastname varchar(255), 5 | birth date 6 | ); 7 | 8 | create sequence contact_seq; -------------------------------------------------------------------------------- /xml-file-reading-start/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | --------------------------------------------------------------------------------