├── .gitattributes ├── .github └── workflows │ ├── build-main.yml │ └── release-to-maven-central.yml ├── .gitignore ├── LICENSE.TXT ├── README.md ├── batch-web-spring-boot-autoconfigure ├── pom.xml └── src │ ├── main │ ├── java │ │ └── de │ │ │ └── codecentric │ │ │ └── batch │ │ │ ├── configuration │ │ │ ├── AutomaticJobRegistrarConfiguration.java │ │ │ ├── AutomaticJobRegistrarConfigurationSupport.java │ │ │ ├── BatchConfigurationProperties.java │ │ │ ├── BatchWebAutoConfiguration.java │ │ │ ├── Jsr352BatchConfiguration.java │ │ │ ├── ListenerProvider.java │ │ │ ├── MetricsConfiguration.java │ │ │ ├── StepExecutionJacksonMixIn.java │ │ │ ├── TaskExecutorBatchConfiguration.java │ │ │ ├── TaskExecutorConfiguration.java │ │ │ └── WebConfig.java │ │ │ ├── jsr352 │ │ │ └── CustomJsrJobOperator.java │ │ │ ├── listener │ │ │ ├── AddListenerToJobService.java │ │ │ ├── JobLoggingApplicationListener.java │ │ │ ├── LoggingAfterJobListener.java │ │ │ ├── LoggingListener.java │ │ │ ├── ProtocolListener.java │ │ │ └── RunningExecutionTrackerListener.java │ │ │ ├── logging │ │ │ ├── DefaultJobLogFileNameCreator.java │ │ │ └── JobLogFileNameCreator.java │ │ │ ├── metrics │ │ │ ├── AbstractBatchMetricsAspect.java │ │ │ ├── BatchMetrics.java │ │ │ ├── BatchMetricsImpl.java │ │ │ ├── MetricsListener.java │ │ │ ├── MetricsOutputFormatter.java │ │ │ └── ReaderProcessorWriterMetricsAspect.java │ │ │ ├── monitoring │ │ │ └── RunningExecutionTracker.java │ │ │ ├── scheduling │ │ │ └── concurrent │ │ │ │ └── MdcThreadPoolTaskExecutor.java │ │ │ └── web │ │ │ ├── JobMonitoringController.java │ │ │ └── JobOperationsController.java │ └── resources │ │ ├── META-INF │ │ ├── additional-spring-configuration-metadata.json │ │ └── spring.factories │ │ ├── batch-web-spring-boot-autoconfigure.properties │ │ └── logback-batch-base.xml │ └── test │ ├── java │ └── de │ │ └── codecentric │ │ └── batch │ │ ├── AutoconfigureBatchWebStarter.java │ │ ├── MetricsTestApplication.java │ │ ├── TestApplication.java │ │ ├── TestConfiguration.java │ │ ├── TestListenerConfiguration.java │ │ ├── item │ │ ├── DelayItemProcessor.java │ │ ├── DummyItemReader.java │ │ ├── LogItemProcessor.java │ │ ├── LogItemWriteListener.java │ │ ├── LogItemWriter.java │ │ └── MetricsItemProcessor.java │ │ ├── jobs │ │ ├── DelayJobConfiguration.java │ │ ├── FlatFileJobConfiguration.java │ │ ├── FlatFileToDbNoSkipJobConfiguration.java │ │ ├── FlatFileToDbSkipJobConfiguration.java │ │ ├── FlatFileToDbSkipProcessorNonTransactionalJobConfiguration.java │ │ ├── FlatFileToDbSkipReaderTransactionalJobConfiguration.java │ │ ├── IncrementerJobConfiguration.java │ │ ├── SimpleBatchMetricsJobConfiguration.java │ │ └── SimpleJobConfiguration.java │ │ ├── listener │ │ ├── ProtocolListenerTest.java │ │ └── TestListener.java │ │ ├── metrics │ │ ├── Action.java │ │ ├── BatchMetricsImplTest.java │ │ ├── Item.java │ │ ├── ListenerMetricsAspect.java │ │ ├── MetricNames.java │ │ ├── MetricsTestException.java │ │ └── item │ │ │ ├── MetricsTestChunkListener.java │ │ │ ├── MetricsTestItemProcessListener.java │ │ │ ├── MetricsTestItemProcessor.java │ │ │ ├── MetricsTestItemReadListener.java │ │ │ ├── MetricsTestItemReader.java │ │ │ ├── MetricsTestItemWriteListener.java │ │ │ ├── MetricsTestItemWriter.java │ │ │ └── MetricsTestSkipListener.java │ │ ├── scheduling │ │ └── concurrent │ │ │ └── MdcThreadPoolTaskExecutorTest.java │ │ └── test │ │ ├── FlatFileJobTest.java │ │ ├── JavaConfigIntegrationTest.java │ │ ├── JobParametersIncrementerIntegrationTest.java │ │ ├── Jsr352IntegrationTest.java │ │ ├── ListenerProviderIntegrationTest.java │ │ ├── PartitionedFlatFileJobTest.java │ │ ├── StopJobIntegrationTest.java │ │ ├── XmlIntegrationTest.java │ │ └── metrics │ │ ├── BatchMetricsAspectIntegrationTest.java │ │ ├── BatchMetricsExporterIntegrationTest.java │ │ ├── BatchMetricsFlatFileToDbIntegrationTest.java │ │ ├── MetricValidator.java │ │ └── MetricValidatorBuilder.java │ └── resources │ ├── META-INF │ ├── batch-jobs │ │ └── simpleJsr352Job.xml │ └── spring │ │ └── batch │ │ └── jobs │ │ ├── flat-file-2-job.xml │ │ ├── flat-file-job.xml │ │ └── partitioned-flat-file-job.xml │ ├── application.properties │ ├── in-javaconfig.txt │ ├── in-xmlconfig.txt │ ├── logback.xml │ ├── metrics │ ├── create-schema.sql │ ├── flatFileToDbNoSkipJob_Failed.csv │ ├── flatFileToDbNoSkipJob_Restart_FirstRun.csv │ ├── flatFileToDbNoSkipJob_Restart_SecondRun.csv │ ├── flatFileToDbNoSkipJob_Success.csv │ ├── flatFileToDbSkipJob_SkipInProcess.csv │ ├── flatFileToDbSkipJob_SkipInProcess_Failed.csv │ ├── flatFileToDbSkipJob_SkipInRead.csv │ └── flatFileToDbSkipJob_SkipInWrite.csv │ ├── partition-1.txt │ └── partition-2.txt ├── batch-web-spring-boot-build └── pom.xml ├── batch-web-spring-boot-dependencies └── pom.xml ├── batch-web-spring-boot-docs ├── deploy-gh-pages.sh ├── pom.xml └── src │ └── main │ └── asciidoc │ └── index.adoc ├── batch-web-spring-boot-samples ├── batch-boot-file-to-db │ ├── .gitignore │ ├── README.md │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ │ └── de │ │ │ │ │ └── codecentric │ │ │ │ │ └── batch │ │ │ │ │ └── filetodb │ │ │ │ │ ├── Application.java │ │ │ │ │ ├── configuration │ │ │ │ │ └── DataSourceConfiguration.java │ │ │ │ │ ├── domain │ │ │ │ │ └── Partner.java │ │ │ │ │ └── item │ │ │ │ │ ├── ExampleService.java │ │ │ │ │ └── LogItemProcessor.java │ │ │ └── resources │ │ │ │ ├── META-INF │ │ │ │ └── spring │ │ │ │ │ └── batch │ │ │ │ │ └── jobs │ │ │ │ │ └── flatfile-job-context.xml │ │ │ │ ├── application.properties │ │ │ │ ├── logback.xml │ │ │ │ ├── partner-import.csv │ │ │ │ └── schema-partner.sql │ │ └── test │ │ │ └── java │ │ │ └── de │ │ │ └── codecentric │ │ │ └── batch │ │ │ └── filetodb │ │ │ ├── ApplicationTests.java │ │ │ └── FlatFileJobIntegrationTest.java │ └── startBatchApplication.launch ├── batch-boot-simple-jsr352 │ ├── .gitignore │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── de │ │ │ │ └── codecentric │ │ │ │ └── batch │ │ │ │ └── simplejsr │ │ │ │ ├── Application.java │ │ │ │ └── item │ │ │ │ ├── DummyItemReader.java │ │ │ │ ├── LogItemProcessor.java │ │ │ │ ├── LogItemWriter.java │ │ │ │ ├── PartitionedItemReader.java │ │ │ │ └── SimplePartitionMapper.java │ │ └── resources │ │ │ ├── META-INF │ │ │ ├── batch-jobs │ │ │ │ ├── partitionMapperJobNoDI.xml │ │ │ │ ├── partitionMapperJobSpringDI.xml │ │ │ │ ├── partitionMapperJobSpringDIBatchXml.xml │ │ │ │ ├── partitionedJobNoDI.xml │ │ │ │ ├── partitionedJobSpringDI.xml │ │ │ │ └── simpleJob.xml │ │ │ └── batch.xml │ │ │ ├── application.properties │ │ │ └── logback.xml │ │ └── test │ │ └── java │ │ └── de │ │ └── codecentric │ │ └── batch │ │ └── simplejsr │ │ ├── ApplicationTests.java │ │ └── TraditionalJsr352Test.java ├── batch-boot-simple │ ├── .gitignore │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── de │ │ │ │ └── codecentric │ │ │ │ └── batch │ │ │ │ └── simple │ │ │ │ ├── Application.java │ │ │ │ ├── item │ │ │ │ ├── DummyItemReader.java │ │ │ │ ├── LogItemProcessor.java │ │ │ │ └── LogItemWriter.java │ │ │ │ └── job │ │ │ │ └── SimpleJobConfiguration.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── logback.xml │ │ │ ├── monitoring.http │ │ │ └── operations.http │ │ └── test │ │ └── java │ │ └── de │ │ └── codecentric │ │ └── batch │ │ └── simple │ │ └── ApplicationTests.java └── pom.xml ├── batch-web-spring-boot-starter └── pom.xml └── pom.xml /.gitattributes: -------------------------------------------------------------------------------- 1 | # All text files should have the "lf" (Unix) line endings 2 | * text eol=lf 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.java text 7 | *.js text 8 | *.css text 9 | *.html text 10 | *.properties text 11 | *.xml text 12 | *.yml text 13 | 14 | # Denote all files that are truly binary and should not be modified. 15 | *.png binary 16 | *.jpg binary 17 | *.jar binary 18 | -------------------------------------------------------------------------------- /.github/workflows/build-main.yml: -------------------------------------------------------------------------------- 1 | name: build main 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | strategy: 11 | matrix: 12 | os: [ubuntu-latest] 13 | 14 | runs-on: ${{ matrix.os }} 15 | steps: 16 | 17 | - uses: actions/checkout@v3 18 | 19 | - name: Set up JDK 8 20 | uses: actions/setup-java@v3 21 | with: 22 | distribution: 'temurin' 23 | java-version: '8' 24 | 25 | - name: Cache local Maven repository 26 | uses: actions/cache@v2.1.7 27 | env: 28 | cache-name: cache-mvn 29 | with: 30 | path: ~/.m2/repository 31 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/pom.xml') }} 32 | restore-keys: | 33 | ${{ runner.os }}-build-${{ env.cache-name }}- 34 | ${{ runner.os }}-build- 35 | ${{ runner.os }}- 36 | 37 | - name: Build Tag with Maven 38 | if: ${{ github.ref_type == 'tag' }} 39 | run: | 40 | mvn -B clean verify -Pcoverage -Drevision=${{ github.ref_name }} 41 | 42 | - name: Build Branch with Maven 43 | if: ${{ github.ref_type == 'branch' }} 44 | run: | 45 | mvn -B clean verify -Pcoverage 46 | 47 | - uses: codecov/codecov-action@v2 48 | with: 49 | files: "**/target/site/jacoco/jacoco.xml" 50 | 51 | publish-snapshot: 52 | needs: build 53 | runs-on: ubuntu-latest 54 | 55 | steps: 56 | - uses: actions/checkout@v3 57 | 58 | - name: Set up settings.xml for GitHub Packages 59 | uses: actions/setup-java@v3 60 | with: 61 | distribution: 'temurin' 62 | java-version: '8' 63 | 64 | - name: Cache local Maven repository 65 | uses: actions/cache@v2.1.7 66 | env: 67 | cache-name: cache-mvn 68 | with: 69 | path: ~/.m2/repository 70 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/pom.xml') }} 71 | restore-keys: | 72 | ${{ runner.os }}-build-${{ env.cache-name }}- 73 | ${{ runner.os }}-build- 74 | ${{ runner.os }}- 75 | 76 | - name: Publish SNAPSHOT version to GitHub Packages (we can skip tests, since we only deploy, if the build workflow succeeded) 77 | run: mvn -B --no-transfer-progress deploy -DskipTests 78 | env: 79 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 80 | 81 | - name: Extract Maven project version for Asciidoc GitHub Pages directory naming 82 | run: echo ::set-output name=version::$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec) 83 | id: project 84 | 85 | - name: Show extracted Maven project version 86 | run: echo ${{ steps.project.outputs.version }} 87 | 88 | - name: Deploy Asciidoc docs output to GitHub Pages 89 | uses: JamesIves/github-pages-deploy-action@v4.3.3 90 | with: 91 | branch: gh-pages # The branch the action should deploy to. 92 | folder: batch-web-spring-boot-docs/target/generated-docs # The folder the action should deploy. 93 | target-folder: ${{ steps.project.outputs.version }} 94 | clean: true # Automatically remove deleted files from the deploy branch 95 | -------------------------------------------------------------------------------- /.github/workflows/release-to-maven-central.yml: -------------------------------------------------------------------------------- 1 | name: release-to-maven-central 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | releaseversion: 7 | description: 'Release version' 8 | required: true 9 | default: '2.4.0' 10 | 11 | jobs: 12 | publish-central-and-pages: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - run: echo "Will start a Maven Central upload with version ${{ github.event.inputs.releaseversion }}" 16 | 17 | - uses: actions/checkout@v3 18 | 19 | - name: Set up settings.xml for Maven Central Repository 20 | uses: actions/setup-java@v3 21 | with: 22 | distribution: 'temurin' 23 | java-version: '8' 24 | server-id: oss.sonatype.org 25 | server-username: MAVEN_USERNAME 26 | server-password: MAVEN_PASSWORD 27 | gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} 28 | gpg-passphrase: MAVEN_GPG_PASSPHRASE 29 | 30 | - name: Cache local Maven repository 31 | uses: actions/cache@v2.1.7 32 | env: 33 | cache-name: cache-mvn 34 | with: 35 | path: ~/.m2/repository 36 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/pom.xml') }} 37 | restore-keys: | 38 | ${{ runner.os }}-build-${{ env.cache-name }}- 39 | ${{ runner.os }}-build- 40 | ${{ runner.os }}- 41 | 42 | - name: Set projects Maven version to GitHub Action GUI set version 43 | run: mvn versions:set "-DnewVersion=${{ github.event.inputs.releaseversion }}" --no-transfer-progress 44 | 45 | - name: Publish package 46 | run: mvn --batch-mode clean deploy --no-transfer-progress -P central-deploy -DskipTests=true 47 | env: 48 | MAVEN_USERNAME: ${{ secrets.OSS_SONATYPE_USERNAME }} 49 | MAVEN_PASSWORD: ${{ secrets.OSS_SONATYPE_PASSWORD }} 50 | MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} 51 | 52 | - name: Deploy Asciidoc docs output to GitHub Pages 53 | uses: JamesIves/github-pages-deploy-action@v4.3.3 54 | with: 55 | branch: gh-pages # The branch the action should deploy to. 56 | folder: batch-web-spring-boot-docs/target/generated-docs # The folder the action should deploy. 57 | target-folder: ${{ github.event.inputs.releaseversion }} 58 | clean: true # Automatically remove deleted files from the deploy branch 59 | 60 | 61 | publish-github-release: 62 | needs: publish-central-and-pages 63 | runs-on: ubuntu-latest 64 | 65 | steps: 66 | - uses: actions/checkout@v3 67 | 68 | - name: Generate changelog 69 | id: changelog 70 | uses: metcalfc/changelog-generator@v3.0.0 71 | with: 72 | myToken: ${{ secrets.GITHUB_TOKEN }} 73 | 74 | - name: Create GitHub Release 75 | id: create_release 76 | uses: actions/create-release@v1 77 | env: 78 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 79 | with: 80 | tag_name: ${{ github.event.inputs.releaseversion }} 81 | release_name: ${{ github.event.inputs.releaseversion }} 82 | body: | 83 | Grab the new version from Maven central https://repo1.maven.org/maven2/de/codecentric/ 84 | 85 | Current docs at https://codecentric.github.io/spring-boot-starter-batch-web/${{ github.event.inputs.releaseversion }}/ 86 | 87 | ### Things that changed in this release 88 | ${{ steps.changelog.outputs.changelog }} 89 | draft: false 90 | prerelease: ${{ contains(github.event.inputs.releaseversion, '-') }} 91 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Maven 2 | target/ 3 | .flattened-pom.xml 4 | 5 | # Eclipse 6 | .settings/ 7 | .classpath 8 | .project 9 | .factorypath 10 | 11 | # Intellij 12 | .idea/ 13 | *.iml 14 | *.iws 15 | 16 | # Apple 17 | .DS_Store 18 | 19 | # GnuPG keyring 20 | /.gnupg 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Enterprise-ready production-ready batch applications powered by Spring Boot 2 | ============================= 3 | [![Build Status](https://github.com/codecentric/spring-boot-starter-batch-web/actions/workflows/build-main.yml/badge.svg)](https://github.com/codecentric/spring-boot-starter-batch-web/actions/workflows/build-main.yml) 4 | [![Coverage Status](https://codecov.io/gh/codecentric/spring-boot-starter-batch-web/branch/master/graph/badge.svg?token=F02AqwYUBa)](https://codecov.io/gh/codecentric/spring-boot-starter-batch-web) 5 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/de.codecentric/batch-web-spring-boot-starter/badge.svg)](https://maven-badges.herokuapp.com/maven-central/de.codecentric/batch-web-spring-boot-starter/) 6 | [![License](http://img.shields.io/:license-apache-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) 7 | 8 | The project batch-web-spring-boot-starter is a Spring Boot starter for Spring Batch taking care of everything except writing the jobs. 9 | 10 | See the documentation for detailed infos, examples and operational details. 11 | * [Latest Snapshot](http://codecentric.github.io/spring-boot-starter-batch-web/2.4.0.SNAPSHOT/) 12 | * [Version 2.3.0](http://codecentric.github.io/spring-boot-starter-batch-web/2.3.0/) 13 | * [Version 1.4.0.RELEASE](http://codecentric.github.io/spring-boot-starter-batch-web/1.4.0.RELEASE/) 14 | 15 | Features include: 16 | 17 | * Starting up a web application and automatically deploying batch jobs to it (JavaConfig, XML or JSR-352). 18 | * Log file separation, one log file for each job execution. 19 | * An operations http endpoint for starting and stopping jobs, for retrieving the BatchStatus and the log file. 20 | * A monitoring http endpoint for retrieving detailed information on a job execution, for knowing all deployed jobs and all running job executions. 21 | 22 | Take a look at the [Getting Started page](http://codecentric.github.io/spring-boot-starter-batch-web/current/#_getting_started). 23 | 24 | There are the following samples available: 25 | 26 | [batch-boot-simple](/batch-web-spring-boot-samples/batch-boot-simple): a very simple JavaConfig sample with an embedded database. 27 | 28 | [batch-boot-file-to-db](/batch-web-spring-boot-samples/batch-boot-file-to-db): a job configured in xml using job parameters that reads from a file and writes to a database. This sample demonstrates the usage of an external database. 29 | 30 | [batch-boot-simple-jsr352](/batch-web-spring-boot-samples/batch-boot-simple-jsr352): job samples in JSR-352 style. 31 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 20 | 4.0.0 21 | batch-web-spring-boot-autoconfigure 22 | Batch Web Spring Boot Autoconfigure 23 | 24 | de.codecentric 25 | batch-web-spring-boot-build 26 | ${revision} 27 | ../batch-web-spring-boot-build 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-batch 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-actuator 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-web 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-jdbc 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-aop 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-configuration-processor 57 | true 58 | 59 | 60 | org.springframework 61 | spring-messaging 62 | 63 | 64 | org.apache.commons 65 | commons-lang3 66 | 67 | 68 | 69 | 70 | org.springframework.boot 71 | spring-boot-starter-test 72 | test 73 | 74 | 75 | commons-io 76 | commons-io 77 | 2.11.0 78 | test 79 | 80 | 81 | org.hsqldb 82 | hsqldb 83 | test 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/configuration/AutomaticJobRegistrarConfigurationSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.configuration; 18 | 19 | import javax.annotation.PostConstruct; 20 | 21 | import org.springframework.batch.core.configuration.support.ApplicationContextFactory; 22 | import org.springframework.batch.core.configuration.support.AutomaticJobRegistrar; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.core.Ordered; 25 | 26 | /** 27 | * Extend this class to add custom {@link ApplicationContextFactory}. 28 | * 29 | * @author Thomas Bosch 30 | */ 31 | public abstract class AutomaticJobRegistrarConfigurationSupport { 32 | 33 | @Autowired 34 | private AutomaticJobRegistrar automaticJobRegistrar; 35 | 36 | @PostConstruct 37 | public void initialize() throws Exception { 38 | // Default order for the AutomaticJobRegistrar is Ordered.LOWEST_PRECEDENCE. Since we want to register 39 | // listeners after the jobs are registered through the AutomaticJobRegistrar, we need to decrement its 40 | // order value by one. The creation of the AutomaticJobRegistrar bean is hidden deep in the automatic 41 | // batch configuration, so we unfortunately have to do it here. 42 | automaticJobRegistrar.setOrder(Ordered.LOWEST_PRECEDENCE - 1); 43 | addApplicationContextFactories(automaticJobRegistrar); 44 | } 45 | 46 | /** 47 | * Add ApplicationContextFactories to the given job registrar. 48 | * 49 | * @param automaticJobRegistrar 50 | * Bean 51 | * @throws Exception 52 | * Some error. 53 | */ 54 | protected abstract void addApplicationContextFactories(AutomaticJobRegistrar automaticJobRegistrar) 55 | throws Exception; 56 | 57 | } 58 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/configuration/Jsr352BatchConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.configuration; 17 | 18 | import org.springframework.batch.core.configuration.JobRegistry; 19 | import org.springframework.batch.core.explore.JobExplorer; 20 | import org.springframework.batch.core.jsr.JsrJobParametersConverter; 21 | import org.springframework.batch.core.repository.JobRepository; 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | import org.springframework.core.task.TaskExecutor; 26 | import org.springframework.transaction.PlatformTransactionManager; 27 | 28 | import de.codecentric.batch.jsr352.CustomJsrJobOperator; 29 | 30 | import javax.sql.DataSource; 31 | 32 | /** 33 | * This configuration creates the components needed for starting JSR-352 style jobs. 34 | * 35 | * @author Tobias Flohre 36 | */ 37 | @Configuration 38 | public class Jsr352BatchConfiguration { 39 | 40 | @Autowired 41 | private JobExplorer jobExplorer; 42 | 43 | @Autowired 44 | private JobRepository jobRepository; 45 | 46 | @Autowired 47 | private DataSource dataSource; 48 | 49 | @Autowired 50 | private TaskExecutor taskExecutor; 51 | 52 | @Autowired 53 | private BatchWebAutoConfiguration batchWebAutoConfiguration; 54 | 55 | @Bean 56 | public CustomJsrJobOperator jsrJobOperator(PlatformTransactionManager transactionManager) throws Exception { 57 | CustomJsrJobOperator jsrJobOperator = new CustomJsrJobOperator(jobExplorer, jobRepository, jsrJobParametersConverter(), 58 | batchWebAutoConfiguration.addListenerToJobService(), transactionManager); 59 | jsrJobOperator.setTaskExecutor(taskExecutor); 60 | return jsrJobOperator; 61 | } 62 | 63 | public JsrJobParametersConverter jsrJobParametersConverter() throws Exception { 64 | JsrJobParametersConverter jsrJobParametersConverter = new JsrJobParametersConverter(dataSource); 65 | jsrJobParametersConverter.afterPropertiesSet(); 66 | return jsrJobParametersConverter; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/configuration/ListenerProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.configuration; 17 | 18 | import java.util.Set; 19 | 20 | import org.springframework.batch.core.JobExecutionListener; 21 | import org.springframework.batch.core.StepExecutionListener; 22 | 23 | /** 24 | * spring-boot-starter-batch-web automatically registers JobExecutionListeners and StepExecutionListeners at each Job 25 | * provided by Spring beans implementing this interface. 26 | * 27 | * @author Tobias Flohre 28 | */ 29 | public interface ListenerProvider { 30 | 31 | /** 32 | * Returns a set of JobExecutionListeners that will be added to each Job. May not return null. 33 | * 34 | * @return Returns a set of JobExecutionListeners that will be added to each Job. May not return null. 35 | */ 36 | public Set jobExecutionListeners(); 37 | 38 | /** 39 | * Returns a set of StepExecutionListeners that will be added to each Job. May not return null. 40 | * 41 | * @return Returns a set of StepExecutionListeners that will be added to each Job. May not return null. 42 | */ 43 | public Set stepExecutionListeners(); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/configuration/MetricsConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.configuration; 17 | 18 | import java.util.HashSet; 19 | import java.util.Set; 20 | 21 | import org.springframework.batch.core.JobExecutionListener; 22 | import org.springframework.batch.core.StepExecutionListener; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 25 | import org.springframework.context.annotation.Bean; 26 | import org.springframework.context.annotation.Configuration; 27 | 28 | import de.codecentric.batch.metrics.BatchMetricsImpl; 29 | import de.codecentric.batch.metrics.MetricsListener; 30 | import de.codecentric.batch.metrics.ReaderProcessorWriterMetricsAspect; 31 | import io.micrometer.core.instrument.MeterRegistry; 32 | 33 | /** 34 | * Configuration containing all metrics stuff. Can be activated by setting the property batch.metrics.enabled to true. 35 | * 36 | * @author Tobias Flohre 37 | */ 38 | @ConditionalOnProperty("batch.metrics.enabled") 39 | @Configuration 40 | public class MetricsConfiguration implements ListenerProvider { 41 | 42 | @Autowired 43 | private MeterRegistry meterRegistry; 44 | 45 | @Bean 46 | public BatchMetricsImpl batchMetrics() { 47 | return new BatchMetricsImpl(); 48 | } 49 | 50 | @ConditionalOnProperty("batch.metrics.profiling.readprocesswrite.enabled") 51 | @Bean 52 | public ReaderProcessorWriterMetricsAspect batchMetricsAspects() { 53 | return new ReaderProcessorWriterMetricsAspect(meterRegistry); 54 | } 55 | 56 | @Bean 57 | public MetricsListener metricsListener() { 58 | return new MetricsListener(meterRegistry); 59 | } 60 | 61 | @Override 62 | public Set jobExecutionListeners() { 63 | Set listeners = new HashSet<>(); 64 | listeners.add(metricsListener()); 65 | return listeners; 66 | } 67 | 68 | @Override 69 | public Set stepExecutionListeners() { 70 | Set listeners = new HashSet<>(); 71 | listeners.add(metricsListener()); 72 | return listeners; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/configuration/StepExecutionJacksonMixIn.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2014 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.configuration; 18 | 19 | import org.springframework.batch.core.JobExecution; 20 | import org.springframework.batch.core.StepExecution; 21 | 22 | import com.fasterxml.jackson.annotation.JsonIgnore; 23 | 24 | /** 25 | * Jackson MixIn for {@link StepExecution} serialization. This MixIn excludes the {@link JobExecution} from being 26 | * serialized. This is due to the fact that it would cause a {@link StackOverflowError} due to a circular reference. 27 | * 28 | * Taken from Spring XD. 29 | * 30 | * @author Gunnar Hillert 31 | */ 32 | public abstract class StepExecutionJacksonMixIn { 33 | 34 | @JsonIgnore 35 | abstract JobExecution getJobExecution(); 36 | } 37 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/configuration/TaskExecutorConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.configuration; 17 | 18 | import org.springframework.beans.factory.annotation.Autowired; 19 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 20 | import org.springframework.context.annotation.Bean; 21 | import org.springframework.context.annotation.Configuration; 22 | import org.springframework.core.task.TaskExecutor; 23 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 24 | 25 | import de.codecentric.batch.scheduling.concurrent.MdcThreadPoolTaskExecutor; 26 | 27 | /** 28 | * This is the default configuration for a {@link org.springframework.core.task.TaskExecutor} used in the 29 | * {@link org.springframework.batch.core.launch.support.SimpleJobLauncher} for starting jobs asynchronously. Its core 30 | * thread pool is configured to five threads by default, which can be changed by setting the property 31 | * batch.core.pool.size to a different number. 32 | * 33 | * Please note the following rules of the ThreadPoolExecutor: If the number of threads is less than the corePoolSize, 34 | * the executor creates a new thread to run a new task. If the number of threads is equal (or greater than) the 35 | * corePoolSize, the executor puts the task into the queue. If the queue is full and the number of threads is less than 36 | * the maxPoolSize, the executor creates a new thread to run a new task. If the queue is full and the number of threads 37 | * is greater than or equal to maxPoolSize, reject the task. 38 | * 39 | * So with the default configuration there will be only 5 jobs/threads at the same time. 40 | * 41 | * The {@link org.springframework.core.task.TaskExecutor} may also be used in job configurations for multi-threaded job 42 | * execution. In XML you can use it by name, which is taskExecutor. In JavaConfig, you can either autowire 43 | * {@link org.springframework.core.task.TaskExecutor} or, if you want to know where it's configured, this class. 44 | * 45 | * @author Dennis Schulte 46 | * 47 | */ 48 | @Configuration 49 | @ConditionalOnMissingBean(TaskExecutor.class) 50 | public class TaskExecutorConfiguration { 51 | 52 | @Autowired 53 | private BatchConfigurationProperties batchConfig; 54 | 55 | @Bean 56 | public TaskExecutor taskExecutor() { 57 | ThreadPoolTaskExecutor taskExecutor = new MdcThreadPoolTaskExecutor(); 58 | taskExecutor.setCorePoolSize(batchConfig.getTaskExecutor().getCorePoolSize()); 59 | taskExecutor.setQueueCapacity(batchConfig.getTaskExecutor().getQueueCapacity()); 60 | taskExecutor.setMaxPoolSize(batchConfig.getTaskExecutor().getMaxPoolSize()); 61 | taskExecutor.afterPropertiesSet(); 62 | return taskExecutor; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/configuration/WebConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.configuration; 18 | 19 | import java.util.List; 20 | 21 | import de.codecentric.batch.monitoring.RunningExecutionTracker; 22 | import org.springframework.batch.core.StepExecution; 23 | import org.springframework.batch.core.configuration.JobRegistry; 24 | import org.springframework.batch.core.explore.JobExplorer; 25 | import org.springframework.batch.core.jsr.launch.JsrJobOperator; 26 | import org.springframework.batch.core.launch.JobLauncher; 27 | import org.springframework.batch.core.launch.JobOperator; 28 | import org.springframework.batch.core.repository.JobRepository; 29 | import org.springframework.beans.factory.annotation.Autowired; 30 | import org.springframework.context.annotation.Bean; 31 | import org.springframework.context.annotation.Configuration; 32 | import org.springframework.http.converter.HttpMessageConverter; 33 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 34 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 35 | 36 | import de.codecentric.batch.web.JobMonitoringController; 37 | import de.codecentric.batch.web.JobOperationsController; 38 | 39 | /** 40 | * This configuration adds the controllers for the two endpoints, and it adds a Jackson MixIn to the message converter 41 | * to avoid a stack overflow through circular references in the JobExecution / StepExecution. 42 | * 43 | * @author Tobias Flohre 44 | */ 45 | @Configuration 46 | public class WebConfig implements WebMvcConfigurer { 47 | 48 | @Autowired 49 | private JobOperator jobOperator; 50 | 51 | @Autowired 52 | private JobExplorer jobExplorer; 53 | 54 | @Autowired 55 | private JobRegistry jobRegistry; 56 | 57 | @Autowired 58 | private JobRepository jobRepository; 59 | 60 | @Autowired 61 | private JobLauncher jobLauncher; 62 | 63 | @Autowired 64 | private RunningExecutionTracker runningExecutionTracker; 65 | 66 | @Autowired(required = false) 67 | private JsrJobOperator jsrJobOperator; 68 | 69 | @Override 70 | public void configureMessageConverters(List> converters) { 71 | for (HttpMessageConverter httpMessageConverter : converters) { 72 | if (httpMessageConverter instanceof MappingJackson2HttpMessageConverter) { 73 | final MappingJackson2HttpMessageConverter converter = (MappingJackson2HttpMessageConverter) httpMessageConverter; 74 | converter.getObjectMapper().addMixIn(StepExecution.class, StepExecutionJacksonMixIn.class); 75 | } 76 | } 77 | } 78 | 79 | @Bean 80 | public JobMonitoringController jobMonitoringController() { 81 | return new JobMonitoringController(jobOperator, jobExplorer, runningExecutionTracker); 82 | } 83 | 84 | @Bean 85 | public JobOperationsController jobOperationsController() { 86 | return new JobOperationsController(jobOperator, jobExplorer, jobRegistry, jobRepository, jobLauncher, jsrJobOperator); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/listener/JobLoggingApplicationListener.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.listener; 2 | 3 | import java.io.File; 4 | 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.springframework.boot.context.event.ApplicationPreparedEvent; 7 | import org.springframework.context.ApplicationListener; 8 | import org.springframework.core.Ordered; 9 | 10 | /** 11 | * This ApplicationListener makes the batch.joblog.path available before the LoggingSystem is started. 12 | * 13 | * @author Johannes Stelzer 14 | */ 15 | public class JobLoggingApplicationListener implements ApplicationListener, Ordered { 16 | 17 | @Override 18 | public void onApplicationEvent(ApplicationPreparedEvent event) { 19 | String jobLogPath = event.getApplicationContext().getEnvironment().getProperty("batch.joblog.path"); 20 | if (!StringUtils.isEmpty(jobLogPath)) { 21 | if (!jobLogPath.endsWith(File.separator)) { 22 | jobLogPath = jobLogPath + File.separator; 23 | } 24 | System.setProperty("JOB_LOG_PATH", jobLogPath); 25 | } 26 | } 27 | 28 | @Override 29 | public int getOrder() { 30 | return Ordered.HIGHEST_PRECEDENCE + 11; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/listener/LoggingAfterJobListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.listener; 18 | 19 | import org.slf4j.MDC; 20 | import org.springframework.batch.core.JobExecution; 21 | import org.springframework.batch.core.JobExecutionListener; 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.core.Ordered; 24 | 25 | import de.codecentric.batch.logging.DefaultJobLogFileNameCreator; 26 | import de.codecentric.batch.logging.JobLogFileNameCreator; 27 | 28 | /** 29 | * This extra listener is needed, because the {@link LoggingListener} removes the variable from the MDC in its afterStep 30 | * method. We re-set it here at the beginning of the execution of all afterJob methods of JobExecutionListeners. 31 | * 32 | * @see LoggingListener 33 | * 34 | * @author Tobias Flohre 35 | * 36 | */ 37 | public class LoggingAfterJobListener implements JobExecutionListener, Ordered { 38 | 39 | private JobLogFileNameCreator jobLogFileNameCreator = new DefaultJobLogFileNameCreator(); 40 | 41 | @Override 42 | public void beforeJob(JobExecution jobExecution) { 43 | } 44 | 45 | private void insertValuesIntoMDC(JobExecution jobExecution) { 46 | MDC.put(LoggingListener.JOBLOG_FILENAME, jobLogFileNameCreator.getBaseName(jobExecution)); 47 | } 48 | 49 | @Override 50 | public void afterJob(JobExecution jobExecution) { 51 | insertValuesIntoMDC(jobExecution); 52 | } 53 | 54 | @Override 55 | public int getOrder() { 56 | return Ordered.LOWEST_PRECEDENCE; 57 | } 58 | 59 | @Autowired(required = false) 60 | public void setJobLogFileNameCreator(JobLogFileNameCreator jobLogFileNameCreator) { 61 | this.jobLogFileNameCreator = jobLogFileNameCreator; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/listener/LoggingListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.listener; 18 | 19 | import org.slf4j.MDC; 20 | import org.springframework.batch.core.ExitStatus; 21 | import org.springframework.batch.core.JobExecution; 22 | import org.springframework.batch.core.JobExecutionListener; 23 | import org.springframework.batch.core.StepExecution; 24 | import org.springframework.batch.core.StepExecutionListener; 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.core.Ordered; 27 | 28 | import de.codecentric.batch.logging.DefaultJobLogFileNameCreator; 29 | import de.codecentric.batch.logging.JobLogFileNameCreator; 30 | 31 | /** 32 | * This listener writes the job log file name to the MDC so that it can be picked up by the logging framework for 33 | * logging to it. It's a {@link JobExecutionListener} and a {@link StepExecutionListener} because in partitioning we may 34 | * have a lot of {@link StepExecution}s running in different threads. Due to the fact that the afterStep - method would 35 | * remove the variable from the MDC in single threaded execution we need to re-set it, that's what's the 36 | * {@link LoggingAfterJobListener} is for. Note that, of the three local parallelization features in Spring Batch, log 37 | * file separation only works for partitioning and parallel step, not for multi-threaded step. 38 | * 39 | * The log file name is determined by a {@link JobLogFileNameCreator}. It's default implementation 40 | * {@link DefaultJobLogFileNameCreator} is used when there's no other bean of this type in the ApplicationContext. 41 | * 42 | * @author Tobias Flohre 43 | * 44 | */ 45 | public class LoggingListener implements JobExecutionListener, StepExecutionListener, Ordered { 46 | 47 | private JobLogFileNameCreator jobLogFileNameCreator = new DefaultJobLogFileNameCreator(); 48 | 49 | public static final String JOBLOG_FILENAME = "jobLogFileName"; 50 | 51 | @Override 52 | public void beforeJob(JobExecution jobExecution) { 53 | insertValuesIntoMDC(jobExecution); 54 | } 55 | 56 | private void insertValuesIntoMDC(JobExecution jobExecution) { 57 | MDC.put(JOBLOG_FILENAME, jobLogFileNameCreator.getBaseName(jobExecution)); 58 | } 59 | 60 | @Override 61 | public void afterJob(JobExecution jobExecution) { 62 | removeValuesFromMDC(); 63 | } 64 | 65 | private void removeValuesFromMDC() { 66 | MDC.remove(JOBLOG_FILENAME); 67 | } 68 | 69 | @Override 70 | public void beforeStep(StepExecution stepExecution) { 71 | insertValuesIntoMDC(stepExecution.getJobExecution()); 72 | } 73 | 74 | @Override 75 | public ExitStatus afterStep(StepExecution stepExecution) { 76 | removeValuesFromMDC(); 77 | return null; 78 | } 79 | 80 | @Override 81 | public int getOrder() { 82 | return Ordered.HIGHEST_PRECEDENCE; 83 | } 84 | 85 | @Autowired(required = false) 86 | public void setJobLogFileNameCreator(JobLogFileNameCreator jobLogFileNameCreator) { 87 | this.jobLogFileNameCreator = jobLogFileNameCreator; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/listener/RunningExecutionTrackerListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.listener; 18 | 19 | import org.springframework.batch.core.JobExecution; 20 | import org.springframework.batch.core.JobExecutionListener; 21 | 22 | import de.codecentric.batch.monitoring.RunningExecutionTracker; 23 | 24 | /** 25 | * This listener is needed for tracking the running JobExecutions on this server. 26 | * 27 | *

28 | * It's easy to find out which jobs are running in general by looking into the database, but it has some drawbacks: 29 | *

    30 | *
  • Data in the database might be corrupted. A job may be in status STARTED simply because someone killed the process 31 | * and Spring Batch didn't have the chance to update the status.
  • 32 | *
  • We cannot tell from the database on which server the job is running.
  • 33 | *
  • We might just use an in-memory database, then we cannot access it.
  • 34 | *
35 | * 36 | *

37 | * This listener uses the {@link RunningExecutionTracker} to keep this information in memory and accessible for the http 38 | * endpoints. 39 | * 40 | * @author Tobias Flohre 41 | * 42 | */ 43 | public class RunningExecutionTrackerListener implements JobExecutionListener { 44 | 45 | private RunningExecutionTracker runningExecutionTracker; 46 | 47 | public RunningExecutionTrackerListener(RunningExecutionTracker runningExecutionTracker) { 48 | super(); 49 | this.runningExecutionTracker = runningExecutionTracker; 50 | } 51 | 52 | @Override 53 | public void beforeJob(JobExecution jobExecution) { 54 | runningExecutionTracker.addRunningExecution(jobExecution.getJobInstance().getJobName(), jobExecution.getId()); 55 | } 56 | 57 | @Override 58 | public void afterJob(JobExecution jobExecution) { 59 | runningExecutionTracker.removeRunningExecution(jobExecution.getId()); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/logging/DefaultJobLogFileNameCreator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.logging; 18 | 19 | import org.springframework.batch.core.JobExecution; 20 | 21 | /** 22 | * Default implementation used when there's no other Spring bean implementing {@link JobLogFileNameCreator} in the 23 | * ApplicationContext. 24 | * 25 | * @author Tobias Flohre 26 | * @author Dennis Schulte 27 | * 28 | */ 29 | public class DefaultJobLogFileNameCreator implements JobLogFileNameCreator { 30 | 31 | private static final String DEFAULT_EXTENSION = ".log"; 32 | 33 | @Override 34 | public String getName(JobExecution jobExecution) { 35 | return getBaseName(jobExecution) + getExtension(); 36 | } 37 | 38 | @Override 39 | public String getBaseName(JobExecution jobExecution) { 40 | return "batch-" + jobExecution.getJobInstance().getJobName() + "-" + Long.toString(jobExecution.getId()); 41 | } 42 | 43 | @Override 44 | public String getExtension() { 45 | return DEFAULT_EXTENSION; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/logging/JobLogFileNameCreator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.logging; 18 | 19 | import org.springframework.batch.core.JobExecution; 20 | 21 | /** 22 | * Components implementing this interface specify the name of the job run specific log file. Data from the JobExecution 23 | * may be used to compose the name. There are also methods to get the specific parts (basename and extension) of the 24 | * filename. Default implementation used when there's no other Spring bean implementing this interface is the 25 | * {@link DefaultJobLogFileNameCreator}. 26 | * 27 | * @author Tobias Flohre 28 | * @author Dennis Schulte 29 | * 30 | */ 31 | public interface JobLogFileNameCreator { 32 | 33 | public String getName(JobExecution jobExecution); 34 | 35 | public String getBaseName(JobExecution jobExecution); 36 | 37 | public String getExtension(); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/metrics/AbstractBatchMetricsAspect.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics; 17 | 18 | import java.util.Arrays; 19 | 20 | import org.aspectj.lang.ProceedingJoinPoint; 21 | import org.springframework.batch.core.StepExecution; 22 | import org.springframework.batch.core.scope.context.StepContext; 23 | import org.springframework.batch.core.scope.context.StepSynchronizationManager; 24 | import org.springframework.util.ClassUtils; 25 | 26 | import io.micrometer.core.instrument.ImmutableTag; 27 | import io.micrometer.core.instrument.MeterRegistry; 28 | import io.micrometer.core.instrument.Timer; 29 | 30 | /** 31 | * This is a helper class for implementing method level profiling. See {@link ReaderProcessorWriterMetricsAspect} for an 32 | * aspect extending this class. All calls to an adviced method are tracked in a RichGauge, so you'll see average 33 | * duration time, maximum / minimum time, number of method calls and so on. For the name of the metric a special naming 34 | * scheme is used so that our {@link MetricsListener} picks up the gauge and writes it to the ExecutionContext of the 35 | * StepExecution and to the log. 36 | * 37 | * Job configurations need to enable auto-proxying so that aspects may be applied. In JavaConfig just add 38 | * {@code @EnableAspectJAutoProxy(proxyTargetClass=true)} as a class level annotation. In xml add 39 | * {@code } to the xml configuration file. This needs to be done 40 | * because jobs reside in child application contexts and don't inherit this kind of configuration from the parent. 41 | * proxyTargetClass=true means using CGLIB as proxy mechanism which allows us to proxy classes without interfaces. 42 | * 43 | * @author Tobias Flohre 44 | */ 45 | public abstract class AbstractBatchMetricsAspect { 46 | 47 | private MeterRegistry meterRegistry; 48 | 49 | public AbstractBatchMetricsAspect(MeterRegistry meterRegistry) { 50 | this.meterRegistry = meterRegistry; 51 | } 52 | 53 | protected Object profileMethod(ProceedingJoinPoint pjp) throws Throwable { 54 | Timer.Sample sample = Timer.start(meterRegistry); 55 | try { 56 | return pjp.proceed(); 57 | } finally { 58 | sample.stop(meterRegistry.timer(MetricsListener.METRIC_NAME, Arrays.asList(// 59 | new ImmutableTag("context", getStepIdentifier()), // 60 | new ImmutableTag("method", ClassUtils.getShortName(pjp.getTarget().getClass()) + "." 61 | + pjp.getSignature().getName())))); 62 | } 63 | } 64 | 65 | private String getStepIdentifier() { 66 | StepContext stepContext = StepSynchronizationManager.getContext(); 67 | StepExecution stepExecution = StepSynchronizationManager.getContext().getStepExecution(); 68 | return stepContext.getJobName() + "." + stepExecution.getStepName(); 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/metrics/MetricsOutputFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics; 17 | 18 | import java.util.Collection; 19 | 20 | import io.micrometer.core.instrument.Gauge; 21 | import io.micrometer.core.instrument.Timer; 22 | 23 | /** 24 | * Used in {@link MetricsListener} to define the format of the metrics log. A component implementing this interface may 25 | * be added to the ApplicationContext to override the default behaviour. 26 | * 27 | * @author Tobias Flohre 28 | */ 29 | public interface MetricsOutputFormatter { 30 | 31 | public String format(Collection gauges, Collection timers); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/metrics/ReaderProcessorWriterMetricsAspect.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics; 17 | 18 | import org.aspectj.lang.ProceedingJoinPoint; 19 | import org.aspectj.lang.annotation.Around; 20 | import org.aspectj.lang.annotation.Aspect; 21 | 22 | import io.micrometer.core.instrument.MeterRegistry; 23 | 24 | /** 25 | * Central aspect-configuration to profile Spring Batch Jobs with AspectJ and Spring Boot Metrics. 26 | * 27 | * @author Dennis Schulte 28 | */ 29 | @Aspect 30 | public class ReaderProcessorWriterMetricsAspect extends AbstractBatchMetricsAspect { 31 | 32 | public ReaderProcessorWriterMetricsAspect(MeterRegistry meterRegistry) { 33 | super(meterRegistry); 34 | } 35 | 36 | @Around("execution(* org.springframework.batch.item.ItemReader.read(..))") 37 | public Object profileReadMethods(ProceedingJoinPoint pjp) throws Throwable { 38 | return profileMethod(pjp); 39 | } 40 | 41 | @Around("execution(* org.springframework.batch.item.ItemProcessor.process(..))") 42 | public Object profileProcessMethods(ProceedingJoinPoint pjp) throws Throwable { 43 | return profileMethod(pjp); 44 | } 45 | 46 | @Around("execution(* org.springframework.batch.item.ItemWriter.write(..))") 47 | public Object profileWriteMethods(ProceedingJoinPoint pjp) throws Throwable { 48 | return profileMethod(pjp); 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/monitoring/RunningExecutionTracker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.monitoring; 18 | 19 | import java.util.HashSet; 20 | import java.util.Map; 21 | import java.util.Map.Entry; 22 | import java.util.Set; 23 | import java.util.concurrent.ConcurrentHashMap; 24 | 25 | import de.codecentric.batch.listener.RunningExecutionTrackerListener; 26 | import de.codecentric.batch.web.JobMonitoringController; 27 | 28 | /** 29 | * Container for keeping track of running JobExecutions in this application. 30 | * 31 | * @see RunningExecutionTrackerListener 32 | * @see JobMonitoringController 33 | * @author Tobias Flohre 34 | * 35 | */ 36 | public class RunningExecutionTracker { 37 | 38 | private Map runningExecutions = new ConcurrentHashMap<>(); 39 | 40 | public void addRunningExecution(String jobName, Long executionId) { 41 | runningExecutions.put(executionId, jobName); 42 | } 43 | 44 | public void removeRunningExecution(Long executionId) { 45 | runningExecutions.remove(executionId); 46 | } 47 | 48 | public Set getAllRunningExecutionIds() { 49 | return new HashSet<>(runningExecutions.keySet()); 50 | } 51 | 52 | public Set getRunningExecutionIdsForJobName(String jobName) { 53 | Set runningExecutionIds = new HashSet<>(); 54 | for (Entry entry : runningExecutions.entrySet()) { 55 | if (entry.getValue().equals(jobName)) { 56 | runningExecutionIds.add(entry.getKey()); 57 | } 58 | } 59 | return runningExecutionIds; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/java/de/codecentric/batch/scheduling/concurrent/MdcThreadPoolTaskExecutor.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.scheduling.concurrent; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ThreadPoolExecutor; 5 | 6 | import org.slf4j.MDC; 7 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 8 | 9 | /** 10 | * A SLF4J MDC-compatible {@link ThreadPoolExecutor}. 11 | *

12 | * In general, MDC is used to store diagnostic information (e.g. logfile name) in per-thread variables, to facilitate 13 | * logging. However, although MDC data is passed to thread children, this doesn't work when threads are reused in a 14 | * thread pool. This is a drop-in replacement for {@link ThreadPoolTaskExecutor} sets MDC data before each task 15 | * appropriately. 16 | *

17 | * 18 | * @author Dennis Schulte 19 | */ 20 | public class MdcThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { 21 | 22 | private static final long serialVersionUID = 1L; 23 | 24 | private boolean useFixedContext = false; 25 | 26 | private Map fixedContext; 27 | 28 | public MdcThreadPoolTaskExecutor() { 29 | super(); 30 | } 31 | 32 | public MdcThreadPoolTaskExecutor(Map fixedContext) { 33 | super(); 34 | this.fixedContext = fixedContext; 35 | useFixedContext = (fixedContext != null); 36 | } 37 | 38 | private Map getContextForTask() { 39 | return useFixedContext ? fixedContext : MDC.getCopyOfContextMap(); 40 | } 41 | 42 | /** 43 | * All executions will have MDC injected. {@code ThreadPoolExecutor}'s submission methods ({@code submit()} etc.) 44 | * all delegate to this. 45 | */ 46 | @Override 47 | public void execute(Runnable command) { 48 | super.execute(wrap(command, getContextForTask())); 49 | } 50 | 51 | public static Runnable wrap(final Runnable runnable, final Map context) { 52 | return () -> { 53 | Map previous = MDC.getCopyOfContextMap(); 54 | if (context == null) { 55 | MDC.clear(); 56 | } else { 57 | MDC.setContextMap(context); 58 | } 59 | try { 60 | runnable.run(); 61 | } finally { 62 | if (previous == null) { 63 | MDC.clear(); 64 | } else { 65 | MDC.setContextMap(previous); 66 | } 67 | } 68 | }; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": [ 3 | { 4 | "name": "batch.metrics.enabled", 5 | "type": "java.lang.Boolean", 6 | "description": "Whether the transaction safe batch metrics framework is activated so that BatchMetrics may be injected and used", 7 | "default": false 8 | }, 9 | { 10 | "name": "batch.web.operations.base", 11 | "type": "java.lang.String", 12 | "description": "URL part to operational methods on batch jobs, like starting, stopping, etc. of jobs", 13 | "default": "/batch/operations" 14 | }, 15 | { 16 | "name": "batch.web.monitoring.base", 17 | "type": "java.lang.String", 18 | "description": "URL part to monitoring methods on batch jobs, like viewing the state of jobs", 19 | "default": "/batch/monitoring" 20 | }, 21 | { 22 | "name": "batch.metrics.profiling.readprocesswrite.enabled", 23 | "type": "java.lang.Boolean", 24 | "description": "Readers, Processors and Writers are profiled with RichGauges when set to true", 25 | "default": false 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | # AutoConfigurations 2 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=de.codecentric.batch.configuration.BatchWebAutoConfiguration 3 | 4 | # Application Listeners 5 | org.springframework.context.ApplicationListener=de.codecentric.batch.listener.JobLoggingApplicationListener -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/resources/batch-web-spring-boot-autoconfigure.properties: -------------------------------------------------------------------------------- 1 | spring.batch.job.enabled=false 2 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/main/resources/logback-batch-base.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | jobLogFileName 10 | batch-default 11 | 12 | 13 | 14 | ${JOB_LOG_PATH}${jobLogFileName}.log 15 | true 16 | 17 | ${FILE_LOG_PATTERN} 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/AutoconfigureBatchWebStarter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch; 18 | 19 | import java.lang.annotation.Documented; 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Inherited; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | import java.lang.annotation.Target; 25 | 26 | import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; 27 | import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; 28 | import org.springframework.boot.autoconfigure.ImportAutoConfiguration; 29 | import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration; 30 | import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration; 31 | import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; 32 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 33 | import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; 34 | 35 | import de.codecentric.batch.configuration.BatchWebAutoConfiguration; 36 | 37 | /** 38 | * 39 | * {@link AutoImportConfoguration} for typical BatchWebStarter tests. Restricts the loaded Autoconfiguration to the 40 | * BatchWebStarter parts and respects the correct ordering. 41 | * 42 | * @author Johannes Edmeier 43 | */ 44 | @Target(ElementType.TYPE) 45 | @Retention(RetentionPolicy.RUNTIME) 46 | @Documented 47 | @Inherited 48 | @ImportAutoConfiguration({ BatchWebAutoConfiguration.class, DataSourceAutoConfiguration.class, 49 | HibernateJpaAutoConfiguration.class, 50 | // since the BatchAutoConfiguration is ordered after HibernateJpaAutoConfiguration we need to 51 | // include it otherwise it will be executed before DataSourceAutoConfiguration 52 | BatchAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, MetricsAutoConfiguration.class, 53 | AopAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }) 54 | public @interface AutoconfigureBatchWebStarter { 55 | } 56 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/MetricsTestApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch; 17 | 18 | import java.util.Collection; 19 | 20 | import org.springframework.beans.factory.annotation.Autowired; 21 | import org.springframework.boot.SpringApplication; 22 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | import org.springframework.context.annotation.Import; 26 | 27 | import de.codecentric.batch.metrics.ListenerMetricsAspect; 28 | import de.codecentric.batch.metrics.MetricsOutputFormatter; 29 | import io.micrometer.core.instrument.Gauge; 30 | import io.micrometer.core.instrument.MeterRegistry; 31 | import io.micrometer.core.instrument.Timer; 32 | 33 | /** 34 | * Application for integration testing. 35 | * 36 | * @author Tobias Flohre 37 | */ 38 | @Configuration 39 | @EnableAutoConfiguration 40 | @Import(TestListenerConfiguration.class) 41 | public class MetricsTestApplication { 42 | 43 | public static void main(String[] args) { 44 | SpringApplication.run(MetricsTestApplication.class, args); 45 | } 46 | 47 | @Autowired 48 | private MeterRegistry meterRegistry; 49 | 50 | @Bean 51 | public ListenerMetricsAspect listenerMetricsAspect() { 52 | return new ListenerMetricsAspect(meterRegistry); 53 | } 54 | 55 | @Bean 56 | public MetricsOutputFormatter metricsOutputFormatter() { 57 | return new MetricsOutputFormatter() { 58 | 59 | @Override 60 | public String format(Collection gauges, Collection timers) { 61 | StringBuilder builder = new StringBuilder( 62 | "\n########## Personal Header for metrics! #####\n########## Metrics Start ##########\n"); 63 | gauges.stream().forEach(gauge -> { 64 | builder.append("Gauge [" + gauge.getId() + "]: "); 65 | builder.append(gauge.value() + "\n"); 66 | }); 67 | timers.stream().forEach(timer -> { 68 | builder.append("Timer [" + timer.getId() + "]: "); 69 | builder.append( 70 | "totalTime=" + timer.totalTime(timer.baseTimeUnit()) + " " + timer.baseTimeUnit() + "\n"); 71 | }); 72 | builder.append("########## Metrics End ############"); 73 | return builder.toString(); 74 | } 75 | 76 | }; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/TestApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch; 17 | 18 | import org.springframework.boot.SpringApplication; 19 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 20 | import org.springframework.context.annotation.Configuration; 21 | import org.springframework.context.annotation.Import; 22 | 23 | /** 24 | * Application for integration testing. 25 | * 26 | * @author Tobias Flohre 27 | */ 28 | @Configuration 29 | @EnableAutoConfiguration 30 | @Import(TestListenerConfiguration.class) 31 | public class TestApplication { 32 | 33 | public static void main(String[] args) { 34 | SpringApplication.run(TestApplication.class, args); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/TestConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch; 18 | 19 | import org.springframework.context.annotation.Configuration; 20 | 21 | @Configuration 22 | public class TestConfiguration { 23 | } 24 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/TestListenerConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch; 17 | 18 | import java.util.HashSet; 19 | import java.util.Set; 20 | 21 | import org.springframework.batch.core.JobExecutionListener; 22 | import org.springframework.batch.core.StepExecutionListener; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | import de.codecentric.batch.configuration.ListenerProvider; 27 | import de.codecentric.batch.listener.TestListener; 28 | 29 | /** 30 | * @author Tobias Flohre 31 | */ 32 | @Configuration 33 | public class TestListenerConfiguration implements ListenerProvider { 34 | 35 | /* 36 | * (non-Javadoc) 37 | * 38 | * @see de.codecentric.batch.configuration.ListenerProvider#jobExecutionListeners() 39 | */ 40 | @Override 41 | public Set jobExecutionListeners() { 42 | Set listeners = new HashSet(); 43 | listeners.add(testListener()); 44 | return listeners; 45 | } 46 | 47 | /* 48 | * (non-Javadoc) 49 | * 50 | * @see de.codecentric.batch.configuration.ListenerProvider#stepExecutionListeners() 51 | */ 52 | @Override 53 | public Set stepExecutionListeners() { 54 | return new HashSet(); 55 | } 56 | 57 | @Bean 58 | public TestListener testListener() { 59 | return new TestListener(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/item/DelayItemProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.item; 17 | 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | import org.springframework.batch.item.ItemProcessor; 21 | 22 | /** 23 | * Dummy {@link ItemProcessor} which waits some time before proceeding. 24 | * 25 | * @author Tobias Flohre 26 | */ 27 | public class DelayItemProcessor implements ItemProcessor { 28 | 29 | private static final Logger LOGGER = LoggerFactory.getLogger(DelayItemProcessor.class); 30 | 31 | @Override 32 | public String process(String item) throws Exception { 33 | LOGGER.info(item); 34 | Thread.sleep(1000); 35 | return item; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/item/DummyItemReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.item; 17 | 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | import org.springframework.batch.item.ItemReader; 21 | 22 | /** 23 | * {@link ItemReader} with hard-coded input data. 24 | */ 25 | public class DummyItemReader implements ItemReader { 26 | 27 | private static final Logger LOGGER = LoggerFactory.getLogger(DummyItemReader.class); 28 | 29 | private String[] input = { "Good", "morning!", "This", "is", "your", "ItemReader", "speaking!" }; 30 | 31 | private int index = 0; 32 | 33 | /** 34 | * Reads next record from input 35 | */ 36 | @Override 37 | public String read() throws Exception { 38 | String item = null; 39 | if (index < input.length) { 40 | item = input[index++]; 41 | LOGGER.info(item); 42 | return item; 43 | } else { 44 | return null; 45 | } 46 | 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/item/LogItemProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.item; 17 | 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | import org.springframework.batch.item.ItemProcessor; 21 | 22 | /** 23 | * Dummy {@link ItemProcessor} which only logs data it receives. 24 | */ 25 | public class LogItemProcessor implements ItemProcessor { 26 | 27 | private static final Logger LOGGER = LoggerFactory.getLogger(LogItemProcessor.class); 28 | 29 | @Override 30 | public String process(String item) throws Exception { 31 | LOGGER.info(item); 32 | return item; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/item/LogItemWriteListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.item; 17 | 18 | import java.util.List; 19 | 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | import org.springframework.batch.core.ItemWriteListener; 23 | 24 | /** 25 | * @author Tobias Flohre 26 | */ 27 | public class LogItemWriteListener implements ItemWriteListener { 28 | 29 | private static final Logger LOGGER = LoggerFactory.getLogger(LogItemWriteListener.class); 30 | 31 | @Override 32 | public void beforeWrite(List items) { 33 | for (String item : items) { 34 | LOGGER.debug("Item: {}", item); 35 | } 36 | } 37 | 38 | @Override 39 | public void afterWrite(List items) { 40 | for (String item : items) { 41 | LOGGER.debug("Item: {}", item); 42 | } 43 | } 44 | 45 | @Override 46 | public void onWriteError(Exception exception, List items) { 47 | for (String item : items) { 48 | LOGGER.debug("Item: {}", item); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/item/LogItemWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.item; 17 | 18 | import java.util.List; 19 | 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | import org.springframework.batch.item.ItemWriter; 23 | 24 | /** 25 | * Dummy {@link ItemWriter} which only logs data it receives. 26 | */ 27 | public class LogItemWriter implements ItemWriter { 28 | 29 | private static final Logger LOGGER = LoggerFactory.getLogger(LogItemWriter.class); 30 | 31 | /** 32 | * @see ItemWriter#write(java.util.List) 33 | */ 34 | @Override 35 | public void write(List data) throws Exception { 36 | LOGGER.info("{}", data); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/item/MetricsItemProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.item; 17 | 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | import org.springframework.batch.item.ItemProcessor; 21 | 22 | import de.codecentric.batch.metrics.BatchMetrics; 23 | 24 | /** 25 | * Dummy {@link ItemProcessor} which logs data it receives and increments a counter. 26 | */ 27 | public class MetricsItemProcessor implements ItemProcessor { 28 | 29 | private static final Logger LOGGER = LoggerFactory.getLogger(MetricsItemProcessor.class); 30 | 31 | private BatchMetrics businessMetrics; 32 | 33 | public MetricsItemProcessor(BatchMetrics businessMetrics) { 34 | this.businessMetrics = businessMetrics; 35 | } 36 | 37 | @Override 38 | public String process(String item) throws Exception { 39 | LOGGER.info(item); 40 | businessMetrics.increment("processor"); 41 | return item; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/jobs/DelayJobConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.jobs; 17 | 18 | import org.springframework.batch.core.Job; 19 | import org.springframework.batch.core.Step; 20 | import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; 21 | import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | import de.codecentric.batch.item.DelayItemProcessor; 27 | import de.codecentric.batch.item.DummyItemReader; 28 | import de.codecentric.batch.item.LogItemWriter; 29 | 30 | @Configuration 31 | public class DelayJobConfiguration { 32 | 33 | @Autowired 34 | private JobBuilderFactory jobBuilderFactory; 35 | 36 | @Autowired 37 | private StepBuilderFactory stepBuilderFactory; 38 | 39 | @Bean 40 | public Job delayJob() { 41 | return jobBuilderFactory.get("delayJob")// 42 | .start(step())// 43 | .build(); 44 | } 45 | 46 | @Bean 47 | public Step step() { 48 | return stepBuilderFactory.get("step")// 49 | .chunk(1)// 50 | .reader(reader())// 51 | .processor(processor())// 52 | .writer(writer())// 53 | .build(); 54 | } 55 | 56 | @Bean 57 | public LogItemWriter writer() { 58 | return new LogItemWriter(); 59 | } 60 | 61 | @Bean 62 | public DelayItemProcessor processor() { 63 | return new DelayItemProcessor(); 64 | } 65 | 66 | @Bean 67 | public DummyItemReader reader() { 68 | return new DummyItemReader(); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/jobs/FlatFileJobConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.jobs; 18 | 19 | import java.io.File; 20 | 21 | import org.springframework.batch.core.Job; 22 | import org.springframework.batch.core.Step; 23 | import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; 24 | import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; 25 | import org.springframework.batch.item.ItemReader; 26 | import org.springframework.batch.item.ItemWriter; 27 | import org.springframework.batch.item.file.FlatFileItemReader; 28 | import org.springframework.batch.item.file.FlatFileItemWriter; 29 | import org.springframework.batch.item.file.mapping.PassThroughLineMapper; 30 | import org.springframework.batch.item.file.transform.PassThroughLineAggregator; 31 | import org.springframework.beans.factory.annotation.Autowired; 32 | import org.springframework.context.annotation.Bean; 33 | import org.springframework.context.annotation.Configuration; 34 | import org.springframework.core.io.ClassPathResource; 35 | import org.springframework.core.io.FileSystemResource; 36 | 37 | @Configuration 38 | public class FlatFileJobConfiguration { 39 | 40 | @Autowired 41 | private JobBuilderFactory jobBuilderFactory; 42 | 43 | @Autowired 44 | private StepBuilderFactory stepBuilderFactory; 45 | 46 | @Bean 47 | public Job flatFileJob() { 48 | return jobBuilderFactory.get("flatFileJob")// 49 | .start(step())// 50 | .build(); 51 | } 52 | 53 | @Bean 54 | public Step step() { 55 | return stepBuilderFactory.get("step")// 56 | . chunk(1)// 57 | .reader(reader())// 58 | .writer(writer())// 59 | .build(); 60 | } 61 | 62 | @Bean 63 | public ItemReader reader() { 64 | FlatFileItemReader reader = new FlatFileItemReader(); 65 | reader.setResource(new ClassPathResource("in-javaconfig.txt")); 66 | reader.setLineMapper(new PassThroughLineMapper()); 67 | return reader; 68 | } 69 | 70 | @Bean 71 | public ItemWriter writer() { 72 | FlatFileItemWriter writer = new FlatFileItemWriter(); 73 | writer.setResource(new FileSystemResource(new File("target/out-javaconfig.txt"))); 74 | writer.setLineAggregator(new PassThroughLineAggregator()); 75 | return writer; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/jobs/IncrementerJobConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.jobs; 17 | 18 | import org.springframework.batch.core.Job; 19 | import org.springframework.batch.core.Step; 20 | import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; 21 | import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; 22 | import org.springframework.batch.core.launch.support.RunIdIncrementer; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.context.annotation.Bean; 25 | import org.springframework.context.annotation.Configuration; 26 | 27 | import de.codecentric.batch.item.DummyItemReader; 28 | import de.codecentric.batch.item.LogItemProcessor; 29 | import de.codecentric.batch.item.LogItemWriter; 30 | 31 | @Configuration 32 | public class IncrementerJobConfiguration { 33 | 34 | @Autowired 35 | private JobBuilderFactory jobBuilderFactory; 36 | 37 | @Autowired 38 | private StepBuilderFactory stepBuilderFactory; 39 | 40 | @Bean 41 | public Job incrementerJob() { 42 | return jobBuilderFactory.get("incrementerJob")// 43 | .start(step())// 44 | .incrementer(incrementer())// 45 | .build(); 46 | } 47 | 48 | @Bean 49 | public Step step() { 50 | return stepBuilderFactory.get("step")// 51 | .chunk(1)// 52 | .reader(reader())// 53 | .processor(processor())// 54 | .writer(writer())// 55 | .build(); 56 | } 57 | 58 | @Bean 59 | public RunIdIncrementer incrementer() { 60 | return new RunIdIncrementer(); 61 | } 62 | 63 | @Bean 64 | public LogItemWriter writer() { 65 | return new LogItemWriter(); 66 | } 67 | 68 | @Bean 69 | public LogItemProcessor processor() { 70 | return new LogItemProcessor(); 71 | } 72 | 73 | @Bean 74 | public DummyItemReader reader() { 75 | return new DummyItemReader(); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/jobs/SimpleBatchMetricsJobConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.jobs; 17 | 18 | import org.springframework.batch.core.Job; 19 | import org.springframework.batch.core.Step; 20 | import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; 21 | import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; 22 | import org.springframework.batch.core.configuration.annotation.StepScope; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 25 | import org.springframework.context.annotation.Bean; 26 | import org.springframework.context.annotation.Configuration; 27 | import org.springframework.context.annotation.EnableAspectJAutoProxy; 28 | 29 | import de.codecentric.batch.item.DummyItemReader; 30 | import de.codecentric.batch.item.LogItemWriteListener; 31 | import de.codecentric.batch.item.LogItemWriter; 32 | import de.codecentric.batch.item.MetricsItemProcessor; 33 | import de.codecentric.batch.metrics.BatchMetrics; 34 | 35 | @Configuration 36 | @ConditionalOnProperty("batch.metrics.enabled") 37 | @EnableAspectJAutoProxy(proxyTargetClass = true) 38 | public class SimpleBatchMetricsJobConfiguration { 39 | 40 | @Autowired 41 | private JobBuilderFactory jobBuilderFactory; 42 | 43 | @Autowired 44 | private StepBuilderFactory stepBuilderFactory; 45 | 46 | @Autowired 47 | private BatchMetrics batchMetrics; 48 | 49 | @Bean 50 | public Job simpleBusinessMetricsJob() { 51 | return jobBuilderFactory.get("simpleBatchMetricsJob")// 52 | .start(step())// 53 | .build(); 54 | } 55 | 56 | @Bean 57 | public Step step() { 58 | return stepBuilderFactory.get("simpleBatchMetricsStep")// 59 | .chunk(3)// 60 | .reader(reader())// 61 | .processor(processor())// 62 | .writer(writer())// 63 | .listener(writeListener())// 64 | .build(); 65 | } 66 | 67 | @Bean 68 | public LogItemWriter writer() { 69 | return new LogItemWriter(); 70 | } 71 | 72 | @Bean 73 | public MetricsItemProcessor processor() { 74 | return new MetricsItemProcessor(batchMetrics); 75 | } 76 | 77 | @StepScope 78 | @Bean 79 | public DummyItemReader reader() { 80 | return new DummyItemReader(); 81 | } 82 | 83 | @Bean 84 | public LogItemWriteListener writeListener() { 85 | return new LogItemWriteListener(); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/jobs/SimpleJobConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.jobs; 17 | 18 | import org.springframework.batch.core.Job; 19 | import org.springframework.batch.core.Step; 20 | import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; 21 | import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | import de.codecentric.batch.item.DummyItemReader; 27 | import de.codecentric.batch.item.LogItemProcessor; 28 | import de.codecentric.batch.item.LogItemWriter; 29 | 30 | @Configuration 31 | public class SimpleJobConfiguration { 32 | 33 | @Autowired 34 | private JobBuilderFactory jobBuilderFactory; 35 | 36 | @Autowired 37 | private StepBuilderFactory stepBuilderFactory; 38 | 39 | @Bean 40 | public Job simpleJob() { 41 | return jobBuilderFactory.get("simpleJob")// 42 | .start(step())// 43 | .build(); 44 | } 45 | 46 | @Bean 47 | public Step step() { 48 | return stepBuilderFactory.get("step")// 49 | .chunk(1)// 50 | .reader(reader())// 51 | .processor(processor())// 52 | .writer(writer())// 53 | .build(); 54 | } 55 | 56 | @Bean 57 | public LogItemWriter writer() { 58 | return new LogItemWriter(); 59 | } 60 | 61 | @Bean 62 | public LogItemProcessor processor() { 63 | return new LogItemProcessor(); 64 | } 65 | 66 | @Bean 67 | public DummyItemReader reader() { 68 | return new DummyItemReader(); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/listener/ProtocolListenerTest.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.listener; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.springframework.batch.core.ExitStatus; 6 | import org.springframework.batch.core.JobExecution; 7 | import org.springframework.batch.core.JobInstance; 8 | import org.springframework.batch.core.JobParametersBuilder; 9 | import org.springframework.batch.core.StepExecution; 10 | import org.springframework.boot.test.system.CapturedOutput; 11 | import org.springframework.boot.test.system.OutputCaptureExtension; 12 | 13 | import java.util.Date; 14 | 15 | import static org.hamcrest.CoreMatchers.containsString; 16 | import static org.hamcrest.MatcherAssert.assertThat; 17 | 18 | @ExtendWith(OutputCaptureExtension.class) 19 | public class ProtocolListenerTest { 20 | 21 | 22 | 23 | @Test 24 | public void createProtocol(CapturedOutput output) throws Exception { 25 | // Given 26 | JobExecution jobExecution = new JobExecution(1L, 27 | new JobParametersBuilder().addString("test", "value").toJobParameters()); 28 | jobExecution.setJobInstance(new JobInstance(1L, "test-job")); 29 | jobExecution.setCreateTime(new Date()); 30 | jobExecution.setStartTime(new Date()); 31 | jobExecution.setEndTime(new Date()); 32 | jobExecution.setExitStatus(new ExitStatus("COMPLETED_WITH_ERRORS", "This is a default exit message")); 33 | jobExecution.getExecutionContext().put("jobCounter", 1); 34 | StepExecution stepExecution = jobExecution.createStepExecution("test-step-1"); 35 | stepExecution.getExecutionContext().put("stepCounter", 1); 36 | ProtocolListener protocolListener = new ProtocolListener(); 37 | // When 38 | protocolListener.afterJob(jobExecution); 39 | // Then 40 | assertThat(output.getOut(), containsString("Protocol for test-job")); 41 | assertThat(output.getOut(), containsString("COMPLETED_WITH_ERRORS")); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/listener/TestListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.listener; 17 | 18 | import org.springframework.batch.core.JobExecution; 19 | import org.springframework.batch.core.JobExecutionListener; 20 | 21 | /** 22 | * TestListener added via ListenerProvider. 23 | * 24 | * @author Tobias Flohre 25 | */ 26 | public class TestListener implements JobExecutionListener { 27 | 28 | private int counter = 0; 29 | 30 | @Override 31 | public void beforeJob(JobExecution jobExecution) { 32 | counter++; 33 | } 34 | 35 | @Override 36 | public void afterJob(JobExecution jobExecution) { 37 | counter++; 38 | } 39 | 40 | public int getCounter() { 41 | return counter; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/Action.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics; 17 | 18 | /** 19 | * @author Tobias Flohre 20 | */ 21 | public enum Action { 22 | FAIL_ON_READ, // 23 | FAIL_ON_AFTER_READ, // 24 | FAIL_ON_READ_ERROR, // 25 | FAIL_ON_BEFORE_PROCESS, // 26 | FAIL_ON_PROCESS, // 27 | FAIL_ON_AFTER_PROCESS, // 28 | FAIL_ON_PROCESS_ERROR, // 29 | FAIL_ON_BEFORE_WRITE, // 30 | FAIL_ON_WRITE, // 31 | FAIL_ON_AFTER_WRITE, // 32 | FAIL_ON_WRITE_ERROR, // 33 | FAIL_ON_SKIP_IN_PROCESS, // 34 | FAIL_ON_SKIP_IN_WRITE, // 35 | FILTER 36 | } 37 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/BatchMetricsImplTest.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.metrics; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.batch.core.JobExecution; 6 | import org.springframework.batch.core.JobInstance; 7 | import org.springframework.batch.core.StepExecution; 8 | import org.springframework.batch.core.scope.context.StepSynchronizationManager; 9 | import org.springframework.transaction.support.TransactionSynchronization; 10 | import org.springframework.transaction.support.TransactionSynchronizationManager; 11 | import org.springframework.transaction.support.TransactionSynchronizationUtils; 12 | 13 | public class BatchMetricsImplTest { 14 | 15 | private BatchMetricsImpl batchMetrics; 16 | 17 | @BeforeEach 18 | public void beforeTest() { 19 | batchMetrics = new BatchMetricsImpl(); 20 | StepSynchronizationManager 21 | .register(new StepExecution("step", new JobExecution(new JobInstance(1L, "jobname"), 1L, null, null))); 22 | } 23 | 24 | @Test 25 | public void incrementBy1Transactional() throws Exception { 26 | // Given 27 | TransactionSynchronizationManager.initSynchronization(); 28 | // When 29 | batchMetrics.increment("counter.test", 1L); 30 | TransactionSynchronizationUtils.triggerAfterCompletion(TransactionSynchronization.STATUS_COMMITTED); 31 | // Then 32 | TransactionSynchronizationManager.clearSynchronization(); 33 | } 34 | 35 | @Test 36 | public void decrementBy1Transactional() throws Exception { 37 | // Given 38 | TransactionSynchronizationManager.initSynchronization(); 39 | // When 40 | batchMetrics.decrement("counter.test", 1L); 41 | TransactionSynchronizationUtils.triggerAfterCompletion(TransactionSynchronization.STATUS_COMMITTED); 42 | // Then 43 | TransactionSynchronizationManager.clearSynchronization(); 44 | } 45 | 46 | @Test 47 | public void incrementBy1NonTransactional() throws Exception { 48 | // Given 49 | // No transaction 50 | // When 51 | batchMetrics.increment("counter.test", 1L); 52 | // Then 53 | } 54 | 55 | @Test 56 | public void submitTransactional() throws Exception { 57 | // Given 58 | TransactionSynchronizationManager.initSynchronization(); 59 | // When 60 | batchMetrics.submit("counter.test", 1L); 61 | TransactionSynchronizationUtils.triggerAfterCompletion(TransactionSynchronization.STATUS_COMMITTED); 62 | // Then 63 | TransactionSynchronizationManager.clearSynchronization(); 64 | } 65 | 66 | @Test 67 | public void submitNonTransactional() throws Exception { 68 | // Given 69 | // No transaction 70 | // When 71 | batchMetrics.submit("counter.test", 1L); 72 | // Then 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/Item.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics; 17 | 18 | import java.util.HashSet; 19 | import java.util.Set; 20 | 21 | /** 22 | * @author Tobias Flohre 23 | */ 24 | public class Item { 25 | 26 | private Action firstAction; 27 | 28 | private Action secondAction; 29 | 30 | private String description; 31 | 32 | private Long id; 33 | 34 | public Set getActions() { 35 | Set actions = new HashSet<>(); 36 | if (firstAction != null) { 37 | actions.add(firstAction); 38 | } 39 | if (secondAction != null) { 40 | actions.add(secondAction); 41 | } 42 | return actions; 43 | } 44 | 45 | public String getDescription() { 46 | return description; 47 | } 48 | 49 | public void setDescription(String description) { 50 | this.description = description; 51 | } 52 | 53 | public Long getId() { 54 | return id; 55 | } 56 | 57 | public void setId(Long id) { 58 | this.id = id; 59 | } 60 | 61 | public Action getFirstAction() { 62 | return firstAction; 63 | } 64 | 65 | public void setFirstAction(Action firstAction) { 66 | this.firstAction = firstAction; 67 | } 68 | 69 | public Action getSecondAction() { 70 | return secondAction; 71 | } 72 | 73 | public void setSecondAction(Action secondAction) { 74 | this.secondAction = secondAction; 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | return "Item [firstAction=" + firstAction + ", secondAction=" + secondAction + ", description=" + description 80 | + ", id=" + id + "]"; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/ListenerMetricsAspect.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics; 17 | 18 | import org.aspectj.lang.ProceedingJoinPoint; 19 | import org.aspectj.lang.annotation.Around; 20 | import org.aspectj.lang.annotation.Aspect; 21 | 22 | import io.micrometer.core.instrument.MeterRegistry; 23 | 24 | @Aspect 25 | public class ListenerMetricsAspect extends AbstractBatchMetricsAspect { 26 | 27 | public ListenerMetricsAspect(MeterRegistry meterRegistry) { 28 | super(meterRegistry); 29 | } 30 | 31 | @Around("execution(* org.springframework.batch.core.ItemWriteListener.beforeWrite(..))") 32 | public Object profileListenerMethods(ProceedingJoinPoint pjp) throws Throwable { 33 | return profileMethod(pjp); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/MetricNames.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics; 17 | 18 | /** 19 | * @author Tobias Flohre 20 | */ 21 | public enum MetricNames { 22 | BEFORE_JOB_COUNT("before.job.count"), // 23 | AFTER_JOB_COUNT("after.job.count"), // 24 | BEFORE_STEP_COUNT("before.step.count"), // 25 | AFTER_STEP_COUNT("after.step.count"), // 26 | BEFORE_CHUNK_COUNT("before.chunk.count"), // 27 | AFTER_CHUNK_COUNT("after.chunk.count"), // 28 | CHUNK_ERROR_COUNT("chunk.error.count"), // 29 | STREAM_OPEN_COUNT("stream.open.count"), // 30 | STREAM_UPDATE_COUNT("stream.update.count"), // 31 | STREAM_CLOSE_COUNT("stream.close.count"), // 32 | BEFORE_READ_COUNT("before.read.count"), // 33 | READ_COUNT("read.count"), // 34 | AFTER_READ_COUNT("after.read.count"), // 35 | READ_ERROR_COUNT("read.error.count"), // 36 | BEFORE_PROCESS_COUNT("before.process.count"), // 37 | PROCESS_COUNT("process.count"), // 38 | AFTER_PROCESS_COUNT("after.process.count"), // 39 | PROCESS_ERROR_COUNT("process.error.count"), // 40 | BEFORE_WRITE_COUNT("before.write.count"), // 41 | WRITE_COUNT("write.count"), // 42 | AFTER_WRITE_COUNT("after.write.count"), // 43 | WRITE_ERROR_COUNT("write.error.count"), // 44 | SKIP_IN_READ_COUNT("skip.read.count"), // 45 | SKIP_IN_PROCESS_COUNT("skip.process.count"), // 46 | SKIP_IN_WRITE_COUNT("skip.write.count"), // 47 | 48 | BEFORE_JOB_GAUGE("before.job.gauge"), // 49 | AFTER_JOB_GAUGE("after.job.gauge"), // 50 | BEFORE_STEP_GAUGE("before.step.gauge"), // 51 | AFTER_STEP_GAUGE("after.step.gauge"), // 52 | BEFORE_CHUNK_GAUGE("before.chunk.gauge"), // 53 | AFTER_CHUNK_GAUGE("after.chunk.gauge"), // 54 | CHUNK_ERROR_GAUGE("chunk.error.gauge"), // 55 | STREAM_OPEN_GAUGE("stream.open.gauge"), // 56 | STREAM_UPDATE_GAUGE("stream.update.gauge"), // 57 | STREAM_CLOSE_GAUGE("stream.close.gauge"), // 58 | BEFORE_READ_GAUGE("before.read.gauge"), // 59 | READ_GAUGE("read.gauge"), // 60 | AFTER_READ_GAUGE("after.read.gauge"), // 61 | READ_ERROR_GAUGE("read.error.gauge"), // 62 | BEFORE_PROCESS_GAUGE("before.process.gauge"), // 63 | PROCESS_GAUGE("process.gauge"), // 64 | AFTER_PROCESS_GAUGE("after.process.gauge"), // 65 | PROCESS_ERROR_GAUGE("process.error.gauge"), // 66 | BEFORE_WRITE_GAUGE("before.write.gauge"), // 67 | WRITE_GAUGE("write.gauge"), // 68 | AFTER_WRITE_GAUGE("after.write.gauge"), // 69 | WRITE_ERROR_GAUGE("write.error.gauge"), // 70 | SKIP_IN_READ_GAUGE("skip.read.gauge"), // 71 | SKIP_IN_PROCESS_GAUGE("skip.process.gauge"), // 72 | SKIP_IN_WRITE_GAUGE("skip.write.gauge"); 73 | 74 | private String name; 75 | 76 | private MetricNames(String name) { 77 | this.name = name; 78 | } 79 | 80 | public String getName() { 81 | return name; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/MetricsTestException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics; 17 | 18 | /** 19 | * @author Tobias Flohre 20 | */ 21 | public class MetricsTestException extends RuntimeException { 22 | 23 | private static final long serialVersionUID = 1L; 24 | 25 | public MetricsTestException() { 26 | } 27 | 28 | public MetricsTestException(String message) { 29 | super(message); 30 | } 31 | 32 | public MetricsTestException(Throwable cause) { 33 | super(cause); 34 | } 35 | 36 | public MetricsTestException(String message, Throwable cause) { 37 | super(message, cause); 38 | } 39 | 40 | public MetricsTestException(String message, Throwable cause, boolean enableSuppression, 41 | boolean writableStackTrace) { 42 | super(message, cause, enableSuppression, writableStackTrace); 43 | } 44 | 45 | public MetricsTestException(Action action) { 46 | super(action.name()); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/item/MetricsTestChunkListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics.item; 17 | 18 | import org.springframework.batch.core.ChunkListener; 19 | import org.springframework.batch.core.scope.context.ChunkContext; 20 | 21 | import de.codecentric.batch.metrics.BatchMetrics; 22 | import de.codecentric.batch.metrics.MetricNames; 23 | 24 | /** 25 | * @author Tobias Flohre 26 | */ 27 | public class MetricsTestChunkListener implements ChunkListener { 28 | 29 | private BatchMetrics businessMetrics; 30 | 31 | public MetricsTestChunkListener(BatchMetrics businessMetrics) { 32 | this.businessMetrics = businessMetrics; 33 | } 34 | 35 | @Override 36 | public void beforeChunk(ChunkContext context) { 37 | businessMetrics.increment(MetricNames.BEFORE_CHUNK_COUNT.getName()); 38 | businessMetrics.submit(MetricNames.BEFORE_CHUNK_GAUGE.getName(), 5); 39 | } 40 | 41 | @Override 42 | public void afterChunk(ChunkContext context) { 43 | businessMetrics.incrementNonTransactional(MetricNames.AFTER_CHUNK_COUNT.getName()); 44 | businessMetrics.submitNonTransactional(MetricNames.AFTER_CHUNK_GAUGE.getName(), 5); 45 | } 46 | 47 | @Override 48 | public void afterChunkError(ChunkContext context) { 49 | businessMetrics.incrementNonTransactional(MetricNames.CHUNK_ERROR_COUNT.getName()); 50 | businessMetrics.submitNonTransactional(MetricNames.CHUNK_ERROR_GAUGE.getName(), 5); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/item/MetricsTestItemProcessListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics.item; 17 | 18 | import org.springframework.batch.core.ItemProcessListener; 19 | 20 | import de.codecentric.batch.metrics.Action; 21 | import de.codecentric.batch.metrics.BatchMetrics; 22 | import de.codecentric.batch.metrics.Item; 23 | import de.codecentric.batch.metrics.MetricNames; 24 | import de.codecentric.batch.metrics.MetricsTestException; 25 | 26 | /** 27 | * @author Tobias Flohre 28 | */ 29 | public class MetricsTestItemProcessListener implements ItemProcessListener { 30 | 31 | private BatchMetrics businessMetrics; 32 | 33 | private boolean processorTransactional; 34 | 35 | public MetricsTestItemProcessListener(BatchMetrics businessMetrics, boolean processorTransactional) { 36 | this.businessMetrics = businessMetrics; 37 | this.processorTransactional = processorTransactional; 38 | } 39 | 40 | @Override 41 | public void beforeProcess(Item item) { 42 | if (processorTransactional) { 43 | businessMetrics.increment(MetricNames.BEFORE_PROCESS_COUNT.getName()); 44 | businessMetrics.submit(MetricNames.BEFORE_PROCESS_GAUGE.getName(), 5); 45 | } else { 46 | businessMetrics.incrementNonTransactional(MetricNames.BEFORE_PROCESS_COUNT.getName()); 47 | businessMetrics.submitNonTransactional(MetricNames.BEFORE_PROCESS_GAUGE.getName(), 5); 48 | } 49 | if (item != null && item.getActions().contains(Action.FAIL_ON_BEFORE_PROCESS)) { 50 | throw new MetricsTestException(Action.FAIL_ON_BEFORE_PROCESS); 51 | } 52 | } 53 | 54 | @Override 55 | public void afterProcess(Item item, Item result) { 56 | if (processorTransactional) { 57 | businessMetrics.increment(MetricNames.AFTER_PROCESS_COUNT.getName()); 58 | businessMetrics.submit(MetricNames.AFTER_PROCESS_GAUGE.getName(), 5); 59 | } else { 60 | businessMetrics.incrementNonTransactional(MetricNames.AFTER_PROCESS_COUNT.getName()); 61 | businessMetrics.submitNonTransactional(MetricNames.AFTER_PROCESS_GAUGE.getName(), 5); 62 | } 63 | if (item != null && item.getActions().contains(Action.FAIL_ON_AFTER_PROCESS)) { 64 | throw new MetricsTestException(Action.FAIL_ON_AFTER_PROCESS); 65 | } 66 | } 67 | 68 | @Override 69 | public void onProcessError(Item item, Exception e) { 70 | businessMetrics.incrementNonTransactional(MetricNames.PROCESS_ERROR_COUNT.getName()); 71 | businessMetrics.submitNonTransactional(MetricNames.PROCESS_ERROR_GAUGE.getName(), 5); 72 | if (item != null && item.getActions().contains(Action.FAIL_ON_PROCESS_ERROR)) { 73 | throw new MetricsTestException(Action.FAIL_ON_PROCESS_ERROR); 74 | } 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/item/MetricsTestItemProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics.item; 17 | 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | import org.springframework.batch.item.ItemProcessor; 21 | 22 | import de.codecentric.batch.metrics.Action; 23 | import de.codecentric.batch.metrics.BatchMetrics; 24 | import de.codecentric.batch.metrics.Item; 25 | import de.codecentric.batch.metrics.MetricNames; 26 | import de.codecentric.batch.metrics.MetricsTestException; 27 | 28 | /** 29 | * @author Tobias Flohre 30 | */ 31 | public class MetricsTestItemProcessor implements ItemProcessor { 32 | 33 | private static final Logger LOGGER = LoggerFactory.getLogger(MetricsTestItemProcessor.class); 34 | 35 | private BatchMetrics businessMetrics; 36 | 37 | private boolean processorTransactional; 38 | 39 | public MetricsTestItemProcessor(BatchMetrics businessMetrics, boolean processorTransactional) { 40 | this.businessMetrics = businessMetrics; 41 | this.processorTransactional = processorTransactional; 42 | } 43 | 44 | @Override 45 | public Item process(Item item) throws Exception { 46 | LOGGER.debug("Processed item: {}", item.toString()); 47 | if (!processorTransactional || item.getActions().contains(Action.FILTER)) { 48 | businessMetrics.incrementNonTransactional(MetricNames.PROCESS_COUNT.getName()); 49 | businessMetrics.submitNonTransactional(MetricNames.PROCESS_GAUGE.getName(), 5); 50 | } else { 51 | businessMetrics.increment(MetricNames.PROCESS_COUNT.getName()); 52 | businessMetrics.submit(MetricNames.PROCESS_GAUGE.getName(), 5); 53 | } 54 | if (item.getActions().contains(Action.FAIL_ON_PROCESS)) { 55 | throw new MetricsTestException(Action.FAIL_ON_PROCESS); 56 | } 57 | if (item.getActions().contains(Action.FILTER)) { 58 | return null; 59 | } 60 | return item; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/item/MetricsTestItemReadListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics.item; 17 | 18 | import org.springframework.batch.core.ItemReadListener; 19 | 20 | import de.codecentric.batch.metrics.Action; 21 | import de.codecentric.batch.metrics.BatchMetrics; 22 | import de.codecentric.batch.metrics.Item; 23 | import de.codecentric.batch.metrics.MetricNames; 24 | import de.codecentric.batch.metrics.MetricsTestException; 25 | 26 | /** 27 | * @author Tobias Flohre 28 | */ 29 | public class MetricsTestItemReadListener implements ItemReadListener { 30 | 31 | private BatchMetrics businessMetrics; 32 | 33 | private boolean readerTransactional; 34 | 35 | public MetricsTestItemReadListener(BatchMetrics businessMetrics, boolean readerTransactional) { 36 | this.businessMetrics = businessMetrics; 37 | this.readerTransactional = readerTransactional; 38 | } 39 | 40 | @Override 41 | public void beforeRead() { 42 | if (readerTransactional) { 43 | businessMetrics.increment(MetricNames.BEFORE_READ_COUNT.getName()); 44 | businessMetrics.submit(MetricNames.BEFORE_READ_GAUGE.getName(), 5); 45 | } else { 46 | businessMetrics.incrementNonTransactional(MetricNames.BEFORE_READ_COUNT.getName()); 47 | businessMetrics.submitNonTransactional(MetricNames.BEFORE_READ_GAUGE.getName(), 5); 48 | } 49 | } 50 | 51 | @Override 52 | public void afterRead(Item item) { 53 | if (readerTransactional) { 54 | businessMetrics.increment(MetricNames.AFTER_READ_COUNT.getName()); 55 | businessMetrics.submit(MetricNames.AFTER_READ_GAUGE.getName(), 5); 56 | } else { 57 | businessMetrics.incrementNonTransactional(MetricNames.AFTER_READ_COUNT.getName()); 58 | businessMetrics.submitNonTransactional(MetricNames.AFTER_READ_GAUGE.getName(), 5); 59 | } 60 | if (item != null && item.getActions().contains(Action.FAIL_ON_AFTER_READ)) { 61 | throw new MetricsTestException(Action.FAIL_ON_AFTER_READ); 62 | } 63 | } 64 | 65 | @Override 66 | public void onReadError(Exception ex) { 67 | businessMetrics.incrementNonTransactional(MetricNames.READ_ERROR_COUNT.getName()); 68 | businessMetrics.submitNonTransactional(MetricNames.READ_ERROR_GAUGE.getName(), 5); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/item/MetricsTestItemWriteListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics.item; 17 | 18 | import java.util.List; 19 | 20 | import org.springframework.batch.core.ItemWriteListener; 21 | 22 | import de.codecentric.batch.metrics.Action; 23 | import de.codecentric.batch.metrics.BatchMetrics; 24 | import de.codecentric.batch.metrics.Item; 25 | import de.codecentric.batch.metrics.MetricNames; 26 | import de.codecentric.batch.metrics.MetricsTestException; 27 | 28 | /** 29 | * @author Tobias Flohre 30 | */ 31 | public class MetricsTestItemWriteListener implements ItemWriteListener { 32 | 33 | private BatchMetrics businessMetrics; 34 | 35 | public MetricsTestItemWriteListener(BatchMetrics businessMetrics) { 36 | this.businessMetrics = businessMetrics; 37 | } 38 | 39 | @Override 40 | public void beforeWrite(List items) { 41 | for (Item item : items) { 42 | businessMetrics.increment(MetricNames.BEFORE_WRITE_COUNT.getName()); 43 | businessMetrics.submit(MetricNames.BEFORE_WRITE_GAUGE.getName(), 5); 44 | if (item != null && item.getActions().contains(Action.FAIL_ON_BEFORE_WRITE)) { 45 | throw new MetricsTestException(Action.FAIL_ON_BEFORE_WRITE); 46 | } 47 | } 48 | } 49 | 50 | @Override 51 | public void afterWrite(List items) { 52 | for (Item item : items) { 53 | businessMetrics.increment(MetricNames.AFTER_WRITE_COUNT.getName()); 54 | businessMetrics.submit(MetricNames.AFTER_WRITE_GAUGE.getName(), 5); 55 | if (item != null && item.getActions().contains(Action.FAIL_ON_AFTER_WRITE)) { 56 | throw new MetricsTestException(Action.FAIL_ON_AFTER_WRITE); 57 | } 58 | } 59 | } 60 | 61 | @Override 62 | public void onWriteError(Exception exception, List items) { 63 | for (Item item : items) { 64 | businessMetrics.incrementNonTransactional(MetricNames.WRITE_ERROR_COUNT.getName()); 65 | businessMetrics.submitNonTransactional(MetricNames.WRITE_ERROR_GAUGE.getName(), 5); 66 | if (item != null && item.getActions().contains(Action.FAIL_ON_WRITE_ERROR)) { 67 | throw new MetricsTestException(Action.FAIL_ON_WRITE_ERROR); 68 | } 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/item/MetricsTestItemWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics.item; 17 | 18 | import java.util.List; 19 | 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | import org.springframework.batch.item.ItemWriter; 23 | 24 | import de.codecentric.batch.metrics.Action; 25 | import de.codecentric.batch.metrics.BatchMetrics; 26 | import de.codecentric.batch.metrics.Item; 27 | import de.codecentric.batch.metrics.MetricNames; 28 | import de.codecentric.batch.metrics.MetricsTestException; 29 | 30 | /** 31 | * @author Tobias Flohre 32 | */ 33 | public class MetricsTestItemWriter implements ItemWriter { 34 | 35 | private static final Logger LOGGER = LoggerFactory.getLogger(MetricsTestItemWriter.class); 36 | 37 | private ItemWriter delegate; 38 | 39 | private BatchMetrics businessMetrics; 40 | 41 | public MetricsTestItemWriter(ItemWriter delegate, BatchMetrics businessMetrics) { 42 | this.delegate = delegate; 43 | this.businessMetrics = businessMetrics; 44 | } 45 | 46 | @Override 47 | public void write(List items) throws Exception { 48 | delegate.write(items); 49 | for (Item item : items) { 50 | LOGGER.debug("Written item: {}", item); 51 | businessMetrics.increment(MetricNames.WRITE_COUNT.getName()); 52 | businessMetrics.submit(MetricNames.WRITE_GAUGE.getName(), 5); 53 | if (item.getActions().contains(Action.FAIL_ON_WRITE)) { 54 | throw new MetricsTestException(Action.FAIL_ON_WRITE); 55 | } 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/metrics/item/MetricsTestSkipListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.metrics.item; 17 | 18 | import org.springframework.batch.core.SkipListener; 19 | 20 | import de.codecentric.batch.metrics.BatchMetrics; 21 | import de.codecentric.batch.metrics.Item; 22 | import de.codecentric.batch.metrics.MetricNames; 23 | 24 | /** 25 | * @author Tobias Flohre 26 | */ 27 | public class MetricsTestSkipListener implements SkipListener { 28 | 29 | private BatchMetrics businessMetrics; 30 | 31 | public MetricsTestSkipListener(BatchMetrics businessMetrics) { 32 | this.businessMetrics = businessMetrics; 33 | } 34 | 35 | @Override 36 | public void onSkipInRead(Throwable t) { 37 | businessMetrics.increment(MetricNames.SKIP_IN_READ_COUNT.getName()); 38 | businessMetrics.submit(MetricNames.SKIP_IN_READ_GAUGE.getName(), 5); 39 | } 40 | 41 | @Override 42 | public void onSkipInWrite(Item item, Throwable t) { 43 | businessMetrics.increment(MetricNames.SKIP_IN_WRITE_COUNT.getName()); 44 | businessMetrics.submit(MetricNames.SKIP_IN_WRITE_GAUGE.getName(), 5); 45 | } 46 | 47 | @Override 48 | public void onSkipInProcess(Item item, Throwable t) { 49 | businessMetrics.increment(MetricNames.SKIP_IN_PROCESS_COUNT.getName()); 50 | businessMetrics.submit(MetricNames.SKIP_IN_PROCESS_GAUGE.getName(), 5); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/scheduling/concurrent/MdcThreadPoolTaskExecutorTest.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.scheduling.concurrent; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.slf4j.MDC; 5 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 6 | 7 | import java.util.concurrent.Callable; 8 | import java.util.concurrent.FutureTask; 9 | 10 | import static org.hamcrest.CoreMatchers.equalTo; 11 | import static org.hamcrest.CoreMatchers.is; 12 | import static org.hamcrest.MatcherAssert.assertThat; 13 | 14 | public class MdcThreadPoolTaskExecutorTest { 15 | 16 | @Test 17 | public void run() throws Exception { 18 | // Given 19 | ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); 20 | taskExecutor.afterPropertiesSet(); 21 | 22 | final ThreadPoolTaskExecutor innerTaskExecutor = new MdcThreadPoolTaskExecutor(); 23 | innerTaskExecutor.afterPropertiesSet(); 24 | 25 | // Simple task which returns always the key from the MDC 26 | final FutureTask innerTask = new FutureTask(new Callable() { 27 | 28 | @Override 29 | public String call() throws Exception { 30 | return MDC.get("key"); 31 | } 32 | }); 33 | 34 | taskExecutor.execute(new Runnable() { 35 | 36 | @Override 37 | public void run() { 38 | MDC.put("key", "1"); 39 | innerTaskExecutor.execute(innerTask); 40 | } 41 | }); 42 | // Wait for Thread and verify that it contains the right value of key 43 | assertThat(innerTask.get(), is(equalTo("1"))); 44 | 45 | // Wait 1sec. for outer thread 46 | Thread.sleep(1000); 47 | 48 | // Simple task which returns always the key from the MDC 49 | final FutureTask innerTask2 = new FutureTask(new Callable() { 50 | 51 | @Override 52 | public String call() throws Exception { 53 | return MDC.get("key"); 54 | } 55 | }); 56 | 57 | taskExecutor.execute(new Runnable() { 58 | 59 | @Override 60 | public void run() { 61 | MDC.put("key", "2"); 62 | innerTaskExecutor.execute(innerTask2); 63 | } 64 | }); 65 | 66 | // Wait for Thread and verify that it contains the right value of key 67 | assertThat(innerTask2.get(), is(equalTo("2"))); 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/test/FlatFileJobTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.test; 18 | 19 | import de.codecentric.batch.AutoconfigureBatchWebStarter; 20 | import de.codecentric.batch.TestConfiguration; 21 | import org.apache.commons.io.FileUtils; 22 | import org.junit.jupiter.api.Test; 23 | import org.springframework.batch.core.BatchStatus; 24 | import org.springframework.batch.core.JobParameters; 25 | import org.springframework.batch.core.launch.JobOperator; 26 | import org.springframework.batch.core.repository.JobRepository; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.boot.test.context.SpringBootTest; 29 | 30 | import java.io.File; 31 | import java.nio.charset.StandardCharsets; 32 | 33 | import static org.junit.jupiter.api.Assertions.assertEquals; 34 | 35 | @AutoconfigureBatchWebStarter 36 | @SpringBootTest(classes = TestConfiguration.class) 37 | public class FlatFileJobTest { 38 | 39 | @Autowired 40 | private JobOperator jobOperator; 41 | 42 | @Autowired 43 | private JobRepository jobRepository; 44 | 45 | @Test 46 | public void runJavaConfigJob() throws Exception { 47 | File file = new File("target/out-javaconfig.txt"); 48 | file.delete(); 49 | jobOperator.start("flatFileJob", ""); 50 | while (jobRepository.getLastJobExecution("flatFileJob", new JobParameters()).getStatus().isRunning()) { 51 | Thread.sleep(100); 52 | } 53 | assertEquals(BatchStatus.COMPLETED, 54 | jobRepository.getLastJobExecution("flatFileJob", new JobParameters()).getStatus()); 55 | assertEquals(3, FileUtils.readLines(file, StandardCharsets.UTF_8).size()); 56 | } 57 | 58 | @Test 59 | public void runXmlJob() throws Exception { 60 | File file = new File("target/out-xmlconfig.txt"); 61 | file.delete(); 62 | jobOperator.start("flatFileJobXml", ""); 63 | while (jobRepository.getLastJobExecution("flatFileJobXml", new JobParameters()).getStatus().isRunning()) { 64 | Thread.sleep(100); 65 | } 66 | assertEquals(BatchStatus.COMPLETED, 67 | jobRepository.getLastJobExecution("flatFileJobXml", new JobParameters()).getStatus()); 68 | assertEquals(10, FileUtils.readLines(file, StandardCharsets.UTF_8).size()); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/test/JavaConfigIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.test; 17 | 18 | import de.codecentric.batch.TestApplication; 19 | import org.junit.jupiter.api.Test; 20 | import org.springframework.batch.core.BatchStatus; 21 | import org.springframework.batch.core.JobExecution; 22 | import org.springframework.batch.core.explore.JobExplorer; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.beans.factory.annotation.Value; 25 | import org.springframework.boot.test.context.SpringBootTest; 26 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 27 | import org.springframework.boot.test.web.client.TestRestTemplate; 28 | 29 | import java.util.List; 30 | 31 | import static org.hamcrest.CoreMatchers.is; 32 | import static org.hamcrest.MatcherAssert.assertThat; 33 | 34 | /** 35 | * This test class starts a batch job configured in JavaConfig and tests several endpoints. 36 | * 37 | * @author Tobias Flohre 38 | */ 39 | @SpringBootTest(classes = TestApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) 40 | public class JavaConfigIntegrationTest { 41 | 42 | private TestRestTemplate restTemplate = new TestRestTemplate(); 43 | 44 | @Autowired 45 | private JobExplorer jobExplorer; 46 | 47 | @Value("${local.server.port}") 48 | int port; 49 | 50 | @Test 51 | public void testRunJob() throws InterruptedException { 52 | Long executionId = restTemplate.postForObject("http://localhost:" + port + "/batch/operations/jobs/simpleJob", 53 | "", Long.class); 54 | while (!restTemplate 55 | .getForObject("http://localhost:" + port + "/batch/operations/jobs/executions/{executionId}", 56 | String.class, executionId) 57 | .equals("COMPLETED")) { 58 | Thread.sleep(1000); 59 | } 60 | String log = restTemplate.getForObject( 61 | "http://localhost:" + port + "/batch/operations/jobs/executions/{executionId}/log", String.class, 62 | executionId); 63 | assertThat(log.length() > 20, is(true)); 64 | JobExecution jobExecution = jobExplorer.getJobExecution(executionId); 65 | assertThat(jobExecution.getStatus(), is(BatchStatus.COMPLETED)); 66 | String jobExecutionString = restTemplate.getForObject( 67 | "http://localhost:" + port + "/batch/monitoring/jobs/executions/{executionId}", String.class, 68 | executionId); 69 | assertThat(jobExecutionString.contains("COMPLETED"), is(true)); 70 | } 71 | 72 | @Test 73 | public void testGetJobNames() { 74 | @SuppressWarnings("unchecked") 75 | List jobNames = restTemplate.getForObject("http://localhost:" + port + "/batch/monitoring/jobs", 76 | List.class); 77 | assertThat(jobNames.contains("simpleJob"), is(true)); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/test/Jsr352IntegrationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.test; 17 | 18 | import de.codecentric.batch.TestApplication; 19 | import org.junit.jupiter.api.Test; 20 | import org.springframework.batch.core.BatchStatus; 21 | import org.springframework.batch.core.JobExecution; 22 | import org.springframework.batch.core.explore.JobExplorer; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.beans.factory.annotation.Value; 25 | import org.springframework.boot.test.context.SpringBootTest; 26 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 27 | import org.springframework.boot.test.web.client.TestRestTemplate; 28 | 29 | import java.util.List; 30 | 31 | import static org.hamcrest.CoreMatchers.is; 32 | import static org.hamcrest.MatcherAssert.assertThat; 33 | 34 | /** 35 | * This test class starts a JSR-352 type batch job and tests several endpoints. 36 | * 37 | * @author Tobias Flohre 38 | */ 39 | @SpringBootTest(classes = TestApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) 40 | public class Jsr352IntegrationTest { 41 | 42 | private TestRestTemplate restTemplate = new TestRestTemplate(); 43 | 44 | @Autowired 45 | private JobExplorer jobExplorer; 46 | 47 | @Value("${local.server.port}") 48 | int port; 49 | 50 | @Test 51 | public void testRunJob() throws InterruptedException { 52 | Long executionId = restTemplate 53 | .postForObject("http://localhost:" + port + "/batch/operations/jobs/simpleJsr352Job", "", Long.class); 54 | while (!restTemplate 55 | .getForObject("http://localhost:" + port + "/batch/operations/jobs/executions/{executionId}", 56 | String.class, executionId) 57 | .equals("COMPLETED")) { 58 | Thread.sleep(1000); 59 | } 60 | String log = restTemplate.getForObject( 61 | "http://localhost:" + port + "/batch/operations/jobs/executions/{executionId}/log", String.class, 62 | executionId); 63 | assertThat(log.length() > 20, is(true)); 64 | JobExecution jobExecution = jobExplorer.getJobExecution(executionId); 65 | assertThat(jobExecution.getStatus(), is(BatchStatus.COMPLETED)); 66 | String jobExecutionString = restTemplate.getForObject( 67 | "http://localhost:" + port + "/batch/monitoring/jobs/executions/{executionId}", String.class, 68 | executionId); 69 | assertThat(jobExecutionString.contains("COMPLETED"), is(true)); 70 | } 71 | 72 | @Test 73 | public void testGetJobNames() { 74 | @SuppressWarnings("unchecked") 75 | List jobNames = restTemplate.getForObject("http://localhost:" + port + "/batch/monitoring/jobs", 76 | List.class); 77 | assertThat(jobNames.contains("simpleJsr352Job"), is(true)); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/test/ListenerProviderIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.test; 17 | 18 | import de.codecentric.batch.TestApplication; 19 | import de.codecentric.batch.listener.TestListener; 20 | import org.junit.jupiter.api.Test; 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.beans.factory.annotation.Value; 23 | import org.springframework.boot.test.context.SpringBootTest; 24 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 25 | import org.springframework.boot.test.web.client.TestRestTemplate; 26 | import org.springframework.util.LinkedMultiValueMap; 27 | import org.springframework.util.MultiValueMap; 28 | 29 | import static org.hamcrest.CoreMatchers.is; 30 | import static org.hamcrest.MatcherAssert.assertThat; 31 | 32 | /** 33 | * This test class starts a batch job configured in JavaConfig and tests the ListenerProvider concept. 34 | * 35 | * @author Tobias Flohre 36 | */ 37 | @SpringBootTest(classes = TestApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) 38 | public class ListenerProviderIntegrationTest { 39 | 40 | private TestRestTemplate restTemplate = new TestRestTemplate(); 41 | 42 | @Autowired 43 | private TestListener testListener; 44 | 45 | @Value("${local.server.port}") 46 | int port; 47 | 48 | @Test 49 | public void testRunJob() throws InterruptedException { 50 | MultiValueMap requestMap = new LinkedMultiValueMap<>(); 51 | requestMap.add("jobParameters", "param1=value1"); 52 | Long executionId = restTemplate.postForObject("http://localhost:" + port + "/batch/operations/jobs/simpleJob", 53 | requestMap, Long.class); 54 | while (!restTemplate 55 | .getForObject("http://localhost:" + port + "/batch/operations/jobs/executions/{executionId}", 56 | String.class, executionId) 57 | .equals("COMPLETED")) { 58 | Thread.sleep(1000); 59 | } 60 | assertThat(testListener.getCounter() > 1, is(true)); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/test/PartitionedFlatFileJobTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.test; 18 | 19 | import de.codecentric.batch.AutoconfigureBatchWebStarter; 20 | import de.codecentric.batch.TestConfiguration; 21 | import org.junit.jupiter.api.Test; 22 | import org.springframework.batch.core.BatchStatus; 23 | import org.springframework.batch.core.JobParameters; 24 | import org.springframework.batch.core.launch.JobOperator; 25 | import org.springframework.batch.core.repository.JobRepository; 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.boot.test.context.SpringBootTest; 28 | 29 | import static org.junit.jupiter.api.Assertions.assertEquals; 30 | 31 | @AutoconfigureBatchWebStarter 32 | @SpringBootTest(classes = TestConfiguration.class, properties = { "batch.metrics.enabled=true" }) 33 | public class PartitionedFlatFileJobTest { 34 | 35 | @Autowired 36 | private JobOperator jobOperator; 37 | 38 | @Autowired 39 | private JobRepository jobRepository; 40 | 41 | @Test 42 | public void runXmlJob() throws Exception { 43 | jobOperator.start("partitionedFlatFileJobXml", ""); 44 | while (jobRepository.getLastJobExecution("partitionedFlatFileJobXml", new JobParameters()).getStatus() 45 | .isRunning()) { 46 | Thread.sleep(100); 47 | } 48 | assertEquals(BatchStatus.COMPLETED, 49 | jobRepository.getLastJobExecution("partitionedFlatFileJobXml", new JobParameters()).getStatus()); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/test/StopJobIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.test; 17 | 18 | import de.codecentric.batch.TestApplication; 19 | import org.junit.jupiter.api.Test; 20 | import org.springframework.batch.core.BatchStatus; 21 | import org.springframework.batch.core.JobExecution; 22 | import org.springframework.batch.core.explore.JobExplorer; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.beans.factory.annotation.Value; 25 | import org.springframework.boot.test.context.SpringBootTest; 26 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 27 | import org.springframework.boot.test.web.client.TestRestTemplate; 28 | 29 | import java.util.List; 30 | 31 | import static org.hamcrest.CoreMatchers.is; 32 | import static org.hamcrest.MatcherAssert.assertThat; 33 | 34 | /** 35 | * This test class starts a batch job that needs some time to finish. It tests the endpoints monitoring running jobs and 36 | * then stops the job. 37 | * 38 | * @author Tobias Flohre 39 | */ 40 | @SpringBootTest(classes = TestApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) 41 | public class StopJobIntegrationTest { 42 | 43 | private TestRestTemplate restTemplate = new TestRestTemplate(); 44 | 45 | @Autowired 46 | private JobExplorer jobExplorer; 47 | 48 | @Value("${local.server.port}") 49 | int port; 50 | 51 | @Test 52 | public void testRunJob() throws InterruptedException { 53 | Long executionId = restTemplate.postForObject("http://localhost:" + port + "/batch/operations/jobs/delayJob", 54 | "", Long.class); 55 | Thread.sleep(500); 56 | String runningExecutions = restTemplate 57 | .getForObject("http://localhost:" + port + "/batch/monitoring/jobs/runningexecutions", String.class); 58 | assertThat(runningExecutions.contains(executionId.toString()), is(true)); 59 | String runningExecutionsForDelayJob = restTemplate.getForObject( 60 | "http://localhost:" + port + "/batch/monitoring/jobs/runningexecutions/delayJob", String.class); 61 | assertThat(runningExecutionsForDelayJob.contains(executionId.toString()), is(true)); 62 | restTemplate.delete("http://localhost:" + port + "/batch/operations/jobs/executions/{executionId}", 63 | executionId); 64 | Thread.sleep(1500); 65 | 66 | JobExecution jobExecution = jobExplorer.getJobExecution(executionId); 67 | assertThat(jobExecution.getStatus(), is(BatchStatus.STOPPED)); 68 | String jobExecutionString = restTemplate.getForObject( 69 | "http://localhost:" + port + "/batch/monitoring/jobs/executions/{executionId}", String.class, 70 | executionId); 71 | assertThat(jobExecutionString.contains("STOPPED"), is(true)); 72 | } 73 | 74 | @Test 75 | public void testGetJobNames() { 76 | @SuppressWarnings("unchecked") 77 | List jobNames = restTemplate.getForObject("http://localhost:" + port + "/batch/monitoring/jobs", 78 | List.class); 79 | assertThat(jobNames.contains("delayJob"), is(true)); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/java/de/codecentric/batch/test/XmlIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.codecentric.batch.test; 17 | 18 | import de.codecentric.batch.TestApplication; 19 | import org.junit.jupiter.api.Test; 20 | import org.springframework.batch.core.BatchStatus; 21 | import org.springframework.batch.core.JobExecution; 22 | import org.springframework.batch.core.explore.JobExplorer; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.beans.factory.annotation.Value; 25 | import org.springframework.boot.test.context.SpringBootTest; 26 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 27 | import org.springframework.boot.test.web.client.TestRestTemplate; 28 | 29 | import java.util.List; 30 | 31 | import static org.hamcrest.CoreMatchers.is; 32 | import static org.hamcrest.MatcherAssert.assertThat; 33 | 34 | /** 35 | * This test class starts a batch job configured in XML and tests several endpoints. 36 | * 37 | * @author Tobias Flohre 38 | */ 39 | @SpringBootTest(classes = TestApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, properties = { 40 | "batch.metrics.enabled=true", "batch.metrics.profiling.readprocesswrite.enabled=true" }) 41 | public class XmlIntegrationTest { 42 | 43 | private TestRestTemplate restTemplate = new TestRestTemplate(); 44 | 45 | @Autowired 46 | private JobExplorer jobExplorer; 47 | 48 | @Value("${local.server.port}") 49 | int port; 50 | 51 | @Test 52 | public void testRunJob() throws InterruptedException { 53 | Long executionId = restTemplate 54 | .postForObject("http://localhost:" + port + "/batch/operations/jobs/flatFile2JobXml", "", Long.class); 55 | while (!restTemplate 56 | .getForObject("http://localhost:" + port + "/batch/operations/jobs/executions/{executionId}", 57 | String.class, executionId) 58 | .equals("COMPLETED")) { 59 | Thread.sleep(1000); 60 | } 61 | String log = restTemplate.getForObject( 62 | "http://localhost:" + port + "/batch/operations/jobs/executions/{executionId}/log", String.class, 63 | executionId); 64 | assertThat(log.length() > 20, is(true)); 65 | JobExecution jobExecution = jobExplorer.getJobExecution(executionId); 66 | assertThat(jobExecution.getStatus(), is(BatchStatus.COMPLETED)); 67 | String jobExecutionString = restTemplate.getForObject( 68 | "http://localhost:" + port + "/batch/monitoring/jobs/executions/{executionId}", String.class, 69 | executionId); 70 | assertThat(jobExecutionString.contains("COMPLETED"), is(true)); 71 | } 72 | 73 | @Test 74 | public void testGetJobNames() { 75 | @SuppressWarnings("unchecked") 76 | List jobNames = restTemplate.getForObject("http://localhost:" + port + "/batch/monitoring/jobs", 77 | List.class); 78 | assertThat(jobNames.contains("flatFile2JobXml"), is(true)); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/META-INF/batch-jobs/simpleJsr352Job.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/META-INF/spring/batch/jobs/flat-file-2-job.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/META-INF/spring/batch/jobs/flat-file-job.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/META-INF/spring/batch/jobs/partitioned-flat-file-job.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | batch.config.package-javaconfig=de.codecentric.batch.jobs 2 | spring.main.allow-bean-definition-overriding=true 3 | logging.path=target/ -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/in-javaconfig.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/in-xmlconfig.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | 7 8 | 8 9 | 9 10 | 10 -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/metrics/create-schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE ITEM ( 2 | ID BIGINT, 3 | DESCRIPTION VARCHAR(100), 4 | FIRST_ACTION VARCHAR(20), 5 | SECOND_ACTION VARCHAR(20) 6 | ) ; 7 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/metrics/flatFileToDbNoSkipJob_Failed.csv: -------------------------------------------------------------------------------- 1 | 0,Bla,,, 2 | 1,Bli,,, 3 | 2,Blo,,, 4 | 3,Ble,,, 5 | 4,Blu,FAIL_ON_PROCESS,, -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/metrics/flatFileToDbNoSkipJob_Restart_FirstRun.csv: -------------------------------------------------------------------------------- 1 | 0,Bla,,, 2 | 1,Bli,,, 3 | 2,Blo,,, 4 | 3,Ble,,, 5 | 4,Blu,FAIL_ON_PROCESS,, 6 | 5,Blio,,, 7 | 6,Bloi,,, 8 | 7,Blaa,,, 9 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/metrics/flatFileToDbNoSkipJob_Restart_SecondRun.csv: -------------------------------------------------------------------------------- 1 | 0,Bla,,, 2 | 1,Bli,,, 3 | 2,Blo,,, 4 | 3,Ble,,, 5 | 4,Blu,,, 6 | 5,Blio,,, 7 | 6,Bloi,,, 8 | 7,Blaa,,, 9 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/metrics/flatFileToDbNoSkipJob_Success.csv: -------------------------------------------------------------------------------- 1 | 0,Bla,,, 2 | 1,Bli,,, 3 | 2,Blo,,, 4 | 3,Ble,,, 5 | 4,Blu,,, -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/metrics/flatFileToDbSkipJob_SkipInProcess.csv: -------------------------------------------------------------------------------- 1 | 0,Bla,,, 2 | 1,Bli,,, 3 | 2,Blo,,, 4 | 3,Ble,,, 5 | 4,Blu,FAIL_ON_PROCESS,, 6 | 5,Blaa,,, 7 | 6,Bloo,,, 8 | 7,Blii,,, -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/metrics/flatFileToDbSkipJob_SkipInProcess_Failed.csv: -------------------------------------------------------------------------------- 1 | 0,Bla,,, 2 | 1,Bli,,, 3 | 2,Blo,,, 4 | 3,Ble,,, 5 | 4,Blu,FAIL_ON_PROCESS,, 6 | 5,Blaa,, 7 | 6,Bloo,, 8 | 7,Blii,, 9 | 8,Blu,FAIL_ON_PROCESS,, 10 | 9,Blu,FAIL_ON_PROCESS,, 11 | 10,Blu,FAIL_ON_PROCESS,, 12 | 11,Blu,FAIL_ON_PROCESS,, 13 | -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/metrics/flatFileToDbSkipJob_SkipInRead.csv: -------------------------------------------------------------------------------- 1 | 0,Bla,,, 2 | 1,Bli,,, 3 | 2,Blo,,, 4 | 3,Ble,,, 5 | 4,Blu,FAIL_ON_READ,, 6 | 5,Blaa,,, 7 | 6,Bloo,,, 8 | 7,Blii,,, -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/metrics/flatFileToDbSkipJob_SkipInWrite.csv: -------------------------------------------------------------------------------- 1 | 0,Bla,,, 2 | 1,Bli,,, 3 | 2,Blo,,, 4 | 3,Ble,,, 5 | 4,Blu,FAIL_ON_WRITE,, 6 | 5,Blaa,,, 7 | 6,Bloo,,, 8 | 7,Blii,,, -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/partition-1.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | 7 8 | 8 9 | 9 10 | 10 -------------------------------------------------------------------------------- /batch-web-spring-boot-autoconfigure/src/test/resources/partition-2.txt: -------------------------------------------------------------------------------- 1 | 11 2 | 12 3 | 13 4 | 14 5 | 15 6 | 16 7 | 17 8 | 18 9 | 19 10 | 20 -------------------------------------------------------------------------------- /batch-web-spring-boot-build/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 20 | 4.0.0 21 | batch-web-spring-boot-build 22 | pom 23 | Batch Web Spring Boot Build 24 | 25 | de.codecentric 26 | batch-web-spring-boot-dependencies 27 | ${revision} 28 | ../batch-web-spring-boot-dependencies 29 | 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-dependencies 35 | ${spring-boot.version} 36 | pom 37 | import 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.codehaus.mojo 45 | flatten-maven-plugin 46 | true 47 | 48 | 49 | 50 | flatten 51 | process-resources 52 | 53 | flatten 54 | 55 | 56 | true 57 | oss 58 | true 59 | 60 | expand 61 | remove 62 | remove 63 | 64 | 65 | 66 | 67 | 68 | 69 | org.codehaus.mojo 70 | build-helper-maven-plugin 71 | 72 | 73 | generate-automatic-module-name 74 | 75 | regex-property 76 | 77 | 78 | automatic-module-name 79 | ${project.groupId}.${project.artifactId} 80 | [^a-zA-Z0-9]+ 81 | . 82 | 83 | 84 | 85 | 86 | 87 | org.apache.maven.plugins 88 | maven-jar-plugin 89 | 90 | 91 | 92 | true 93 | 94 | 95 | ${automatic-module-name} 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /batch-web-spring-boot-dependencies/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 20 | 4.0.0 21 | batch-web-spring-boot-dependencies 22 | pom 23 | Batch Web Spring Boot Dependencies 24 | 25 | de.codecentric 26 | batch-web-spring-boot 27 | ${revision} 28 | .. 29 | 30 | 31 | 32 | 33 | de.codecentric 34 | batch-web-spring-boot-autoconfigure 35 | ${revision} 36 | 37 | 38 | de.codecentric 39 | batch-web-spring-boot-starter 40 | ${revision} 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.codehaus.mojo 48 | flatten-maven-plugin 49 | false 50 | 51 | 52 | 53 | flatten 54 | process-resources 55 | 56 | flatten 57 | 58 | 59 | true 60 | bom 61 | 62 | remove 63 | remove 64 | resolve 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /batch-web-spring-boot-docs/deploy-gh-pages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## 3 | # Makes a shallow clone for gh-pages branch, copies the new docs, adds, commits and pushes 'em. 4 | # 5 | # Requires the environment variable GH_TOKEN to be set to a valid GitHub-api-token. 6 | # 7 | # Usage: 8 | # ./deploy-gh-pages.sh 9 | # 10 | # project-version The version folder to use in gh-pages 11 | ## 12 | set -o errexit -o nounset 13 | 14 | GH_URL="https://${GITHUB_TOKEN}@github.com/codecentric/spring-boot-starter-batch-web.git" 15 | TEMPDIR="$(mktemp -d /tmp/gh-pages.XXX)" 16 | TARGET_DIR="${GITHUB_REF_NAME/master/current}" 17 | 18 | echo "Cloning gh-pages branch..." 19 | git clone --branch gh-pages --single-branch --depth 1 "$GH_URL" "$TEMPDIR" 20 | 21 | if [[ -d "$TEMPDIR"/"${TARGET_DIR}" ]]; then 22 | echo "Cleaning ${TARGET_DIR}..." 23 | rm -rf "$TEMPDIR"/"${TARGET_DIR}" 24 | fi 25 | 26 | echo "Copying new docs..." 27 | mkdir -p "$TEMPDIR"/"${TARGET_DIR}" 28 | cp -r target/generated-docs/* "$TEMPDIR"/"${TARGET_DIR}"/ 29 | 30 | pushd "$TEMPDIR" >/dev/null 31 | git add --all . 32 | 33 | if git diff-index --quiet HEAD; then 34 | echo "No changes detected." 35 | else 36 | echo "Commit changes..." 37 | git commit --message "Docs for ${TARGET_DIR}" 38 | echo "Pushing gh-pages..." 39 | git push origin gh-pages 40 | fi 41 | 42 | popd >/dev/null 43 | 44 | rm -rf "$TEMPDIR" 45 | exit 0 46 | -------------------------------------------------------------------------------- /batch-web-spring-boot-docs/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 20 | 4.0.0 21 | batch-web-spring-boot-docs 22 | pom 23 | Batch Web Spring Boot Docs 24 | 25 | de.codecentric 26 | batch-web-spring-boot-build 27 | ${revision} 28 | ../batch-web-spring-boot-build 29 | 30 | 31 | 32 | 33 | pl.project13.maven 34 | git-commit-id-plugin 35 | 36 | 37 | 38 | revision 39 | 40 | 41 | false 42 | false 43 | false 44 | dd.MM.yyyy 45 | 46 | 47 | 48 | 49 | 50 | org.asciidoctor 51 | asciidoctor-maven-plugin 52 | 53 | 54 | output-html 55 | generate-resources 56 | 57 | process-asciidoc 58 | 59 | 60 | index.adoc 61 | html5 62 | coderay 63 | 64 | 65 | src/main/asciidoc 66 | 67 | **/*.adoc 68 | 69 | 70 | 71 | 72 | ${project.version} 73 | ${git.commit.time} 74 | ${project.build.sourceDirectory} 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/.gitignore: -------------------------------------------------------------------------------- 1 | /.settings 2 | /target 3 | /bin 4 | /.classpath 5 | /.project 6 | /.springBeans 7 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/README.md: -------------------------------------------------------------------------------- 1 | File-to-db sample for spring-boot-starter-batch-web 2 | ============================= 3 | This sample demonstrates the usage of an external database. 4 | To run it, start the main class org.hsqldb.server.Server, which is part of the dependencies, then run de.codecentric.batch.db.DatabaseInitializer to initialize the database. Now you can startup the Spring Boot application either by running the class de.codecentric.batch.Application directly in the IDE or by packaging everything up via mvn package, and then running it via java -jar xxx.jar. 5 | 6 | The default port is 8080. To start a job, copy partner-import.csv to /tmp and then use this curl command: 7 | 8 | $ curl --data 'jobParameters=pathToFile=file:/tmp/partner-import.csv' localhost:8080/batch/operations/jobs/flatfileJob -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 4.0.0 20 | batch-boot-file-to-db 21 | Sample Batch Web File-to-DB 22 | Demo project 23 | 24 | de.codecentric 25 | batch-web-spring-boot-samples 26 | ${revision} 27 | .. 28 | 29 | 30 | 31 | de.codecentric 32 | batch-web-spring-boot-starter 33 | 34 | 35 | org.hsqldb 36 | hsqldb 37 | 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-test 43 | test 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-maven-plugin 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | 56 | 57 | **/*Test.java 58 | 59 | 60 | **/*IntegrationTest.java 61 | 62 | 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-failsafe-plugin 67 | 68 | 69 | **/*IntegrationTest.java 70 | 71 | 72 | 73 | 74 | integration-test 75 | 76 | integration-test 77 | 78 | 79 | 80 | verify 81 | 82 | verify 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/src/main/java/de/codecentric/batch/filetodb/Application.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.filetodb; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.SpringBootConfiguration; 5 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 6 | import org.springframework.context.annotation.Import; 7 | 8 | import de.codecentric.batch.filetodb.configuration.DataSourceConfiguration; 9 | 10 | @SpringBootConfiguration 11 | @EnableAutoConfiguration 12 | @Import(DataSourceConfiguration.class) 13 | public class Application { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(Application.class, args); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/src/main/java/de/codecentric/batch/filetodb/configuration/DataSourceConfiguration.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.filetodb.configuration; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | import java.util.Map; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.batch.core.repository.ExecutionContextSerializer; 13 | import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer; 14 | import org.springframework.context.annotation.Bean; 15 | import org.springframework.context.annotation.Configuration; 16 | import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; 17 | import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; 18 | 19 | @Configuration 20 | public class DataSourceConfiguration { 21 | 22 | @Bean 23 | public DataSource dataSourcePartner() { 24 | return new EmbeddedDatabaseBuilder()// 25 | .setType(EmbeddedDatabaseType.HSQL)// 26 | .ignoreFailedDrops(true)// 27 | .addScripts("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql", 28 | "classpath:org/springframework/batch/core/schema-hsqldb.sql", "classpath:schema-partner.sql")// 29 | .build(); 30 | } 31 | 32 | @Bean 33 | public ExecutionContextSerializer serializer() { 34 | return new CustomSerializer(); 35 | } 36 | 37 | private static class CustomSerializer extends Jackson2ExecutionContextStringSerializer { 38 | 39 | private static final Logger LOGGER = LoggerFactory.getLogger(CustomSerializer.class); 40 | 41 | @Override 42 | public void serialize(Map context, OutputStream out) throws IOException { 43 | LOGGER.info("I will do serialization"); 44 | super.serialize(context, out); 45 | } 46 | 47 | @Override 48 | public Map deserialize(InputStream in) throws IOException { 49 | LOGGER.info("I will do deserialization"); 50 | return super.deserialize(in); 51 | } 52 | 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/src/main/java/de/codecentric/batch/filetodb/domain/Partner.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.filetodb.domain; 2 | 3 | public class Partner { 4 | 5 | private String name; 6 | 7 | private String email; 8 | 9 | public String getName() { 10 | return name; 11 | } 12 | 13 | public void setName(String name) { 14 | this.name = name; 15 | } 16 | 17 | public String getEmail() { 18 | return email; 19 | } 20 | 21 | public void setEmail(String email) { 22 | this.email = email; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return "Partner [name=" + name + ", email=" + email + "]"; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/src/main/java/de/codecentric/batch/filetodb/item/ExampleService.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.filetodb.item; 2 | 3 | public class ExampleService { 4 | 5 | public String echo(String echo) { 6 | return echo; 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/src/main/java/de/codecentric/batch/filetodb/item/LogItemProcessor.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.filetodb.item; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.batch.item.ItemProcessor; 6 | 7 | /** 8 | * Dummy {@link ItemProcessor} which only logs data it receives. 9 | */ 10 | public class LogItemProcessor implements ItemProcessor { 11 | 12 | private static final Logger LOGGER = LoggerFactory.getLogger(LogItemProcessor.class); 13 | 14 | private ExampleService exampleService; 15 | 16 | @Override 17 | public Object process(Object item) throws Exception { 18 | LOGGER.info("{}", exampleService.echo("test")); 19 | return item; 20 | } 21 | 22 | public void setExampleService(ExampleService exampleService) { 23 | this.exampleService = exampleService; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/src/main/resources/META-INF/spring/batch/jobs/flatfile-job-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.path=/tmp/ 2 | server.port=8090 3 | spring.main.allow-bean-definition-overriding=true 4 | spring.batch.initialize-schema=never -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/src/main/resources/partner-import.csv: -------------------------------------------------------------------------------- 1 | Mustermann,Max,max.mustermann@codecentric.de,m 2 | Musterfrau,Martha,martha.musterfrau@codecentric.de,w 3 | Mustermann,Michael,michael.mustermann@codecentric.de,m 4 | Meier,Alfred,alfred.meier@codecentric.de,m 5 | Mueller,Marie,marie.mueller@codecentric.de,w 6 | Schulte,Daniel,daniel.schulte@codecentric.de,m -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/src/main/resources/schema-partner.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE PARTNER ( 2 | NAME VARCHAR(100), 3 | EMAIL VARCHAR(100) 4 | ) ; 5 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/src/test/java/de/codecentric/batch/filetodb/ApplicationTests.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.filetodb; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | public class ApplicationTests { 8 | 9 | @Test 10 | public void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/src/test/java/de/codecentric/batch/filetodb/FlatFileJobIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package de.codecentric.batch.filetodb; 18 | 19 | import org.junit.jupiter.api.Test; 20 | import org.springframework.batch.core.ExitStatus; 21 | import org.springframework.boot.test.context.SpringBootTest; 22 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 23 | import org.springframework.boot.web.client.RestTemplateBuilder; 24 | import org.springframework.util.LinkedMultiValueMap; 25 | import org.springframework.util.MultiValueMap; 26 | import org.springframework.web.client.RestTemplate; 27 | 28 | import static org.junit.jupiter.api.Assertions.assertEquals; 29 | 30 | @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT, properties = { 31 | "server.port=8090", 32 | "spring.main.allow-bean-definition-overriding=true" 33 | }) 34 | public class FlatFileJobIntegrationTest { 35 | 36 | private RestTemplate restTemplate = new RestTemplateBuilder().build(); 37 | 38 | @Test 39 | public void testLaunchJob() throws Exception { 40 | // Given 41 | String jobParameters = "pathToFile=classpath:partner-import.csv"; 42 | // When 43 | ExitStatus exitStatus = runJobAndWaitForCompletion("localhost", "8090", "flatfileJob", jobParameters); 44 | // Then 45 | assertEquals(ExitStatus.COMPLETED.getExitCode(), exitStatus.getExitCode()); 46 | } 47 | 48 | protected ExitStatus runJobAndWaitForCompletion(String hostname, String port, String jobName, String jobParameters) 49 | throws InterruptedException { 50 | MultiValueMap parameters = new LinkedMultiValueMap(); 51 | parameters.add("jobParameters", jobParameters); 52 | String jobExecutionId = restTemplate.postForObject( 53 | "http://" + hostname + ":" + port + "/batch/operations/jobs/" + jobName + "", parameters, String.class); 54 | ExitStatus exitStatus = getStatus(hostname, port, jobExecutionId); 55 | // Wait for end of job 56 | while (exitStatus.isRunning()) { 57 | Thread.sleep(100); 58 | exitStatus = getStatus(hostname, port, jobExecutionId); 59 | } 60 | return exitStatus; 61 | } 62 | 63 | private ExitStatus getStatus(String hostname, String port, String jobExecutionId) { 64 | String jobstatus = restTemplate.getForObject( 65 | "http://" + hostname + ":" + port + "/batch/operations/jobs/executions/" + jobExecutionId, 66 | String.class); 67 | return new ExitStatus(jobstatus); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-file-to-db/startBatchApplication.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/.gitignore: -------------------------------------------------------------------------------- 1 | /.settings 2 | /target 3 | /bin 4 | /.classpath 5 | /.project 6 | *.DS_Store 7 | /.springBeans 8 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 20 | 4.0.0 21 | batch-boot-simple-jsr352 22 | Sample Batch Web Simple JSR352 23 | Demo project 24 | 25 | de.codecentric 26 | batch-web-spring-boot-samples 27 | ${revision} 28 | .. 29 | 30 | 31 | 32 | de.codecentric 33 | batch-web-spring-boot-starter 34 | 35 | 36 | javax.inject 37 | javax.inject 38 | 1 39 | 40 | 41 | org.hsqldb 42 | hsqldb 43 | 44 | 45 | org.apache.commons 46 | commons-dbcp2 47 | 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-test 53 | test 54 | 55 | 56 | org.springframework.batch 57 | spring-batch-test 58 | test 59 | 60 | 61 | 62 | 63 | 64 | org.springframework.boot 65 | spring-boot-maven-plugin 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/java/de/codecentric/batch/simplejsr/Application.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simplejsr; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.SpringBootConfiguration; 5 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 6 | 7 | @SpringBootConfiguration 8 | @EnableAutoConfiguration 9 | public class Application { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(Application.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/java/de/codecentric/batch/simplejsr/item/DummyItemReader.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simplejsr.item; 2 | 3 | import javax.batch.api.chunk.AbstractItemReader; 4 | 5 | public class DummyItemReader extends AbstractItemReader { 6 | 7 | private String[] input = { "Good", "morning!", "This", "is", "your", "ItemReader", "speaking!", null }; 8 | 9 | private int index = 0; 10 | 11 | @Override 12 | public Object readItem() throws Exception { 13 | return input[index++]; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/java/de/codecentric/batch/simplejsr/item/LogItemProcessor.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simplejsr.item; 2 | 3 | import javax.batch.api.chunk.ItemProcessor; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * Dummy {@link ItemProcessor} which only logs data it receives. 10 | */ 11 | public class LogItemProcessor implements ItemProcessor { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(LogItemProcessor.class); 14 | 15 | @Override 16 | public Object processItem(Object item) throws Exception { 17 | LOGGER.info("ItemProcessor: {}", item); 18 | return item; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/java/de/codecentric/batch/simplejsr/item/LogItemWriter.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simplejsr.item; 2 | 3 | import java.util.List; 4 | 5 | import javax.batch.api.chunk.AbstractItemWriter; 6 | import javax.batch.api.chunk.ItemWriter; 7 | import javax.inject.Inject; 8 | import javax.sql.DataSource; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.util.Assert; 13 | 14 | /** 15 | * Dummy {@link ItemWriter} which only logs data it receives. 16 | * 17 | * It also serves as an example how to inject resources (Spring beans) from the parent context into batch artifacts even 18 | * if they are referenced by full class name in the batch job xml. 19 | */ 20 | public class LogItemWriter extends AbstractItemWriter { 21 | 22 | private static final Logger LOGGER = LoggerFactory.getLogger(LogItemWriter.class); 23 | 24 | @Inject 25 | private DataSource dataSource; 26 | 27 | @Override 28 | public void writeItems(List items) throws Exception { 29 | Assert.notNull(dataSource, "DataSource should not be null"); 30 | LOGGER.info("ItemWriter: {}", items); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/java/de/codecentric/batch/simplejsr/item/PartitionedItemReader.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simplejsr.item; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | 6 | import javax.batch.api.BatchProperty; 7 | import javax.batch.api.chunk.AbstractItemReader; 8 | import javax.inject.Inject; 9 | 10 | public class PartitionedItemReader extends AbstractItemReader { 11 | 12 | private static Map data = new ConcurrentHashMap<>(); 13 | static { 14 | data.put("key1", new String[]{ "Good", "morning!", "This", "is", "your", "ItemReader", "speaking!", null }); 15 | data.put("key2", new String[]{ "Eins", "zwei", "Polizei", "drei", "vier", "Grenadier", null }); 16 | data.put("key3", new String[]{ "Heja", "BVB", "Heja", "BVB", "Heja", "Heja", "Heja", "BVB", null }); 17 | } 18 | 19 | private int index = 0; 20 | 21 | @Inject 22 | @BatchProperty(name = "datakey") 23 | private String key; 24 | 25 | @Override 26 | public Object readItem() throws Exception { 27 | return data.get(key)[index++]; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/java/de/codecentric/batch/simplejsr/item/SimplePartitionMapper.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simplejsr.item; 2 | 3 | import java.util.Properties; 4 | 5 | import javax.batch.api.partition.PartitionMapper; 6 | import javax.batch.api.partition.PartitionPlan; 7 | import javax.batch.api.partition.PartitionPlanImpl; 8 | 9 | public class SimplePartitionMapper implements PartitionMapper { 10 | 11 | @Override 12 | public PartitionPlan mapPartitions() throws Exception { 13 | PartitionPlan partitionPlan = new PartitionPlanImpl(); 14 | partitionPlan.setPartitions(3); 15 | partitionPlan.setThreads(2); 16 | Properties[] propertiesArray = new Properties[3]; 17 | for (int i = 0; i < 3; i++) { 18 | Properties properties = new Properties(); 19 | properties.put("datakeyPartition", "key" + (i + 1)); 20 | propertiesArray[i] = properties; 21 | } 22 | partitionPlan.setPartitionProperties(propertiesArray); 23 | return partitionPlan; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/resources/META-INF/batch-jobs/partitionMapperJobNoDI.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/resources/META-INF/batch-jobs/partitionMapperJobSpringDI.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/resources/META-INF/batch-jobs/partitionMapperJobSpringDIBatchXml.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/resources/META-INF/batch-jobs/partitionedJobNoDI.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/resources/META-INF/batch-jobs/partitionedJobSpringDI.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/resources/META-INF/batch-jobs/simpleJob.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/resources/META-INF/batch.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.path=/tmp/ 2 | 3 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/test/java/de/codecentric/batch/simplejsr/ApplicationTests.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simplejsr; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | public class ApplicationTests { 8 | 9 | @Test 10 | public void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple-jsr352/src/test/java/de/codecentric/batch/simplejsr/TraditionalJsr352Test.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simplejsr; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.batch.test.JsrTestUtils; 5 | 6 | import java.util.concurrent.TimeoutException; 7 | 8 | public class TraditionalJsr352Test { 9 | 10 | @Test 11 | public void testTraditionalJsr352() throws TimeoutException{ 12 | JsrTestUtils.runJob("partitionMapperJobSpringDIBatchXml", null, 1000000); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple/.gitignore: -------------------------------------------------------------------------------- 1 | /.settings 2 | /target 3 | /bin 4 | /.classpath 5 | /.project 6 | /.DS_Store 7 | /.springBeans 8 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 4.0.0 20 | batch-boot-simple 21 | Sample Batch Web Simple 22 | Demo project 23 | 24 | de.codecentric 25 | batch-web-spring-boot-samples 26 | ${revision} 27 | .. 28 | 29 | 30 | 31 | de.codecentric 32 | batch-web-spring-boot-starter 33 | 34 | 35 | org.hsqldb 36 | hsqldb 37 | 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-test 43 | test 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-maven-plugin 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple/src/main/java/de/codecentric/batch/simple/Application.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simple; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.SpringBootConfiguration; 5 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 6 | 7 | @SpringBootConfiguration 8 | @EnableAutoConfiguration 9 | public class Application { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(Application.class, args); 13 | } 14 | 15 | // If you would like to configure your own batch infrastructure via BatchConfigurer, 16 | // just add a bean of that type to the ApplicationContext, like in the following code. 17 | // This starter's implementation will step aside then. 18 | // @Bean 19 | // public BatchConfigurer batchConfigurer(DataSource dataSource){ 20 | // return new DefaultBatchConfigurer(dataSource); 21 | // } 22 | 23 | // If you would like to use your own JobParametersConverter in JobOperationsController, 24 | // just add a bean of that type to the JobParametersConverter, like in the following code. 25 | // This starter's implementation will step aside then. 26 | // @Bean 27 | // public JobParametersConverter jobParametersConverter(){ 28 | // return new MyOwnJobParametersConverter(); 29 | // } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple/src/main/java/de/codecentric/batch/simple/item/DummyItemReader.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simple.item; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.batch.item.ItemReader; 6 | 7 | /** 8 | * {@link ItemReader} with hard-coded input data. 9 | */ 10 | public class DummyItemReader implements ItemReader { 11 | 12 | private static final Logger LOGGER = LoggerFactory.getLogger(DummyItemReader.class); 13 | 14 | private String[] input = { "Good", "morning!", "This", "is", "your", "ItemReader", "speaking!" }; 15 | 16 | private int index = 0; 17 | 18 | /** 19 | * Reads next record from input 20 | */ 21 | @Override 22 | public String read() throws Exception { 23 | String item = null; 24 | if (index < input.length) { 25 | item = input[index++]; 26 | LOGGER.info(item); 27 | return item; 28 | } else { 29 | return null; 30 | } 31 | 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple/src/main/java/de/codecentric/batch/simple/item/LogItemProcessor.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simple.item; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.batch.item.ItemProcessor; 6 | 7 | /** 8 | * Dummy {@link ItemProcessor} which only logs data it receives. 9 | */ 10 | public class LogItemProcessor implements ItemProcessor { 11 | 12 | private static final Logger LOGGER = LoggerFactory.getLogger(LogItemProcessor.class); 13 | 14 | @Override 15 | public String process(String item) throws Exception { 16 | LOGGER.info(item); 17 | return item; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple/src/main/java/de/codecentric/batch/simple/item/LogItemWriter.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simple.item; 2 | 3 | import java.util.List; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.batch.item.ItemWriter; 8 | 9 | /** 10 | * Dummy {@link ItemWriter} which only logs data it receives. 11 | */ 12 | public class LogItemWriter implements ItemWriter { 13 | 14 | private static final Logger LOGGER = LoggerFactory.getLogger(LogItemWriter.class); 15 | 16 | /** 17 | * @see ItemWriter#write(java.util.List) 18 | */ 19 | @Override 20 | public void write(List data) throws Exception { 21 | LOGGER.info("{}", data); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple/src/main/java/de/codecentric/batch/simple/job/SimpleJobConfiguration.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simple.job; 2 | 3 | import org.springframework.batch.core.Job; 4 | import org.springframework.batch.core.Step; 5 | import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; 6 | import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | 11 | import de.codecentric.batch.simple.item.DummyItemReader; 12 | import de.codecentric.batch.simple.item.LogItemProcessor; 13 | import de.codecentric.batch.simple.item.LogItemWriter; 14 | 15 | @Configuration 16 | public class SimpleJobConfiguration { 17 | 18 | @Autowired 19 | private JobBuilderFactory jobBuilderFactory; 20 | 21 | @Autowired 22 | private StepBuilderFactory stepBuilderFactory; 23 | 24 | @Bean 25 | public Job job(){ 26 | return jobBuilderFactory.get("job") 27 | .start(step()) 28 | .build(); 29 | } 30 | 31 | @Bean 32 | public Step step(){ 33 | return stepBuilderFactory.get("step") 34 | .chunk(1) 35 | .reader(reader()) 36 | .processor(processor()) 37 | .writer(writer()) 38 | .build(); 39 | } 40 | 41 | @Bean 42 | public LogItemWriter writer() { 43 | return new LogItemWriter(); 44 | } 45 | 46 | @Bean 47 | public LogItemProcessor processor() { 48 | return new LogItemProcessor(); 49 | } 50 | 51 | @Bean 52 | public DummyItemReader reader() { 53 | return new DummyItemReader(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8081 2 | 3 | batch.config.package-javaconfig=de.codecentric.batch.simple.job 4 | batch.web.operations.base=/batch 5 | 6 | logging.path=/tmp/ 7 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple/src/main/resources/monitoring.http: -------------------------------------------------------------------------------- 1 | GET http://localhost:8081/batch/monitoring/jobs 2 | Content-Type: application/json 3 | 4 | ### 5 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple/src/main/resources/operations.http: -------------------------------------------------------------------------------- 1 | POST http://localhost:8081/batch/jobs/job 2 | Content-Type: application/json 3 | 4 | {} 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/batch-boot-simple/src/test/java/de/codecentric/batch/simple/ApplicationTests.java: -------------------------------------------------------------------------------- 1 | package de.codecentric.batch.simple; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | import org.springframework.test.context.web.WebAppConfiguration; 6 | 7 | @SpringBootTest 8 | @WebAppConfiguration 9 | public class ApplicationTests { 10 | 11 | @Test 12 | public void contextLoads() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /batch-web-spring-boot-samples/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 13 | 4.0.0 14 | batch-web-spring-boot-samples 15 | pom 16 | Batch Web Spring Boot Samples 17 | 18 | de.codecentric 19 | batch-web-spring-boot-build 20 | ${revision} 21 | ../batch-web-spring-boot-build 22 | 23 | 24 | batch-boot-simple 25 | batch-boot-simple-jsr352 26 | batch-boot-file-to-db 27 | 28 | 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-maven-plugin 34 | ${spring-boot.version} 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /batch-web-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 20 | 4.0.0 21 | batch-web-spring-boot-starter 22 | Batch Web Spring Boot Starter 23 | 24 | de.codecentric 25 | batch-web-spring-boot-build 26 | ${revision} 27 | ../batch-web-spring-boot-build 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter 33 | 34 | 35 | de.codecentric 36 | batch-web-spring-boot-autoconfigure 37 | 38 | 39 | 40 | --------------------------------------------------------------------------------