Skip to content
This repository was archived by the owner on Jan 30, 2019. It is now read-only.

Latest commit

 

History

History
132 lines (92 loc) · 4.87 KB

File metadata and controls

132 lines (92 loc) · 4.87 KB

Lab: Batchlet and Multi-steps Job

In the first exercise, we have developed a simple job made of a single step, a Chunk step. This exercise will introduce you to Batchlet, the second type of step supported by JSR 352. Chunk step are used to work on data while Batchlets are useful for performing a variety of tasks that are not item-oriented, such as executing a command or performing a task (like copying files, preparing reports etc.).

To illustrate this, we will define a multi-steps job that combine 2 steps: a Chunk step and a Batchlet step.

Set the stage

Open the "lab2" project in NetBeans ("File" , "Open Project" and select the "lab2" directory). If you run the project and access the "BatchJobSubmitter" servlet, you will see that it is very similar to what we have done in the previous exercise.

It is a simple batch job made of a single Chunk step, the "prepare" step (check the JSL file describing the batch job).

Implement the Batchlet step

A Batchlet is a class that extends and implements the javax.batch.api.AbstractBatchlet interface. So create, in the source package, a new Java class called "SummaryProcessor" that extends the AbstractBatchlet interface. Use NetBeans to resolve the missing import and implement the abstract process() method.

Decorate the class with the @Named annotation and inject the PayrollDataHolderBean bean as follow :

    @EJB
    PayrollDataHolderBean payrollDataHolderBean;

The process() method is doing the work of the Batchlet is supposed to do so let’s re-write it as follow :

  public String process() throws Exception {
     SummaryRecord summaryRecord = new SummaryRecord();

     try {
         for (PayrollOutputRecord outputRecord : payrollDataHolderBean.getPayrollOutputRecords()) {
            summaryRecord.addBonus(outputRecord.getBonus());
            summaryRecord.addNet(outputRecord.getNet());
            summaryRecord.addSalary(outputRecord.getSalary());
            summaryRecord.addSocialSecurityTax(outputRecord.getSocialSecurityTax());
         }
     } catch (Exception ex) {
         return "FAILED";
     }

     payrollDataHolderBean.setSummaryRecord(summaryRecord);
     return "COMPLETED";
  }

This Batchlet computes the total net, total salary and total socialsecurity of all the payroll records processed by first step. Once the imports have been fixed, the final SummaryProcessor Batchlet should looks like this:

package org.glassfish.javaee7.batch.lab2;
// imports omitted !

@Named
public class SummaryProcessor extends AbstractBatchlet {

    @EJB
    PayrollDataHolderBean payrollDataHolderBean;

    public String process() throws Exception {
       SummaryRecord summaryRecord = new SummaryRecord();

       try {
           for (PayrollOutputRecord outputRecord : payrollDataHolderBean.getPayrollOutputRecords()) {
              summaryRecord.addBonus(outputRecord.getBonus());
              summaryRecord.addNet(outputRecord.getNet());
              summaryRecord.addSalary(outputRecord.getSalary());
              summaryRecord.addSocialSecurityTax(outputRecord.getSocialSecurityTax());
           }
       } catch (Exception ex) {
           return "FAILED";
       }

       payrollDataHolderBean.setSummaryRecord(summaryRecord);
       return "COMPLETED";
    }

}
Tip
The return type of the process() method of a batchlet is the exit status of the Batchlet.

Update the JSL

We now need to update the JSL file to make sure the Batchlet is part of the job. Open "PayRollJob.xml" (in "web/WEB-INF/classes/META-INF/batch-jobs") and add the Batch "summary" step to the job as follow:

<job id="PayrollJob" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">

     <step id="prepare" next="summary">
        <chunk item-count="3">
            <reader ref="payrollInputRecordReader"></reader>
            <processor ref="netPayProcessor"></processor>
            <writer ref="payrollOutputRecordWriter"></writer>
        </chunk>
    </step>

    <step id="summary">
        <batchlet ref="summaryProcessor"/>
    </step>

</job>

As mentioned before, the execution commences by executing the first step listed in the job xml. If the step completes normally, then the step specified in the "next" attrinute will be executed.

Tip
Be aware that if you don’t specify the next attribute, the execution stops after the first step!

Testing the Payroll application

If you run the job again, you should now see an additional "TOTAL" line in the right table. Those data are computed in in the Batchlet and displayed by the displayProcessedPayrollRecords() method when summaryRecord is not null.

E2.3
Figure 1. Total values computed by the Batchlet step

Summary

In this Lab, we learnt

  • how to write a Batchlet step

  • how to combine multiple steps within a single Job