Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
gopalanand
Product and Topic Expert
Product and Topic Expert
In the previous blog, we saw how to access data from a S/4HANA system using SAP Cloud SDK in a multitenant application.

In this blog, we will see how to schedule periodic jobs for each of the subscribing tenants to pull data periodically from the backend system and ensure data isolation for each tenant.

 

SAP Job Scheduling Service


SAP Job Scheduling service allows you to define and manage jobs that run once or on a recurring schedule. Use this runtime-agnostic service to schedule action endpoints in your application or long-running processes using Cloud Foundry tasks. Use REST APIs to schedule jobs, including long-running jobs asynchronously, and create multiple schedule formats for simple and complex recurring schedules. Manage jobs and tasks and manage schedules with a web-based user interface.


Implementation


We have admin-srv where the job scheduler is implemented. This microservice is responsible for Updating the application name to adapt to subscribing customers' names and logos.

 

Creating a Job :

Admin Service offers API where we can pass the job frequency, it then processes it and defines the job.
const JobSchedulerClient = require('@sap/jobs-client');
const xsenv = require('@sap/xsenv');

const jobSchedulerCreds = xsenv.serviceCredentials({ tag: 'jobscheduler' });
const jwt = require('../utility/jwt');

const createJob = async (req, logger) => {
try {
const subdomain = req.authInfo.getSubdomain();
const domain = `https://${subdomain}.${jobSchedulerCreds.uaa.uaadomain}`;
const token = await jwt(domain, jobSchedulerCreds);
const options = {
baseURL: `${jobSchedulerCreds.url}`,
token: token.accessToken,
};
const scheduler = new JobSchedulerClient.Scheduler(options);
// name field is where we are trying to generate a unique name for the job
const myJob = {
name: `${subdomain.split("-")[0] + new Date().getMilliseconds()}`,
description: "cron job that calls HTTP endpoint",
action: `${process.env.businessPartnerAPI}/api/v1/new/bp`,
// action: URL to the backend service which should be called periodically
active: true,
httpMethod: "GET",
schedules: [
{
cron: `* * * * * */${req.query.time} 0`,
// cron: frequency of job
description: `this schedule runs every ${req.query.time} minutes to fetch the tenant data and find new businesspartners`,
active: true,
startTime: {
date: `${new Date().toISOString().split('T')[0]} 00:00 +0000`,
format: "YYYY-MM-DD HH:mm Z",
},
},
],
};
const scJob = { job: myJob };

return new Promise((resolve, reject) => {
scheduler.createJob(scJob, (error, body) => {
if (error) {
logger.error('Error registering new job %s', error);
return reject(error);
}
return resolve(body);
});
});
} catch (schedulererr) {
logger.error(schedulererr);
throw new Error("Error While creating the job");
}
};

Getting Scheduled Jobs

This method returns a list of scheduled jobs for tenants ensuring data isolation for each of tenant.
const getJob = async (req, logger) => {
try {
const subdomain = req.authInfo.getSubdomain();
const domain = `https://${subdomain}.${jobSchedulerCreds.uaa.uaadomain}`;
const token = await jwt(domain, jobSchedulerCreds);
const options = {
baseURL: `${jobSchedulerCreds.url}`,
token: token.accessToken,
};
const scheduler = new JobSchedulerClient.Scheduler(options);
const data = {};
return new Promise((resolve, reject) => {
scheduler.fetchAllJobs(data, (err, result) => {
if (err) {
logger.error('Error retrieving jobs: %s', err);
return reject(err);
}
// Jobs retrieved successfully
logger.info(result)
return resolve(result);
});
});

} catch (errr) {
logger.error(errr);
throw errr;
}
};

 

Here's how it looks from the Admin dashboard


Scheduled Jobs from the job scheduler dashboard:


Conclusion:  Using re-use services like SAP Job scheduling service in a multitenant application helps in reducing the total cost of application ownership significantly. It is a powerful concept that makes the implementation easier.

Hope this blog series helped you in understanding how to implement a multitenant extension, and application using Nodejs as a programming language and Various service offering on Business Technology Platform.

Further Read:


Other multitenant applications and Missions: