Job
A "Job" is a sequence of operations that has to be executed asynchronously with respect to the user interaction. This means that jobs are automatically triggered by the application. It's possible to schedule a job at a specific time or interval.
For example, you can schedule a job to start when the Web application starts. It's also possible to schedule a job at runtime, which means that a user can schedule a job without the use of triggers by deciding when to execute the job, manually. In a "CRM" application, typical examples of jobs might include the newsletter sent once a month to all customers and the weekly report, about the best customer, sent to the all the sales managers.
Quartz Scheduler
WebRatio Platform uses the "Quartz" framework to implement the job’s business logic at runtime. "Quartz" is a full-featured, open source, job scheduling system that can be integrated with, or used alongside, virtually any J2EE or J2SE application - from the smallest stand-alone application to the largest e-commerce system.
Service View
Jobs must be modeled in a dedicated view of the Web Project, which is the "Service View". A "Service View" is a Container of Web Services and scheduled operation models made available by the application. You can have several "Service Views" in the same Web Project. Each "Service View" is represented as a new tab in the Web Project. When working with jobs, it is good practice to create a dedicated view for them, so you can easily separate Web Services from jobs.
How to Add a Service View
Let’s continue working on our "CRM" web project. The first thing you need to do in order to be able to model a job is to add a "Service View" into the Web Project.
To add a "Service View" to your project, open the "Project" tab. In the main work area, right-click on the "Service Views" icon, and choose the "Add Service View" command. The best practice is to give a meaningful name to each object in your project to make it easier to recall the element’s purpose, such as "Jobs". Press the "Finish" button to confirm.
Job Skeleton
Let’s suppose that the sales managers want to model the job that sends a weekly report to all the CRM users assessing which is the best customer of the week. All jobs can be modeled using the same skeleton.
A "Job" has its own container, named "Job". There is an entry point, which is the "Init Job" Operation, and then the "Action" containing all the business logic you want to execute. Even though it’s not mandatory to use an "Action", and you can model the operation chain inside the "Job Container", it is strongly suggested to use the proposed skeleton in order to have a reusable operation chain and a well structured project.
In this case, the action contains all the business logic needed in order to send a report to all CRM users. To learn more about modeling an "Action Definition", refer to the dedicated lessons. Each "Job" can have one or more triggers. A "Trigger" is a temporal event specifying when the job must be executed. In this example, the "Job" is executed every Friday evening at 11 PM. Let’s review the details of each part of the job skeleton.
Job Container
The "Job Container" is a graphical container used to group all the elements related to a specific job. Every time you place a Job Container in a Service View, the "Init Job" operation is automatically added.
Init Job
The "Init Job" operation is the entry point of a scheduled job. In most cases, the "Job" has an auto-consistent business logic. Auto-consistent means that the business logic does not require any further information from the external environment in order to work properly. Nevertheless, there can be cases where you want to let the Web application user schedule a job that needs some specific information to be fed in when the job is triggered.
Trigger
The "Trigger" is the timestamp at which the job must start and execute the contained business logic. It is represented by a "Cron Expression", or by an event that you can easily configure in the Properties View.
Let’s see the options you have at your disposal. First, you have to choose the "Schedule Policy", which influences the state of all other properties you can see in the Properties View. The "Schedule Policy" defines exactly when and how often you want to get the job executed. Depending on the value of this property, you are asked to fill in the other fields, namely "Hours", "Minutes", "Seconds", "Day of the Week", "Day", "Month" and "Year".
Here is the list of all the available scheduling options with an example. On the other hand, if you are familiar with the "Cron Expression", you can select the "Custom" option in the "Schedule Policy" and write your own trigger. If you want to see more about the "Cron Expression", refer to the official "Quartz" website.
The "Trigger" is not mandatory. In fact, if you plan to let the Web application user schedule the Job, you can model the job without any associated trigger.
How to Model the "Send Weekly Report" Job
Let’s suppose you want to model the job that sends a weekly report to all the CRM users assessing which is the best customer of the week. We have already created the "Jobs" service view. We have also a Domain Model defined, composed of the "Company" and "Best Customer" objects, a "Module Definition View" named "Action Definition" and an action definition named "Send Best-Customer Report". Let's add the "Job Container" that will contain all the elements for the operation of this job. To add "Job Container", select the "Job" icon from the "Container" section of the toolbar and click in the work area. Give a meaningful name to the "Job", such as "Send Weekly Report". Every time you place a "Job" in a "Service View", the "Init Job" operation is automatically added by default.
Now let’s add the "Send Best-Customer Report" action that contains the business logic. Select the "Action" icon from the "Container" sections of the toolbar and click in the "Send Weekly Report" job container. In this case, the "Action" is directly associated to the "Send Best-Customer Report" action definition, because there is only one "Action Definition" in the "Module Definitions View". But if there is more than one "Action Definition" in the "Module Definitions View", we must associate the instance of the action to the correct "Action Definition" property. Then select the "Action" in the "Job Container", move to the Properties View and press the "Select" button next to the "Action Definition" property and, in the dialog that opens up, select the "Action Definition" you want to reference. Press the "OK" button to confirm.
In order to start the "Action" let's use an "OK Flow” connecting the "Init Job" operation and the "Action". To add an "OK Flow", select the "OK Flow" icon from the "Flows" section of the toolbar and click first on the "Init Job" Operation and then on the "Action".
Now, let's define a trigger specifying how often the job must be executed. In this example the job is executed every Friday evening at 11 PM. To add a "Trigger", right-click on the "Send Weekly Report" Job Container and select the "Add" and then the "Trigger" option. Give a meaningful name to the "Trigger", such as "everyFriday". Move to the Properties View; set the "Schedule Policy" property as "Once a Week". Then all the other properties needed to configure the "Trigger" are enabled. Let's choose, "Friday evening at 11 PM". Set the "Day of Week" property as "Friday". Set the "Hours" property as "23". Set the "Minutes" property as "00". Set the "Seconds" property as "00".
Job Scheduled by the User
Now that you know how to model a Job, let's see how you can easily model a piece of IFML in order to let the Web application’s user schedule an existing job. Let’s use the job for sending the weekly report we have just modeled. Let’s suppose you want to let the Web application’s user decide when the report must be sent. Then you need to model a piece of IFML, providing a form for the user to use for scheduling the Job at a specific date. The key component of this model is the "Schedule Job" operation, which can be used to explicitly schedule a "Job". It has two main properties:
- Job. The reference to the modeled Job you want to schedule.
- Schedule Policy. Specifies when the Job must start. You can choose different options.
The "Schedule Policy" is set to "Now" by default, but there are other possible options that you can choose, for example "Every Day", "Once a Week", "Specific Date" and so on. The available list of options is similar to the ones you have at your disposal when configuring a trigger. The difference with respect to the trigger is: with the trigger the specific value, for example "07/02/2014 23:00:00", is set in the Properties View, while for the "Schedule Job" Operation, this value is decided by the user and passed as the "Input Parameter" to the "Component".
Depending on the choice of the "Policy Schedule" property, you have several items of input data to the "Schedule Job" that allow you to dynamically set the execution of a particular job.
In our example with the "Specific Date" property, the user passes a specific timestamp to the "Schedule Job" Operation. Instead, if you set the "Once a Week" in the "Schedule Policy" property, the user would have to pass as input parameters a day of the week (SUN, MON, ..) and a specific time.
How to Schedule a Job
Let's open the "Public" site view of the project and start adding a page to allow the user to send the report. Select the "Page" from the "Containers" section of the toolbar and click on the "Site View" work area to add it. Type a meaningful name for the page, such as "Schedule Best Customer Report". Be sure that your page can be reached from the other points of the "Site View". An option is to make it a landmark; select the "Page" and from the Properties View check the "Landmark" property.
To allow the user to decide the sending date for the report, let's use the "Form" view component with a "Date" field. Select the "Form" component from the "View Components" section of the toolbar and click on the "Page" to add it. Type a name for it, such as "Select Date".
To add the "Field", right-click on the "Form" component, choose "Add" and then the "Field" option. Type a meaningful name for the "Field", such as "Date" and move to the Properties View to configure the "Field". Select an option in the "Type" dropdown list. In our example, let’s select the "timestamp" option.
Now let’s add the "Action" that allows the user to schedule the "Job". Select the "Action" icon from the "Container" section of the toolbar and click in the "Site View".
To let the user send the report, let’s use a "Normal Navigation Flow". Select the "Flow" icon from the "Flows" section of the toolbar and click first on the "Form" view component, and then on the "Action". Type a name for the "Flow", such as "Submit".
Now, let’s see how to model an "Action Definition" for scheduling the "Job". Use the same "Module Definitions View" used for the "Send Best-Customer Report" action definition. Select the "Action Definition" icon from the toolbar and place it inside the work area. Then type the desired name for that "Action Definition"; for example, "Schedule Best Customer Job". Double-click on the "Schedule Best Customer Job" Action Definition to open it and start modeling its behavior.
Now you have to add a "Schedule Job" operation to the "Action Definition" that allows you to start the job that you want to associate. Select the "Schedule Job" operation from the "Service Components" section of the toolbar and click inside the work area. Type a name for it, such as "Schedule Best Customer Report", and move to Properties View. You can see that the "Job" property is automatically associated with the only job present in the "Service View". But if there is more than one "Job Container" in the "Service View", we must associate the "Job" property to the correct job. Press the "Select" button next to the "Job" property and, in the opening dialog, select the "Job Container" you want to reference . Finally, press the "OK" button to confirm.
Set the "Schedule Policy" property as "Specific Date" option; in this way you can pass the date chosen by the user. Let's now add an "Input Parameter" for the "Input Port" that corresponds to the selected date. Right-click on the "Input Port", choose "Add" and then "Input Port Parameter". Type a meaningful name for it, such as "date".
To express the activation of the "Schedule Job" operation, add an "OK Flow" from the "Input Port" to the "Schedule Job" operation, by selecting the "OK Flow" icon from the "Flows" section of the toolbar and clicking on the "Input Port" and then on the "Schedule Best Customer Report" operation. Now, define the "Parameter Bindings" between the "Input Port" and the "Schedule Job" by double-clicking on the " OK Flow", uncheck the "Enable Default Binding" property and bind the "date" Input Parameter with the "Timestamp (yyyy-MM-dd hh:mm:ss)" parameter. Press the "OK" button to confirm.
To make a reference from the "Action" to the "Schedule Best Customer Report" action definition, move to the "Public" site view. Select the "Action" and press the "Select" button next to the "Action Definition" property and choose the "Schedule Best Customer Report" action definition from the opening dialog. Press the "OK" button to confirm.
In order to make the "Action Definition" work properly, it’s necessary to provide the "Date" to it, through the "Parameters Binding". Define the "Parameters Binding" between the "Select Date" form component and the "Schedule Best Customer job" Action by double-clicking on the "Flow" outgoing from the "Form" component, uncheck the "Enable Default Binding" property and bind the "Date" Field with the "date" Parameter. Press the "OK" button to confirm.
Storing the triggers
The "Quartz" framework uses a set of tables to store information about jobs and their triggers. WebRatio Platform lets you decide where you want to store this information. This is a general setting of the Web Project, so this information can be configured in the "General" tab of the Web Project, selecting the "Services/Jobs" tab.
The Properties View shows you several properties. The main one, to be chosen carefully, is the "Job Store Type" property. The "Job Store Type" indicates where scheduling information (jobs and triggers) are stored. The possible values are:
- Memory: scheduling information is stored within the Web application memory; this kind of job store is fast and lightweight, but all scheduling information is lost when the application server is stopped.
- Database: scheduling information is stored within a relational database, which must be a database used in the Web Project. This is the suggested option, because the scheduled jobs can be monitored and can register any abnormalities reported during their execution.
Depending on the selected option for the "Job Store Type" property, you then have another set of additional properties to configure:
- Job Database [MANDATORY]. This option is available only if the "Database" option is chosen. It is mandatory to set this option because it is necessary to indicate a database that will store the scheduling information. It's one of the databases defined in the project, where scheduling information is stored.
- Job Schema. The database schema where the scheduling information is stored.
- Job Table Prefix. The prefix given to tables storing scheduling information; you can have multiple sets of scheduling tables within the same database if they use different table prefixes.
- Clustered Job Store. This property must be set to true if the Web application is deployed in a clustered environment, such as when you want to manage the execution of jobs on the server. For example, you would use this when an application is running on more than one server.
How to Synchronize Domain Model with Quartz Tables
Let's suppose you decide to store the scheduling information within the CRM database used in the Web Project. Open the "Project" tab, and move to the Properties View. Select the "Services/Jobs" tab, and then set the "Job Store Type" property as "Database". In this way you can store the job scheduling information so as to use the "Quartz" tables. In this case the "Job Database" and the "Job Schema" properties are directly associated to the "CRM" database node, because there is only one "database" in the Web Project.
But if there is more than one database in the Web Project, you have to select one of them. Press the "Select" button next to the "Job Database" property and, in the opening dialog, select the database you want to reference. Press the "OK" button to confirm. Set the correct schema in the "Job Schema" property based on the associated database.
To synchronize the database with the scheduling information, move to the "Domain Model" tab. Right-click on the "CRM" database node in the Outline View and select the "Synchronize..." option to start the synchronization process. In this case, the result of the synchronization process is a dialog showing the "Job Store Mapping" node that represents the "Job Tables" as the element to be exported from the Domain Model to the database. Right-click on the "Job Store Mapping" node and select the "Export to Database" option. Then press the "Next" button. Now you will see a dialog showing the SQL code necessary to create all the "Quartz" tables. Press the "Finish" button to complete the synchronization process.
In the database, the tables will be created with the prefix "qrtz". You can see these tables by using an external software app that allows you to manage your database. The "Job Tables", once exported, are ignored by the "Database Synchronizer". This means that by default you cannot import a "Job Table" into the Domain Model.
If you want to change this behavior, you have to change an option in the "Preferences". Select "Window" and then the "Preferences" option from the main menu (on a PC) or Select "WebRatio Platform" and then the "Preferences" option from the main menu (on a Mac). In the opening dialog expand "WebRatio" node and then "Modeling" option. Here is the option "Ignore Quartz tables". By default this option is checked. If you want to import some "Job Tables", uncheck this option. And press the "OK" button to confirm.