This chapter describes how to use the Oracle Enterprise Scheduler runtime service APIs for submitting and managing job requests and for querying job request information from the job request history.
This chapter includes the following sections:
Oracle Enterprise Scheduler lets you define and run different job types including: Java classes, PL/SQL procedures, and process job types (forked processes). To run these job types you need to submit a job definition.
You can use the runtime service to perform different types of operations, including:
Submit: These operations let you supply a job definition to Oracle Enterprise Scheduler to create job requests.
Manage: These operations allow you to change the state of job requests and to update job requests.
Query: These operations let you find the status of job requests and report job request history.
Like the metadata service, Oracle Enterprise Scheduler provides a runtime MBean proxy interface.
The runtime service open()
method begins each Oracle Enterprise Scheduler runtime service user transaction. In an Oracle Enterprise Scheduler application client you obtain a RuntimeServiceHandle
reference that is created by open()
and you pass the reference to runtime service methods. The RuntimeServiceHandle
reference provides a connection to the runtime service for the client application. In the client application you must explicitly close the runtime service by calling close()
. This ends the transaction and causes the transaction to be committed or rolled back (undone). The close()
not only controls the transactional behavior within the runtime service, but it also allows Oracle Enterprise Scheduler to release the resources associated with the RuntimeServiceHandle
.
Oracle Enterprise Scheduler exposes the runtime service to your application program as a Stateless Session Enterprise Java Bean (EJB). You can use JNDI to locate the Oracle Enterprise Scheduler runtime service Stateless Session EJB.
Example 14-1 shows a lookup for the Oracle Enterprise Scheduler runtime service using the RuntimeServiceLocalHome
object.
Example 14-1 JNDI Lookup to Access Oracle Enterprise Scheduler Runtime Service
import oracle.as.scheduler.core.JndiUtil; // Demonstration of how to lookup runtime service from a // Java EE application component RuntimeService runtime = JndiUtil.getRuntimeServiceEJB(); RuntimeServiceHandle rHandle = null; . . . try { ... rHandle = runtime.open(); ... } finally { if (rHandle != null) { runtime.close(rHandle); } }
Note:
When you access the runtime service:JndiUtil.getRuntimeServiceEJB()
assumes that the RuntimeService EJB has been mapped to the local JNDI location "ess/runtime". This happens automatically in the hosted application's message-driven bean (MDB).
The open()
call provides a RuntimeServiceHandle
reference. You use this reference with the methods that access the runtime service in your application program.
When you finish using the runtime service you must call close()
to release the resources associated with the RuntimeServiceHandle
.
When you submit a job definition you create a new job request. You can submit a job request using a job definition that is persisted to a metadata repository, or you can create a job request in an ad hoc manner where the job definition or the schedule is not stored in the metadata repository (for information about ad hoc requests, see Section 14.6, "Submitting Ad Hoc Job Requests").
You create a job request by calling submitRequest()
. Depending on your needs, you can create a job request with one of the following formats:
Create a new job request using a job definition stored in the metadata repository, to run once at a specific time.
Create a new job request using a job definition and a schedule, each stored in the metadata repository.
Example 14-2 shows the submitRequest()
method that creates a new job request with a job definition that resides in the metadata repository. You can also submit an ad hoc job request where the job definition and schedule are not stored in the metadata repository. For more information, see Section 14.6, "Submitting Ad Hoc Job Requests". You can also submit a sub-request. For more information, see Chapter 15, "Using Subrequests".
Example 14-2 Creating a Job Request with submitRequest()
long requestID = 0L; MetadataObjectId jobDefnId; RequestParameters p = new RequestParameters(); p.add(SystemProperty.CLASS_NAME, "demo.jobs.Job"); Calendar start = Calendar.getInstance(); start.add(Calendar.SECOND, startsIn); requestID = runtime.submitRequest(r, "My Java job", jobDefnId, start, p);
Note:
When you submit a job request using the runtime service:You obtain the runtime service handle as shown in Example 14-1.
The runtime service internally uses the metadata service to obtain job definition metadata with the supplied MetadataObjectId
, jobDefnId
.
When you create a job request Oracle Enterprise Scheduler resolves and stores the properties associated with the job request. Oracle Enterprise Scheduler requires that certain system properties are associated with a job request. If you do not set these required properties anywhere in the properties hierarchy when a job request is submitted, then Oracle Enterprise Scheduler provides default values.
Table 14-1 shows the runtime service field names and the corresponding system properties for the required job request properties.
Table 14-1 Runtime Service Default Value Fields and Corresponding System Properties
Value | Runtime Service Default Value Field | Corresponding System Property | Description |
---|---|---|---|
0 |
|
|
The default expiration time, in minutes, for a request. The default value is 0 which means the request will never expire. |
4 |
|
|
The default system priority associated with a request. |
5 |
|
|
The default period, in minutes, in which processing must be postponed by a callout handler that returns |
0 |
|
|
The default number of times a failed request will be retried. The default value is 0 which means a failed request is not retried. |
All Oracle Enterprise Scheduler Metadata associated with a job request is persisted in the runtime store at the time of request submission. Persisted metadata objects include job definition, job type, job set, schedule, incompatibility definitions, and exclusion definition. Metadata is stored in the context of a top level request, and each metadata object is uniquely identified by the absolute parent request id and its metadata id. Each unique metadata object is stored only once for a top-level request, even if the definition is used multiple times in the request. This ensures that every child request uses the same definition.
When a request is submitted, all known metadata for the request is persisted. For subrequests, the metadata is not know until the subrequest is submitted, so subrequest metadata is persisted when the subrequest is submitted, after first checking that the metadata object is not already persisted in the runtime store.
Metadata persisted in the runtime store is removed when the absolute parent request is deleted.
After you submit a job request, using the requestID
you can do the following:
Get request information
Change the state of the request
Update request parameters
Purge a request
Using the runtime service, with a requestID
, you can obtain information about a job request that is in the system. Table 14-2 shows the runtime service methods that allow you to obtain job request information.
Table 14-2 Runtime Service Get Request Methods
Runtime Service Method | Description |
---|---|
|
Retrieves complete runtime details for the specified request |
|
Retrieves basic runtime details of the specified request. The RequestDetail returned by this method includes most of the information as |
|
Retrieves the value of a request parameter. |
|
Retrieves an enumeration of immediate child request identifiers associated with the specified request. This will include IDs for requests that did not complete, such as when the request transaction is rolled back or an error occurs. |
|
Retrieves the current state of the specified request |
Example 14-3 shows code that determines if there is any immediate child request in the HOLD state.
Example 14-3 Determining Whether Any Immediate Child Job Requests Are on Hold
h = s_runtime.open(); try { s_runtime.holdRequest(h,reqid); Enumeration e = s_runtime.getRequests(h, reqid); boolean foundHold = false; while (e.hasMoreElements()) { long childid = ((Long)e.nextElement()).longValue(); State state = s_runtime.getRequestState(h,childid); if (state == State.HOLD) { foundHold = true; break; } }
Using the runtime service, with a requestID
, you can change the state of a job request. Table 14-3 shows the runtime service job request state change methods. The job request management methods allow you to change the state of a request, depending on the state of the job request. For example, you cannot cancel a request with cancelRequest()
if the request is in the COMPLETED
state.
Table 14-3 Runtime Service Job Request State Methods
Runtime Service Method | Description |
---|---|
|
Cancels the processing of a request that is not in a terminal state. |
|
Marks a request in a terminal state for deletion. |
|
Withholds further processing of a request that is in |
|
Releases a request from the |
Example 14-4 shows a submitRequest()
with methods that control the state of the job request. The holdRequest()
holds the processing of the job request. The corresponding releaseRequest()
releases the request. This example does not show the conditions that require the hold for the request.
Example 14-4 Runtime Service releaseRequest() Usage
rHandle = s_runtime.open(); try { s_runtime.holdRequest(rHandle,reqid); Enumeration e = s_runtime.getRequests(rHandle, reqid); while (e.hasMoreElements()) { long childid = ((Long)e.nextElement()).longValue(); State state = s_runtime.getRequestState(rHandle,childid); if (state == State.HOLD) { foundHold = true; break; } } . . . s_runtime.releaseRequest(rHandle, reqid); . . .
Note:
Note the following in Example 14-4:You obtain the runtime service handle, rHandle
, as shown in Example 14-1.
The holdRequest()
places the request in the HOLD
state.
You may do some required processing while the request is in the HOLD
state.
The releaseRequest()
releases the request from the HOLD
state.
Using the runtime service you can update job request system properties or request parameters. Table 14-4 shows the runtime service methods that allow you to lock and update up a job request.
Table 14-4 Runtime Service Update Methods
Runtime Service Method | Description |
---|---|
|
Acquires a lock for the given request. The lock is released when |
|
Updates the property value of the specified request subject to the property read-only constraints. |
Example 14-5 shows code that updates a job request parameter. This code would be wrapped in a try/finally block as shown in Example 14-1.
Example 14-5 Sample Runtime Service Parameter Update
... s_runtime.lockRequest(rhandle, reqid); s_runtime.updateRequestParameter(rhandle, reqId, paramName, "yy"); ...
Example 14-5 shows the following:
Obtain the runtime service handle, rhandle
, as shown in Example 14-1.
Acquire a lock for either the request using lockRequest()
Perform the update operation with updateRequestParameter()
Use close()
to cause the transaction to be committed or rolled back (undone). The close()
not only controls the transactional behavior within the runtime service, but it also allows Oracle Enterprise Scheduler to release the resources associated with the RuntimeServiceHandle
.
Using the runtime service you can query job request information. This involves the following steps:
Query for request identifiers and limit results with a filter.
Get request details to provide additional information for each request ID that the query returns.
There is only one query method; the runtime service queryRequests()
method returns an enumeration of request IDs that match the query. The queryRequests() method
includes a filter argument that contains field, comparator, and value combinations that help select query results. Note that the return value will include IDs for requests that did not complete, such as when the request transaction is rolled back or an error occurs. For more information on filters, see Section 6.4.1, "How to Create a Filter".
When you create a filter for a query, you can use any of the field names shown in Table 14-5 when querying the runtime store.
Table 14-5 Query Filter Fields For Querying the Runtime (Defined in Enum RuntimeService.QueryField)
Name | Description |
---|---|
|
The absolute parent request ID of a request. |
|
The application name. |
|
Indicates if the job is asynchronous, synchronous or unknown. The value of the field is not set until the request is processed. The field data type is |
|
The name of the executable class that processed the request |
|
The date and time that Oracle Enterprise Scheduler finished processing the request. This field represents the time the process phase was set to COMPLETED. |
|
The job definition ID (Metadata Object ID). |
|
The amount of time, in milliseconds, that elapsed while the request was running. |
|
The enterprise ID. |
|
The request error type. |
|
The identifier for an external portion of an Oracle Enterprise Scheduler asynchronous Java job. |
|
The request ID of the instance parent request. |
|
The job type ID (Metadata Object ID). |
|
The request description. |
|
The parent request ID. |
|
The priority of the request. |
|
The process phase of the request. |
|
The date and time that the process ended. The |
|
The name of the instance that processed the request. |
|
The date and time that the process started. The |
|
The product name. |
|
The amount of time, in milliseconds, a request has been waiting to run since it became READY. |
|
The request category specified for the request. |
|
The requested end time. |
|
The requested start time. |
|
The request ID of a submitted request. |
|
The type of request (that is, an element of |
|
Controls the starting and ending index of the returned results. This field allows users to express result constraints such as "return only results 10 through 20". |
|
The retried count associated with a job. This field represents the number of times the job was retried. |
|
The schedule ID (Metadata Object ID). |
|
The time when the request is scheduled to be executed. |
|
The job request state. |
|
The submission time of the request. |
|
The submitter of the request. |
|
The submitter GUID of the request. |
|
Indicates whether the job has timed out. |
|
The execution type of the request. |
|
The name of the user who submitted the request. |
|
The amount of time, in milliseconds, a request has been waiting to run. |
|
The name of the work assignment that was active when the request was processed. |
Table 14-6 shows the runtime service method for querying job requests and Example 14-6 shows the use of this method.
Table 14-6 Runtime Service Query Methods
Runtime Query Method | Description |
---|---|
|
Gets a summary of requests. |
Example 14-6 Using queryRequest() Method
Filter filter = new Filter(RuntimeService.QueryField.DEFINITION.fieldName(), Filter.Comparator.EQUALS, m_myJavaSucJobDef.toString()) .and(RuntimeService.QueryField.STATE.fieldName(), Filter.Comparator.EQUALS, new Integer(12) ); // Enumeration requests = s_runtime.queryRequests(h, filter, RuntimeService.QueryField.REQUESTID, false);
To use an ad hoc request you supply request parameters, a job definition, and optionally a schedule that you create and define without saving it to a metadata repository. An ad hoc request does not require you define the details of a job request in a metadata repository. Thus, ad hoc requests support an abbreviated job request submission process that can occur without using a connection to the metadata repository.
Note:
Ad hoc requests have the following limitation: job sets are not supported with ad hoc requests.To create an ad hoc request you use the ad hoc version of submitRequest()
. For the job definition, instead of supplying a job definition MetadataObjectId
, you can define the job definition object and use a system property that corresponds to the job type, as shown in Table 14-7.
Table 14-7 Ad Hoc Request Job Definition System Properties for Job Types
System Property | Description |
---|---|
|
Specifies the Java class to execute (for a Java job type). |
|
Specifies the PL/SQL stored procedure to execute (for an SQL job type). |
|
Specifies the command line used to invoke an external program for a process job request. |
With one signature of the ad hoc version of submitRequest()
you do not need to supply MetadataObjectIds
, you can provide the Schedule
object as an argument as object instances directly to submitRequest()
. Other ad hoc submitRequest()
signatures allow you to submit a job request using a job definition from metadata and an instance for the Schedule
object.
Example 14-7 shows sample code for an ad hoc request submission that uses a schedule.
Example 14-7 Creating Request Parameters and a Schedule for an Ad Hoc Request
RequestParameters p = new RequestParameters(); String propName = "testProp"; String propValue = "testValue"; p.add(propName, propValue); p.add(SystemProperty.REQUEST_EXPIRATION, new Integer(10)); p.add(SystemProperty.LISTENER, "test.listener.TestListener"); p.add(SystemProperty.EXECUTE_PAST, "TRUE"); p.add("application", getApplication()); p.add(SystemProperty.CLASS_NAME, "test.job.HelloWorld"); Calendar start = Calendar.getInstance(); start.add(Calendar.SECOND, 5); Calendar end = (Calendar) start.clone(); end.add(Calendar.SECOND, 5); Recurrence recur = new Recurrence(RecurrenceFields.FREQUENCY.SECONDLY, 2, start, end); Schedule schedule = new Schedule("mySchedule", "Run every 2 sec for 3 times.", recur); // adhoc submission, no metadata definitions passed reqId = s_runtime.submitRequest(h, "testAdhocJavaWithSchedule", JobType.ExecutionType.JAVA_TYPE, schedule, null, Calendar.getInstance(), null, p);
In this example, note the following ad hoc specific details for the request submission:
The CLASS
name is set to define the Java class that runs when Oracle Enterprise Scheduler executes the job request: p.add(SystemProperty.CLASS_NAME, "test.job.HelloWorld
");
The submitRequest()
includes an argument that specifies the job type: JobType.ExecutionType.JAVA_TYPE
.
Specify the Java class, the procedure name, or the command line program to execute when the ad hoc Request is processed by setting one of the system properties shown in Table 14-7.
Call the ad hoc version of submitRequest()
specifying the type argument to correspond with the system property you set to define the request. The type you supply must be one of JAVA_TYPE
, SQL_TYPE
, or PROCESS_TYPE
.
As with any job request, set the appropriate system properties to be associated with the job request.
The ad hoc submitRequest()
returns the request identifier for the request. You can use this request identifier with runtime calls such as updateRequestParameter()
or getRequestDetail()
as you would with any other job request.
There is only one submitRequest
signature that will create a request with an ad hoc job definition. The job definition ID, obtained from RequestDetail.getJobDefn()
, is null in this case. Without an ad hoc job definition, a request cannot be considered ad hoc.
If you want to define a schedule to use with an ad hoc request and you want to specify exclusion dates, you need to exclude the dates using the addExclusionDate()
method for the schedule. For ad hoc requests, you cannot use a schedule that specifies exclusion dates using addExclusion()
method for the schedule.
Currently, if the schedule is ad hoc, a check of ExclusionDefinition
is skipped. Thus, if you use a schedule and use addExclusion()
and submit an ad hoc job request, then Oracle Enterprise Scheduler does not use the ExclusionsDefinition
IDs with the job request.
Along with the core logic of your job, you can include code that executes before and after the job's main execution code. With code that executes before, known as a pre-process handler, you can do such things as set up certain conditions for the job executable. With code that executes after, known as a post-process handler, you can do such things as processing the results of the job executable, perhaps by printing reports or sending notifications.
You provide pre- and post-process handlers by implementing specific interfaces, then connecting your implementations to the service through a system property that indicates which of your classes to use.
With a pre-process handler, your code can do things to create an environment for your job to execute. This could include creating connections to resources that your job requires, for example.
The pre-processor is instantiated and invoked at the start of request execution when the request transitions to RUNNING state. This is done each time the request is executed, including when a failed request is retried or a paused request is resumed after its sub-requests have completed.
You create a pre-process handler by implementing the oracle.as.scheduler.PreProcessHandler
interface. With your pre-process handler class in hand, you specify that it should be used by setting the SYS_preProcess
system property to the fully-qualified name of your handler class. You can define the property on job metadata or include it in the request submission parameters.
Your PreProcessHandler
implementation should do the pre-process actions your job requires, then return an oracle.as.scheduler.HandlerAction
instance from the interface's one method, preProcess
. (Your class may also implement the Cancellable
interface if you want the job to support cancellation. It must also provide an empty constructor.)
The HandlerAction
instance your preProcess
implementation returns should give status about whether, and under what conditions, the job should proceed. When constructing the HandlerAction
class, you pass it a HandlerStatus
instance that indicates the status of pre-processing for the request.
Supported HandlerStatus
values and actions are listed below. An unsupported status will cause the request to transition to an error state and be subject to retries if configured.
PROCEED
informs Oracle Enterprise Scheduler that request processing should commence. The request will remain in RUNNING state.
WARN
informs Oracle Enterprise Scheduler that request processing should commence but that a warning should be logged. The request will remain in RUNNING state.
CANCEL
informs Oracle Enterprise Scheduler that request pre-processing has been cancelled. The request will transition to CANCELLED state.
DELAY
informs Oracle Enterprise Scheduler to postpone request processing by the quantum of time specified by the SYS_reprocessDelay
system property. The request remains in RUNNING state during the delay.
SYSTEM_ERROR
informs Oracle Enterprise Scheduler that the handler has experienced an error. The request will transition to an error state and is subject to retries if configured.
BIZ_ERROR
informs Oracle Enterprise Scheduler that the handler has experienced a business error. The request will transition to an error state not subject to retries.
With a post-process handler, your code can do things that should take place after your job has executed. This could include releasing connections to resources that your job required, for example, or generating a report based on request-specific data or status.
The post-processor is instantiated and invoked after job execution, when the request transitions to COMPLETED state. The post-processor is invoked only once for a request, in contrast to the pre-processor.
You create a post-process handler by implementing the oracle.as.scheduler.PostProcessHandler
interface. With your post-process handler class in hand, you specify that it should be used by setting the SYS_postProcess
system property to the fully-qualified name of your handler class. You can define the property on job metadata or include it in the request submission parameters.
Your PostProcessHandler
implementation should do the post-process actions your job requires, then return an oracle.as.scheduler.HandlerAction
instance from the interface's one method, postProcess
. (Your class may also implement the Cancellable
interface if you want the job to support cancellation. It must also provide an empty constructor.)
The HandlerAction
instance your postProcess
implementation returns should give status about whether, and under what conditions, the job should conclude. When constructing the HandlerAction
class, you pass it a HandlerStatus
instance that indicates the status of post-processing for the request.
Supported HandlerStatus
values and actions are listed below. An unsupported status will cause the request to transition to WARNING state.
PROCEED
to inform Oracle Enterprise Scheduler that request post-processing completed successfully. The request will transition to SUCCEEDED state or WARNING state depending on the status of the request prior to invoking the post-processor.
WARN
to inform Oracle Enterprise Scheduler that request post-processing resulted in a warning. The request will transition to WARNING state.
CANCEL
informs Oracle Enterprise Scheduler that request post-processing has been cancelled. The request will transition to WARNING state.
DELAY
to inform Oracle Enterprise Scheduler to postpone request processing by the quantum of time specified by the SYS_reprocessDelay
system property. The request remains in COMPLETED state during the delay.
SYSTEM_ERROR
to inform Oracle Enterprise Scheduler that the handler has experienced an error. The request will transition WARNING state.
BIZ_ERROR
to inform Oracle Enterprise Scheduler that the handler has experienced a business error. The request will transition to WARNING state.