Tuesday

Wrapping business rules rmi clients with JAX-WS

Most often after deploying new business rules in BRES, we have to redeploy IlrSession beans with our custom beans(XOM). Also developing new client for the business rules is time consuming work. Bres(Business rules execution server) provide rmi protocol and some web service support(Decision service) to invoke rules in bres. Deployed rules will be exposed only when you add your domain class(XOM) in the jrules-bres-ootbds.ear and redeploy it again in application server. All the life cycle is too time consuming to manage the whole project. However, often business analyst (Most of time, project mangers require such thing to fulfill customers demand) requires expose business rules through web service for solving business requirement with customer. In today's post i will show a agile way to expose business rules through web service and run it into jdk 6 embedded http server.
We have one web service with a few methods, every method expose one business rules as a web method. For developing i have use jdk 6 and OAS 10.1.3.3 (where installed and deployed ours business rules).
Web service Class:BusinessRulesServices
package ru.fors.test.rules.project;

import ru.fors.pak.jrules.bom.Result;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;
import javax.naming.Context;
import javax.wsdl.extensions.soap.SOAPBinding;
import java.util.Properties;

import ilog.rules.bres.session.*;
import ilog.rules.xml.model.IlrXsdXomProcessor;
import ilog.rules.data.IlrSourceStructure;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Package: ru.fors.test.rules.project
* Author: sahmed
* Date: 03.02.2009
*/
@WebService(name = "BusinessRulesServices",
serviceName="BusinessRulesServices",
targetNamespace = "http://com.blu.rules/services")
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT,
use = SOAPBinding.Use.LITERAL,
parameterStyle = SOAPBinding.ParameterStyle.BARE)
public class BusinessRulesServices {
private static Log log = LogFactory.getLog(BusinessRulesServices.class);

private static final String UFTP_RULESPATH = "/UFTPNRuleAppS/1.0/rmReportUPFT/1.0";
private static IlrStatelessRuleSession session;

static{
IlrSourceStructure.Properties jndi = new Properties();
jndi.put(IlrXsdXomProcessor.Context.INITIAL_CONTEXT_FACTORY,"com.evermind.server.rmi.RMIInitialContextFactory");
jndi.put(Context.PROVIDER_URL,"ormi://Host:12402/NAME_OF_IRLRULESSESION");
jndi.put(Context.SECURITY_PRINCIPAL,"bres");
jndi.put(IlrXsdXomProcessor.Context.SECURITY_CREDENTIALS,"bres");
try {
IlrRuleSessionProvider rsProvider = new IlrRuleSessionProviderFactory.Builder(jndi).build();
session = rsProvider.createStatelessRuleSession();
if(log.isInfoEnabled()){
log.info("[Session Initilized.]");
}
} catch (IlrRuleSessionCreationException e) {
log.error("["+e.getMessage()+"]");
} 
}
@WebMethod(operationName = "uftpRules")
public Result callUftpRules(Long paramOperation){
IlrSessionRequest request = new IlrSessionRequest(UFTP_RULESPATH);
IlrSessionExecutionSettings sessionExecutionSettings = request.getExecutionSettings();
IlrSessionParameters inputParameters = sessionExecutionSettings.getInputParameters();
inputParameters.setParameter("paramOperation", paramOperation);
// enable trace
request.getSessionDescriptor().enableTrace();
Result  result = null;
try {
IlrSessionResponse response = session.executeRules(request);
IlrSessionExecutionResult executionResult = response.getExecutionResult();
//System.out.println("FiredRule:"+ executionResult.getNumRulesFired());
result = (Result)executionResult.getOutputParameters().getObjectValue("paramOutput");
} catch (RemoteException e) {
log.error("["+e.getMessage()+"]");
} catch (IlrRuleSessionException e) {
log.error("["+e.getMessage()+"]");
}
if(log.isInfoEnabled()){
log.info("[Request completed.]");
}
return result;
}
// more web methods goes here.
}

Now we will create the agent to start embedded http server and run the web service.
Agent:
package ru.fors.test.rules.project;

import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.Endpoint;

/**
* Package: ru.fors.test.rules.project
* Author: sahmed
* Date: 03.02.2009
*/
public class TestWs {
public static void main(String[] args) {
Endpoint.publish("http://localhost:8080/invokeRules",new BusinessRulesServices());
System.out.println("Server start...");
}
}

Now you can run the class TestWs and the wsdl of the web service will be available on the following url: http://localhost:8080/invokeRules?wsdl
Actually it's a simple well known wrapping pattern to expose legacy code as web service.
To run successes fully the agent, you need following libraries in your classpath:
bcel.jar
jrules-engine.jar
oc4jclient.jar
ilrsession.jar
jrules-bres-execution.jar
log4j.jar
commons-logging.jar
commons-discovery.jar
Post a Comment