Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Enterprise Web App. Development (7): Jakarta Batch Training

Enterprise Web App. Development (7): Jakarta Batch Training

This is the seventh course of a series of courses for Enterprise Web Application development based on several Open Source products. As we finished JAX-RS course, we are going to move on to the part part, “Jakarta Batch”, as the fourth course of Jakarta EE framework specification. After taking this course, we can obtain the minimum skills to develop Enterprise Web Application. In those courses, we refer to some “Application Architecture Design Patterns”. Therefore this series require the basic skills of Windows 10, CentOS, Eclipse IDE, Java SE (Oracle JDK or OpenJDK), Payara Server and PostgreSQL. Regarding the Payara Server, we can use another Web Application Server conforming to Jakarta EE specification. As for PostgreSQL, we might be able to use another RDBMS product instead. We can also make use of another Linux distribution instead of CentOS.

E7d0d73badb1cc1df2bc44f58d51aaff?s=128

Koichi NAKAGAWA

November 26, 2020
Tweet

Transcript

  1. JAKARTA BATCH A part of Jakarta EE™ specification Batch Processing

    Framework 1 By Koichi NAKAGAWA
  2. jBatch Jakarta Batch 2

  3. EWA development course curriculum Object Oriented Development Methodology JSF with

    CDI JPA + JTA with CDI JAX-RS Application Architecture Design Patterns Eclipse IDE™ Version Control Tool with Git™ Build Tool with Apache Maven™ Payara Server™ Administration Windows 10™ + Linux (CentOS™) Total EWA Development Exercise Jakarta Batch Java SE (Oracle JDK™/OpenJDK™) Required Skills to take courses Test Tool with JUnit5 PostgreSQL™ Administration 3
  4. Trademarks Notice • Jakarta™ EE and its logo( ) are

    trademarks of the Eclipse Foundation. • PostgreSQL™ and its logo( ) are registered trademarks of the PostgreSQL Community Association of Canada. • Apache Derby™ and its logo ( ) are trademarks of the Apache Software Foundation. • Payara™ Server and their logo( ) are trademarks of Payara Services® LTD. • EclipseLink™, EclipseLink™ logo ( ), Eclipse IDE for Enterprise Java Developer™, the Eclipse IDE for Enterprise Java Developer ™ logo( ), Eclipse M2Eclipse™, M2Eclipse™, Eclipse GitTeam Provider™, Eclipse EGit™, EGit™, Eclipse Java development tools™, Java development tools™, Eclipse JDT™, JDT™ are trademarks of the Eclipse Foundation. • Apache Maven™, Maven™ are trademarks of the Apache Software Foundation (ASF). • Git™ and the Git™ logo( ) are either registered trademarks or trademarks of Software Freedom Conservancy, Inc., corporate home of the Git Project, in the United States and/or other countries. • Java™ is trademark of Oracle Corporation. 4
  5. Assumption for this course • The trainees who take this

    course are required the following skills in advance • PostgreSQL (Version: 12) – Basic Administration Operations • Payara Server (Version: 5.2020.5) – Basic Administration Operations • Oracle JDK/OpenJDK (Version: 8) • Eclipse IDE for Enterprise Java Developers (Version: 2020-09 (4.17.0)) • Build Tool Training Course • Version Control Tool Training Course • Test Tool Training Course • JSF with CDI Training Course • JPA + JTA with CDI Training Course • JAX-RS Training Course 5
  6. Objectives This course is aimed to obtain the following skills

    • Jakarta Batch technology • Development of Batch applications using Jakarta Batch • Integration with JAX-RS in presentation layer 6
  7. Jakarta Batch • Concept of Jakarta Batch • How to

    use Jakarta Batch • Architecture Design with Jakarta Batch and JAX-RS • First Jakarta Batch Application • Exercise 7
  8. Concept of Jakarta Batch 8

  9. Concept of Jakarta Batch • What’s Batch Processing Framework 9

    Batch Processing Framework Batch Job A DB, File, … DB, File, … • No User Interface • Long-time Execution • Job Flow Definitions • Job Management Batch Job B DB, File, … DB, File, … . . . Ex. Billing System, Reporting Generation System, Image Processing System, etc.
  10. Concept of Jakarta Batch • Required Functionalities for Batch Processing

    Framework 10 Define jobs, steps, decision elements, and the relationships between them Execute some groups of steps or parts of a step in parallel Maintain state information for jobs and steps Launch jobs and resume interrupted jobs Handle errors
  11. Job X Batch Runtime Job Y Job X Concept of

    Jakarta Batch • Components in Jakarta Batch 11 Batch Artifact A Batch Artifact B Batch Artifact C Java API Job A Job A Job X Instance Job A Job A Job Y Instance . . . Batch Client App. • Job Execution • Job Interruption • Job Information Jakarta Batch Processing Framework Job X Job Definition File Jakarta EE Container
  12. Concept of Jakarta Batch • Job and Step 12 Each

    Job application comprises several Steps. Job A Step A1 Step A2 Step A3 Job B Step B1 Step B2 Job C Step C1 Step C2 Step C3 Step C4 Job D Step D1
  13. Input Retrieval (Item Reader) Business Processing (Item Processor) Output Results

    (Item Writer) Concept of Jakarta Batch • Step Implementation Style – Chunk Step and Task Step 13 Chunk Step: Step A1 Task Step: Step A2 Task Processing (Batchlet) Batch Artifact Batch Artifact Batch Artifact Batch Artifact
  14. Concept of Jakarta Batch • Flow, Split and Decision 14

    Job X Flow X11 Flow X12 Split X1 Decision X3 Step X2 Step X4 Step X111 Step X121 Step X122 Step X112
  15. How to use Jakarta Batch 15

  16. Batch Runtime Job Y Job X How to use Jakarta

    Batch • Architecture of Jakarta Batch 16 Batch Client App. Job Request (Start, Stop, Restart, Check Info., …) Job Response (Exec ID, Info., …) Jakarta EE Container JobOperator Job A Job A Job X Instance Job A Job A Job Y Instance . . . Batch Artifact A Job X Job Definition File Batch Artifact A Batch Artifact A
  17. Batch Runtime Job Y Job X How to use Jakarta

    Batch • Job Definition File 17 Batch Client App. Job Request (Start, Stop, Restart, Check Info., …) Job Response (Exec ID, Info., …) Jakarta EE Container JobOperator Job A Job A Job X Instance Job A Job A Job Y Instance . . . Batch Artifact A Batch Artifact A Batch Artifact A Job X Job Definition File
  18. Job X How to define Batch Job • Job Definition

    File in Job Specification Language (JSL) 18 Job Definition File for Batch Job ID X (X.xml) <?xml version="1.0" encoding="UTF-8"?> <job id=“X" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> : : : </job> Define Batch Job META-INF batch-jobs X.xml Y.xml Z.xml Location (Under Class Path) [Job ID].xml . . .
  19. How to define Batch Job • Job Steps and Batch

    Artifacts 19 Job Definition File Batch Artifact A (CDI: @Named("A")) Batch Artifact B2 (CDI: @Named("B2")) Batch Artifact C (CDI: @Named("C")) . . . Job X Step X1 Step X2 Step X3 <?xml version="1.0" encoding="UTF-8"?> <job id=“X" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> : <step id="X1" next="X2"> <batchlet ref=“A"></batchlet> </step> <step id="X2" next="X3"> <chunk> <reader ref=“B1"></reader> <processor ref=“B2"></processor> <writer ref=“B3"></writer> </chunk> </step> <step id="X3" > <batchlet ref="C"></batchlet> </step> : </job> Batch Artifact B1 (CDI: @Named("B1")) Batch Artifact B3 (CDI: @Named("B3"))
  20. How to define Batch Job • Job Flows, Splits and

    Decisions 20 <?xml version="1.0" encoding="UTF-8"?> <job id=“X" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> : <flow id=“X1"> <split id=“X11" next=“X12"> <flow id=“X111">...</flow> <flow id=“X112">...</flow> <flow id=“X113">...</flow> </split> <step id=“X12" next=“X13>…</step> <decision id=“X13" ref=“myImpl"> : <next on=“NEXT_STEP” to=“X14” /> <end on=“COMPLETED” /> </decision> <step id=“X14">…</step> </flow> : </job> Job Definition File Job X Flow X1 Flow X111 Flow X112 Flow X113 Split X11 Decision X13 Step X12 Step X14
  21. How to define Batch Job • “Batch Status” (Runtime Status

    Value) 21 Status(*) Description STARTING Job has been submitted to the batch runtime. STARTED Job is running. STOPPING Job has been requested to stop. STOPPED Job has stopped. FAILED Job finished executing because of an error. COMPLETED Job finished executing successfully. ABANDONED Job was marked abandoned. (*)The above batch status is automatically set by the Batch Runtime. • “Exit Status” (User-Defined Value) “Exit Status” is user-defined value and set by Batch Artifacts or Job Definition Files. Default value is the same as Batch Status. During the execution of a Batch Job, “Batch Status” and “Exit Status” for the Job are set several times and changing. Step X1 • Batch Status and Exit Status Split X11 Flow X111 Job X Decision X13
  22. How to define Batch Job • Transition Elements in Step,

    Decision (and Flow) 22 <?xml version="1.0" encoding="UTF-8"?> <job id=“X" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> : <flow id=“X1"> <split id=“X11" next=“X12"> <flow id=“X111">...</flow> <flow id=“X112">...</flow> <flow id=“X113">...</flow> </split> <step id=“X12" next=“X13>…</step> <decision id=“X13" ref=“myImpl"> : <next on=“NEXT_STEP” to=“X14” /> <end on=“COMPLETED” /> </decision> <step id=“X14">…</step> </flow> : </job> Job Definition File Transition Elements Batch Status Job ends with <next on="{exit status}" to="{step id | flow id | split id}"/> <fail on="{exit status}" [exit-status="{exit status}“]/> FAILED <end on="{exit status}" [exit-status="{exit status}“]/> COMPLETED <stop on="{exit status}" [exit-status="{exit status}“ restart="{step id | flow id | split id}“]/> STOPPED on="{exit status}": If exit status equals to specified value, the transition happens. to="{step id | flow id | split id}": Transition is done to specified id. exit-status="{exit status}": Exist status is changed to specified value. (Optional) restart="{step id | flow id | split id}": job is restarted from specified id. (Optional)
  23. Batch Runtime How to define Batch Job • Listeners 23

    Job Definition File <?xml version="1.0" encoding="UTF-8"?> <job id=“X" xmlns= " http://xmlns.jcp.org/xml/ns/javaee " version="1.0"> : <listeners> <listener ref="JobListener" /> ... </listeners> : </job> Intercept Job Execution Job X Job Level Listener (CDI: @Named("JobListener")) Types of Listeners Job Level Listener, Step Level Listener, Chunk Listener, Item Read Listener, Item Process Listener, Item Write Listener, Skip Listener, Retry Listener Job Execution
  24. Batch Runtime Job X Job Execution How to define Batch

    Job • Properties 24 Job Definition File <?xml version="1.0" encoding="UTF-8"?> <job id=“X" xmlns= " http://xmlns.jcp.org/xml/ns/javaee " version="1.0"> : <properties> <property name="input_file" value="input.txt"/> <property name="output_file" value="output.txt"/> </properties> : </job> passing Static Properties Job Level Properties input_file= input.txt output_file = output.txt Types of Properties Job Level Properties, Step Level Properties, Step Level Listener Properties, Reader Properties, Processor Properties, Writer Properties, Checkpoint Algorithm Properties, Batchlet Properties, Partition Properties, Mapper Properties, Partition Reducer Properties, Partition Collector Properties, Partition Analyzer Properties, Decision Properties
  25. Batch Runtime How to define Batch Job • Partitioned Step

    25 Job Definition File . . . Step X1 Step X2 : <step id="X1" next="X2"> <batchlet ref=“A"></batchlet> <partition> <plan partitions=“2” /> <properties partition="0"> <property name="filename" value="/tmp/file1.txt"/> </properties> <properties partition="1"> <property name="filename" value="/tmp/file2.txt"/> </properties> </partition> </step> <step id="X2"> <chunk> … </chunk> <partition> <plan partitions=“4” threads=“2” /> </partition> </step> : Partition #0 Partition #1 Partition #0 Partition #1 Partition #2 Thread #1 Thread #2 Thread #1 Thread #2 Partition #3 Job X Partition Properties filename = /tmp/file1.txt Partition Properties filename = /tmp/file2.txt Wait …
  26. Batch Runtime Job Y Job X How to use Jakarta

    Batch • Batch Artifact 26 Batch Client App. Job Request (Start, Stop, Restart, Check Info., …) Job Response (Exec ID, Info., …) Jakarta EE Container JobOperator Job A Job A Job X Instance Job A Job A Job Y Instance . . . Batch Artifact A Batch Artifact A Batch Artifact A Job X Job Definition File
  27. Batch Runtime How to develop Batch Artifacts • Batch Context

    27 Batch Context Job Context Step Context Batch Artifact • Information about running batch jobs/steps • Storage of interim values for batch jobs/steps Get/Set Job Information Job Job A Job A Job Instance Job Job Definition File
  28. Batch Runtime How to develop Batch Artifacts • Run-time Job

    Parameters 28 Batch Artifact Start Job with Job Parameters Job Job A Job A Job Instance Batch Client App. JobOperator Obtain Job Parameters
  29. How to develop Batch Artifacts • Reader, Processor and Writer

    in Chunk Step 29 Chunk Step: Step A1 MyReader (Item_Reader) MyProcessor (Item_Processor) MyWriter (Item_Writer) <?xml version="1.0" encoding="UTF-8"?> <job id=“A" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> <properties> <property name="input_file" value="input.txt"/> <property name="output_file" value="output.txt"/> </properties> <step id=“A1" next=“A2"> <chunk> <reader ref="MyReader"></reader> <processor ref="MyProcessor"></processor> <writer ref="MyWriter"></writer> </chunk> </step> <step id=“A2"> <batchlet ref="MyBatchlet"></batchlet> <end on="COMPLETED"/> </step> </job> Job Definition File MyReader MyProcessor 10 Items processed? MyWriter No Yes Read Next 10 Items Batch Artifact Batch Artifact Batch Artifact
  30. How to develop Batch Artifacts • Check Point Class for

    Chunk Step 30 public class MyCheckpoint implements Serializable { private long lineNum = 0; public void increase() { lineNum++; } public long getLineNum() { return lineNum; } } (*) MyCheckpoint class keeps track of the line number currently processed an input file. Serializable interface must be implemented.
  31. How to develop Batch Artifacts • ItemReader Class for Chunk

    Step 31 @Dependent @Named("MyReader") public class MyReader implements javax.batch.api.chunk.ItemReader { private MyCheckpoint checkpoint; private BufferedReader breader; @Inject JobContext jobCtx; public MyReader() {} @Override public void open(Serializable ckpt) throws Exception { if (ckpt == null) checkpoint = new MyCheckpoint(); else checkpoint = (MyCheckpoint) ckpt; String fileName = jobCtx.getProperties().getProperty("input_file"); breader = new BufferedReader(new FileReader(fileName)); for (long i = 0; i < checkpoint.getLineNum(); i++) breader.readLine(); } @Override public void close() throws Exception { breader.close(); } @Override public Object readItem() throws Exception { String line = breader.readLine(); if (line != null) checkpoint.increase(); return line; } @Override public Serializable checkpointInfo() throws Exception { return checkpoint; } } For resuming this job, move the reading point. Obtain the static parameter values from Job Definition File. Named CDI Inject JobContext
  32. How to develop Batch Artifacts • ItemProcessor Class for Chunk

    Step 32 @Dependent @Named("MyProcessor") public class MyProcessor implements javax.batch.api.chunk.ItemProcessor { public MyProcessor() {} @Override public Object processItem(Object obj) throws Exception { String line = (String) obj; return line.toUpperCase(); } }
  33. How to develop Batch Artifacts • ItemWriter Class for Chunk

    Step 33 @Dependent @Named("MyWriter") public class MyWriter implements javax.batch.api.chunk.ItemWriter { private BufferedWriter bwriter; @Inject private JobContext jobCtx; @Override public void open(Serializable ckpt) throws Exception { String fileName = jobCtx.getProperties().getProperty("output_file"); bwriter = new BufferedWriter(new FileWriter(fileName, (ckpt != null))); } @Override public void close() throws Exception { bwriter.close(); } @Override public void writeItems(List<Object> items) throws Exception { for (int i = 0; i < items.size(); i++) { String line = (String) items.get(i); bwriter.write(line); bwriter.newLine(); } } @Override public Serializable checkpointInfo() throws Exception { return new MyCheckpoint; } } For the first time, this opens the output file with OVERWRITE mode. Otherwise, it opens the file with the APPEND mode.
  34. How to develop Batch Artifacts • Batchlet in Task Step

    34 <?xml version="1.0" encoding="UTF-8"?> <job id=“A" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> <properties> <property name="input_file" value="input.txt"/> <property name="output_file" value="output.txt"/> </properties> <step id=“A1" next=“A2"> <chunk> <reader ref="MyReader"></reader> <processor ref="MyProcessor"></processor> <writer ref="MyWriter"></writer> </chunk> </step> <step id=“A2"> <batchlet ref="MyBatchlet"></batchlet> <end on="COMPLETED"/> </step> </job> Job Definition File Task Step: Step A2 Task Processing (Batchlet)
  35. How to develop Batch Artifacts • Batchlet Class for Task

    Step 35 @Dependent @Named("MyBatchlet") public class MyBatchlet implements javax.batch.api.Batchlet { @Inject private JobContext jobCtx; @Override public String process() throws Exception { JobOperator jobOperator = BatchRuntime.getJobOperator(); Properties jobParameters = jobOperator.getParameters(jobCtx.getExecutionId()); String value1 = (String)jobParameters.get("parameter1"); System.out.println("The value of parameter1 is " + value1 + "."); String fileName = jobCtx.getProperties().getProperty("output_file"); System.out.println("The size of the output file processed by Batch Job is " + (new File(fileName)).length() + "."); return "COMPLETED"; } : Obtain the Job Parameter values. Set an Exit Status. : @Override public void stop() throws Exception { System.out.println("MyBatchlet(" + jobCtx.getExecutionId() + ") is stopping ..."); } }
  36. Batch Runtime Job Y Job X How to use Jakarta

    Batch • Batch Client App. 36 Batch Client App. Job Request (Start, Stop, Restart, Check Info., …) Job Response (Exec ID, Info., …) Jakarta EE Container JobOperator Job A Job A Job X Instance Job A Job A Job Y Instance . . . Batch Artifact A Batch Artifact A Batch Artifact A Job X Job Definition File
  37. Batch Runtime Job Y How to develop Batch Client App.

    • Job Execution 37 Job X JobInstance (Exec ID = 2, 3) JobInstance (Exec ID = 4) JobInstance (Exec ID = 1) JobOperator Batch Client App. Job Request (Start, Stop, Restart, Check Info., …) Job Response (Exec ID, Info., …) JobExecution (Exec ID = 1) JobExecution (Exec ID = 2) JobExecution (Exec ID = 3) . . . . . . JobExecution (Exec ID = 4) Fail
  38. How to develop Batch Client Apps • Batch Client App.

    38 public class BatchJobClient { : public Long startJob(Properties props ) throws Exception { JobOperator jobOperator = BatchRuntime.getJobOperator(); Long execID = jobOperator.start("simplejob", props); return execID; } : public String getJobStatus(Long execID) throws Exception { JobOperator jobOperator = BatchRuntime.getJobOperator(); JobExecution jobExec = jobOperator.getJobExecution(execID); String status = jobExec.getBatchStatus().toString(); return status; } : } Start Job with the Job Parameters. Obtain the JobOperator object. Obtain the JobExecution object. Obtain the Job Status.
  39. Architecture Design of Jakarta Batch and JAX-RS 39

  40. Business Domain Service Batch Runtime Architecture Design • Architecture Design

    of Jakarta Batch along with JAX-RS 40 Presentation REST Req. Handler Web Resource CDI Web Req. Handler Named CDI Action Method Transactional CDI Service Method Data Access O-R Mapper Entity/VO Entity/VO RDB Entity/VO Entity/VO Name: Vendor: ABC XYZ Update Update Results: Name ABC Vendor XYZ DTO DTO Jakarta EE Container Requester Resource Method Batch Client App. Job X Job A Job A Job X Instance Job Request
  41. Batch Client App. with JAX-RS • Batch Client Application Program

    Example of Web Resource CDI 41 Web Resource Class (CDI) Resource Method @RequestScoped @Path("/batchJob") public class BatchJob { : @PUT @Path("/simplejob") @Produces(MediaType.TEXT_PLAIN) @Consumes(MediaType.APPLICATION_JSON) public Response simplejob(Properties props) { Long execID = 0L; try { JobOperator jobOperator = BatchRuntime.getJobOperator(); execID = jobOperator.start("simplejob", props); } catch (Exception e) { throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); } return Response.status(Response.Status.OK).entity(execID).build(); } } Batch Client App.
  42. First Jakarta Batch Application 42

  43. Example of First Jakarta Batch Application • Use Case 

    Develop a Batch Job of “simplejob” implementing the followings. • Job Definition File (META-INF/batch-jobs/simplejob.xml) • Batch Artifacts (MyReader.java, MyProcessor.java, MyWriter.java, MyBatchlet.java)  Develop a Batch Client App. inside Web Resource CDI (BatchJob.java) to start a Batch Job named “simplejob”. 43 Jakarta EE Container Batch Runtime Job “simplejob” Job A Job A Job “simplejob” Instance <?xml version="1.0" encoding="UTF-8"?> <job id= "simplejob" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> <properties> <property name="input_file" value="input.txt"/> <property name="output_file" value="output.txt"/> </properties> <step id= " A1" next= " A2"> <chunk> <reader ref="MyReader"></reader> <processor ref="MyProcessor"></processor> <writer ref="MyWriter"></writer> </chunk> </step> <step id= "A2"> <batchlet ref="MyBatchlet"></batchlet> <end on="COMPLETED"/> </step> </job> Batch Artifact (MyReader.java) Batch Artifact (MyProcessor.java) Batch Artifact (MyWriter.java) Batch Artifact (MyBatchlet.java) Job Definition File (simplejob.xml) Web Resource CDI (BatchJob.java) Resource Method Batch Client App. Exercise: Let’s make the First Jakarta Batch Application.
  44. REST Req. Handler Requester Example of First Jakarta Batch Application

    JUnit5 makes a PUT request to a REST Service Provider to start a Batch Job instance of “simplejob”. • PUT Request URI: http://localhost:8080/jbatch_jaxrs_jsf_jpa/webapi/batchJob/simplejob • Request Message: A Property where the name is “parameter1” and the value is “value1” (MIME Type: “application/JSON”) • Response Message: An Execution ID in Long (MIME Type: “text/plain”) 44 Jakarta EE Container Web Resource CDI (BatchJob.java) Resource Method REST Request Message (URI:http://localhost:8080/jbatch_jaxrs_jsf_jpa/ webapi/batchJob/simplejob) (JSON: {“parameter1”: “value1”}) REST Response Message (Long: 123) JUnit5 System Test (integration-test) Eclipse Batch Client App. Batch Runtime Job “simplejob” Job A Job A Job “simplejob” Instance Exercise: Let’s make use of JUnit5 and make a Test Case as REST Client.
  45. First Jakarta Batch Application Development • This project of “jbatch_jaxrs_jsf_jpa”

    is based on the “jaxrs_jsf_jpa” project and add necessary components newly created on the Eclipse IDE. 45 jaxrs_jsf_jpa Copy jbatch_jaxrs_jsf_jpa Add • simplejob.xml : Job Definition File • MyReader.java: Batch Artifact Class • … • BatchJob.java : Web Resource Class • BatchJobIT.java : System Test
  46. • Procedure of the Development Edit pom.xml and Change package

    names Change the Message folder and the associated Class Create the Required Class Execute the REST System Test with Maven Test with Talend API Tester 46 First Jakarta Batch Application Development
  47. • Modify the created Maven Object Model file (pom.xml) 

    Change the artifactId to “jbatch_jaxrs_jsf_jpa”. • Change the package names  Refactor all the packages to rename the packages from “jaxrs_jsf_jpa” to “jbatch_jaxrs_jsf_jpa” creating new packages of “org.example.jbatch_jaxrs_jsf_jpa.batch” under “src/main/java”.  Change the JPA configuration file for the JPA Unit Test, persistence.xml, under “src/test/resources/META-INF” to rename the packages for <class> tags. <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>jbatch_jaxrs_jsf_jpa</artifactId> <packaging>war</packaging> <version>0.0.1</version> 47 New pom.xml New persistence.xml Renamed First Jakarta Batch Application Development New New Package Names
  48. • Procedure of the Development Edit pom.xml and Change package

    names Change the Message folder and the associated Class Create the Required Class Execute the REST System Test with Maven Test with Talend API Tester 48 First Jakarta Batch Application Development
  49. • Change the Message folder Rename the Message folder to

    “org/example/jbatch_jaxrs_jsf_jpa”. • Change the Message Utility Class Modify the Message Utility Class, Messages.java, under the package of “org.example.jbatch_jaxrs_jsf_jpa.util” about the new folder name. 49 New Message Folder Name Renamed Revised Messages.java Renamed First Jakarta Batch Application Development
  50. • Procedure of the Development Edit pom.xml and Change package

    names Change the Message folder and the associated Class Create the Required Classes Execute the REST System Test with Maven Test with Talend API Tester 50 First Jakarta Batch Application Development
  51. • Create required Classes 1. Create the Job Definition File,

    simplejob.xml, under the “src/main/resources/META-INF/batch-jobs”. 2. Create MyCheckpoint.java and the Batch Artifacts, MyReader.java, MyProcessor.java, MyWriter.java and MyBatchlet.java, of the “org.example.jbatch_jaxrs_jsf_jpa.batch” package under the “src/main/java”. 3. Create a new Web Resource Class, BatchJob.java, of the “org.example.jbatch_jaxrs_jsf_jpa.rest” package under the “src/main/java” folder, which specifies the Web Resource Class Path of “/batchJob” and create a Resource Method of “simplejob(Properties props)” in the class passing JSON encoded Properties Class and returning a Long value of Job Execution ID whose MIME type is “text/plain” as a response to the PUT request for the Resource Method Path of “/simplejob”. 4. Implement the Resource Method of “simplejob(Properties props)” to start an instance of the Batch Job of “simplejob” passing the Properties object given by the parameter of this method. 5. Modify the Custom REST Application Class, RestApplication.java, of the “org.example.jbatch_jaxrs_jsf_jpa.rest” package under the “src/main/java” folder to add the BatchJob.java as a Web Resource Class. 6. A new System Test Class, BatchJobIT.java, of the “org.example.jbatch_jaxrs_jsf_jpa.rest” package under the “src/test/java” folder is provided to execute a System Test for the Batch Job. 51 First Jakarta Batch Application Development
  52. • BatchJobIT.java (1) – Preparation for System Test A new

    System Test Class, BatchJobIT.java, of the “org.example.jbatch_jaxrs_jsf_jpa.rest” package under the “src/test/java” folder is provided to execute a System Test for the BatchJob.class. 52 class BatchJobIT { private static Client client; private static String baseUri = ""; @BeforeAll public static void loadTestConfig() { final String hostname = System.getProperty("servlet.host"); final String port = System.getProperty("servlet.port"); final String context = System.getProperty("servlet.context"); final String REST_APPLICATION_PATH = "webapi"; baseUri = "http://" + hostname + ":" + port + "/" + context + "/" + REST_APPLICATION_PATH; client = ClientBuilder.newClient(); } First Jakarta Batch Application Development
  53. • BatchJobIT.java (2) – Execution of the System Test 53

    @Test public void testSimpleBatchJob() { final String WEB_RESOURCE_PATH = "/batchJob"; String RESOURCE_METHOD_PATH = "/simplejob"; WebTarget myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); Properties props = new Properties(); props.setProperty("parameter1", "value1"); Long execID = myResource.request(MediaType.TEXT_PLAIN). put(Entity.entity(props, MediaType.APPLICATION_JSON), Long.class); assertNotNull(execID); assertTrue(execID > 0L); } } First Jakarta Batch Application Development
  54. • Final Java Source Folder Structure 54 Provided First Jakarta

    Batch Application Development New New New New New New Modify New Rename
  55. • Procedure of the Development Edit pom.xml and Change package

    names Change the Message folder and the associated Class Create the Required Classes Execute the REST System Test with Maven Test with Talend API Tester 55 First Jakarta Batch Application Development
  56. • Execute JUnit through M2Eclipse™ for the provided REST System

    Test Class (1)  Right click on the project and select “Run As”  “4 Maven build” Specify “jbatch_jaxrs_jsf_jpa – integration-test” for the “Name” field and “clean integration-test” for the “Goals” field. 56 First Jakarta Batch Application Development
  57. • Execute JUnit through M2Eclipse™ for the provided REST System

    Test Class (2)  Click “Run” button. Confirm that test completes successfully in “Console” 57 First Jakarta Batch Application Development
  58. • Procedure of the Development Edit pom.xml and Change package

    names Change the Message folder and the associated Class Create the Required Classes Execute the REST System Test with Maven Test with Talend API Tester 58 First Jakarta Batch Application Development
  59. • Execute “Talend API Tester – Free Edition” (1) –

    Request REST Service  Click the icon of on the Chrome browser.  Select “PUT” Method, specify “http://localhost:8080/jbatch_jaxrs_jsf_jpa/webapi/batchJob/simplejob” as the URI field, add a header of “Content-Type: application/json”, put {“parameter1”:”value1”} in the BODY field and click the “Send” button. 59 First Jakarta Batch Application Development
  60. • Execute “Talend API Tester – Free Edition” – Response

    for the REST Service Request  Confirm that the expected HEADERS and BODY were responded. 60 First Jakarta Batch Application Development Execution ID
  61. Exercise 61

  62. Exercise for Processing Departments with Job • Required features 

    Create a new Job Definition File for the batch job of “personneljob” to process “Department” Entities.  Develop 4 Batch Artifacts: • “PersonnelReader”: Read all “Department” Entities from RDB with EnterpriseService Transactional CDI and save them to a local property. And then read a Department Entity from the local property. • “PersonnelProcessor”: Capitalize the name of the Department Entity • “PersonnelWriter”: Update the processed Items in RDB with EnterpriseService Transactional CDI. • “PersonnelBatchlet”: Show all the names of Department Entities with EnterpriseService Transactional CDI. 62 Jakarta EE Container Business Data Access Transactional CDI O-R Mapper Domain Service Business Methods RDB Batch Runtime Job “personneljob” Job “simplejob” Instance <?xml version="1.0" encoding="UTF-8"?> <job id=“personneljob" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> <step id=“A1" next=“A2"> <chunk> <reader ref=“PersonnelReader"></reader> <processor ref=“PersonnelProcessor"></processor> <writer ref=“PersonnelWriter"></writer> </chunk> </step> <step id=“A2"> <batchlet ref=“PersonnelBatchlet"></batchlet> <end on="COMPLETED"/> </step> </job> Batch Artifact (PersonnelReader.java) Batch Artifact (PersonnelProcessor.java) Batch Artifact (PersonnelWriter.java) Batch Artifact (PersonnelBatchlet.java) Job “simplejob” Instance Job Instance Job Definition File (personneljob.xml)
  63. Exercise for Processing Departments with Job • Required features Add

    2 Resource Methods to the existing Web Resource Class of “BatchJob” • Start the Batch Job of “personneljob” with Properties passed in JSON and return the Execution ID as a Long value (“plain/text”). • Check the Job Status with Execution ID passed by a Query Parameter and return the Job Status as a String (“plain/text”). 63 Requestor Presentation Jakarta EE Container Web Resource CDI (Request Scoped) Resource Methods REST Request Message (URI:http://localhost:8080/jbatch_jaxrs_jsf _jpa/webapi/batchJob/personelJob/ Body(JSON): {“parameter1”:“value1”} REST Response Message (Long: “53”) JUnit5 System Test (integration-test) Eclipse Business Data Access Transactional CDI O-R Mapper Provider Domain Service Business Methods RDB Batch Runtime Job “personneljob” Job Instance Batch Client App. Job Instance Job Instance
  64. Exercise for Processing Departments with Job • PersonnelJobIT.java – System

    Test for the Batch Job processing Personnel Information 64 class PersonnelJobIT { private static Client client; private static String baseUri = ""; private static String WEB_RESOURCE_PATH = ""; private static String RESOURCE_METHOD_PATH = ""; private static String hostname = ""; private static String port = ""; private static String context = ""; private static String REST_APPLICATION_PATH = ""; private static HashMap<Long, String> departmentMap = new HashMap<Long, String>(); : Keep the maps between Primary Key and expected Name in Department Entities processed.
  65. Exercise for Processing Departments with Job • PersonnelJobIT.java – System

    Test for the Batch Job (prepareEntities(): Set Variables) 65 @BeforeAll public static void prepareEntities() { hostname = System.getProperty("servlet.host"); port = System.getProperty("servlet.port"); context = System.getProperty("servlet.context"); REST_APPLICATION_PATH = "webapi"; WEB_RESOURCE_PATH = "/personnelService"; baseUri = "http://" + hostname + ":" + port + "/" + context + "/" + REST_APPLICATION_PATH; client = ClientBuilder.newClient(); :
  66. Exercise for Processing Departments with Job • PersonnelJobIT.java – System

    Test for the Batch Job (prepareEntities(): Initialize DB) 66 // Initialize DB RESOURCE_METHOD_PATH = "/initializeDB"; WebTarget myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); Integer result = myResource.request(MediaType.TEXT_PLAIN).get(Integer.class); assertEquals(result, new Integer(Response.Status.OK.getStatusCode())); :
  67. Exercise for Processing Departments with Job • PersonnelJobIT.java – System

    Test for the Batch Job (prepareEntities(): Create New Entities) 67 // Create a New Department Entity RESOURCE_METHOD_PATH = "/newDepartment"; Department department = new Department("Marketing"); myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); department = myResource.request(MediaType.APPLICATION_JSON) .post(Entity.entity(department, MediaType.APPLICATION_JSON), Department.class); assertNotNull(department); assertEquals(department.getName(), "Marketing"); departmentMap.put(department.getId(),"MARKETING"); : } Set the maps between Primary Key and expected Name in Department Entities processed. In the same way, create Department Entities of “Sales” and “Development”
  68. Exercise for Processing Departments with Job • PersonnelJobIT.java – System

    Test for the Batch Job (testDepartmentJob(): Start Job) 68 @Test public void testDepartmentJob() { // Start a job named "personneljob" WEB_RESOURCE_PATH = "/batchJob"; String RESOURCE_METHOD_PATH = "/personneljob"; WebTarget myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); Properties props = new Properties(); props.setProperty("parameter1", "value1"); Long execID = myResource.request(MediaType.TEXT_PLAIN).put(Entity.entity(props, MediaType.APPLICATION_JSON), Long.class); assertNotNull(execID); assertTrue(execID > 0L); :
  69. Exercise for Processing Departments with Job • PersonnelJobIT.java – System

    Test for the Batch Job (testDepartmentJob(): Check Job Status) 69 try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } // Check the status of the above job RESOURCE_METHOD_PATH = "/jobstatus"; myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH) .queryParam("execID", execID); String jobStatus = myResource.request(MediaType.TEXT_PLAIN).get(String.class); assertNotNull(jobStatus); assertTrue(jobStatus.length() > 0); assertEquals(jobStatus, "COMPLETED"); :
  70. Exercise for Processing Departments with Job • PersonnelJobIT.java – System

    Test for the Batch Job (testDepartmentJob(): Check Results) 70 // Check the results WEB_RESOURCE_PATH = "/personnelService"; RESOURCE_METHOD_PATH = "/getAllDepartments"; myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); List<Department> departments = myResource.request(MediaType.APPLICATION_JSON) .get(new GenericType<List<Department>>() {}); assertNotNull(departments); assertEquals(departments.size(), 3); for (int i = 0; i < 3; i++) assertEquals(departmentMap.get(departments.get(i).getId()), departments.get(i).getName()); }
  71. Exercise for Processing Departments with Job • PersonnelJobIT.java – System

    Test for the Batch Job (deleteAllEntities(): Initialize DB) 71 @AfterAll public static void deleteAllEntities() { // Initialize DB WEB_RESOURCE_PATH = "/personnelService"; RESOURCE_METHOD_PATH = "/initializeDB"; WebTarget myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); Integer result = myResource.request(MediaType.TEXT_PLAIN).get(Integer.class); assertEquals(result, new Integer(Response.Status.OK.getStatusCode())); }
  72. Exercise for Processing Departments with Job • Final Java Source

    Folder Structure 72 Provided Modify New New