Skip to Content
Technical Articles
Author's profile photo Apurva Sahay

Customized Scheduling for integrations in SAP Cloud Integration

Start Timer is the mechanism for self-triggered integrations in SAP Cloud Integration. With its many inbuilt configurations, there still are scenarios that the present offers fails to provide. This blog utilizes the power of Scripts and Router in demonstrating how custom schedule configurations can be accomplished in a simple way.

How?

“Execute on last day of every month” is once such trigger scenario which we will achieve using a combination of JavaScript step and a Router step. The scenario is quite simple where a reminder mail should be sent to a user on last day of every month.

Let’s model this scenario step by step as follows:

  1. Drag and Drop a Start Timer step into the Integration Process.
  1. Configure it to run Daily (as our scenario is having date as the filtering parameter).
  2. Put a Script step in the Integration Process and connect Timer to Script (Here we are using JavaScript but either of the two i.e., JavaScript or GroovyScript can be used whichever the user is comfortable with).
    importClass(com.sap.gateway.ip.core.customdev.util.Message);
    importClass(java.util.HashMap);
    
    /**
     * [Default Generated Function]
     * @param  {[object]} message [The message being transferred]
     */
    function processData(message) {
        var dateObj = new Date();
        var currentDate = dateObj.getDate();
        if (dateObj && currentDate === getLastDateOfTheMonth(dateObj.getMonth(), dateObj.getYear())) {
            return getMessage(message, true);
        }
        return getMessage(message, false);    
    }
    
    /**
     * [Get message to be passed on from script step]
     * @param  {[object]}  message [The message being transferred]
     * @param  {[boolean]} custom  [Specifes if the day is the Last day or not]
     */
    function getMessage(message, custom) {
        //body
        var body = message.getBody();
        message.setBody(body + " modified from js");
        //headers  
        var map = message.getHeaders();
        var value = map.get("oldHeader");
        message.setHeader("oldHeader", value + "modified");
        message.setHeader("newHeader", "newHeader");
                   //properties 
        map = message.getProperties();
        value = map.get("oldProperty");
        message.setProperty("oldProperty", value + "modified");
        message.setProperty("newProperty", "newProperty");
        if(!custom) {
          message.setProperty("execute", custom);
        }
        return message;
    }
    
    function getLastDateOfTheMonth(month, year) {
        var d = new Date(year, (month + 1), 0);
        return d.getDate();
    }​
  3. Modify the existing script to add a header/property by the name “execute” (any name can be given here) with value “false” (again this can have any value that you would like to use as truth value) when the current day is not the last day of the month. Don not set any header/property in case the current day is last day of the month. The code implementation depends on the user. For reference purpose the following JavaScript snippet can be used.
  4. Save the Script and now add a Router step to the flow and connect the Script step to the Router.
  5. The Router will have two outgoing branches:
    • First branch will be the default branch and name it some interpretable name (we are using “Execute”).
    • For the Second branch provide some interpretable name (we are using “DoNotExecute”) and configure ‘Expression Type’ as ‘Non-XML’ and provide the condition as “${property.execute} = ‘false’” or “${header.execute} = ‘false’”  (depending on whichever you have used in Script with correct name).
  6. Connect the “DoNotExecute” branch to an End Message step.
  7. Connect the “Execute” branch to the process you want to execute on Last Day of Every Month. (A process call can be used to call another Integration process containing the actual logic to be implemented). Here we connect it to and End Message which is connected to a Receiver via Mail Adapter as we need to send the mail on Last Day of Every Month. Sample overview of the scenario is as shown below.
  8. Save the scenario and deploy it.

The above example can be followed and modified by the users as per requirement to achieve new custom trigger configurations.

On similar lines, I tried a few more scenarios that came to my mind which involve and are listed below:

S. No. Scenario Code Snippet
1. Run every even week in a month.
function runEveryEvenWeekInAMonth(message) {
    var dateObj = new Date();
    if(getWeekNumberForTheMonth(dateObj)%2 !== 0) {
        return processData(message, true);
    }
    return processData(message, false);
}

function getWeekNumberForTheMonth(dateObj) {
    var date = dateObj.getDate();
    var day = dateObj.getDay();
    return Math.ceil((date - 1 - day) / 7); 
}
2. Run every odd week in a month.
function runEveryOddWeekInAMonth(message) {
    var dateObj = new Date();
    if(getWeekNumberForTheMonth(dateObj)%2 === 0) {
        return processData(message, true);
    }
    return processData(message, false);
}

function getWeekNumberForTheMonth(dateObj) {
    var date = dateObj.getDate();
    var day = dateObj.getDay();
    return Math.ceil((date - 1 - day) / 7); 
}​
3. Run on 45th minute of every hour.
function runEvery45thMinuteOfAnHour(message) {
	var dateObj = new Date();
	if((dateObj.getMinutes()%45) === 0) {
		return true;
	} else {
		return false;
	}
}
4. Run on Weekends.
function runOnWeekends(message) {
	var dateObj = new Date();
	var day = dateObj.getDay();
	if(day === 0 || day === 6) {
		return true;
	} else {
		return false;
	} 
}
5. Run on Weekdays.
function runOnWeekdays(message) {
	var dateObj = new Date();
	var day = dateObj.getDay();
	if(day !== 0 && day !== 6) {
		return true;
	} else {
		return false;
	} 
}
6. Run on Last Weekday of the Month
function getLastWeekdayOfTheMonth(year, month) {
	var dateObj = new Date(year, (month + 1), 0);
	var day = dateObj.getDay();
	if (day > 0 && day < 6) {
		return dateObj;
	} else {
		if (day === 6) {
			return dateObj.setDate(dateObj.getDate() - 1);
		} else {
			return dateObj.setDate(dateObj.getDate() - 2);
		}
	}
}

 

Therefore, by using a combination of Scheduler, a Script and a Router we can easily achieve trigger scenarios which are otherwise not possible to achieve via using Scheduler only.

Assigned Tags

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

      awesome. thank you Apurva Sahay. Good Information

      Author's profile photo Apurva Sahay
      Apurva Sahay
      Blog Post Author

      Hi Praveen,

       

      Thank you for your kind words

      Author's profile photo Maximiliano Colman
      Maximiliano Colman

      Hi,

      Please correct the logic for:

       

      Run on Weekdays.
      function runOnWeekdays(message) {
      	var dateObj = new Date();
      	var day = dateObj.getDay();
      	if(day !== 0 && day !== 6) {
      		return true;
      	} else {
      		return false;
      	} 
      }

       

      😉

      Author's profile photo Apurva Sahay
      Apurva Sahay
      Blog Post Author

      Hi Maximiliano,

       

      Thanks for the suggestion. The logic is rectified now.

      Author's profile photo Murugavel Singaravel
      Murugavel Singaravel

      Hi Apurva Apurva Sahay ,

      Thanks a lot for sharing the information. I have a requirement same as this but there are times were we want to run the package manually like middle of the month based on user request. How that can be handled with this routing logic setup ?

      thanks and regards,

      Murugavel

      Author's profile photo Hemachandan A S
      Hemachandan A S

      Murugavel Singaravel  - We can externalize the parameters used in the above scripts so that we can deploy the iFlow by changing these values according to ad-hoc request timestamp.

      Author's profile photo Murugavel Singaravel
      Murugavel Singaravel

      Thanks a lot Hemachandan, it worked ....

      Author's profile photo Sunny Sumiati
      Sunny Sumiati

      Hi Apurna, thank you for sharing.

      My requirement is to run the iflow:

      -every 10 min between 06:00 am - 08:00 am in time zone UTC+10

      -every hour between 08:00 am - 06:am in time zone UTC+10

      Hence 2 intervals within a day.

      Is this achievable using the script? Otherwise I can only think of copying the iFlow for the second schedule.

      Thank you for any suggestion.

       

       

      Author's profile photo Apurva Sahay
      Apurva Sahay
      Blog Post Author

      Hi Sunny,

       

      There are multiple ways to achieve this behavior.

      You can put your main integration logic in a local integration process which will be called only when the condition in the scripts is satisfied.

      Also could you please clarify if the second schedule "Execute every hour between 08:00 am - 06:am in time zone UTC+10" is every hour between 08:00 am and 06:00 pm or 06:00 am next day ?

       

      Thanks

      Author's profile photo Ezhilkumar Asaithambi
      Ezhilkumar Asaithambi

      Hi Apurva,

      Thanks much for sharing the information!

      I have a requirement to schedule it once on quarterly basis on a particular day of every Quarter. How this can be handled.

      Thanks,

      Ezhil.

      Author's profile photo Apurva Sahay
      Apurva Sahay
      Blog Post Author

      Hi Ezhil,

       

      You can configure the scheduler to run Monthly and in the script you can check the current month and if it is the quarter month you can return "execute" as true else it will be false.

       

      Hope this helps.

       

       

      Author's profile photo Debashis Mohanty
      Debashis Mohanty

      Hi Apurva,

      We have requirement to run the iflow daily at 6 PM IST from Monday - Saturday, and at 5:15 PM IST only on Sundays.

      Can you please suggest the best way to achieve this ?

      Regards,

      Debashis

      Author's profile photo Apurva Sahay
      Apurva Sahay
      Blog Post Author

      Hi Debashis,

       

      I see that you need two different schedules altogether for your case:

      • Run at 6PM IST Monday-Saturday

             

      • Run at 5:15 PM IST on Sunday

       

      There are two possible approaches to achieve this:

      Approach 1:

      1. Create one integration flow with your actual logic and expose it using a HTTP Sender or Process Direct Sender.
      2. Create two timer based integration flows with the above shown configurations which will invoke your master integration created in step 1.

      Approach 2:

      1. You can configure your scheduler to trigger your scenario every 5 min from 17:00 to 19:00 Hrs daily.
      2. Use the script router combination as shown in the blog with script setting the execute property true only when the current time satisfies your requirement.

      Both approaches should solve your problem. You can pick whichever suits your case.

       

      Regards,

      Apurva

      Author's profile photo Poushali Bhandari
      Poushali Bhandari

      Hi Apurva Sahay,

      Thank you for sharing. We have a requirement to run the iflow :

      Monday – 7AM, 8AM, 9AM, 10AM, 11AM, 12PM and 4PM

      Tuesday to Sunday – 7AM.

      Can you please help how to handle this.

      Thanks & Regards,

      Poushali Bhandari

      Author's profile photo Apurva Sahay
      Apurva Sahay
      Blog Post Author

      Hi Poushali,

      Using the Script-Router combination you can achieve this as follow:

      1. Configure your scheduler to trigger your scenario every 1 Hr from 7 AM to 5 PM daily.
      2. Use the script to set the "execute" property true only when the current time satisfies your requirement.

      Regards,

      Apurva

      Author's profile photo Chethan Kumar
      Chethan Kumar

      Hi Apurva,

      Thanks for this useful info.

      I have a requirement where the interface should execute at the 30th Minute.  In CPI, currently we don't have 30 min interval option.

      If we choose to run the interface every hour, the first execution happens at 00:00. Instead of this it should run 00:30, 01:30, 02:30 so on.. Could you please let me know if this can be achieved.

       

      First%20Run%20of%20the%20interface%20should%20happen%20at%200030%20instead%20of%200000%20We%20do%20not%20have%20a%20standard%20option%20in%20CPI%20for%20this.

      First Run of the interface should happen at 0030 instead of 0000 We do not have a standard option in CPI for this.

      Author's profile photo Apurva Sahay
      Apurva Sahay
      Blog Post Author

      Hi Chethan,

       

      From your question I understand that you want to configure the start time of the scheduler in your interface to 00:30 and then run every 1 Hr i.e., 00:30, 01:30, 02:30, 03:30 and so on.

      It is possible to achieve this with Script-Router combination as follows:

      1. Configure your scheduler to trigger every 30 mins for the required duration.
      2. In the script you need to check if the minutes component in the current time object is 30 as shown below.
        function runEvery30thMinuteOfAnHour(message) {
        	var dateObj = new Date();
                return (dateObj.getMinutes() === 30);
        }​

      This should give you the desired trigger pattern.

       

      Regards,

      Apurva

      Author's profile photo Sahaj Shetty
      Sahaj Shetty

      Hi Apurva,

      We have a requirement where we need to trigger Purchase Order Details (Create, Update or Delete) to a thirdy party via REST APIs, they want CPI to initiate the call for triggering the data from the S/4 HANA system is this achievable using the Timer Functionality.

      Appreciate your help.

      Regards,

      Sahaj

      Author's profile photo Apurva Sahay
      Apurva Sahay
      Blog Post Author

      Hi Sahaj,

      If I understand your use case correctly you want to use a timer triggered scenario which fetches data from S/4 HANA and sends it to a third party REST API. This can be easily done in SAP Cloud Integration.

      For sending data to third party REST APIs you can use the HTTPS Receiver Adapter and for fetching data from S/4 HANA system you can use a request reply with the respective receiver adapter(based on the type of endpoint exposed by S/4 HANA system e.g., SOAP, HTTPS OData). You can configure and use the Timer step to schedule the triggering of this scenario. If you need a custom scheduling pattern you can follow the steps mentioned in this blog.

       

      Regards,

      Apurva

      Author's profile photo Sivachandran D
      Sivachandran D
      Hi Apurva,
      The requirement is to execute the queries to fetch the data from SuccessFactor, we do have four different queries (OData query). 2 queries have to execute every one hour and the rest of the 2 queries have to execute once a day and 12 AM CET.
      Appreciate your help !
      Thanks,
      Siva
      Author's profile photo Sunitha Mamidi
      Sunitha Mamidi

      Hi Apurva,

      We have a requirement to run the IFlow on 1st, 3rd , 5th Friday of the month.

      For Example in the Month of Dec, 2021 - The interface should run on 3rd,17th,31st.

      Can you please help on how to handle this scenario.

       

      Appreciate your help,

      Sunitha

      Author's profile photo MALASANI JAYAKANTH REDDY
      MALASANI JAYAKANTH REDDY

      Hi Apurva,

      I have a requirement to run my flow on every 4th Monday of the month.

      Im%20using%20this%20script%20still%20im%20getting%20error.if%20there%20are%20any%20changes%20please%20let%20me%20know

      I'm using this script still i'm getting error. if there are any changes please let me know

      Author's profile photo Rajat Kumar
      Rajat Kumar

      I have a requirement where i want my interface to run once a year on the first day of the year.

      Could you please share the groovy for the same ?

       

      Author's profile photo Akash Dutta
      Akash Dutta

      how i tested this iflow , i didn't get any endpoint url . but it is successfully deployed