Introduction
This blog discusses how to build a scenario where IBM Operational Decision Manager (ODM) rules are invoked from a CICS Java program.
The scenario currently runs the COBOL mini loan sample in a zRules Execution Server (zRES) running in a CICS JVM Server. This is shown in Figure 1.
|
Figure 1: The initial starting point for the scenario, a CICS COBOL Program using a zRules Execution Server in CICS JVM Server for Rule Execution.
|
The CICS Java miniloan program will call the same ODM rule application used by the COBOL miniloan sample. The scenario creates a J2SE ODM rule engine with the same configuration as the zRES . The Java application will create its own J2SE eXecution Unit (XU) exclusively for this Java application. This is shown in Figure 2.
|
Figure 2: CICS Java Program using a local J2SE XU for Rule Execution
|
By using the same ra.xml configuration file, the J2SE XU will have access to the same management and rule deployment options as the existing zRES.
The way this scenario is implemented, each Java application creates its own XU on first execution. The Java application will reuse the XU on subsequent executions.
|
Figure 3: Cobol programs share the same XU, as this example shows a Java program creating its own XU
|
Note: An alternative solution would be to create a management or factory singleton class which would allow each Java application to share the same XU.
|
Prepare your environment
You will need to use the ODM for z/OS infocenter to create a working ODM in CICS configuration. Ensure that you have completed all these steps before you continue:
- Configure a zRules Execution Server Console
- Configure the DB2 persistence layer
- Configure zRules Execution Server for z/OS to execute rules on a CICS JVM server. Ensure that you also follow the mini loan sample application set-up steps.
- Test the JVM configuration by running the HBRC transaction to connect CICS to zRules Execution Server for z/OS. Checking that message GBRZC9001I is issued showing that CICS succeeded in connecting to and initialising the zRules Execution Server in the CICS JVM. If CICS fails to connect to the server, message GBRZC9000E is issued with a return code containing diagnostic information.
- Test the zRules Execution Server and DB2 persistence layer running the Miniloan application as a CICS application.
- The Rule Designer tooling should be installed with the samples and tutorials.
Import the Miniloan Java XOM
The first step is to import the z/OS miniloan sample into eclipse so that we can use it to build this example. In order to do this you must have the Rule Designer eclipse environment installed with the samples and tutorials. The samples and tutorials are an installation option provided by the IBM installation manager.
- Open Rule Designer, click Window > Show View > Other... > Samples and Tutorials.
- Expand Rule Designer > Tutorials > Cobol > Creating a copybook-based ruleset for zRules Execution Server for Z.
- Click the import projects for the answer
|
Figure 4: Import the projects from the answer for Creating a copybook-based ruleset for zRules Execution for z/OS
|
Create the Java project
The next step is to create a Java project and configure the build path, this can be done by opening the Java perspective in Rule Designer.
- To switch perspective clicking Window > Open Perspective > Other... > Java > OK.
- Create a new Java Project by clicking File > New > Java Project
- Set the name to JCICS_MiniLoan and click Next
- This panel enables use to configure the build path, click on the libraries tab.
- Add the following jars by clicking on Add External jars...:
- From the executionserver/lib directory of the installation add jrules-res-session-java.jar, jrules-engine.jar and jrules-res-execution.jar.
- Add com.ibm.cics.server.jar from the CICS installation lib folder.
- Add ibmjzos.jar from the lib/ext folder of the z/OS Java installation.
|
Figure 5: Configure the external jars for the build
|
- Click on the Projects tab
- Click Add...
- Check the MiniLoanDemo-xom project so that we have access to the XOM for building the RuleApp parameters.
- Click OK
- Click Finish
Modify the XOM
It is useful if the XOM's borrower and loan classes override the Object.toString method. This allows us to easily print the borrower and loan to the logs to verify rule execution. To do this open the MiniLoanDemo-xom project and edit the Borrower.java and Loan.java files.
- Add the following method to the Borrower.java file
public String toString() {
return "Borrower: " + name + " CreditScore:" + creditScore
+ " YearlyIncome: " + yearlyIncome + " Age:" + age;
}
|
- Add the following method to the Loan.java file
public String toString() {
String out = "Loan: $" + amount + " EffectDate:" + effectDate
+ " Approved: " + approved + " Messages:\n";
for (int i = 0; i < messages.size(); i++) {
out = out + messages.get(i) + "\n";
}
return out;
}
|
Create the Java CICS Application code
We are now going to create a single static class to demonstrate the minimal code required to call rules using a J2SE XU with a stateless session.
- Create the Java class by;
- Right clicking the JCICS_MiniLoan project
- Click New > Class
- Set the Package to com.ibm.rules.miniloan
- Set the name to MiniRunner.
- Click Finish
- Add the following fields to the class
private static IlrSessionFactory sessionFactory;
private final static String PARAM_BORROWER = "borrower";
private final static String PARAM_LOAN = "loan";
private static final String rulesetPath = "/MiniLoanDemoRuleApp/MiniLoanDemo";
|
- Add the following main method which will control our program flow. We will read each line from the SCENARIO DD from the JCL and create borrower and loan objects from the input. Then we will call the executeRules method with the RuleSet path and the parameter objects.
public static void main(CommAreaHolder commArea) {
try {
PrintWriter out = new PrintWriter(System.out, true);
out.println();
out.println("----------------------------------------------");
out.println("Starting the JAVA CICS Miniloan sample");
out.println();
// Read the SCENARIO file from the SCENARIO DD
ZFile dd = new ZFile("//DD:SCENARIO", "r");
BufferedReader in = new BufferedReader(new InputStreamReader(
dd.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
String[] input = line.split(",");
Borrower borrower = new Borrower();
Loan loan = new Loan();
// Create the borrower
borrower.setName(input[0]);
borrower.setCreditScore(new Long(input[1]).longValue());
borrower.setYearlyIncome(new Long(input[2]).longValue());
borrower.setAge(new Short(input[3]).shortValue());
// Create the loan
loan.setAmount(new Long(input[4]).longValue());
loan.setYearlyInterestRate(new Short(input[5]).shortValue());
loan.setYearlyRepayment(new Long(input[6]).longValue());
loan.setEffectDate(input[7].trim());
loan.setApproved(true);
loan.setMessages(new ArrayList());
// Execute the rules and output exception or success message
out.println(executeRules(IlrPath.parsePath(rulesetPath),
borrower, loan));
// Print out the returned parms
out.println(borrower.toString());
out.println(loan.toString());
out.println();
} out.println("----------------------------------------------");
} catch (Throwable e) {
System.err.print(e);
}
}
|
- In order to create a stateless session to the XU we will need to add the following methods. The getRuleSession method provides the stateless session. The use of the synchronized method and the static variable ensures that this application only creates one XU, even when it is ran multiple times.
- Add the following code to your application:
// Initialization of the session factory; in this case we initialize the
// Execution Unit
public static synchronized IlrSessionFactory getRuleSessionFactory() {
if (sessionFactory == null) {
sessionFactory = new IlrJ2SESessionFactory();
}
return sessionFactory;
}
// Return a stateless rule Session
public static IlrStatelessSession getRuleSession() throws Exception {
return getRuleSessionFactory().createStatelessSession();
}
/*
* Makes the parms object
*/
public static HashMap makeParams(Borrower borrower,
Loan loan) {
HashMap params = new HashMap();
params.put(PARAM_BORROWER, borrower);
params.put(PARAM_LOAN, loan);
return params;
}
|
- Next add the executeRules method below, this contains the rule code which will create the request and session objects so that we can call for rule execution.
// Execute the rules from a path
public static String executeRules(IlrPath rulesetPath, Borrower borrower,
Loan loan) {
String output = "";
// Create the request
IlrSessionRequest request = getRuleSessionFactory().createRequest();
// Select the ruleset to execute
request.setRulesetPath(rulesetPath);
// Inject the parameters
request.getInputParameters().putAll(makeParams(borrower, loan));
IlrSessionResponse response;
try {
// response contains:
// all the results of the execution
// output parameters
// execution trace which rule was executed in which order, what was
// not executed...
response = getRuleSession().execute(request);
borrower = (Borrower) response.getOutputParameters().get(
PARAM_BORROWER);
loan = (Loan) response.getOutputParameters().get(PARAM_LOAN);
output = "Success: " + response.getRulesetExecutionOutput();
} catch (IlrSessionException e) {
e.printStackTrace();
output = e.getMessage();
} catch (Exception e) {
e.printStackTrace();
output = e.getMessage();
}
return output;
}
|
- If you use the CTRL + shift + O shortkey the imports will automatically be added to the class.
- Ensure you have no build errors.
- The last step is to export the project to make a JAR file which contains the binaries for the MiniRunner and the XOM objects.
- Right click the JCICS_Miniloan project and click Export...
- Select JAR file and click Next
- Tick both JCICS_Miniloan and MiniLoanDemo-xom
- Export to a Jar file called JCICS_Miniloan.jar.
- Click Finish
Configure CICS to run the Java mini loan application
The next step is to configure CICS so that it knows about the new Java application. This is done by telling the JVM profile about the jar file and creating the CICS resources required.
- Create a directory called <HOMEDIR>/javacics with 755 permissions.
- FTP the JCICS_Miniloan.jar to the <HOMEDIR>/javacics folder, ensure it also has 755 permissions.
- Add the following to your JVM server profile CLASSPATH_SUFFIX, this is a file called HBRJVM in the JVM Profile directory.
<HOMEDIR>/javacics/JCICS_Miniloan.jar:\ <CICSINSTPATH>/lib/com.ibm.cics.server.jar:\
|
- Ensure the HBRJVM profile file has 755 permissions.
- Restart your CICS region and then log onto it.
- To create the ra.xml config file in ++HBRWORKPATH++/config/res, you need to run HBRC once. This should have been completed in the Prepare your environment. Redo this step if you need to update the DB2 persistence configuration.
Note: The ra.xml file in ++HBRWORKPATH++/config/res gets re-written everytime you run the HBRC transaction. Therefore, do not manually update the ra.xml file in the WORKPATH, instead configure the JVM profile to use another ra.xml file and location.
|
- Run
CEDA AD
in CICS to add a group called JAVAMINI in list LA01
- Run
CEDA DEF PROG(HBRMINIJ) GROUP(JAVAMINI)
in CICS and set these field values:
DESCRIPTION => DEMO J2SE DIRECT FROM CICS
EXECUTIONSET => Fullapi
JVM => Yes
JVMCLASS => com.ibm.rules.miniloan.MiniRunner
JVMPROFILE => HBRJVM
|
- Run
CEDA DEF TRANS(MINJ) GROUP(JAVAMINI)
in CICS and enter:
DESCRIPTION => DEMO J2SE DIRECT FROM CICS TRANSACTION
PROGRAM => HBRMINIJ
|
- Run
CEDA I GROUP(JAVAMINI)
to install the new transaction and program
- Run the MINJ transaction in CICS
- Check the CICS JVM log dfhjvmout and dfhjvmerr (in the same directory as your JVM profile) to see the results.
----------------------------------------------
Starting the JAVA CICS Miniloan sample
Success:
Borrower: Joe CreditScore:600 YearlyIncome: 80000 Age:25
Loan: $500000 EffectDate:20131231 Approved: true Messages:
Success:
Borrower: John CreditScore:600 YearlyIncome: 80000 Age:75
Loan: $250000 EffectDate:20131231 Approved: false Messages:
The age exceeds the maximum.
Success:
Borrower: Sarah CreditScore:100 YearlyIncome: 80000 Age:25
Loan: $500000 EffectDate:20131231 Approved: false Messages:
Credit score below 200
Success:
Borrower: Andy CreditScore:600 YearlyIncome: 32000 Age:25
Loan: $500000 EffectDate:20131231 Approved: false Messages:
Too big Debt-To-Income ratio
Success:
Borrower: David CreditScore:600 YearlyIncome: 12000 Age:45
Loan: $250000 EffectDate:20131231 Approved: false Messages:
The yearly income is lower than the basic request
Success:
Borrower: Michelle CreditScore:600 YearlyIncome: 80000 Age:32
Loan: $1000100 EffectDate:20131231 Approved: false Messages:
The loan cannot exceed 1000000
----------------------------------------------
|
The logging for the XU will be outputted to the dfhjvmerr file, this can be configured by providing the XU with extra logging information. To check that the XU did not encounter any errors check the dfhjvmerr log for SEVERE or ERROR messages.
Console Management
Once the application has been run once, the XU will appear in the Server Info tab of the zRules Execution Server management console. You are then able to run Diagnostics and update the miniloan application and have any rule updates picked up by the application.
|
Figure 6: Server Info tab showing 5 execution units, 127.0.0.1:8198 is the XU created by this application
|