Technical Articles
Using Job Scheduler in SAP Cloud Platform [1]: First simple scenario
This series of blogs intends to show in an easy step-by-step way how to use the Job Scheduler service in SAP Cloud Platform
Quicklinks:
Intro Blog
Project Files
Overview
In this first blog, we’re going to go through a sample scenario to cover the basic steps
It is meant to be executed by anybody
Really, no coding skills are required
Scenario
We’re creating a small Node.js application which starts an express server
This little app does nothing more than exposing a REST endpoint
When this endpoint is invoked, it writes a log and returns a string
The only reason for being: it can be invoked automatically by Job Scheduler
As such, the second small thing we’re creating is a little Job in Job Scheduler dashboard
The only reason for being: Job invokes the REST endpoint of our small Node.js app
The scenario is meant to be executed on a Trial account of SAP Cloud Platform
(There’s only small difference in productive environment, please refer to next blog)
Steps
We’re going to cover the following steps:
* Create service instances
* Create sample app
* Use Job Scheduler Dashboard to define job and view result
Although the scenario is pretty simple, let’s have a look at the involved components:
Explanation:
Our app is bound against the 2 service instances
Our app exposes a REST endpoint, whose URL is used by the Job (when created in the Dashboard)
We assume that our app contains any application logic (although it isn’t true in this sample)
Note:
Since our current scenario is designed for Trial account, there’s no OAuth flow required/supported
Prerequisites
We’re creating a Node.js application so Node.js must be installed on your machine (see appendix for installation info)
The Cloud Foundry Command Line Client is not mandatory, but it makes life easier (see appendix for installation info)
Preparation
Create instance of Job Scheduler service
Follow the description in the Intro-Blog to create an instance with name jobschedulerinstance
Create instance of XSUAA service
In the Service Marketplace, find tile “Authorization & Trust Management” and create instance:
Service plan: “broker”
Parameters: leave empty
Instance Name: xsuaaforsimplejobs
Create application
Now we can create our app
This app will be triggered by Job Scheduler
For this example, we’re using Node.js, it is the easiest way of exposing an endpoint
We’re dealing with only 3 files, so let’s start
Create project files and folders
This is the project structure we want to create:
To start, let’s create the project root folder:
C:\tmp
manifest.yml
Inside the root folder, create a file called manifest.yml and paste the following content:
(Make sure to change the name to any unique name)
---
applications:
- name: jobapp
path: app
memory: 128M
buildpacks:
- nodejs_buildpack
services:
- xsuaaforsimplejobs
- jobschedulerinstance
Explanation:
Apart from the usual descriptor info, it contains the references to the 2 service instances created earlier.
Make sure to adapt the service names match the names of your instances
Also, you might need to adapt the name of the app, if you get an error during deploy
Note:
the order of binding is relevant:
First bind XSUAA -> then JobScheduler
Again: remember: Binding: XSUAA first
In case you forget, don’t worry: during deployment, when binding JobScheduler instance, you’ll get an error, if JobScheduler doesn’t find an XSUAA binding
Nevertheless: don’t forget: bind XSUAA first
In case you tend to forget, you can use this (silly) mnemonic: “Bind xs-USA first again”
(sorry for that…)
At this point in time, we have the root folder and the manifest.yml file
Now create the application folder inside the root folder:
C:\tmp\app
Inside the app folder, create a file with name package.json
package.json
Paste below content into the package.json file
{
"main": "server.js",
"dependencies": {
"express": "^4.16.3"
}
}
Explanation:
The descriptor file for the Node.js runtime declares the dependency
and also it states which javascript file should be executed upon startup of the app
server.js
In the same app folder, next to package.json, create a file with name server.js
This is the executable program
const express = require('express');
const app = express();
app.get('/runjob', function(req, res){
console.log('==> [APP JOB LOG] Job is running . . .');
res.send('Finished job');
});
const port = process.env.PORT || 3000;
app.listen(port, function(){
console.log('listening');
})
Explanation:
When this little program is executed, it starts a little server (using the express module)
It also defines an endpoint “runjob”.
When this endpoint is invoked by an HTTP GET request, then the above code is executed
This is all we want to demonstrate in this blog:
A sample app with REST endpoint to be triggered by Job Scheduler
Deploy
To build the application, open command prompt, navigate to the app folder C:\tmp\app
then execute npm install
To deploy the application, after successful build, navigate to the root folder C:\tmp
and execute cf push
(see appendix if you don’t like the command line)
During deployment, you can observe how
First the XSUAA service is bound
Afterwards the Jobscheduler service is bound
After deploy, we can test our endpoint:
Get the app URL from command prompt (or from app details in the cockpit)
And append the endpoint segment
Then invoke in browser
In my example:
https://jobapp.cfapps.eu10.hana.ondemand.com/runjob
As a result, the browser window should print the text as coded in our little app
That’s it.
We’re done with the first part
Next part is to work with Job Scheduler
Job Scheduler
Our little app is meant to simulate a productive application
After successful deployment, we can now learn how to use Job Scheduler
Open Dashboard
To open the dashboard, go to your subaccount -> space -> “Service Instances”
Find the instance created above (name jobschedulerinstance) and press the icon “Open Dashboard”
Note:
To open the dashboard you might need to enter your cloud user credentials
Note:
In case you face problems with display of Job Scheduler Dashboard:
Are you using old Microsoft browser?
Background:
Newer UI5 versions (from 1.88) don’t support the legacy browsers IE11 and Edge Legacy (Edge HTML) anymore (more info)
To solve the problem, you should use modern browser
Create Job
First thing we do – after enjoying the beautiful UI – is to create a job
Hence, click on “Jobs” on the left hand menu
Then click the button “create Job”
In the creation dialog, specify the required information
Explanation:
Name:
A name of your choice, so you can find the job later in the list
Description:
The usual description
Target Application:
you might have bound many apps to the JobScheduler, so now you have to choose the desired one
Action:
here the full URL of the endpoint has to be entered. That’s the URL we’ve tried above, the app’s root URL and appended the endpoint segment
In my example:
https://jobapp.cfapps.eu10.hana.ondemand.com/runjob
HTTP Method:
This depends on how you’ve implemented your endpoint.
in our example, it is a simple GET request (remember, we wrote app.get)
Start Time / End Time:
This is not the schedule, this is the duration for the created job
You can leave it empty
Activate:
Should be a YES, we want to let it run
After pressing save, the Job is added to the list
But it is marked with a warning, which is a polite hint to tell us:
This job is useless, as long as we don’t define a Schedule
Create Schedule
Click on the Job name
Then click on “Schedules” on the left Menu
Press “Create Schedule”
In the dialog, enter some meaningful values
In my example:
To keep the example short, I’ve configured to run just one time in the near future
This dialog looks self-explaining, however, there’s one little possible pitfall
Explanation:
Description:
No explanation required
Pattern:
Basically 2 choices: run once + run repeatedly
For the second option, there are a couple of possibilities
In our example, we choose the simplest configuration
Value:
This refers to the chosen pattern.
Pressing the icon on the right side of the field opens the help page, which is indeed helpful
In our simple example we enter the text “in 10 seconds”
Start Time (UTC):
This entry makes rather sense in conjunction with recurring pattern, however:
Important: if you don’t enter a value here, I assume that the dialog enters the current time as default
But, the current time in my time zone is not the current time in the cloud.
Luckily, the Dialog has stated the relevant time zone in the label: it is UTC
As such, if you’re not located in UTC, like me, you have to adapt the current time, proposed by the dialog, to the current time in UTC
Otherwise, the scheduled job won’t start as expected
Bottom line: you might always need to enter a value here
End Time (UTC):
Same like above
Data:
This is relevant for REST endpoints which are executed viy POST request and expect a request payload
After pressing Save, the countdown starts and we have to hurry to view the result
View Result
First we see the created schedule is active
Click on the Description (link) Then Run logs
We see status SCHEDULED/SCHEDULED
We might need to refresh the browser window
After the job has finished, we see the green status COMPLETED/SUCCESS
View Run Log
Click the spectacles icon to open a dialog containing the details of the execution
Check:
List of Schedules: we can see: our created schedule is red and inactive
List of Jobs, to realize that the warning has gone
Note:
Although the job run is finished, the status of the Job itself doesn’t change as long as the jobs “active” period is not over
Want negative test?
Above job run has shown the happy path, it completed with green success status
To view a red result, we can either change the code of our app, or follow these easy steps:
Stop your deployed app (cockpit or command line via cf stop jobapp)
Then create a schedule to run once (or just re-activate the existing schedule) and see the result as red status COMPLETED/ERROR
Run Log shows the HTTP response of the call to a non-existing endpoint
Summary
In this blog we’ve learnt the basics about SAP Cloud Platform Job Scheduler
1) We’ve created an application, to simulate a real-world app
The app exposes a REST endpoint
The app is bound to Jobscheduler and xsuaa services
2) We’ve create a Job and Schedule which invokes that endpoint
Remember: Order of Binding
First bind XSUAA
——>
then JobScheduler
With other words: “Bind XS-USA first again”
Next Steps
Example in productive landscape with security: next blog
Explain flow with existing app and service instances, to keep the correct order and avoid errors
Links
See Intro-Blog
Appendix 1: Install Node.js
Go to the Node.js homepage, download the stable release (“Recommended for most users”) and follow the installation instructions,
You might need to restart your computer
After installation, you can verify if Node.js is up and running:
Open a command prompt and type: <span style=”color: #0000ff; font-family: Courier New;”>node -v</span>
It should respond with a version information and no error message
Appendix 2: Install CLI
Installation of Cloud Foundry CLI, the official command line client for Cloud Foundry is simple and no cryptic configuration required
Just
Download -> Unzip -> Install
Download the zip from here: https://github.com/cloudfoundry/cli#downloads
I would choose the installer. Direct link
After download, unzip it.
Right click the installer.exe file and choose “Run as administrator”
That’s it.
The installer installs the binary file to C:\Program Files\Cloud Foundry
If you look into that directory, you’ll see a cf.exe file.
This is “THE TOOL”
Verify the installation:
Open your command shell and type cf , then press enter
As a result, the version of “Cloud Foundry command line tool” is printed, along with the usual usage instructions
Note:
In case of proxy issues, see http://docs.cloudfoundry.org/cf-cli/http-proxy.html
Note:
I’ve copied from this great blog, there are useful examples for beginners
How to login to Cloud Foundry
cf login -a <api> -u <user> -p <pwd> -o <org> -s <space>
Example:
cf login -a api.cf.eu10.hana.ondemand.com -u usr@mail.com -p abc -o P123trial -s dev
From where do I get the info?
In the cockpit, navigate to the your subaccount and see:
Appendix 3: All Project Files
In this appendix you can find all files required to run the described sample application.
For your convenience, see here again the folder structure:
Find below the content of all 3 requried files
manifest.yml
Don’t forget to adapt the name and the service instances
---
applications:
# make sure to adapt the name to a unique name, otherwise deploy might fail
- name: jobapp
path: app
memory: 128M
buildpacks:
- nodejs_buildpack
services:
- xsuaaforsimplejobs
- jobschedulerinstance
package.json
{
"main": "server.js",
"dependencies": {
"express": "^4.16.3"
}
}
server.js
const express = require('express');
const app = express();
app.get('/runjob', function(req, res){
console.log('==> [APP JOB LOG] Job is running . . .');
res.send('Finished job');
});
const port = process.env.PORT || 3000;
app.listen(port, function(){
console.log('Server is running');
})
Appendix 4: Deploy
For the sake of completeness, in case you aren’t familiar, find below 2 ways of deploying an app to SAP Cloud Platform Cloud Foundry Environment
Using the Cloud Cockpit
If you don’t want to install the CLI, you can use the Cockpit, which offers a user interface for deployment of local applications
Prerequisite:
You need to have a zip file with the application on root level.
I mean, the zip doesn’t contain a folder which contains the app.
The app must be directly zipped
The manifest.yml file is located on file system, not in the zip
Go to your subaccount and space and click on Applications in the left menu
On top of the list of applications, there’s the “Deploy” button
Press the button.
In the “Deploy Application” dialog, enter the path to the zip file and to the manifest.yml file
After deploy, click on the app-name-link to go into the application details screen
There, you can see the “Logs” menu entry on the left side, which allows access to the application log
Using the CLI
Using the command line client dis recommended, as it is faster (and you’ll anyways need it, once you have to update a service)
Deploy:
Use cf push if you have manifest.yml file and it is at the same level as your command prompt
Logs:
To stream the logs: cf logs my App
Otherwise cf logs my App –recent
Hi, Thks for this blog !
I would like to schedule a flowgraph execution with the job scheduler (flowgraph developped in Web IDE).
Is it possible ?
Thks per advance
Maxime
Hi MAXIME RIOLAND ,
I wish to do the same thing. Did you manage to schedule your flowgragh? It would be really helpful if you could share your solution.
Regards,
Sanket
Hi Maxime,
The basic dynamics behind job scheduler is restfull api. I will propose 2 solution to this
1: use the SAP HANA SDI restful api for task scheduling
2: create your own small xsjs based app in web ide which includes your flowgraphs , and then bond the hana job scheduler api . You can bind also uaa on top to have authorization enabled.
Hope that helps
Mihir
Hello Mihir,
do you know if we can use option 1 (1: use the SAP HANA SDI restful api for task scheduling) in SAP Cloud Foundry?
thanks and regards
Mariele
Hello Mihir,
Could you please attach a code for the .xsjs file?
I struggle with the syntaxis and always shows error.
Thanks!
Hello Carlos,
thanks for this blog post (and for many others I read, while trying to get a handle on Cloud Foundry development).
I saw that you had planned to do more parts of it, unfortunately it didn't materialize yet. I'm currently working on a MTA (with Java service module) and I'd like to leverage CAP and Cloud SDK as much as possible, so it seems like that the following parts would have been perfect for me 😉
Nevertheless, from what I learned in CAP so far and what I read here, I feel pretty confident, it can be accomplished with a service definition with action/function(?) and some event handlers.
BR
Hello Daniel Gent ,
Thanks so much, I'm very glad that those writings are a bit useful...! 😉
I think you can write a direct message to discuss your questions
Cheers,
Carlos
Sorry to reply on an old message, but I am also interested in this cause I'm migrating some xsjs from a client and want to call the functions within those as the old job scheduler on HANA does before.
Is it possible or I need an endpoint for each function or at least a parameter to pass trough the request to identify the specific function to run?
Thanks and excellent blog by the way.
Thx Carlos Roggan for this blog post.
Simple & usefull.
I was wondering how I can execute anykind of REST Endpoint via this service. For example: a FaaS trigger, a EMS trigger, whatever...
Without having any application bound to the job-scheduler I wasn't able to create one job. After deploying your light-example, I changed the "Action" to a complete other endpoint like my FaaS service. This was working fine 🙂
So in a nutshell:
If you wanna use the job-schedule service for anykind of REST endpoint, deploy anykind of app and bind it to the job-schedule service. You can insert any action as you wish.
In a multiscale environment like Cloud Foundry, I guess this would be no big change to have this ability without an deployed app .... *wink to product-design*
Thx Carlos, regards to your cats,
Cedric
Hi Cedric Heisel ,
Thanks for your comment – probably one of the coolest comments I’ve ever seen ?
and worth a special award…*wink to community-team*
?
And thanks for your efforts to find that workaround – probably it is possible because JS (JobSched) cannot know anything about URLs / routes of endpoints of bound apps
I guess you’re right and I agree that it would make sense to enhance JS to become a more universal and also lightweight tool
Nevertheless, in productive scenarios, REST endpoints are usually protected with OAuth (even in FaaS it makes sense, and also the EMS REST endpoints are protected)
And here JS shows its strength:
JS automatically supports OAuth-Flow, including foreign scopes
Thanks Cedric and keep sending feedback!
Cheers,
Carlos + (hungry) Cat … *wink to shopping cart*
Hi Cedric,
I still did not get whats the point in creating a dummy app in CF and use a different url in Action.
Can i use any 3rd party endpoint in action ?
Thanks,
Akash
Hi Akash S,
you need this "dummy app" as the job-scheduler is requiring you to select an application. This does make sense as the architecture of this service is based on oAuth-xsuaa-authentification out of the box. But in my case, who I want to call something else and not an xsuaa protected application, like and service url instead, this is necessary to enter the url.
Regards,
Cedric
Hi Cedric,
Thanks, so if I want to call a 3rd party API end-point which is protected, I need to call this inside the app which is bind to job scheduler instance?
Thanks,
Akash
Hi,
No, you don't. This App we're talking about is just a dummy that you can select an application while creating a new job-scheduler.
Go ahead and try this without the application. You will find a drop-down in the job-scheduler, who is holding you back 😉
I just checked, in Action field I provided the 3rd party API but I got failed because of authentication.
How can I provide the authentication details?
Thanks,
Akash
Hi Carlos Roggan ,
How can we schedule SAP IRPA Cloud studio bots using job schedule service.
And how we deploy the cloud studio bot in SAP BTP.
Any info on this is very helpful.
Thanks,
Rajasekhar
Hi,
Ive tried to get your email address but im unable to find it.
Can you perhaps mail me as i too am trying to figure out how to call a flowgraph within the Job Scheduler.
Thanks,
naren.gokal@bcx.co.za