Introduction: What is HTDS and why automate?
HTDS is the RESTful endpoint provided by IBM Operational Decision Manager (ODM) for executing business rules. It accepts input parameters, runs the decision logic, and returns the results in real time.
For my project, HTDS served as the designated interface for retrieving decisions. I needed to develop a program to verify that the ODM endpoint continues to function correctly after product installations or upgrades. Since I work on the mainframe, this type of validation is commonly referred to as an IVP (Installation Verification Program) in my terminology.

Manually testing the endpoint
Before deciding on the best way to automate the test program, I started by manually testing the HTDS endpoint using the Rule Execution Server console, leveraging the built-in button available on each ruleset view.

Pressing the test button launched the HTDS test endpoint in a new window.

The test page included default values. They are of the correct type, but they may not match the expectations of the rules. Therefore, I supplied my own custom values, deliberately choosing an extremely old age to trigger a rejection rule:

When I pressed the 'Execute Request' button, the server responded after executing the rules:

As we can see, the expected message is returned, indicating that the borrower is too old for the loan.
As mentioned earlier, including this step in the verification process is valuable for confirming that ODM has been installed or upgraded correctly, as it demonstrates proper rule execution behaviour. For instance, it could be implemented as a Java program and executed via a shell script on a UNIX system or through JCL on the mainframe.

Lets use project Bob the AI development partner
I was about to start coding my own Java program or writing a shell script to call curl. However, I reminded myself that we should now always ask: “How can AI help with this task?”
With that in mind, I turned to Bob – IBM’s AI development partner.
My first thought was: “What prompt can I use to get Bob to do this for me?”
As shown below, I’m instructing Bob in much the same way we might speak to a human developer—explaining what we’ve done and what we’d like Bob to do next: “We sent this and it worked; can you automate it for me?”
Prompt:
|
sending this xml
<par:Request xmlns:par="http://www.ibm.com/rules/decisionservice/MiniLoanDemoRuleApp/MiniLoanDemo/param">
<par:borrower>
<age>100</age>
<creditScore>300</creditScore>
<name>string</name>
<yearlyIncome>100000</yearlyIncome>
</par:borrower>
<par:loan>
<amount>500000</amount>
<approved>true</approved>
<effectDate>2012-05-12T19:14:28</effectDate>
<messages></messages>
<yearlyInterestRate>1</yearlyInterestRate>
<yearlyRepayment>10</yearlyRepayment>
</par:loan>
</par:Request>
To this endpoint
http://internalhost.location.ibm.com:42042/DecisionService/rest/MiniLoanDemoRuleApp/1.0/MiniLoanDemo/1.0
works nicely. Produce me a java program to do the same please
|

A step by step journey of Bob’s solution
You can see below I have entered my prompt into Bob:

Bob made a to-do list:

..and then started working on it, by creating the new java program

Each time an action needs to be performed in my workspace, Bob asks for permission. For example, as shown above, I was notified that Bob wanted to create a file, and I needed to click Save to approve the action.
Once that step was completed, Bob marked “creating the program” as done and moved on to generating the documentation.

Again asking me if it was OK to save it once Bob was done.
As a final step Bob generated a summary of what had been accomplished:

The code Bob produced looks good!
|
package com.example.loan;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
/**
* Java client for IBM Decision Service - MiniLoanDemo
* Sends XML request to evaluate loan application
*/
public class MiniLoanServiceClient {
private static final String SERVICE_URL = "http://internalhost.site.ibm.com:42042/DecisionService/rest/MiniLoanDemoRuleApp/1.0/MiniLoanDemo/1.0 ";
public static void main(String[] args) {
try {
// XML request payload
String xmlRequest =
"<par:Request xmlns:par=\"http://www.ibm.com/rules/decisionservice/MiniLoanDemoRuleApp/MiniLoanDemo/param\">\n" +
" <par:borrower>\n" +
" <age>100</age>\n" +
" <creditScore>300</creditScore>\n" +
" <name>string</name>\n" +
" <yearlyIncome>100000</yearlyIncome>\n" +
" </par:borrower>\n" +
" <par:loan>\n" +
" <amount>500000</amount>\n" +
" <approved>true</approved>\n" +
" <effectDate>2012-05-12T19:14:28</effectDate>\n" +
" <messages></messages>\n" +
" <yearlyInterestRate>1</yearlyInterestRate>\n" +
" <yearlyRepayment>10</yearlyRepayment>\n" +
" </par:loan>\n" +
"</par:Request>";
// Send request and get response
String response = sendXmlRequest(SERVICE_URL, xmlRequest);
// Print response
System.out.println("Response from Decision Service:");
System.out.println("================================");
System.out.println(response);
} catch (Exception e) {
System.err.println("Error occurred: " + e.getMessage());
e.printStackTrace();
}
}
/**
* Sends XML request to the specified URL and returns the response
*
* @param urlString The endpoint URL
* @param xmlPayload The XML request body
* @return The response as a String
* @throws Exception if connection or I/O error occurs
*/
private static String sendXmlRequest(String urlString, String xmlPayload) throws Exception {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try {
// Configure connection
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/xml; charset=UTF-8");
connection.setRequestProperty("Accept", "application/xml");
connection.setDoOutput(true);
connection.setConnectTimeout(10000); // 10 seconds
connection.setReadTimeout(10000); // 10 seconds
// Send XML payload
try (OutputStream os = connection.getOutputStream()) {
byte[] input = xmlPayload.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
// Get response code
int responseCode = connection.getResponseCode();
System.out.println("HTTP Response Code: " + responseCode);
// Read response
BufferedReader reader;
if (responseCode >= 200 && responseCode < 300) {
reader = new BufferedReader(
new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
} else {
reader = new BufferedReader(
new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8));
}
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line).append("\n");
}
reader.close();
return response.toString();
} finally {
connection.disconnect();
}
}
}
// Made with Bob
|
At this point, I realized I hadn’t asked for enough. What I really wanted was a complete Maven project that I could build and run without extra setup.
So, I asked Bob to take it further!
Bob immediately created a new checklist and got to work.

First, Bob generated a pom.xml for Maven and, as always, asked for permission before saving it.

Next, Bob moved the Java file into the correct directory structure for a Maven project—again checking with me before making changes.

Bob didn’t stop there and next added a .gitignore file in case I wanted to push the project to GitHub:

Being a diligent developer, Bob even wrote a README explaining how to compile and run the program:

Being thorough, Bob then asked permission to run a build to confirm everything worked
the build ran and succeeded!

Finally, Bob displayed a summary of all the steps completed.:

A quick look in Windows Explorer confirmed that I now had a proper Maven project:

To validate, I ran my own Maven build:
Which succeeded:

Finally I then executed the program. The result? A fully functional test program that verifies the HTDS REST endpoint works exactly as intended.


Outcome & Benefits
So in a matter of less than 5 minutes I have gone from testing a rest endpoint in the browser to having created a documented and working java test program for the endpoint. This would normally have taken me longer, and it is possible I’d have made some mistakes along the way.
No doubt I could have asked Bob to have done the same thing in Python, or using Wget from shell, but my current need was for something in Java – as I want to call it from JCL on the mainframe and this should do the job nicely.
I invite you to get hold of Bob, to integrate into your daily development work. I think you will be impressed with what Bob can do for you!