Skip to Content
Author's profile photo Philip MUGGLESTONE

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:

Job Scheduler – Introduction

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:

Job Scheduler – XSJS

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.

Job Scheduler – XSJS deploy

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

Assigned Tags

      19 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Great blog, thanks for the breakdown!

      Author's profile photo John Patterson
      John Patterson

      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

      Author's profile photo Philip MUGGLESTONE
      Philip MUGGLESTONE
      Blog Post Author

      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

      Author's profile photo John Patterson
      John Patterson

      Hi Philip

      doh of-course, than for replying with those options

      JSP

      Author's profile photo Kiran Jayaram
      Kiran Jayaram

      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

      Author's profile photo Philip MUGGLESTONE
      Philip MUGGLESTONE
      Blog Post Author

      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

      Author's profile photo Bittu Gorai
      Bittu Gorai

      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:

      {"code":"UNABLE_TO_GET_ISSUER_CERT_LOCALLY"}
      
      Can you please comment and help me solve this issue?
      Author's profile photo Luis Eusa Mendia
      Luis Eusa Mendia

      Hello,

       

      Were you able to solve this issue?

       

      Thanks!

      Luis

      Author's profile photo Tin de Zeeuw
      Tin de Zeeuw

      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

      Author's profile photo Ajinkya Jadhav
      Ajinkya Jadhav

      Hi,

      Did you got any solution for this?

       

      Author's profile photo Rama Shankar
      Rama Shankar

      An Awesome Blog Phillip - thanks !

      Author's profile photo Nishant Nayyar
      Nishant Nayyar

      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

      Author's profile photo Philip MUGGLESTONE
      Philip MUGGLESTONE
      Blog Post Author

      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:

      "data": {"myparam":"myvalue"}

      An endpoint written in Nodejs using Express might look like this for HTTP GET/DELETE:

      var myparam = req.param('myparam');

      And this for HTTP POST/PUT use the body-parser module something like this:

      var bodyParser = require('body-parser');
      app.use(bodyParser.json());
      var myparam = req.body('myparam');

      Hope that helps?

      Philip

      Author's profile photo Srilaxmi divi
      Srilaxmi divi

      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

      Author's profile photo Philip MUGGLESTONE
      Philip MUGGLESTONE
      Blog Post Author

      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

      Author's profile photo Srilaxmi divi
      Srilaxmi divi

      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

      Author's profile photo Philip MUGGLESTONE
      Philip MUGGLESTONE
      Blog Post Author

      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.

      Author's profile photo Rajesh Kumar Katkoori
      Rajesh Kumar Katkoori

      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.

      1. We are not getting the same Response message after Job creation as shown in Video and getting different message( even is job creation failed )
      2. We could not overwrite this response message to custom message. This is for Create/Delete job Could you please help on how to achieve this requirement?

      Regards,

      Rajesh

      Author's profile photo Philip MUGGLESTONE
      Philip MUGGLESTONE
      Blog Post Author

      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