In this
blog we will see how to run multiple Rules of Enterprise Profitability and Cost
Management (EPCM) using Groovy in Sequential and proceed with the next rule
only after completion the previous rule.
/**************************************************************************************/
/*
Run IC Calcs All Region
*/
/*
Creation Date : 10th Apr 2024 */
/* Version : 1.0 */
/* Modifications : */
/* The Rule uses the Sub Var &CurMth,
&CurYr. */
/* The Rule will be executing the following, */
/*
1. Clear for EMEA */
/* 2.
Clear for APAC */
/* 3.
Clear for Americas */
/*
4. Merge Slices */
/*
5. Run Ruleset Ranges: */
/* Start End */
/* 1 999 */
/**************************************************************************************/
connectionName is a variable that stores the name of the connection to the server. In this case, it's set to 'Localhost'. This variable is later used to specify which server to connect to when making HTTP requests.
def
connectionName = 'Localhost'
Closure
subVarValue = { String subVar ->
operation.application.getSubstitutionVariable(subVar).value }
String
CurYr = subVarValue('CurYr')
String
CurMth = subVarValue('CurMth')
println "The Rule is using the Sub Var Current Year : " +CurYr +" " + "Current Month : " +CurMth
Here, a closure named subVarValue is defined. A closure is essentially a block of code that can be assigned to a variable and executed later.
This
closure takes a single parameter subVar, which is a string representing a
substitution variable.
Within
the closure, it retrieves the value of the substitution variable specified by
subVar using operation.application.getSubstitutionVariable(subVar).
Finally,
it returns the value of the substitution variable using .value.
This invokes the closure subVarValue with the argument 'CurYr'. & CurMth. This means it fetches the value of the substitution variable named 'CurYr' & ‘CurMth’.The result is assigned to the variables.
/* Wait for the Rules to complete */
boolean
WaitforCompletion
HttpResponse<String>
jsonResponse
def
payload
def
awaitCompletion(HttpResponse<String> jsonResponse, String connectionName,
String operation) {
final int IN_PROGRESS = -1
if (!(200..299).contains(jsonResponse.status))
{
throwVetoException("Error occured:
$jsonResponse.statusText")
}
// Parse the JSON response to get the
status of the operation. Keep polling the DM server until the operation
completes.
ReadContext ctx =
JsonPath.parse(jsonResponse.body)
int status = ctx.read('$.status')
for(long delay = 50; status == IN_PROGRESS;
delay = Math.min(1000, delay * 2)) {
sleep(delay)
status = getJobStatus(connectionName,
(String)ctx.read('$.jobId'))
}
println("$operation ${status == 0 ||
status == -1 ? "successful" : "failed"}.\n")
return status == 0
}
This
code defines a function awaitCompletion that waits for a job to complete
by polling the server until the operation finishes. It checks the status of the
job in the JSON response and sleeps for increasing intervals until the job
status changes from in-progress to completion or failure. If the HTTP response
status indicates an error, it throws an exception.
int
getJobStatus(String connectionName, String jobId) {
HttpResponse<String> pingResponse =
operation.application.getConnection(connectionName).get("/rest/v3/applications/ICPCM/jobs/"
+ jobId).asString()
return JsonPath.parse(pingResponse.body).read('$.status')
}
This
function, getJobStatus, retrieves the status of a job by sending a GET
request to the server's API endpoint for fetching job status. It utilizes the
provided connectionName to determine which server to connect to. The
response is then parsed using JsonPath to extract the job status, which is
returned as an integer value representing the job's current status code.
/*
1. Clear for EMEA */
/*
Rule Name:
Clear_for_EMEA_IC_Calcs
*/
/*********************************************************************************************/
println "1. Clear for EMEA"
jsonResponse = operation.application.getConnection("Localhost").post('/rest/v3/applications/ICPCM/jobs')
.header("Content-Type",
"application/json")
.body(json([
"jobType" : "Clear
Cube",
"jobName" :
"Clear_for_EMEA_Calcs"
])
)
.asString();
println 'Response Received'
println jsonResponse.body
WaitforCompletion = awaitCompletion(jsonResponse, "Localhost", "Clear Cube")
This code segment initiates a "Clear for EMEA" operation by sending a POST request to the server's API endpoint for creating jobs. It specifies the job type as "Clear Cube" and provides a job name "Clear_for_EMEA_Calcs". The response received is printed to the console, and then the script waits for the completion of this operation by calling the awaitCompletion function with the appropriate parameters.
/***********************************************************************************************/
/*
2. Clear for APAC
*/
/*
Rule Name:
Clear_for_APAC_IC_Calcs */
/**********************************************************************************************/
println "2. Clear for APAC"
.header("Content-Type",
"application/json")
.body(json([
"jobType" : "Clear
Cube",
"jobName" :
"Clear_for_APAC_IC_Calcs"
])
)
.asString();
println 'Response Received'
println jsonResponse.body
This code segment initiates a "Clear for APAC" operation by sending a POST request to the server's API endpoint for creating jobs. It specifies the job type as "Clear Cube" and provides a job name "Clear_for_APAC_Calcs". The response received is printed to the console, and then the script waits for the completion of this operation by calling the awaitCompletion function with the appropriate parameters.
/*
3. Clear for Americas */
/*
Rule Name:
Clear_for_Americas_IC_Calcs */
/**********************************************************************************************/
println "3. Clear for Americas"
jsonResponse = operation.application.getConnection("Localhost").post('/rest/v3/applications/ICPCM/jobs')
.header("Content-Type",
"application/json")
.body(json([
"jobType" : "Clear
Cube",
"jobName" :
"Clear_for_Americas_IC_Calcs"
])
)
.asString();
println 'Response Received'
println jsonResponse.body
WaitforCompletion = awaitCompletion(jsonResponse, "Localhost", "Clear Cube")
Similarly for running the code for Americas in this part of the code.
/************************************************************************************************/
/*
4. Merge Data Slices
*/
/*
Rule Name: Merge Data Slices PCM.PCM_CLC
*/
/************************************************************************************************/
println "4. Merge Data Slices"
jsonResponse = operation.application.getConnection("Localhost").post('/rest/v3/applications/PCM/jobs')
.header("Content-Type",
"application/json")
.body(json([
"jobType" : "Merge Data
Slices",
"jobName" : "Merge Data
Slices PCM.PCM_CLC",
"parameters": [
"cubeName":
"PCM_CLC",
"mergeSliceType":
"allIncrementalSlicesInMain",
"keepZeroCells":
"false"
]
])
)
.asString();
println 'Response Received'
println jsonResponse.body
WaitforCompletion = awaitCompletion(jsonResponse, "Localhost", "Merge Data Slices")
This
code segment initiates a "Merge Data Slices" operation by sending a
POST request to the server's API endpoint for creating jobs. It specifies the
job type as "Merge Data Slices" and provides a job name "Merge
Data Slices ICPCM.PCM_CLC". Additionally, it includes parameters such as
the cube name ("PCM_CLC"), the merge slice type, and whether to keep
zero cells. The response received is printed to the console, and then the
script waits for the completion of this operation by calling the awaitCompletion
function with the appropriate parameters.
/************************************************************************************************/
/*
5. Run Calculation */
/************************************************************************************************/
println "5 Run Calculation for Range - 1 TO 999"
jsonResponse = operation.application.getConnection("Localhost").post('/rest/v3/applications/ICPCM/jobs/')
.header("Content-Type",
"application/json")
.body(json([
"jobType":"Calculation",
"jobName":"Run Calculation
for Range - 1 TO 999",
"parameters":[
"povDelimiter":":",
"povName":"$CurYr:$CurMth:Actual:Working",,
"modelName":"2-IC
Calcs",
"executionType":"RULESET_SUBSET",
"rulesetSeqNumStart":"1",
"rulesetSeqNumEnd":"999",
"clearCalculatedData":"true",
"executeCalculations":"true",
"optimizeForReporting":"true",
"captureDebugScripts":"false"]
])
)
.asString();
println
'Response Received'
println
jsonResponse.body
WaitforCompletion = awaitCompletion(jsonResponse, "Localhost", "Run Calculation for Range - 1 TO 999")
This code segment initiates a "Run Calculation" operation for a specified range (1 to 999) by sending a POST request to the server's API endpoint for creating jobs. It specifies the job type as "Calculation" and provides a job name "Run Calculation for Range - 1 TO 999". Additionally, it includes parameters such as the point of view (pov) name, model name, execution type, ruleset sequence numbers, and other configuration options. The response received is printed to the console, and then the script waits for the completion of this operation by calling the awaitCompletion function with the appropriate parameters.
//
Print a message indicating the user who executed the rule
println("Rule
was executed by $operation.user.fullName")
Finally print the person who executed this rule.
On Execution the Rules ran in Sequential manner,
And to notice the Main rule is waiting for all the child jobs to get completed.
Hope this was useful!!! Happy days on the Cloud!!!
No comments:
Post a Comment