2015-06-18

The Java Cloud Service (JCS) provides a platform to develop and deploy
business applications in the cloud. In Fusion Applications Cloud
deployments customers do not have the option to deploy custom
applications developed with JDeveloper to ensure the integrity and
supportability of the hosted application service. Instead the custom
applications can be deployed to the JCS and integrated to the Fusion
Application Cloud instance.

This series of articles will go
through the features of JCS, provide end-to-end examples on how to
develop and deploy applications on JCS and how to integrate them with
the Fusion Applications instance.

Previous articles covered ADF
web application; next we cover options to implement scheduling in JCS.
Sometimes there are requirements for the ability to schedule large
transactions to run at a future time or automate the running of
an application based on a defined schedule. In Fusion Applications these
types of requirements are met with Oracle Enterprise Scheduler (ESS), unfortunately ESS is not available in JCS.

In previous article we covered Timer and Worker API and Timer Service, this article covers popular scheduler library Quartz. In future articles other options will be covered.

Pre-requisites

Access to Cloud instance

In order to deploy the
application access to a JCS instance is needed, a free trial JCS instance can
be obtained from Oracle Cloud site. To register you will need a credit card even if the credit card
will not be charged. To register simply click "Try it" and choose the
"Java" option. The confirmation email will contain the connection
details. See this video
for example of the registration.

Once the request is
processed you will be assigned 2 service instances; Java and Database. Applications
deployed to the JCS must use Oracle Database Cloud Service as their underlying
database. So when JCS instance is created a database instance is associated
with it using a JDBC data source.

The cloud services can
be monitored and managed through the web UI. For details refer to Getting
Started with Oracle Cloud.

JDeveloper

JDeveloper contains
Cloud specific features related to e.g. connection and deployment. To use these
features download the JDeveloper from JDeveloper
download site by clicking the “Download JDeveloper 11.1.1.7.1 for ADF
deployment on Oracle Cloud” link, this version of JDeveloper will have the JCS
integration features that will be used in this article. For versions that do not include the Cloud
integration features the Oracle Java Cloud Service SDK or the JCS Java
Console can be used for deployment.

For details on
installing and configuring the JDeveloper refer to the installation
guide.

For details on SDK refer to Using the Command-Line Interface to Monitor Oracle Java Cloud Service and Using the Command-Line Interface to Manage Oracle Java Cloud Service.

Implementation

In this example we create an application that consists of the following:

Scheduling is implemented using Quartz

The monitoring UI is implemented with ADF using a programmatic view object

Create Application

First create an empty application with "Fusion Web Application (ADF)" in this sample I named the application "JcsDemoQuartz". For details on how to create an application refer to this blog post.

Also since in this example security is not implemented navigate to the web.xml and disable authentication by adding the "<login-config/>" element.

Also set the web context root for "ViewController" project by navigating "Project Properties > Java EE Web Context Root" to "quartz".

Install Quartz

First download the Quartz libraries. The installation consists of:

Creating the data model

Configuring the data source

Including the libraries to the application

Create Quartz Data Model

First create the data model in the database, the package downloaded contains a script to create the data model, in my case:

Run the script against the target database.

Add Quartz Libraries to the Application

Since in this sample the Quartz libraries are accessed from both model and view layer, a separate project is created to encapsulate the Quartz related logic into a separate project.  Create a new "Generic Project" in the application and name it "Quartz"

Copy the jar files to a suitable location e.g. under "lib", navigate "Project Properties > Libraries and Classpath > Add JAR/Directory" and include all the Quartz jar files.

Next include the Quartz project as dependency for both "ViewController" and "Model" projects; navigate "Project Properties > Dependencies > Edit" and check the "Build Output" under the "Quartz" project.

Configure Quartz Datasource

By default all Jobs and Triggers are stored in RAM and therefore do not
persist between program executions. There is also support for storing
the definitions in relational database using JDBC, to do this we need to
configure the data store. Data source is configured by introducing "quartz.properties" file or alternatively doing the same configuration run time when the scheduler is initialized. In this sample the goal is to de-couple the configuration from the code, such that change in the configuration does not require deploying the application again, so the configuration is based on a file uploaded to JCS. Following is an example of the quartz.properties file to be used in JCS, change the value of "jndiURL" to match the name of the data source in the JCS instance:

For details of the configuration refer to the Quartz Scheduler Configuration Guide.

In JCS access to the local file system is restricted so if included in the project directly an error occurs:

In order for the Quartz to be able to access the configuration the file must be uploaded into the accessible location in a separate step. First start the file-system access shell:

and upload the file with:

Create Quartz Scheduler Singleton

Next we create the logic to interact with the Quartz library.

ScheduledJob

This class represents a scheduled object in Quartz framework. The
object is used by the model and view logic to encapsulate details of a
scheduled job during processing. Create a Java file with name
"ScheduledJob" and package "oracle.demo":

Scheduler Jobs

Next we create a class that does the actual processing. Create a Java file with name "TestJob" and package  "oracle.demo":

Also create another similar job with e.g. name "TestJob2".

QuartzSchedulerSingleton

Singleton pattern
is used; create new java class with name "QuartzSchedulerSingleton" and
include the following logic. For details of the logic refer to the
comments in code:

Create ADFbc Objects

To implement UI to monitor and manage the scheduled jobs we will create some ADFBc objects accessing the Quarts data using APIs.

ScheduledJobsVO

This is a programmatic view object is used to query the scheduled jobs using the Quartz APIs. Create the programmatic VO by navigating "File > New > Business Tier > ADF Business Components > View Object". Use name "ScheduledJobsVO", package "oracle.demo.model" and choose "Rows populated programmatically, not based on a query". On the following screen add the following transient attributes with following properties:

JobName; String, primary key, always updatable

GroupName; String, primary key, always updatable

NextExecution; Timestamp, always updatable. On control hints set "Format Type" to "Simple Date" and "Format" to "dd-MMM-yyyy hh:mm"

JobClass; String, always updatable

Rows for the VO are populated programmatically so on the "Java" step check the "generate the View Object Class" checkbox and click "Finish". Next we implement the logic to obtain data from Quartz to be displayed on the UI. Open the file ScheduledJobsVOImpl.java; in executeQueryForCollection we use the Quartz APIs to populate an iterator with data for scheduled jobs. In createRowFromResultSet we create programmatically create a row for an entry in the iterator. For details of the implementation refer to the comments in code:

QuartzAM

Next we create application module to access the VO from the UI. Create the AM by navigating "File > New > Business
Tier > ADF Business Components > Application Module". Use name
"QuartzAM", package "oracle.demo.model". On the "Data Model" screen add the ScheduledJobsVO to the AM.

Also navigate to "Configurations ->
QuartzAMLocal -> Edit" and choose "JDBC DataSource" as the connection
type and "database" (or whatever the data source name is in your JCS
instance) for the "Datasource name".

Create UI

The UI will use the ADFbc components to display and manage the Quartz jobs.

Managed Bean

Next we create a managed bean which will include the following key logic. For "ViewController" project create a Java file; use name "JcsDemoQuartzBean" and package "oracle.demo":

_jobClass: Class variable used to store value obtained from the user through the UI, defaulting to TestJob

_cronScheduler: Class variable used to store value obtained from the user through the UI, defaulting to expression for scheduling execution every 30 seconds

scheduleJob: Called from the UI when the "ScheduleJob" button is pressed. The logic will use the singleton logic to schedule a job using "class reference" and the "scheduler expression" entered by the user on the UI

For details refer to the comments in code:

Register the java class as managed bean. Open adfc-config.xml, navigate to "Overview > Managed Beans" and create a new managed bean with:

Name: JcsDemoQuartzBean

Class: oracle.demo.JcsDemoQuartzBean

Create Page

Finally we create the page; navigate "New > Web Tier > JSF > JSF Page", enter name JcsDemoQuartz.jspx, check the "Create as XML Document (*.jspx)" and "Blank Page". Build the UI as follows:

Create "Input Text" component and bind the value to #{JcsDemoQuartzBean.jobClass}", this allows the user to enter the name of the class to be scheduled

Create "Input Text" component and bind the value to #{JcsDemoQuartzBean.cronScheduler}", this allows the user to enter the cron expression to schedule the job with

Create "Button" component and bind the "ActionListener" value to "#{JcsDemoQuartzBean.scheduleJob}"

Navigate to "Data Controls > QuartzAMDataControl > ScheduleJobsVO1", drag and drop it as a read only table to the UI. Set "Row Selection" to "Single Row"

Navigate to "Data Controls > QuartzAMDataControl > ScheduleJobsVO1
> Operations > Execute", drag and drop it as button to the UI

Navigate to "Data Controls > QuartzAMDataControl > ScheduleJobsVO1 > Operations > Delete", and add as column to the read only table

The UI definitions should look like the following:

For the system to automatically query the data when navigate to the page open the page definition for the file, select the "ScheduledJobsVO1Iterator", go to the properties window and set the value of property "Refresh" to "always".

Testing

Deploy the application to the JCS. Once deployed to the JCS we can access the application with URL:



Click "ScheduleJob" which will schedule the default job to execute
every 30 seconds. Change the value of "Class Reference" to "oracle.demo.TestJob2" and click "ScheduleJob" to schedule another job:



From the JCS console you can observe the Jobs executing:



The scheduled jobs can then be deleted with the "Delete" button.

Summary

In this article we
learned how to use Quartz to implement scheduling for Java Cloud Service. In future
articles various other technologies and features for scheduling in JCS will be covered.

Appendix

QuartzInitializerListener

Alternatively if access is only needed from UI the scheduler can be automatically started and configured with the application using QuartzInitializerListener. The listener can be configured in the web.xml to point to the properties file uploaded to JCS using parameter, an example configuration would be:

Show more