Skip to Content
Technical Articles
Author's profile photo Andrew Lunde

SAP Cloud Platform Job Scheduler service, I’ll get to that later.

If you’ve ever wanted to get something done but not right away, or you wanted something done over and over without having to remember to do it(hint, see my next blog post), or you started doing something and it took so long that you forgot you were even doing it, then the SAP Cloud Platform Job Scheduler service is what you’re looking for.

This blog post introduces a sample project originally conceived to fill a feature gap in the SAP Cloud Platform Continuous Integration and Delivery service.  If you’re looking for a way trigger builds on a schedule, then STOP reading here and go check the latest version of that product since scheduled builds are an upcoming feature and may be implemented by the time you’re reading this.

If you’re still reading then I’ll assume you’re actually interested in the mundane topic of job scheduling.  I’ve created a fully functional Node.js code sample that I’ll be going over in this blog post.   The project is structured as a Multi-Target Application(MTA) so it can be deployed in SAP Cloud Platform Multicloud(Cloud Foundry) or to an on-premise HANA XS-Advanced system.  Here I’ll focus on the Cloud Foundry approach, but it has been tested on HANA Rev45 and HANA Express.



Let’s continue.

Carlos Roggan wrote a nice series of blog posts on the job scheduler last year at Using Job Scheduler in SAP Cloud Platform .

He did a good job of explaining what’s going underneath the covers so I’ll focus primarily on the sample code usage.

Setting Up


Go your your SAP Cloud Platform account(productive/trial) and subscribe to the Business Application Studio if you haven’t already.  Don’t forget to assign your user the proper Business_Application_Studio_?? Role Collections.

Click on the Go to Application link on the SAP Business Application Studio tile.

Create a new Dev Space.  This is how I did it.

Open a new Terminal and git clone the sample code project into the projects folder.

git clone

Change into the project folder you just cloned.

cd mta-job-scheduler

Expand the files in the project and notice a file called  We are going to build the project manually and deploy it manually so that we can better control the process.  This file has the needed commands for handy reference.  Open it in Preview mode.

Now you can cut/paste with wild abandon!

Build It Right


If you haven’t already done a build, create the mta_archives folder.  Now build the mtar file.

mbt build -p=cf -t=mta_archives --mtar=job-sched-cf.mtar

Because we want to be able to deploy this same project into XSA and due to some caveats with the xs deploy command, we want to override some settings in the mta.yaml file.  We do this by deploying with an mtaext file.  Run this command at the prompt.

cf deploy mta_archives/job-sched-cf.mtar -f -e deploy_cf_ded.mtaext

If all goes well, the project should deploy to completion.

Make It Yours


Get the name your application was assigned.  We need it in the next steps.

cf app job-sched-app | grep routes

Mine looks like this.  You’ll have to substitute yours in the subsequent steps.

We could either set this value in the mta.yaml file(look for JOB_SCHED) or just set it in the environment.  I’ll do the latter for now.  This way you don’t have to redeploy everything.


cf set-env job-sched-srv JOB_SCHED_APP_URL ''
cf restage job-sched-srv



Now go to the job-scheduler application in the browser.

Click on the /util/ link.  Links under this path do not require authorization and so they can be triggered by the job scheduler process.

Click on the Test trigger link.  The path to this link is formed by the JOB_SCHED_APP_URL value we set above, so if all works right we should see a date.

Awesome!  This is what the job scheduler will do for us on or behalf once we create a job for it to do so.

Aside:  By now you’ve probably noticed that my sample code is a bit thin on UI fanciness.  This is because I wanted to show the bare bones of interactions with the job scheduler without any UI distractions.  You will want to build your own interfaced into your application depending on your needs and I wanted to make it easy to cut/paste/refactor code from this sample.  Also, the nature of the job scheduler is largely behind the scenes.  In fact you can’t see everything that’s going on in the browser, so let’s go back to the Business Application Studio and watch the logs.

Behind The Curtain


cf logs job-sched-srv

There is quite a bit of debug logging turned on.  You can turn it off by commenting out this line in the mta.yaml file.

#NODE_DEBUG: 'scheduler'

Go back to the app in the browser and this time pick the /sched/ link.

Accessing this page requires authorization, but since we’re likely already logged in, you probably won’t get prompted.  Scroll down to the bottom and click on date_in_1_min.  These example links will take some parameters on the the query line but you may need to edit the code to fit them to your purpose.

You should see this in the browser.

Notice that the action is our application url and the startTime is 1 minute in the future.

Flip over to the studio and watch the output of the cf logs command issued earlier.

You should see the following once 1 minute has expired.

We can click on the get_all_jobs link on the /sched/ page and now see that there is a job definition returned.

We can also go to the Job Scheduler Dashboard and confirm the same thing.  These are different views of the same underlying data.  Get the dashboard URL with the following.

cf service JOB-SCHED_SCH | grep dashboard

Clean Up


You can delete the job here or explore it’s schedules and job runs.  I’ve created links for all the library calls that the Node.js library provides.  Also, in the results of the get_all_jobs link, I’ve included links to get the schedules and delete the jobs.  Just click the deleteURL for easy cleanup.

Warning: Be sure to delete all jobs before attempting to undeploy the application.

There is a lot more to cover, but I’ve tried to make exploring the various features easy with links and returning the json results in the browser.  Make sure you have a JSON plugin installed in your browser that formats the JSON in a readable way.  The links demonstrate passing arguments to the various functions and how the callbacks are managed.  Currently the library doesn’t support promises so things could get deep if you’re chaining a bunch of calls together.

I’m going to stop here at this simple use.  Take a look at the create_job link to see how a recurring job is specified.  The project repo has links to all the relevant documentation.

In a follow up blog post, I’ll discuss recurring jobs and use them to trigger a Jenkins style webhook.

Let me know if you have and questions or issues by leaving me a question below or better yet, asking it on the SAP community.


Partners: If you have a question, click here to ask it in the SAP Community . Be sure to tag it with Partnership and leave your company name in the question so that we can better assist you.


Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Carlos Roggan
      Carlos Roggan

      Hi Andrew Lunde !
      Nice blog and good sample and thanks for your mention 😉
      Cheers, Carlos

      Author's profile photo Matthias Thoma
      Matthias Thoma

      Hello Andrew

      What was your solution when "(...) you wanted something done over and over without having to remember to do it" and something goes wrong? The one killer feature I am missing is an alerting / montoring solution (other than writing it by myself using the REST APIs or doing some analysis on the logs) e.g. an integration into the alerting serving on cloud platform?


      Author's profile photo Andrew Lunde
      Andrew Lunde
      Blog Post Author

      Hey Matthias,

      That part of my intro was a tease for a follow on blog post.  I wanted to test that code a bit more before releasing in into the wild.  If you have an immediate need for long-running jobs, let me know and I'll try to get it out quicker.


      Author's profile photo Andrew Lunde
      Andrew Lunde
      Blog Post Author

      Author's profile photo Cedric Heisel
      Cedric Heisel

      That’s exactly that what I wanted to ask Carlos Roggan for. I checked the API - yes, there would be a way. But let’s be honest:

      setting up a node.js application who is checking the API for crashes jobs, setting up a job for this app, isn’t so convenient.
      At the end the job-scheduler is the issue and will not call the node app who should notify me if a job wasn’t working.

      this could be something for product development again ...? 🙂

      Author's profile photo Andrew Lunde
      Andrew Lunde
      Blog Post Author

      Following up with the next post that explains recurring schedules and webhooks.




      Author's profile photo Mansour Ilyes
      Mansour Ilyes

      First thank you for creating this blog and also the blog about Multi-tenancyin CAP .

      But the job scheduler in that way will not work in Multi-tenancy context,

      as the job need to be tenant aware and to be able to achieve this the 'standard' plan of the job service is mandatory,

      which is not available in trial version of SCP. (we need also to implement the getDependency and use user-token grant using the job xsuaa itself -> in trial only basic authentification is available).

      - the second case : using the app url as action when creating the job will not execute the job but we will have a kind of redirection to a login page.

      something like this :

      This result is normal, we use passport and trust ACL srv side, the app still protected (and may require user roles also).


      -> if in context of maintenance you create job which is not tenant aware, and the job is destined to do db queries, you will get an error something like => instance.credentials are missing for tenantId: uaa

      this is normal because the identityZone which is in runtime eq to the tenantID but in our case it is equal to uaa as default ( = the job identityZone itself) :

      So to summarize, if you have to work in trial mode, forget the idea to create a job scheduler which is tenant aware.

      Please correct if am wrong ^^.