Skip to Content

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

To report this post you need to login first.

7 Comments

You must be Logged on to comment or reply to a post.

  1. 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

    (0) 
    1. Philip Mugglestone 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

      (0) 
  2. Former Member

    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

    (0) 
  3. 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?
    (0) 

Leave a Reply