Using RedwoodScript in Processes
RedwoodScript is the ideal language to automate complex tasks, adding custom code to a Chain Definition, for example. The following code will illustrate some example features you would like to implement. The easiest way to develop your code is to use the web-based shell first. If it runs in there, it should run in a Process Definition, please see the RedwoodScript, Redwood Expression Language, and Scripting Contexts sections for a list of examples, functions, contexts and predefined objects, respectively. Please note that the web-based shell does not have parent processes, so parent/child examples will not run in it.
Note: Redwood Software does not warrant that this is the most effective way in solving your specific problem. The examples are provided to illustrate the use of RedwoodScript.
Note: When you set the Requested Start Time of a process, pay attention to not specify dates before 1901 or your process will be vetoed.
Create a Process Definition
To create a Process Definition, you first need to know if the Definition Type requires a source, then you create the Process Definition and source (in a Script object) and link the source to the process.
{
JobDefinition jDefinition = jcsSession.createJobDefinition();
jDefinition.setName("JD_GetCurrentSales");
jDefinition.setPartition(jcsSession.getPartitionByName("SALES"));
jDefinition.setJobDefinitionType(jcsSession.getJobDefinitionTypeByName("JDBC"));
Script script = jcsSession.createScript();
script.setLibrary(jcsSession.getLibraryByName("Custom"));
script.setJobDefinition(jDefinition);
script.setRunAsUser("Example");
script.setSource("select prod_ID,prod_name,prod_inc,prod_out from prod where prod_mon = 123");
jcsSession.persist();
}
Access the Parameters
To access the current parameters, remember that the current process is already defined as jcsJob
and the SchedulerSession is defined as jcsSession
.
{
jcsOut.println(Name);
jcsOut.println(Address);
jcsOut.println(City);
jcsOut.println(Zip);
}
You can also use the process (technical name Job
) to retrieve the parameters and then their values. The below code is also used when you want to retrieve the values of parameters of other processes (replace the otherJob
object with an object that points to the correct process).
{
// Replace this line with code to get the other process
Job otherProcess = jcsJob;
//get the In value of parameter pName and print its value
JobParameter pNameVal = otherProcess.getJobParameterByName("pName");
jcsOut.println(pNameVal);
//or, without retrieving the parameter
jcsOut.println(pName);
//set the Out value of the parameter
pName = "GoodBye World!";
//print out the Out value
jcsOut.println(pName);
//write it to the database
jcsSession.persist();
}
Submit a Simple Job
Basic code to create a process from a Process Definition and submit the process, without specifying any parameters. If the Process Definition has parameters, the defaults will be used.
{
// code to submit a job running System_Sleep
// get the job definition
JobDefinition jDefinition = jcsSession.getJobDefinitionByName("System_Sleep");
// create the job from the job definition
Job process = jDefinition.prepare();
// submit the job definition and write unsaved data to the database
jcsSession.persist();
}
Submit a Simple Process with Parameters
The same basic code to submit a process used previously but this time with parameters. If you do not specify a value for a parameter, the default value will be used. Special care needs to be taken, if a Process Definition has a required parameter with no default value you must specify a value, or the process will not get submitted.
{
// code to submit SAP_AbapRun that runs the ABAP program RSUSR000
// get the job definition SAP_AbapRun
JobDefinition jDefinition = jcsSession.getJobDefinitionByName("SAP_AbapRun");
// create the job
Job process = jDefinition.prepare();
// assign parameters
process.getJobParameterByName("SAP_SYSTEMS").setInValueString("TR1");
process.getJobParameterByName("ABAP_PROGRAM_NAME").setInValueString("RSUSR000");
process.getJobParameterByName("JOBNAME").setInValueString("RSUSR000 made with RedwoodScript");
// assign queue as SAP jobs require a queue
Partition partition = jcsSession.getPartitionByName("RW_DEMO");
Queue queue = jcsSession.getQueueByName(partition, "TR1_Queue");
process.setQueue(queue);
// submit the job definition and write unsaved data to the database
jcsSession.persist();
// wait for all children
jcsSession.waitForAllChildren(process);
}
Submit a Simple Process with Parameters using REL Evaluation
The same basic code to submit a process with parameters used previously but this time specifying a REL expression as a value; the expression will be evaluated and the parameter value will be set to the result of the expression.
{
// code to submit SAP_AbapRun that runs the ABAP program RSUSR003
// get the job definition SAP_AbapRun
JobDefinition jDefinition = jcsSession.getJobDefinitionByName("SAP_AbapRun");
// create the job
Job process = jDefinition.prepare();
// assign parameters
process.getJobParameterByName("SAP_SYSTEMS").setInValueString("TR1");
process.getJobParameterByName("ABAP_PROGRAM_NAME").setInValueString("RSUSR003");
process.getJobParameterByName("JOBNAME").setInValueByEvaluatingREL(jcsSession, "='From ' + getSystemId()");
// assign queue as SAP jobs require a queue
Partition partition = jcsSession.getPartitionByName("RW_DEMO");
Queue queue = jcsSession.getQueueByName(partition, "TR1_Queue");
process.setQueue(queue);
// submit the job definition and write unsaved data to the database
jcsSession.persist();
// wait for all children
jcsSession.waitForAllChildren(process);
}
Access Parent/Child Parameters
A child process retrieves the parameter values of its direct parent. Remember that a Chain Process has a Step as a parent and a Step has no parameters.
{
//get the parent job
Job parent = jcsJob.getParentJob();
//get the job parameters and respective values
JobParameter parentName = parent.getJobParameterByName("pName");
JobParameter parentName2 = parent.getJobParameterByName("pName2");
Object parentNameInValue = parentName.getInValue();
Object parentName2InValue = parentName2.getInValue();
//log the values of the parent parameters
jcsOutLog.info("Parent Parameter pName is set to " + parentNameInValue);
jcsOutLog.info("Parent Parameter pName2 is set to " + parentName2InValue);
//set the Out value of the current (child) job
jcsJob.getJobParameterByName("childParam").setOutValue("Done");
jcsSession.persist();
}
Access Chain Parameters
A Chain Process retrieves Chain-level parameters.
{
//get the step job (up one level)
Job step = jcsJob.getParentJob();
//get the inner-most chain process (up another level)
Job parent = step.getParentJob();
//get the parameters and respective values
JobParameter chainName = parent.getJobParameterByName("pName");
JobParameter chainName2 = parent.getJobParameterByName("pName2");
Object chainNameInValue = parentName.getInValue();
Object chainName2InValue = parentName2.getInValue();
//log the values of the parameters
jcsOutLog.info("Parent Parameter pName is set to " + chainNameInValue);
jcsOutLog.info("Parent Parameter pName2 is set to " + chainName2InValue);
//set the Out value of the current job
jcsJob.getJobParameterByName("JobpName").setOutValue("Done");
jcsSession.persist();
}
Another example:
{
//get the parameters and respective values
JobParameter chainName = jcsJob.getParentJob().getParentJob().getJobParameterByName("pName");
JobParameter chainName2 = jcsJob.getParentJob().getParentJob().getJobParameterByName("pName2");
//log the values of the parent parameters
jcsOutLog.info("Parent Parameter pName is set to " + chainName);
jcsOutLog.info("Parent Parameter pName2 is set to " + chainName2);
//set the Out value of the current (child) job
childParam = "Done";
jcsSession.persist();
}
Delete Processes that ran on a Process Server, using executeObjectQuery
You want to delete all the processes of a Process Server because you want to delete the Process Server, you may proceed as follows:
The following example illustrates how to delete all the processes that ran on Process Server MSLN_WINS3
.
{
// Note that the following query uses query parameters for the
// query. User content should never be injected directly into
// the SQL query that is sent to the database.
String query = "select Job.* from Job where ProcessServer = ?";
for (Job process : jcsSession.executeObjectQuery(Job.TYPE, query, new Object[] {jcsSession.getProcessServerByName("MSLN_WINS1").getUniqueId()}))
{
if(process.getStatus().getState() == JobStatusState.Final)
{
jcsOut.println("Deleting process "
+ process.getDescription()
+ ", which has the status "
+ process.getStatus()
+ ".");
process.deleteObject();
}
jcsSession.persist();
}
}
Count the number of Processes on a Process Server using executeQuery
{
LongCallBack callback = new LongCallBack(1);
String query = "select count(*) from Job where Job.ProcessServer = ?";
try
{
jcsSession.executeQuery(query, new Long[] { jcsSession.getProcessServerByName("MSLN_WINS3").getUniqueId() }, callback);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
Long myCount = (Long) callback.getResult().get(0);
if (myCount != null)
{
jcsOut.println(myCount);
}
}
Creating Chain Definitions in RedwoodScript
Creating Chain Definitions in RedwoodScript is a multi-step process, you first create a JobDefinition
, you then create a JobChain
and set the Chain Definition to your newly created JobDefinition. You can then create child Steps and Chain Process children of the Steps.
{
String pName = "RW_DEMO";
String jDefinitionName = "JC_Sleep";
String stepName = "Step 1";
//get or create a partition (here we create one if it does not exist)
Partition partition = jcsSession.getPartitionByName(pName);
if (partition == null)
{
partition = jcsSession.createPartition();
partition.setName(pName);
}
JobDefinition jDefinition = jcsSession.getJobDefinitionByName(partition, jDefinitionName);
if (jDefinition == null)
{
//Create JobDefinition of type JOB_CHAIN
jDefinition = jcsSession.createJobDefinition();
jDefinition.setName(jDefinitionName);
jDefinition.setJobDefinitionType(jcsSession.getJobDefinitionTypeByName(JobDefinitionType.JOB_CHAIN));
jDefinition.setPartition(partition);
//Create jobchain object with one step and one job chain call
JobChain jChain = jcsSession.createJobChain();
jChain.setJobDefinition(jDefinition);
//step
JobChainStep jcStep = jChain.createJobChainStep();
jcStep.setSequenceNumber(Long.valueOf(0));
jcStep.setName(stepName);
//job chain call (chain process)
JobChainCall jcCall = jcStep.createJobChainCall();
JobDefinition jDefinitionSleep = jcsSession.getJobDefinitionByName("System_Sleep");
jcCall.setJobDefinition(jDefinitionSleep);
jcCall.setSequenceNumber(Long.valueOf(0));
}
else
{
jcsOut.println("JobDefinition " + jDefinitionName + " exists!");
jcsOut.println("You can change the name of the JobDefinition on the line:\n String jDefinitionName = \"JC_Sleep\";");
}
jcsSession.persist();
}
Creating User Messages in RedwoodScript
{
String pName = "RW_DEMO";
String uMessageName = "UM_ReviewWorldSalesReport";
//get or create a partition (here we create one if it does not exist)
Partition partition = jcsSession.getPartitionByName(pName);
if (partition == null)
{
partition = jcsSession.createPartition();
partition.setName(pName);
}
JobDefinition jDefinition = jcsSession.getJobDefinitionByName(partition, uMessageName);
if (jDefinition == null)
{
JobDefinition jd = jcsSession.createJobDefinition();
jd.setName(uMessageName);
jd.setPartition(partition);
JobDefinitionType um = jcsSession.getJobDefinitionTypeByName("UserMessage");
jd.setJobDefinitionType(um);
UserMessageDefinition umd = jcsSession.createUserMessageDefinition();
umd.setJobDefinition(jd);
umd.setText("Please review world sales report.");
UserMessageDefinitionResponse umr = umd.createUserMessageDefinitionResponse();
umr.setStatus(JobStatus.Completed);
umr.setName("Done");
umr.setReturnCode(Long.valueOf(0));
umr = umd.createUserMessageDefinitionResponse();
umr.setStatus(JobStatus.Error);
umr.setName("Failed");
umr.setReturnCode(Long.valueOf(1));
UserMessageDefinitionParticipant umdp = umd.createUserMessageDefinitionParticipant();
umdp.setType(SubjectType.Role);
umdp.setName("scheduler-user");
//The following only works in a chain with a process at position 1,
//in the step named "Step 1" producing output in a file named stdout.log - for illustration
//purposes, only.
//UserMessageDefinitionAttachment umda = umd.createUserMessageDefinitionAttachment();
//umda.setDescription("World Sales Report");
//umda.setSpecification("Step 1, Job 1:stdout.log");
}
else
{
jcsOut.println("JobDefinition " + uMessageName + " exists!");
jcsOut.println("You can change the name of the JobDefinition on the line:\n String uMessageName = \"UM_ReviewWorldSalesReport\";");
}
jcsSession.persist();
}
Creating a JobFile in RedwoodScript
{
JobFile jf = jcsJob.createJobFile();
jf.setFileType(JobFileType.Output);
jf.setName("SomeTextFile.txt");
jf.setFormat(jcsSession.getFormatByName("HTMLText")); //You can also create your own in Definitions > Formats
jf.setOrder(JobFile.CUSTOMER_ORDER_START); //Sort order must be >= CUSTOMER_ORDER_START
jcsOut.println(jf.getType().getCodeExString());
jf.setFileNameAutomatic(); //Filename must be generated
jcsSession.persist();
String fileToWriteTo = jf.getFileName();
//Standard Java code to create and populate the actual file
java.io.PrintWriter writer = new java.io.PrintWriter(fileToWriteTo, "UTF-8");
writer.println("The first line");
writer.println("The second line");
writer.close();
}