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

Enterprise Web App. Development (7): Jakarta Ba...

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

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 last part of the Jakarta EE framework specification course, “Jakarta Batch”. 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 requires the basic skills of Windows 10, Rocky Linux, 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 Rocky Linux.

Koichi NAKAGAWA

November 26, 2020
Tweet

More Decks by Koichi NAKAGAWA

Other Decks in Programming

Transcript

  1. JAKARTA BATCH (VER. 3.1) A part of Jakarta EE™ specification

    Batch Processing Framework 1 By Koichi NAKAGAWA Enterprise Web Application Development Course (7)
  2. Update Information • Ver. 3: Use Rocky Linux™ instead of

    CentOS™ as a Linux platform and Payara Server 6™ certified as Jakarta EE 9.1 Platform Compatible Products. • Ver. 2 : Use JDK 11 instead of JDK 8 and Jakarta EE 9 instead of Jakarta EE 8 in all exercises. 2
  3. EWA development course curriculum 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 (Rocky Linux™) Total EWA Development Exercise Jakarta Batch Java SE (Oracle JDK™/OpenJDK™) Required Skills to take courses Test Tool with JUnit5 PostgreSQL™ Administration 4 Object Oriented Development Methodology
  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. 5
  5. Assumption for this course • The trainees who take this

    course are required the following skills in advance • PostgreSQL (Version: 13.5) – Basic Administration Operations • Payara Server (Version: 6.2021.1.Alpha1) – Basic Administration Operations • Oracle JDK/OpenJDK (Version: 11) • Eclipse IDE for Enterprise Java Developers (Version: 2021-12 (4.22.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 6
  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 7
  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 8
  8. Concept of Jakarta Batch • What’s Batch Processing Framework 10

    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.
  9. Concept of Jakarta Batch • Required Functionalities for Batch Processing

    Framework 11 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
  10. Job X Batch Runtime Job Y Job X Concept of

    Jakarta Batch • Components in Jakarta Batch 12 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
  11. Concept of Jakarta Batch • Job and Step 13 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
  12. Input Retrieval (Item Reader) Business Processing (Item Processor) Output Results

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

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

    Batch • Architecture of Jakarta Batch 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 Job X Job Definition File Batch Artifact A Batch Artifact A
  15. Batch Runtime Job Y Job X How to use Jakarta

    Batch • Job Definition File 18 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
  16. Job X How to define Batch Job • Job Definition

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

    Artifacts 20 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=" https://jakarta.ee/xml/ns/jakartaee" version=“2.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"))
  18. How to define Batch Job • Job Flows, Splits and

    Decisions 21 <?xml version="1.0" encoding="UTF-8"?> <job id=“X" xmlns=" https://jakarta.ee/xml/ns/jakartaee" version=“2.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
  19. How to define Batch Job • “Batch Status” (Runtime Status

    Value) 22 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
  20. How to define Batch Job • Transition Elements in Step,

    Decision (and Flow) 23 <?xml version="1.0" encoding="UTF-8"?> <job id=“X" xmlns=" https://jakarta.ee/xml/ns/jakartaee" version=“2.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)
  21. Batch Runtime How to define Batch Job • Listeners 24

    Job Definition File <?xml version="1.0" encoding="UTF-8"?> <job id=“X" xmlns= " https://jakarta.ee/xml/ns/jakartaee" version=“2.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
  22. Batch Runtime Job X Job Execution How to define Batch

    Job • Properties 25 Job Definition File <?xml version="1.0" encoding="UTF-8"?> <job id=“X" xmlns= " https://jakarta.ee/xml/ns/jakartaee" version=“2.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
  23. Batch Runtime How to define Batch Job • Partitioned Step

    26 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 …
  24. Batch Runtime Job Y Job X How to use Jakarta

    Batch • Batch Artifact 27 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
  25. Batch Runtime How to develop Batch Artifacts • Batch Context

    28 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
  26. Batch Runtime How to develop Batch Artifacts • Run-time Job

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

    in Chunk Step 30 Chunk Step: Step A1 MyReader (Item_Reader) MyProcessor (Item_Processor) MyWriter (Item_Writer) <?xml version="1.0" encoding="UTF-8"?> <job id=“A" xmlns=" https://jakarta.ee/xml/ns/jakartaee" version=“2.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
  28. How to develop Batch Artifacts • Check Point Class for

    Chunk Step 31 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.
  29. How to develop Batch Artifacts • ItemReader Class for Chunk

    Step 32 @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
  30. How to develop Batch Artifacts • ItemProcessor Class for Chunk

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

    Step 34 @Dependent @Named("MyWriter") public class MyWriter implements jakarta.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.
  32. How to develop Batch Artifacts • Batchlet in Task Step

    35 <?xml version="1.0" encoding="UTF-8"?> <job id=“A" xmlns="https://jakarta.ee/xml/ns/jakartaee" version=“2.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)
  33. How to develop Batch Artifacts • Batchlet Class for Task

    Step 36 @Dependent @Named("MyBatchlet") public class MyBatchlet implements jakarta.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 ..."); } }
  34. Batch Runtime Job Y Job X How to use Jakarta

    Batch • Batch Client App. 37 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
  35. Batch Runtime Job Y How to develop Batch Client App.

    • Job Execution 38 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
  36. How to develop Batch Client Apps • Batch Client App.

    39 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.
  37. Business Domain Service Batch Runtime Architecture Design • Architecture Design

    of Jakarta Batch along with JAX-RS 41 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
  38. Batch Client App. with JAX-RS • Batch Client Application Program

    Example of Web Resource CDI 42 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.
  39. First Jakarta Batch Application Dev. Exercise • 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”. 44 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="https://jakarta.ee/xml/ns/jakartaee" version=“2.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.
  40. REST Req. Handler Requester First Jakarta Batch Application Dev. Exercise

    JUnit5 makes a PUT request to a REST Service Provider to start a Batch Job instance of “simplejob”. • PUT Request URI: http://localhost:8080/jsf_jpa_jaxrs_jbatch/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”) 45 Jakarta EE Container Web Resource CDI (BatchJob.java) Resource Method REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs_jbatch/ 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.
  41. First Jakarta Batch Application Dev. Exercise • This project of

    “jsf_jpa_jaxrs_jbatch” is based on the “jsf_jpa_jaxrs” project and add necessary components newly created on the Eclipse IDE. 46 jsf_jpa_jaxrs Copy jsf_jpa_jaxrs_jbatch Add • simplejob.xml : Job Definition File • MyReader.java: Batch Artifact Class • … • BatchJob.java : Web Resource Class • BatchJobIT.java : System Test
  42. • 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 47 First Jakarta Batch Application Dev. Exercise
  43. • Modify the created Maven Object Model file (pom.xml) 

    Change the artifactId to “jsf_jpa_jaxrs_jbatch”. • Change the package names  Refactor all the packages to rename the packages from “jaxrs_jsf_jpa” to “jsf_jpa_jaxrs_jbatch” creating new packages of “org.example. jsf_jpa_jaxrs_jbatch.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>jsf_jpa_jaxrs_jbatch</artifactId> <packaging>war</packaging> <version>0.0.1</version> 48 Revised pom.xml Revised persistence.xml Renamed First Jakarta Batch Application Dev. Exercise New Package Names
  44. • 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 49 First Jakarta Batch Application Dev. Exercise
  45. • Change the Message folder Rename the Message folder to

    “org/example/jsf_jpa_jaxrs_jbatch”. • Change the Message Utility Class Modify the Message Utility Class, Messages.java, under the package of “org.example.jsf_jpa_jaxrs_jbatch.util” about the new folder name. 50 Renamed Revised Messages.java Renamed First Jakarta Batch Application Dev. Exercise
  46. • 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 51 First Jakarta Batch Application Dev. Exercise
  47. • 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.jsf_jpa_jaxrs_jbatch.batch” package under the “src/main/java”. 3. Create a new Web Resource Class, BatchJob.java, of the “org.example.jsf_jpa_jaxrs_jbatch.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.jsf_jpa_jaxrs_jbatch.rest” package under the “src/main/java” folder to add the BatchJob.class as a Web Resource Class. 6. A new System Test Class, BatchJobIT.java, of the “org.example.jsf_jpa_jaxrs_jbatch.batch.rest” package under the “src/test/java” folder is provided to execute a System Test for the Batch Job. 52 First Jakarta Batch Application Dev. Exercise
  48. • BatchJobIT.java (1) – Preparation for System Test A new

    System Test Class, BatchJobIT.java, of the “org.example.jsf_jpa_jaxrs_jbatch.batch.rest” package under the “src/test/java” folder is provided to execute a System Test for the BatchJob.class. 53 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 Dev. Exercise
  49. • BatchJobIT.java (2) – Execution of the System Test 54

    @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 Dev. Exercise
  50. • Final Java Source Folder Structure 55 Provided First Jakarta

    Batch Application Dev. Exercise New New New New New New Modify New Rename Modify
  51. • 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 56 First Jakarta Batch Application Dev. Exercise
  52. • 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 “jsf_jpa_jaxrs_jbatch – integration-test” for the “Name” field and “clean integration-test” for the “Goals” field. 57 First Jakarta Batch Application Dev. Exercise
  53. • Execute JUnit through M2Eclipse™ for the provided REST System

    Test Class (2)  Click “Run” button. Confirm that “BatchJobIT” test completes successfully on “Console” 58 First Jakarta Batch Application Dev. Exercise
  54. • 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 59 First Jakarta Batch Application Dev. Exercise
  55. • 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/jsf_jpa_jaxrs_jbatch/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. 60 First Jakarta Batch Application Dev. Exercise
  56. • Execute “Talend API Tester – Free Edition” – Response

    for the REST Service Request  Confirm that the expected HEADERS and BODY were responded. 61 First Jakarta Batch Application Dev. Exercise Execution ID
  57. Processing Departments with Job Exercise • 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. 63 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="https://jakarta.ee/xml/ns/jakartaee" version=“2.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)
  58. Processing Departments with Job Exercise • 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”). 64 Requestor Presentation Jakarta EE Container Web Resource CDI (Request Scoped) Resource Methods REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs_jb atch/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
  59. Processing Departments with Job Exercise • PersonnelJobIT.java – System Test

    for the Batch Job processing Personnel Information 65 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.
  60. Processing Departments with Job Exercise • PersonnelJobIT.java – System Test

    for the Batch Job (prepareEntities(): Set Variables) 66 @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(); :
  61. Processing Departments with Job Exercise • PersonnelJobIT.java – System Test

    for the Batch Job (prepareEntities(): Initialize DB) 67 // 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())); :
  62. Processing Departments with Job Exercise • PersonnelJobIT.java – System Test

    for the Batch Job (prepareEntities(): Create New Entities) 68 // 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”
  63. Processing Departments with Job Exercise • PersonnelJobIT.java – System Test

    for the Batch Job (testDepartmentJob(): Start Job) 69 @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); :
  64. Processing Departments with Job Exercise • PersonnelJobIT.java – System Test

    for the Batch Job (testDepartmentJob(): Check Job Status) 70 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"); :
  65. Processing Departments with Job Exercise • PersonnelJobIT.java – System Test

    for the Batch Job (testDepartmentJob(): Check Results) 71 // 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()); }
  66. Processing Departments with Job Exercise • PersonnelJobIT.java – System Test

    for the Batch Job (deleteAllEntities(): Initialize DB) 72 @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())); }