-
Notifications
You must be signed in to change notification settings - Fork 0
Async Jobs via Quartz
David An edited this page Oct 13, 2023
·
6 revisions
So, you want to create a new async API, or at least a new async job.
look at ImportService
, which creates ImportJobInput
and TdrManifestSchedulable
and eventually executes TdrManifestQuartzJob
.
The high-level development tasks for a new async job are:
- Define the API signature, including request and response payloads, in OpenAPI YAML. New "v1" APIs should go in
apis-v1.yaml
. - Define a model for the user-supplied input arguments, i.e. the request payload, by subclassing
JobInput
- Define a model for the user-facing output, i.e. the response payload, by subclassing
JobResponse
- Define the internal job metadata, such as its description and implementation class, by subclassing
Schedulable
or usingSchedulable
as-is - Writing the internal implementation code for the functionality you want to execute asynchronously, in a subclass of
QuartzJob
.- This must be a Spring Bean - for instance, annotated with @Component - and therefore can/must include injected resources such as
JobDao
.
- This must be a Spring Bean - for instance, annotated with @Component - and therefore can/must include injected resources such as
- Stitch all these together, following the execution flow defined below
At a high level, the flow of an asynchronous API is:
- End user makes a request to your async API
- Controller class processes the request, deserializing the payload into an auto-generated model class, and hands off to a Service class
- Service class:
- Translates the auto-generated model class into your
JobInput
subclass - Uses the
JobInput
class to create aJob
instance - Persists the
Job
to the Postgressys_wds.job
table viaJobDao.createJob()
- Generates the inputs for the async process and creates a
Schedulable
defining what should be run asynchronously - Persists the
Schedulable
to Quartz viaSchedulerDao.schedule()
. This begins the async execution. - Marks the
Job
asQUEUED
viaJobDao.updateStatus()
- Returns some value to the controller class
- Translates the auto-generated model class into your
- Controller class responds with a 202 Accepted to the end user
- Quartz notices the async process that was scheduled in step 3.v. - it may have already started.
- Quartz finds the Spring Bean matching the class defined in your
Schedulable
- Quartz calls
execute()
on that bean. Note that if your code subclassesQuartzJob
, you are likely to have implementedexecuteInternal()
instead;QuartzJob
provides a best-practice implementation ofexecute()
.
- Quartz finds the Spring Bean matching the class defined in your
- Your implementation code, inside your subclass of
QuartzJob
, must:- Retrieve any necessary inputs from
JobExecutionContext.getMergedJobDataMap()
, potentially using the helper methods insideQuartzJob
- Perform your custom business logic
- Throw an exception on any failures, potentially using
JobExecutionException
- Persist any user-facing output to the
Job
using aJobResult
subclass
- Retrieve any necessary inputs from