Reputation: 23
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 ??
Upvotes: 2
Views: 4872
Reputation: 3749
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
.
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
.
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>
Job
is not always so obvious, because you have to deal with Jalos
and I hate Jalos
:pFortunately, 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);
}
}
}
JobPerformable
as a Spring bean :<bean id="ExporterJob" class="com.foo.bar.ExporterJob" parent="abstractJobPerformable" />
JobPerformable
should be attached to an instance of the ServicelayerJob
:Via impex :
INSERT_UPDATE ServicelayerJob ;code[unique=true] ;springId
;ExporterJob ;ExporterJob
Or via HMC :
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/
Upvotes: 8
Reputation: 20065
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.
Upvotes: 1