5
votes

I'm trying to configure a Flow in spring batch using java-config, this flow basically has to do this:

  1. Execute a init step(which adds a record in the database),

  2. then execute a decider to check file existence,

2.1. IF the files exists it will execute the load job (which is another flow with a bunch of steps in parallel)

  1. Execute a finish step (which adds a record in the database), this should always run, even if 2.1 was not executed.

I tried to do this configuration, but the finish step never runs:

        Flow flow = new FlowBuilder<SimpleFlow>("commonFlow")
            .start(stepBuilderFactory.get("initStep").tasklet(initTasklet).build())
            .next(decider)
                .on(FlowExecutionStatus.COMPLETED.getName())
                    .to(splitFlow)
                .from(decider).on("*")
                    .end()
    .next(stepBuilderFactory.get("finishStep").tasklet(finishTasklet).build())
            .end();

I'm able to make it work doing as below, but it is not elegant at all:

    Step finishStep = stepBuilderFactory.get("finishStep").tasklet(finishTasklet).build();

    Flow flow = new FlowBuilder<SimpleFlow>("commonFlow")
            .start(stepBuilderFactory.get("initStep").tasklet(initTasklet).build())
            .next(decider)
                .on(FlowExecutionStatus.COMPLETED.getName())
                    .to(splitFlow)
                    .next(finishStep)
                .from(decider).on("*")
                    .to(finishStep)
            .end();

Does anybody know how is the right way to execute a step after a decision using java-config?

2
In your first sample code, you have included two 'end()'. Try removing the first 'end()'. - Sudarshan_SMD
The return of the .on is a TransitionBuilder, I have to have something after the on. I also tried to put a Dumb step after the on but didn't work. - Daniel Diehl

2 Answers

1
votes

It sounds like this is being made MUCH more complicated than it needs to be. You do not need to configure a flow or decider. This is a VERY simple in and out job.

The simplest option is to use Spring Integration to detect the presents of a file and trigger the job.

The next simplest option is just to have a quartz or CRON job check for the file and start the batch job.

Last but not least you can have the job run and if the ItemReader can not find the file(s) just swallow the exception. Or set a FileItemReader Listener to check for files on it's before method.

0
votes

You can use two separate Flows to achieve this.

Flow flowWithDecider = new FlowBuilder<SimpleFlow>("flow-with-decider")
  .start(decider)
    .on("ok")
    .to(okStep1)
    .next(okStep2)
  .from(decider)
    .on("failed")
    .to(failedStep)
  .build()

Flow commonFlow = new FlowBuilder<SimpleFlow>("common-flow")
  .start(commonStep)
  .build()


Job job = jobs
  .get("my-job")
  .start(flowWithDecider())
  .next(commonFlow()) // this will execute after the previous flow, regardless of the decision
  .end()
  .build();