A while back I posted about using Groovy to run a data map with administrator credentials. This makes it possible for a non-administrator to run data maps. A couple of things have changed since I wrote that post. First, Oracle changed how to configure connections. Second, I learned some better ways to write the Groovy script.
The first step is to set up a connection in the planning application that points back to the same application. We refer to this as a loopback connection and it is configured with the credentials of a service administrator.
Create a new connection for Oracle Enterprise Performance Management Cloud.

Configure the connection to the application.

- Name the connection.
- Enter the URL of the application.
- Planning URLs may end with ‘epmcloud’, remove that or anything else that comes after ‘oraclecloud.com/’ and replace with ‘HyperionPlanning’. The URL should look like this: https://clientspecificdetails.oraclecloud.com/HyperionPlanning
- Enter service administrator credentials. The Application Type and Application Name will populate based on the URL, and Domain does not need to be entered.
Validate the connection and then click Save and Close. Remember the name used for the connection.
Now we can create a Groovy rule that will use this connection.

- Use a run-time-prompt (RTPS) for entity and define the variable to use it. Define another variable for cost centre by retrieving the user variable.
Next we add parameters to monitor and log the status of the job.

- Monitors the job and logs connection information.
Now we call the rule that we want to launch with administrator credentials, which is a rule we recently posted about for running a data map.

- Gets the connection ‘Loopback_Rest’ that was created previously. This is the connection credentials used in the next step that calls the rule with the data map.
- Define the job type and job name. We are also identifying the variables defined at the beginning as parameters to pass along to the rule.
- Logging the results of the job.
After running the rule, we check the results from the Job Console.

- The first job executed is our new rule with the loopback connection that calls the second rule.
- The second job is the rule executed with administrator credentials.
The log for the rule Loopback Push FS to Rpt has the information of the connection.

The log for the rule Push FS to Rpt has the details of the data map executed.

- The prompts are from the parameters passed through from the loopback rule.
The Groovy rule is useful for calling rules as well as rulesets. The same coding is used to call a ruleset except for the job type, job name, and parameters definitions.

- Job type is ‘Ruleset’ and the job name is the ruleset. We are not passing any variables to the ruleset, so we do not define any parameters.
Combining this with the rule for executing data maps is a good way to allow non-administrator users to run data maps. There could be other uses where the user needs to execute rules that they normally do not have access to run.
As always, happy EPM’ng!
Here’s the full script.
/*RTPS: {Entity} */
//define variables for entity and cost centres
def EntityVar= rtps.Entity.enteredValue
def ccVar = operation.application.getUserVariable("COGs CCs").value.name
/* Parameters to wait for PLANAPP Rules */
boolean ReversePush
HttpResponse<String> jsonResponse
def awaitCompletion(HttpResponse<String> jsonResponse, String connectionName, String operation) {
final int IN_PROGRESS = -1
// Parse the JSON response to get the status of the operation. Keep polling the PLANAPP 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
}
int getJobStatus(String connectionName, String jobId) {
HttpResponse<String> pingResponse = operation.application.getConnection(connectionName).get("/rest/v3/applications/WFPlan/jobs/" + jobId).asString()
return JsonPath.parse(pingResponse.body).read('$.status')
}
/* Build the json string to execute the REST job defined in the payload – update connection name and application name */
jsonResponse = operation.application.getConnection("Loopback_Rest").post('/rest/v3/applications/WFPlan/jobs')
.header("Content-Type", "application/json")
.body(json([
"jobType":"Rules",
"jobName":"WF_Push FS to Rpt_Groovy",
"parameters":["Entity":"$EntityVar","varCCs":"$ccVar"]
])
)
.asString();
println jsonResponse.body
ReversePush = awaitCompletion(jsonResponse, "Loopback_Rest", "Data push to Rpt Complete")