2
votes

What is difference between Cron Job and Job in hybris ?

<!-- Cron Job -->
<itemtype code="DemoCronJob" extends="CronJob"
      autocreate="true" generate="true">

<!-- Job -->
<itemtype code="DemoCronJob"  extends="Job" 
      autocreate="true" generate="true">

What is difference between creation/Implementation of both ??

2

2 Answers

8
votes

The following diagram describes the complete view of how Jobs/Cronjobs works in Hybris, we will take it as a starting point to explain the difference between Job and Cronjob.

enter image description here

As the Car needs the Engine to work, the Cronjob needs the Job too. As well as a Car without Engine is not a Car anymore the Cronjob without Job is nothing.

The Job is the conscious element in this equation it defines the logic to be executed by the Cronjob. Meanwhile the Cronjob is the intermediate between the Job and Users, Through the Cronjob the user can send information ( priority, triggers, node,…) and orders ( start, stop, abort,…) to the Job to work properly and the Job can display messages ( data, status, results, logs,…) to the user through the Cronjob too.

I believe that the most effective way to learn is through examples, so let’s make one :

One of the most Hybris world requirements is creating a Cronjob that exports all the products of a selected catalogVersion.

  1. First, let’s create the Cronjob, in the Cronjob we will define the inputs that we will send to the Job.
<itemtype code="ExporterCronJob" extends="Cronjob" autocreate="true" generate="true" >
    <attributes>

        <!-- The input is the catalogVersion -->
        <attribute qualifier="catalogVersion" type="CatalogVersion" >
            <persistence type="property" />
        </attribute>

    </attributes>
</itemtype>
  1. Next is to make the Job to hold the logic of exporting, however creating the Job is not always so obvious, because you have to deal with Jalos and I hate Jalos :p

Fortunately, Hybris possesses another way of creating Job without using Jalos, we will get to it later.

The traditional way to create a Job is the one presented in the question, which is to create an item that extends from JobModel and in the corresponding Jalo of the created item implement the method performCronJob(CronJob cronJob) and make all your logic inside this method.

I have never used this approach before, so the recommended way is to use ServicelayerJobModel, the ServicelayerJobModel is already extending JobModel and implementing performCronJob(CronJob cronJob) for you.

How ServicelayerJobModel works ? it refers to a JobPerformable via it’s SpringID and then execute the logic defined in the JobPerformable.

So all what we need to do to create a JobPerformable is to extend from AbstractJobPerformable and implement perform(CronJobModel CronJob) :

public class ExporterJob extends AbstractJobPerformable<ExporterCronJobModel> {

    @Override
    public PerformResult perform(ExporterCronJobModel exporterCronJob) {
        try {

            //get inputs from the Cronjob...
            CatalogVersionModel catalogVersion = exporterCronJob.getCalaogVersion();

            //do logic...

            exportProducts(catalogVersion);

            //end of logic...

            //return Success (output)...
            return new PerformResult(CronJobResult.SUCCESS, CronJobStatus.FINISHED);

        } catch(Exception e) {

            //return Failure (output)...
            return new PerformResult(CronJobResult.FAILURE, CronJobStatus.ABORTED);
        }
    }
}
  1. We need to register our JobPerformable as a Spring bean :
<bean id="ExporterJob" class="com.foo.bar.ExporterJob" parent="abstractJobPerformable" />
  1. The JobPerformable should be attached to an instance of the ServicelayerJob :

Via impex :

INSERT_UPDATE ServicelayerJob  ;code[unique=true]  ;springId
;ExporterJob  ;ExporterJob

Or via HMC :

enter image description here

  1. Finally attach the Job ExporterJob to the Cronjob ExporterCronJob and Run your Cronjob :)

Via impex :

$productCatalog= ...
$Version= ...

INSERT_UPDATE ExporterCronJob; code[unique=true]  ;job(code) ;catalogVersion(catalog(id),version)   ;sessionLanguage(isocode)   ;sessionUser(uid)
;exporterCronJob ;ExporterJob ;$productCatalog:$Version  ;en  ;admin

Edit : http://www.stackextend.com/hybris/everything-about-cronjobs-in-hybris-part-1/

0
votes

The cronjob is the container that will handle configuration, triggers, logs and execution results, there is no logic.

The job does not contains any logic either, it only refers to a springId. If it is a ServicelayerJob, that references a Spring bean definition.

The Spring bean contains the logic. This bean should extends abstractJobPerformable, this way you do not define an new item. You continue to use the Servicelayerjob type and all beans extending abstractJobPerformable will be available to use in any cronjob.

In your exemple, delete below line from items.xml

<itemtype code="DemoCronJob"  extends="Job" 
  autocreate="true" generate="true">` 

Instead add this in spring.xml

<bean id="demoJobPerformable" class="com.foo.bar.DemoJobPerformable" parent="abstractJobPerformable"/>

Finally you link both with Impex or in the hmc/backoffice directly

INSERT_UPDATE DemoCronJob;code[unique=true];job(code);sessionLanguage(isocode)
;DemoCronJobNameYouWant;demoJobPerformable;en

BUG IN JUNIT TENANT

Above impex won't work in junit tenant (tested in hybris 6.2). In the impex, there is a part to reference the job : job(code). So it expect to have an instance of a JobModel set there.

In the master tenant, a filter or something like that take the bean referenced in the impex and automatically create an instance of JobModel (ServicelayerjobModel actually) with the name of the bean and the name of the springId (there are the same).

Unfortunatelly in junit this filter seems to not be activated by default (and I don't know yet how to activate it). So it's mandator to create yourself the instance of JobModel.

INSERT_UPDATE ServicelayerJob;code[unique=true];springId
;demoJobPerformable;demoJobPerformable

Note

There is still code in hybris that use the "legacy" system. But I think now it's not considered a good practice to create a new item for each Job.