Announcement Announcement Module
Collapse
No announcement yet.
issues with conditional Step flow Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • issues with conditional Step flow

    Here’s a sample of my spring batch config XML file:

    <bean id="batchjob" class="org.springframework.batch.core.job.SimpleJo b" scope="singleton">
    <property name="name" value="batchjob"/>
    <property name="steps">
    <list>
    <ref bean="step1"/>
    <ref bean="step2"/>
    <ref bean="step3"/>
    <list></property>
    </bean>

    Where mostly each step is a tasklet step (for example as shown below)

    <bean id=" step1" class="org.springframework.batch.core.step.tasklet .TaskletStep" scope="singleton">
    <property name="jobRepository" ref="jobRepository"/>
    <property name="transactionManager" ref="transactionManager"/>
    <property name="tasklet" ref="step1Tasklet"/>
    </bean>

    <bean id=" step1Tasklet" class="gov.pbgc.pas.events.jobs.Step1Tasklet">
    <property name="message" value="TestTasklet"/>
    <property name="dataSource" ref="dataSource"/>
    </bean>


    I want to execute in this sequence: If Step1 completes, then execute step2 and stop (Step1-->Step-->Ends). But if Step1 fails, then execute step3 and stop (Step1-->Step3 -->Ends).

    I know how we can do it in the other format which is this:
    <step id =”stepA”>
    <next on=”Failed” to “stepB”/>
    <next on=”*” to=”stepC” />
    </step>
    <step id =”stepB”/>
    <step id =”stepC”/>

    But I don’t know how to do it with my format, I cannot use next in the <ref bean=”step1”> (its not allowed in a ref tag), How do I do it, Pls suggest how to do it.

    Thanks in Advance!!!

  • #2
    Just follow the patterns shown in the reference documementation:

    http://static.springsource.org/sprin...onfiguringAJob
    http://static.springsource.org/sprin...onditionalFlow

    Comment


    • #3
      Format is different

      Hi DHGarrette,

      I could have done that, but as I said, my format is very different and it is already in testing and I can't change everything back to this format now, all I need to do is add some conditional flows, but I don't see any examples for this with my format.. If you know of anyway I can do that with my <ref Bean format, pls do let me know, Thanks!!

      Comment


      • #4
        If you want conditional step flow, you should use the batch namespace. There is no other reasonable way to get the same functionality.

        That said, converting a <bean/> to a <job/> is pretty trivial and shouldn't cause you any problems since the <job/> tag is just a wrapper for the <bean/> functionality. Just replace
        Code:
        <bean id="batchjob" class="org.springframework.batch.core.job.SimpleJob" scope="singleton">
            <property name="name" value="batchjob"/>
            <property name="steps">
                <list>
                    <ref bean="step1"/>
                    <ref bean="step2"/>
                    <ref bean="step3"/>
                <list>
            </property>
        </bean>
        with:
        Code:
        <job id="batchjob">
            <step id="step1">
                <tasklet ref="step1Tasklet"/>
                <next on="*" to="step2"/>
                <next on="FAILED" to="step3"/>
            </step>
            <step id="step2">
                <tasklet ref="step2Tasklet"/>
            </step>
            <step id="step3">
                <tasklet ref="step3Tasklet"/>
            </step>
        </job>
        and you should be good to go.

        Comment


        • #5
          Thanks so much for looking into this, I will try to do that.

          Not all my steps are tasklet steps, some are simpleStepFactoryBean with reader and writer like this:

          <bean id="step4SimpleStep" class="org.springframework.batch.core.step.item.Si mpleStepFactoryBean" scope="singleton">
          <property name="jobRepository" ref="jobRepository"/>
          <property name="itemReader" ref="reader4"/>
          <property name="itemWriter" ref="writer4"/>
          <property name="transactionManager" ref="transactionManager"/>
          <property name="commitInterval" value="1000"/>
          </bean>


          So if I reference "step4SimpleStep" in the <steps> do I do it like this? (since I cannot use the <tasklet> tag in that case)

          <job id="batchjob">
          <step id="step1">
          <tasklet ref="step1Tasklet"/>
          <next on="*" to="step2"/>
          <next on="FAILED" to="step3"/>
          </step>
          <step id="step2">
          <tasklet ref="step2Tasklet"/>
          </step>
          <step id="step3">
          <tasklet ref="step3Tasklet"/>
          </step>
          <step id="step4" ref="step4SimpleStep"/>
          </job>

          Also how can I use just <job id="batchjob"> tag when I am using a different format for that as well which is given below:

          <bean id="batchjob" class="org.springframework.batch.core.job.SimpleJo b" scope="singleton">
          <property name="name" value="batchjob1"/>
          <property name="steps">

          Also, one more question, since you are using next on"*", it means that if exitstatus not equal to Failed right?, But are all the exitStatuses except for Failed considered as Pass/Completed. My requirement is that I need to send a fail email if any of the steps in the sequence fails and send a success email if all the steps execute fine, will "*" work for me or do you think I should specifically use "Completed" and "Failed" status?

          Sorry for these many questions, but I am trying to see if I can do these changes and get it working in time, because I have almost 9-10 steps to change.

          Comment


          • #6
            First, please use CODE tags when posting code.

            So if I reference "step4SimpleStep" in the <steps> do I do it like this? (since I cannot use the <tasklet> tag in that case)
            To reference a "standalone" step, you use the "parent=" attribute:
            Code:
            <step id="step4" parent="step4SimpleStep"/>
            Also how can I use just <job id="batchjob"> tag when I am using a different format for that as well
            I'm not sure what you mean by this question. The job bean will only be defined once. That is why you replace the <bean id="batchJob"/> with <job id="batchJob"/>

            Also, one more question, since you are using next on"*", it means that if exitstatus not equal to Failed right?
            The most specific pattern is the one that takes effect. So in the case of "*" versus "FAILED", a status of "FAILED" will go to step3, but everything else will go to step2.

            Comment


            • #7
              I have a lot of autowiring with all the job beans and the steps, so it looks like it is going to be hard for me to change the code now, probably I should have thought abt this earlier.

              Is there any way that I can get the status of the run and then send a failure email. Basically I am using Quarts scheduler to trigger the job using JobLauncher.run() method. After the job is run I can get the status of the run and if it is "FAILED", I can specifically code for sending email in java code.

              The problem is that even if I put the code for checking the status after the JobLauncher.run() method, it seems like the code is executed even before the job is finished and I get an "Executing" status. Do you know how/where I should put the code for checking status, so it is executed after the Batch job completes its execution(failed or completed or whatever), if I can do that, that would be great!! because all I want is to send a "Failure" email if the complete job fails for whatever reason(any of the steps fails etc)

              Comment


              • #8
                You can use an @AfterJob listener method.

                Comment


                • #9
                  I didn't see any code examples for this on the net.

                  I came up with this:

                  @AfterJob
                  public void callBack(JobExecution jobExecution){
                  if(jobExecution.getStatus() == BatchStatus.FAILED){
                  //Send failure email
                  }

                  But where do I put this code, do I put it in the class where I have my JobLauncher, JobParameters and runJob() method(which is called by quartz scheduler).

                  How would the job know that after completion this callback method needs to be called and is the passing of jobExecution to this method automatically taken care of?

                  Comment


                  • #10
                    I digged a little bit more and I think what I wrote earlier was not correct,

                    I think my XML should look like this:

                    <bean id="testJob" class="org.springframework.batch.core.job.SimpleJo b" scope="singleton">
                    <property name="name" value="testJob"/>
                    <property name="steps">
                    <list>
                    <ref bean="Step1"/>
                    .......
                    .......
                    </list>
                    </property>
                    <property name="jobRepository" ref="jobRepository"/>
                    <property name="jobExecutionListener" ref="testJobListener"/>
                    </bean>

                    (The above step is probably how to register a listener to the job, but not sure if this works because there is no setJobExecutionListener but there is a registerJobExecutionListener)...

                    <bean id="testJobListener" class="org.springframework.batch.core.listener.Job ExecutionListenerSupport"/>

                    And if I understand correctly, the afterJob method would be in JobExecutionListenerSupport class.

                    But I am not sure how to go further, do I have to create a seperat eclass extending
                    JobExecutionListenerSupport and have an afterJob method in it??

                    Comment


                    • #11
                      Hi DHGarrette,

                      I think I could get it working, What I did was quite similar to my previous post, but created a class extending JobExecutionListenerSupport and adding my code to the overriden afterJob method, it seems like it is working now, will have to do some more testing though,

                      Thanks a ton to help point me to the solution, it helped a lot

                      Comment

                      Working...
                      X