1

I'm using Spring batch for our batch processing, before I do batch processing I would like to do validate all job params like productName, productID, start date, end date, productType, if these Job params are null or contains bad value I have to fail the validation step and make the job failed.

I've written validation step and Tasklet, in my Tasklet I'm planning to handle the job param validation (to do null check for all the job param). Since I'm doing first time Spring batch I would like to hear from the expert is this right place to handle the job param validation or is there any efficient way of doing it. It would be really helpful if someone can help me to provide your valuable suggestion or example.

Appreciated your help in advance! Thanks

Please find my sample code below:

MyJobConfig.java

@Configuration
public class MyJobConfig {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Bean("myBatchJob")
    public Job job(@Qualifier("validateProductJobParam") Step validateProductJobParametersStep) {
        Job job = jobBuilderFactory.get("myBatchJob")
                .incrementer(new RunIdIncrementer())
                .start(validateProductJobParametersStep)
                .on("FAILED")
                .end()
                .from(validateProductJobParametersStep).on("*").to(processProductBatch)
                .end()
                .build();
        return job;
    }

    @Bean(name = "validateProductJobParam")
    public Step validateProductJobParametersStep() {
        return stepBuilderFactory.get("validate-product-param")
                .tasklet(new JobParamValidateTasklet())
                .allowStartIfComplete(true)
                .build();
    }

}

JobParamValidateTasklet.java

import org.springframework.batch.core.*;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

import java.util.Map;

public class JobParamValidateTasklet implements Tasklet, StepExecutionListener {

    private StepExecution stepExecution;
    private JobExecution jobExecution;
    private bookean isValidation;

    @Override
    public void beforeStep(StepExecution stepExecution) {
        this.stepExecution = stepExecution;
        this.jobExecution = stepExecution.getJobExecution();

    }

    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {

        Map<String,JobParameter> jobMap = jobExecution.getJobParameters().getParameters();

        String productName = (String)jobMap.get("PRODUCT_NAME").getValue();
        String productId = (String)jobMap.get("PRODUCT_ID").getValue();
        String prdouctType = (String)jobMap.get("PRODUCT_TYPE").getValue();

        if (productName == null &&  productId == null && prdouctType == null ) {
            isValidation = false;
        } else {
        isValidation = true;
        }
        
        return null;
    }

    public ExitStatus afterStep(StepExecution stepExecution) {
        if(!isValidation)
            return ExitStatus.FAILED;
        else
            return ExitStatus.COMPLETED;
    }

}
Dave Brady
  • 193
  • 9

1 Answers1

1

Spring batch will use JobParametersValidator before every job execution. You don’t need to call it manually, but have to register it in your job definition and it gets called automatically. By default DefaultJobParametersValidator will be used if no custom validator is specified.

You can use https://docs.spring.io/spring-batch/docs/4.3.x/reference/html/job.html#jobparametersvalidator documentation for reference it shows how’s to register a validator.

update your MyJobConfig.class as below:

@Bean("myBatchJob")
public Job job(@Qualifier("validateProductJobParam") Step validateProductJobParametersStep) {
    Job job = jobBuilderFactory.get("myBatchJob")
            .incrementer(new RunIdIncrementer()).validator(validate())
            .start(processProductBatch)
            .end()
            .build();
    return job;
}

//implementation of validation

@Bean
public JobParametersValidator validate() {
    JobParametersValidator j = new JobParametersValidator() {
        
        @Override
        public void validate(JobParameters jparams) throws JobParametersInvalidException {
            Map<String, JobParameter> params = jparams.getParameters();
            if(null == params.get("PRODUCT_NAME").getValue() || null == params.get("PRODUCT_ID").getValue()
                    || null == params.get("PRODUCT_TYPE").getValue()){
                throw new JobParametersInvalidException("Cant be null");
            }
        }
    };
    return j;       
}
  • 1
    Thank you Ravi! I'm new to Spring world, would you mind providing some sample using my above use case. I looked at the documentation what you referred but I'm not getting where to register and call the validator and pass all the job params. – Dave Brady Nov 02 '21 at 20:00
  • Hi Dave, I have updated the answer with what you asked. Add the validate method after the bean of job. Hope you will understand from this answer. I'm new contributor so please ignore if any mistakes in format for the answer – Ravi Korrapati Nov 02 '21 at 22:16