diff --git a/docs/src/site/docbook/reference/step.xml b/docs/src/site/docbook/reference/step.xml index 96103f2b2..c1d61cf5a 100644 --- a/docs/src/site/docbook/reference/step.xml +++ b/docs/src/site/docbook/reference/step.xml @@ -965,11 +965,11 @@
Controlling Step Flow - With the ability to group steps together within an owning job, comes + With the ability to group steps together within an owning job comes the need to be able to control how the job 'flows' from one step to another. The failure of a Step doesn't necessarily mean that the Job should fail. Furthermore, there - may be more than one type of 'success', which determines which + may be more than one type of 'success' which determines which Step should be executed next. Depending upon how a group of Steps is configured, certain steps may not even be processed at all. @@ -993,8 +993,8 @@ - This can be achieved using the 'next' attribute of - Step: + This can be achieved using the 'next' attribute of the step + element: <job id="job"> @@ -1003,31 +1003,42 @@ <step name="stepC" /> </job> -In the scenario above, 'step A' will execute first. If 'step - A' completes normally, then 'step B' will execute and so on. However, if - 'step A' fails, then the entire Job will fail and - 'step B' will not execute. +In the scenario above, 'step A' will execute first because it + is the first Step listed. If 'step A' completes + normally, then 'step B' will execute, and so on. However, if 'step A' + fails, then the entire Job will fail and 'step B' + will not execute. + + + With the Spring Batch namespace, the first step listed in the + configuration will always be the first step + executed by the Job. The order of the other + step elements does not matter, but the first step must always appear + first in the xml. +
Conditional Flow - In the example above, there's only two possibilities: + In the example above, there are only two possibilities: - The Step is successful and the next Step should be - executed + The Step is successful and the next + Step should be executed. - The Step failed and thus the Job should fail. + The Step failed and thus the + Job should fail. - In many cases this may be sufficient. However, what about a - scenario in which the failure of a Step should trigger a different Step, - rather than causing failure? + In many cases, this may be sufficient. However, what about a + scenario in which the failure of a Step should + trigger a different Step, rather than causing + failure? @@ -1040,11 +1051,37 @@ - In order to handle this scenario, the next step can be determined - based on the result of the step by adding a next element to the Step. - The "on" attribute uses a simple pattern-matching scheme to match the - exit code of the Step to the various next elements declared. Only two - special characters are allowed: + In order to handle more complex scenarios, the + Spring Batch namespace allows transition elements to be defined within + the step element. One such transition is the "next" element. Like the + "next" attribute, the "next" element will tell the + Job which Step to execute + next. However, unlike the attribute, any number of "next" elements are + allowed on a given Step, and there is no default + behavior the the case of failure. This means that if transition elements + are used, then all of the behavior for the Step's + transitions must be defined explicitly. Note also that a single step + cannot have both a "next" attribute and a transtion element. + + The next element specifies a pattern to match and the step to + execute next: + + + <job id="job"> + <step name="stepA"> + <next on="FAILED" to="stepB" /> + <next on="*" to="stepC" /> + </step> + <step name="stepB" next="stepC" /> + <step name="stepC" /> + </job> + + + + The "on" attribute of a transition element uses a simple + pattern-matching scheme to match the ExitStatus + that results from the exeution of the Step. Only + two special characters are allowed in the pattern: @@ -1059,27 +1096,17 @@ For example, "c*t" will match "cat" and "count", while "c?t" will match "cat" but not "count". - Any number of "next" elements is allowed, but if the step has an - exit code that is not covered by a "next" element, then the framework - will throw an exception and the job will fail. It is important to note - that the framework will automatically order transitions from most - specific to least specific. So even if the "next" elements were swapped - for "stepA" below, an exit status of "FAILED" would still go to - "stepB". + While there is no limit to the number of transition elements on a + Step, if the Step's + execution results in an ExitStatus that is not + covered by an element, then the framework will throw an exception and + the Job will fail. It is important to note that + the framework will automatically order transitions from most specific to + least specific. This means that even if the elements were swapped for + "stepA" in the example above, an ExitStatus of + "FAILED" would still go to "stepB". - - <job id="job"> - <step name="stepA"> - <next on="FAILED" to="stepB" /> - <next on="*" to="stepC" /> - </step> - <step name="stepB" next="stepC" /> - <step name="stepC" /> - </job> - - - -
+
Batch Status vs. Exit Status When configuring a Job for conditional @@ -1092,7 +1119,7 @@ record the status of a Job or Step. It can be one of the following values: COMPLETED, STARTING, STARTED, FAILED, STOPPING, STOPPED, or UNKNOWN. - Most of them are self explanatory, COMPLETED is the status set when a + Most of them are self explanatory: COMPLETED is the status set when a step or job has completed successfully, FAILED is set when it fails, and so on. The example above contains the following 'next' element: @@ -1104,13 +1131,12 @@ At first glance, it would appear that the 'on' attribute references the BatchStatus of the - Step to which it belongs. However, it + Step to which it belongs. However, it actually references the ExitStatus of the Step. As the name implies, ExitStatus represents the status of a Step after it finishes execution. More - specifically, the 'next' element above references the - ExitCode of the + specifically, the 'next' element above references the exit code of the ExitStatus. To write it in English, it says: "go to stepB if the exit code is FAILED". By default, the exit code is always the same as the BatchStatus for the @@ -1131,17 +1157,19 @@ - The step failed, in which case the job should fail. + The Step failed, in which case the + job should fail. - The Step completed successfully. + The Step completed + successfully. - The Step completed successfully, but with an exit code of - 'COMPLETED WITH SKIPS'. In this case, a different step should be - run to handle the errors. + The Step completed successfully, but + with an exit code of 'COMPLETED WITH SKIPS'. In this case, a + different step should be run to handle the errors. @@ -1149,19 +1177,18 @@ change the exit code based on the condition of the execution having skipped records: - public class SkipCheckingListener implements StepExecutionListener { + public class SkipCheckingListener extends StepExecutionListenerSupport { - public ExitStatus afterStep(StepExecution stepExecution) { - if (!stepExecution.getExitStatus().getExitCode().equals(ExitStatus.FAILED.getExitCode()) - && stepExecution.getSkipCount() > 0) { - return new ExitStatus("COMPLETED WITH SKIPS"); - } else { - return null; + public ExitStatus afterStep(StepExecution stepExecution) { + if (!stepExecution.getExitStatus().getExitCode().equals(ExitStatus.FAILED.getExitCode()) + && stepExecution.getSkipCount() > 0) { + return new ExitStatus("COMPLETED WITH SKIPS"); + } else { + return null; + } } - } - ... -} + } The above code is a StepExecutionListener that first checks to make sure the Step was @@ -1175,32 +1202,140 @@
Configuring for Stop - If it is desired that the batch job stop under certain conditions, - then either the "stop" tag or the "end" tag may be used. + After the discussion of BatchStatus and + ExitStatus, one might wonder how the + BatchStatus and ExitStatus + are determined for the Job. While these statuses + are determined for the Step by the code that is + executed, the statuses for the Job will be + determined based on the configuration. - The "stop" tag indicates the job should stop processing with an - exit status of "STOPPED". The "to" attribute tells the framework which - step should be first when the job is subsequently restarted. This - mechanism allows the job to pause temporarily. + So far, all of the job configurations discussed have had at least + one final Step with no transitions. For example, + after the following step executes, the Job will + end: - On the other hand, the "end" tag will stop the job but does not - allow for a "to" attribute. The "status" attribute is optional. It will - determine the exit status of the step if the flow ends at that location. - The only legal values for the "status" are "COMPLETED", "FAILED", and - "STOPPED". If no status is specified, then the default is - "COMPLETED". + <step name="stepC" /> - - <step name="step1"> + If no transitions are defined for a Step, + then the Job's statuses will be defined as + follows: + + + + If the Step ends with + ExitStatus FAILED, then the + Job's BatchStatus and + ExitStatus will both be FAILED. + + + + Otherwise, the the Job's + BatchStatus and + ExitStatus will both be COMPLETED. + + + + While this method of terminating a batch job is sufficient for + some batch jobs, such as a simple sequential step job, custom defined + job-stopping scenarios may be required. For this purpose, Spring Batch + provides three transition elements to stop a Job + (in addition to the "next" element + that we discussed previously). Each of these stopping elements will stop + a Job with a particular + BatchStatus. It is important to note that the + stop transition elements will have no effect on either the + BatchStatus or ExitStatus + of any Steps in the Job: + these elements will only affect the final statuses of the + Job. For example, it is possible for every step + in a job to have a status of FAILED but the job to have a status of + COMPLETED, or vise versa. + +
+ The 'End' Element + + The 'end' element instructs a Job to stop + with a BatchStatus of COMPLETED. A + Job that has finished with status COMPLETED + cannot be restarted (the framework will throw a + JobInstanceAlreadyCompleteException). The 'end' + element also allows for an optional 'status' attribute that can be + used to customize the ExitStatus of the + Job. If no 'status' attribute is given, then + the ExitStatus will be "COMPLETED" by default, + to match the BatchStatus. + + In the following scenario, if step2 fails, then the + Job will stop with a + BatchStatus of COMPLETE and an + ExitStatus of "COMPLETED" and step3 will not + execute; otherwise, execution will move to step3. Additionally, if + step2 fails, the Job will not be + restartable. + + <step name="step1" next="step2"> + <step name="step2"> + <end on="FAILED"/> + <next on="*" to="step3"/> + </step> + <step name="step3"> +
+ +
+ The 'Fail' Element + + The 'fail' element instructs a Job to + stop with a BatchStatus of FAILED. Unlike the + 'end' element, the 'fail' element will not prevent the + Job from being restarted. The 'fail' element + also allows for an optional 'status' attribute that can be used to + customize the ExitStatus of the + Job. If no 'status' attribute is given, then + the ExitStatus will be "FAILED" by default, to + match the BatchStatus. + + In the following scenario, if step2 fails, then the + Job will stop with a + BatchStatus of FAILED and an + ExitStatus of "EARLY TERMINATION" and step3 + will not execute; otherwise, execution will move to step3. + Additionally, if step2 fails, and the Job is + restarted, the execution will begin again on step2. + + <step name="step1" next="step2"> + <step name="step2"> + <fail on="FAILED" status="EARLY TERMINATION"/> + <next on="*" to="step3"/> + </step> + <step name="step3"> +
+ +
+ The 'Pause' Element + + The 'pause' element instructs a Job to + stop with a BatchStatus of STOPPED. Pausing a + Job is a meant to be a temporary so that the + operator can take some action before restarting the + Job. The 'pause' element requires a 'to' + attribute that specifies the step where execution should pick up once + the Job is restarted after being paused. + + In the following scenario, step1 will execute and COMPLETE. The + job will then stop. Once it is restarted, execution will begin on + step2. + + <step name="step1"> <stop on="COMPLETED" to="step2"/> </step> <step name="step2"> <next on="FOO" to="step3"/> <end on="*" status="FAILED"/> </step> - <step name="step3" /> - - + <step name="step3" /> +
@@ -1248,18 +1383,19 @@
+
-
- Late binding of Job and Step Attributes +
+ Late binding of Job and Step Attributes - Both the XML and Flat File examples above use the Spring - Resource abstraction to obtain a file . This - works because Resource has a - getFile method, which returns a - java.io.File. Both XML and Flat File resources - can be configured using standard Spring constructs: + Both the XML and Flat File examples above use the Spring + Resource abstraction to obtain a file . This works + because Resource has a getFile + method, which returns a java.io.File. Both XML and + Flat File resources can be configured using standard Spring + constructs: - + <bean id="flatFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader"> <property name="resource" @@ -1268,15 +1404,15 @@ - The above Resource will load the file from - the file system location specified. Note that absolute locations have to - start with a double slash ("//"). In most spring applications, this - solution is good enough because the names of these are known at compile - time. However, in batch scenarios, the file name may need to be - determined at runtime as a parameter to the job. This could be solved - using '-D' parameters, i.e. a system property: + The above Resource will load the file from + the file system location specified. Note that absolute locations have to + start with a double slash ("//"). In most spring applications, this + solution is good enough because the names of these are known at compile + time. However, in batch scenarios, the file name may need to be determined + at runtime as a parameter to the job. This could be solved using '-D' + parameters, i.e. a system property: - + <bean id="flatFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader"> <property name="resource" value="${input.file.name}" /> @@ -1284,21 +1420,21 @@ - All that would be required for this solution to work would be a - system argument (-Dinput.file.name="file://file.txt"). (Note that - although a PropertyPlaceholderConfigurer can be - used here, it is not necessary if the system property is always set - because the ResourceEditor in Spring already - filters and does placeholder replacement on system properties.) + All that would be required for this solution to work would be a + system argument (-Dinput.file.name="file://file.txt"). (Note that although + a PropertyPlaceholderConfigurer can be used here, + it is not necessary if the system property is always set because the + ResourceEditor in Spring already filters and does + placeholder replacement on system properties.) - Often in a batch setting it is preferable to parameterize the file - name in the JobParameters of - the job, instead of through system properties, and access them that way. - To accomplish this, Spring Batch allows for the late binding of various - Job and Step attributes: + Often in a batch setting it is preferable to parameterize the file + name in the JobParameters of the + job, instead of through system properties, and access them that way. To + accomplish this, Spring Batch allows for the late binding of various Job + and Step attributes: - + <bean id="flatFileItemReader" scope="step" class="org.springframework.batch.item.file.FlatFileItemReader"> <property name="resource" value="#{jobParameters[input.file.name]}" /> @@ -1306,12 +1442,12 @@ - Both the JobExecution and - StepExecution level - ExecutionContext can be accessed in the same - way: + Both the JobExecution and + StepExecution level + ExecutionContext can be accessed in the same + way: - + <bean id="flatFileItemReader" scope="step" class="org.springframework.batch.item.file.FlatFileItemReader"> <property name="resource" value="#{jobExecutionContext[input.file.name]}" /> @@ -1319,7 +1455,7 @@ - + <bean id="flatFileItemReader" scope="step" class="org.springframework.batch.item.file.FlatFileItemReader"> <property name="resource" value="#{stepExecutionContext[input.file.name]}" /> @@ -1327,13 +1463,13 @@ -
- Step Scope +
+ Step Scope - All of the late binding examples from above have a scope of - "step" declared on the bean definition: + All of the late binding examples from above have a scope of "step" + declared on the bean definition: - + <bean id="flatFileItemReader" scope="step" class="org.springframework.batch.item.file.FlatFileItemReader"> <property name="resource" value="#{jobParameters[input.file.name]}" /> @@ -1341,17 +1477,16 @@ - Using a scope of Step is required in - order to use late binding since the bean cannot actually be - instantiated until the Step starts, which - allows the attributes to be found. Because it is not part of the - Spring container by default, it must be added explicitly: + Using a scope of Step is required in order + to use late binding since the bean cannot actually be instantiated until + the Step starts, which allows the attributes to + be found. Because it is not part of the Spring container by default, it + must be added explicitly: - + <bean class="org.springframework.batch.core.scope.StepScope" /> -