Using the Job Scheduler in XS Advanced
If you’ve been developing HANA applications you’ll probably have come across the need to to initiate a given task on a given schedule – perhaps a long-running batch job or maybe something short and sweet to be executed on a frequent basis?
SAP HANA XS Advanced Model provides a job scheduling capability which enables all this and more.
If you’re already familiar with XS “Classic” you’ll know that it’s possible to schedule a job using an .xsjob script. With XS Advanced that’s also possible – however a host of additional capabilities including a fully fledged job scheduling dashboard UI and a REST API are also available!
So where do you start if you want to schedule a HANA job?
It’s a great idea to first familiarize yourself with the job scheduler dashboard UI – however to access it you’ll need some specific authorizations which are not configured by default. You’ll need to create a role collection with the required job scheduling scope(s) and assign that role collection to your user.
Additionally, you’ll need to create a jobscheduler service instance in the XS Advanced space that will then be bound to your MTA application – just like HDI containers and User and Account Authentication (aka UAA) service instances.
To see how to perform the above “hands-on” watch this video tutorial from the SAP HANA Academy:
Something you’ll quickly notice about the job scheduling dashboard is that whilst you can manage existing jobs and schedules it’s not possible to create new jobs – don’t worry however as there are a number of ways to do that from your MTA project…
Probably the simplest way (especially if you already have knowledge of XS “Classic”) is to create a Node.js module with XS support enabled and configure an .xsjob. This will allow you to create a job which you can then further manage in the job scheduling dashboard and only requires a few lines of JSON to define.
{
"description": "Perform my task",
"action": "myTasks.xsjs::create",
"schedules": [{
"description": "Perform my task every 15 seconds",
"xscron": "* * * * * * */15",
"parameter": {}
}]
}
You’ll need to reference the jobscheduler service instance we created earlier in the mta.yaml of your project:
You can see how to build all of this this from scratch in the following video tutorial:
However something that’s missing from the above example is authentication. The action the job scheduler launches is an XSJS function – but when that function requires authentication how can the job scheduler be authenticated? Ouch!
Well there’s a mechanism to enable this which involves “auto-assigning” an application scope to the jobscheduler from your project’s xs-security.json file:
{
"name": "$XSAPPNAME.JOBSCHEDULER",
"description": "Scope for Job Scheduler",
"grant-as-authority-to-apps": ["jobscheduler"]
}
Then adding the following property in your mta.yaml:
SAP_JWT_TRUST_ACL: '[{"clientid":"*","identityzone":"*"}]'
You can see every step of the process in the following video tutorial:
Job Scheduler – XSJS with authentication
Once the application is finished you’ll probably want to deploy it to another space such as test or production. You can see how to do that in this video tutorial and what’s nice is that the jobscheduler and UAA service instances get created automagically.
If you’d like to try this yourself without writing a line of code simply clone this GitHub repository into you own HANA XS Advanced landscape: https://github.com/saphanaacademy/xsaJobsXSJS
So now you know how to get started with the job scheduler – but you might want to take advantage of some of the more advanced capabilities, in particular the REST API. Read on…
The following scenario shows how to create a project with job scheduling via pure Node.js (no need for XSJS support!) and in conjunction with the REST API. It’s a little more involved but does provide a huge amount of flexibility.
The first video covers getting started – creating the project with HDB and Node.js modules and registering the UAA and jobscheduler service instances in the mta.yaml:
Job Scheduler – Node.js – Part 1 of 4
In the second video we review the code covering how to perform our desired action which for us is to insert a row into a HANA table. In the real world it would likely be something much more sophisticated but I wanted to keep the example as succinct as possible and focus on the job scheduling aspects.
We also cover how to invoke the Job Scheduler REST API to create/delete our job (there are a number of REST API actions but once you’ve seen one or two you’ll have no problem using the others):
Job Scheduler – Node.js – Part 2 of 4
What’s nice is that XS Advanced provides a useful node module to make the REST API calls for us – so you don’t have to get bogged down in dealing with the standard Node.js request object. Should you want to invoke the REST API another way (from outside XS Advanced for example) that’s fine – just be sure to authenticate. Here’s a snippet from the code that invokes the REST API from Node.js in order to create a new job:
// setup connection to job scheduler REST API
var jobOptions = xsenv.getServices({
jobs: {
tag: "jobscheduler"
}
});
var schedulerOptions = {
baseURL: jobOptions.jobs.url,
user: jobOptions.jobs.user,
password: jobOptions.jobs.password,
timeout: 15000
};
var scheduler = new jobsc.Scheduler(schedulerOptions);
app.get("/create", function(req, res) {
if (req.authInfo.checkScope("$XSAPPNAME.Admin")) {
// get the full URI of this app
var thisApp = JSON.parse(process.env.VCAP_APPLICATION);
var thisAppURI = thisApp.full_application_uris[0];
var myJob = {
job: {
"name": "myJob",
"description": "Perform my action",
"action": thisAppURI + "/js/hana/insert",
"active": true,
"httpMethod": "POST",
"schedules": [{
"description": "Perform my action every 15 seconds",
"repeatInterval": "15 seconds",
"data": {},
"active": true
}]
}
};
scheduler.createJob(myJob, function(err, body) {
if (err) {
res.status(500).json(err);
} else {
res.status(200).json(body);
}
});
} else {
res.type("text/plain").status(403).send("Forbidden");
}
});
So that we can test the scenario interactively we’ll also create a simple HTML5 module to give the ability to authenticate so we’ll then be able to access the Node.js back-end.
In the third video tutorial we finally get to test out the application – create a job, see that the job is running as configured and see the results:
Job Scheduler – Node.js – Part 3 of 4
Finally we deploy the completed application to another space and test it there:
Job Scheduler – Node.js – Part 4 of 4
If you’d like save time when trying this yourself try cloning this GitHub repository into you own HANA XS Advanced landscape: https://github.com/saphanaacademy/xsaJobsJS
I hope that these scenarios provide food for thought about what’s possible and help you get started with the powerful job scheduling capabilities of HANA.
As always your feedback is most welcome – below, in the YouTube comments section, or on Twitter @pmugglestone.
Happy job scheduling!
Philip
Great blog, thanks for the breakdown!
Hi Philip
Thanks so much for help on the jobscheduler.
Whilst the jobscheduler is mentioned a lot in the SAP HANA XSA Developer guide, its not within context and it doesn't actually tell you how to set up a job or that you need to grant access to the jobscheduler to run the job.
To close the loop, is there a way to automatically trigger the creation of a NodeJS job on 'xs deploy' or 'xs install', ie when the service starts up fire the REST call?
Cheers
John P
Hi John,
Thanks for watching the tutorials and your kind feedback.
The simplest way to automatically trigger job creation on deployment is probably to use XSJS compatibility with .xsjob as that will result in the job being created during deployment.
In pure Node.js you could also achieve this by explicitly making the REST call to create the job during startup by making the REST call from server.js. In that case you might also include a REST call to check whether the job already exists - so you can avoid trying to create it more than once or intentionally delete then re-create depending on what behavior you require?
Hope that helps,
Philip
Hi Philip
doh of-course, than for replying with those options
JSP
Hi Philip,
I am using the XSJS compatability mode for the jobs.
I'm reading out of a classic schema and writing back into that schema. I've defined all the authorisations required in the roles that are used as part of the User provided service (INSERT on table etc)
The stored procedures that run insert into this table works in the call.
However, when this is wrapped in a job, it ends up giving me an error with insufficient privileges.
When checking the trace in the logs, I find that there's an SBSS_* user which doesn't have a Debug on the calculation scenario. Should I provide DEBUG on the stored procedure to this user?
How does one provide this authorisation?
Cheers
Kiran
Hi Kiran,
Thanks for reading and your feedback.
This isn't a situation I've ever tried myself but possibly the way to provide the authorizations could be via the "SQL Console (Admin)" in Database Explorer.
See the following blog/videos: https://blogs.sap.com/2018/01/24/the-easy-way-to-make-your-hdi-container-accessible-to-a-classic-database-user/
Hope that helps.
Philip
Hello Philip,
I have tried the both xsjs and node js part, xsjs worked fine but while calling the create route in node js, it's giving me following error:
Hello,
Were you able to solve this issue?
Thanks!
Luis
Hi Philip,
we've got the jobs working, following your tutorials. Except that our job (a nodeJS function) takes a while to complete and sometimes gives the error ESOCKETTIMEDOUT after 15 seconds.
Is there any way to increase this timeout?
One of the things I think might be relevant is if we have a synchronous or asynchronous job mode (Scheduling Jobs in XS Advanced - https://help.sap.com/viewer/6b94445c94ae495c83a19646e7c3fd56/2.0.02/en-US/4de4ea4f04ea460cbccb7d97c78e7183.html). But I can't find any reference on how to set this mode and what the differences are in execution.
Kind regards,
Tin de Zeeuw
Hi,
Did you got any solution for this?
An Awesome Blog Phillip - thanks !
Hi Philip,
A great compilation around the XS Job Scheduler. In your example, you are passing a blank
data{}
object.Can you also share, how we can pass some data while triggering the job?
We can populate the data{}. But, how and where do we receive it when the job gets triggered?
Kind Regards,
NIshant
Hi Nishant,
Thanks for asking. It seems this isn't well covered in the documentation and indeed we don't have videos showing that as yet. My understanding is that the data is passed based on the HTTP method. For the HTTP method “PUT” or “POST”, the data parameters are sent in the request body while invoking the endpoint. For the HTTP method “GET” or “DELETE”, the data parameters are sent as query strings. It's up to the receiving endpoint to process the data parameters accordingly. Exact details depend on the technology that the endpoint is created with.
So if you call with:
An endpoint written in Nodejs using Express might look like this for HTTP GET/DELETE:
And this for HTTP POST/PUT use the body-parser module something like this:
Hope that helps?
Philip
Great Blog & Videos, Thanks Philip.
Could you please explain how to call stored procedures and update data in staging tables with REST API job scheduler? I was able to figure it out through XSJS periodic job scheduler but not with REST API. Any blogs or videos will be really helpful.
Thanks,
Srilaxmi
Hi Srilaxmi,
Thanks for the nice feedback.
Most of our focus these days is on SAP's cloud offerings however we'll add your request to our to-do list.
Thanks,
Philip
Thanks Philip,
Could you please help me in knowing how to inactivate job in the job schedular dashboard through JS code.
I am able to delete the job using "scheduler.deleteJob" but unable to make it inactive. Couldn't able to find any standard method to inactivate job.
Thanks,
Srilaxmi
Hi Srilaxmi,
The best I can do at this point is recommend to ask the wider SAP Community where you'll hopefully find knowledgeable folks that are up to date on this.
Thanks.
Hi Philip,
Thanks for your details blog.
I have followed the same process and able to Schedule the Jobs and Delete the job. How ever we are facing two issues.
Regards,
Rajesh
Hi Rajesh,
It sounds like there have been some changes since the video tutorials were published.
Unfortunately we don't have bandwidth to continually review, update & refresh all of our published content.
Have you consulted the reference guide for the version you're using?
Otherwise I'd recommend asking here.
Thanks,
Philip