Monday, May 31, 2010

JRules, using Java BOM to pass an input parameter

Having done the tutorial on how to write a Business Rule with Java BOM, once I deploy and try to get the WSDL the RES (Rule Execution Server) tells me:

This ruleset cannot be parsed. It uses a Java XOM, which is not supported by the hosted transparent decision service., error code: XU-WS10010

Yet, the "New Rule Project" gives you a template "Rule Project with a BOM" and it says:

This template creates a rule project using the following standard options :
Java XOM settings. Path on java folders, jars or projects.
Dynamic XOM settings. Path on XML schemas or dynamic XOM files.
Rule project references. Optional rule project dependencies.
In addition, BOM entries and verbalization are automatically created for each XOM specified.
The generated project enables you to edit rules and execute them.




Note: A XOM is a "Execution Object Model".

If you wonder what a "transparent" decision service is, you might have a read here, basically "transparent" means "exposed through WS":

http://publib.boulder.ibm.com/infocenter/brjrules/v7r0m2/index.jsp?topic=/com.ibm.websphere.ilog.jrules.doc/Content/Business_Rules/Documentation/_pubskel/JRules/ps_JRules_Global800.html

"A hosted transparent decision service: this is essentially a ruleset deployed as a Web service. It is installed on the same application server as Rule Execution Server, then integrated with Rule Execution Server." It's also nicknamed htds.

So basically should I resort to using XSDs to specify input parameters, in order to expose my Rules as Web Services? Oh my my.... what an I missing?

JRules exposed via Web Services

Typically you have a RuleApp, which contains several RuleSets.

When you produce a RuleSet, you can write several BusinessRules in it.

Here http://publib.boulder.ibm.com/infocenter/brjrules/v7r0m2/index.jsp?topic=/com.ibm.websphere.ilog.jrules.doc/Content/Business_Rules/Documentation/_pubskel/JRules/ps_JRules_Global800.html it says:

The decision service automatically generates a Web Services Description Language (WSDL) file for each deployed ruleset archive

In our example, helloWorldRuleApp contains helloWorldRuleApp,
and helloWorldRuleApp contains 2 BusinessRule: greetingsItalian and greetingsEnglish.
They will return respectively Buongiorno and Good morning!.

JRules  exposes them automatically via Web Services, the endpoint looks like:

http://localhost:8080/DecisionService/ws/helloWorldRuleApp/1.0/greetingsRuleset/1.0

This will fire all the Rules inside the greetingsRuleset.


The result will be:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ds="http://www.ilog.com/rules/DecisionService">
   <soapenv:Body>
      <DecisionServiceResponse xmlns="http://www.ilog.com/rules/DecisionService">
         <ilog.rules.outputString>Buongiorno
Good morning!</ilog.rules.outputString>
         <ilog.rules.firedRulesCount>2</ilog.rules.firedRulesCount>
      </DecisionServiceResponse>
   </soapenv:Body>
</soapenv:Envelope>


that is:
ilog.rules.outputString is the output of all the Rules invoked
ilog.rules.firedRulesCount is the count of the rules fired


The WSDL associated to the Web Service is:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://www.ilog.com/rules/DecisionService" xmlns:tns="http://www.ilog.com/rules/DecisionService" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.ilog.com/rules/DecisionService" xmlns:param="http://www.ilog.com/rules/param" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsd:import namespace="http://www.ilog.com/rules/param"/>
<xsd:element name="DecisionServiceRequest">
<xsd:complexType>
<xsd:sequence>
</xsd:sequence>
</xsd:complexType>

</xsd:element>
<xsd:element name="DecisionServiceResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ilog.rules.outputString" type="xsd:string"/>
<xsd:element name="ilog.rules.firedRulesCount" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

<xsd:element name="DecisionServiceException">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="exception" nillable="false" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<xsd:schema targetNamespace="http://www.ilog.com/rules/param" xmlns:ns0="http://www.ilog.com/rules/param"/>

</wsdl:types>
<wsdl:message name="DecisionServiceSoapResponse">
<wsdl:part name="parameters" element="tns:DecisionServiceResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="DecisionServiceSoapFault">
<wsdl:part name="fault" element="tns:DecisionServiceException">
</wsdl:part>
</wsdl:message>

<wsdl:message name="DecisionServiceSoapRequest">
<wsdl:part name="parameters" element="tns:DecisionServiceRequest">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="DecisionServiceJRulesPVHelloWorld">
<wsdl:operation name="executeDecisionService">
<wsdl:input message="tns:DecisionServiceSoapRequest">
</wsdl:input>
<wsdl:output message="tns:DecisionServiceSoapResponse">

</wsdl:output>
<wsdl:fault name="DecisionServiceSoapFault" message="tns:DecisionServiceSoapFault">
</wsdl:fault>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="DecisionServiceSOAP" type="tns:DecisionServiceJRulesPVHelloWorld">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="executeDecisionService">
<soap:operation soapAction="executeDecisionService" style="document"/>

<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="DecisionServiceSoapFault">
<soap:fault name="DecisionServiceSoapFault" use="literal"/>
</wsdl:fault>

</wsdl:operation>
</wsdl:binding>
<wsdl:service name="DecisionServiceJRulesPVHelloWorld">
<wsdl:port name="DecisionServiceSOAPesp50ws17206.crb.acme.net" binding="tns:DecisionServiceSOAP">
<soap:address location="http://localhost:8080/DecisionService/ws/helloWorldRuleApp/1.0/greetingsRuleset/1.0"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>


Let's watch an example where you pass an XML parameter (thank you David Selman for your excellent presentation, but next time can you ask a beautiful girl to show her face instead of yours :O)? We are all men in this business and seing a girl once in a while would help...):




In fact it's all about invoking a Web Service, the video shows how to do it with a Eclipse Plugin and Axis2 Java generated code.


The way I see it is that there is a DecisionService servlet serving all RuleApps and acting as a Proxy to the Rules Engine.

Saturday, May 29, 2010

WLST development with PyDev in Eclipse

My understanding is that Satya Ghattu has not been working on WLST for quite some time (cmiiaw)
and his blog doesn't say much on this topic.
I really wish Oracle put some development effort in WLST as honestly it's a bit primitive and lacks many features that for a Java Developer are essential (debugging, remote debugging, a proper IDE etc).
When people say "just use notepad" it makes me FURIOUS, it's like saying a surgeon "just use a Swiss Army knife instead of a bisturi"....

So in an attempt to make my WLST life easier...

download Python 2.6.5 here (is Python required? I don't think so)
http://www.python.org/ftp/python/2.6.5/python-2.6.5.msi

and Jython here (Is Jython required? NO! You already have C:\bea11\oracle_common\util\jython\jython.jar !)
http://sourceforge.net/projects/jython/files/jython/jython_installer-2.5.1.jar


install into Eclipse the PyDev plugin by following their instructions:

http://pydev.org/manual_101_install.html

DO NOT declare the system variable PYTHONPATH as c:\Python26, since this will be done automatically by the Intepreter configuration wizard

Configure the Intepreter (Window/Preferences/Pydev/Interpreter Jython...)
specifying C:\Python26\python.exe for Python
http://pydev.org/manual_101_interpreter.html

and accept the path proposed by default.

Configure the Jython Intepreter (WLST IS Jython, so.... who cares about the Python interpreter!)
and specify
C:\bea11\oracle_common\util\jython\jython.jar

and accept the defaults.

mmm it doesn't seem to recognize the WLST commands, like connect and edit... there must be some trick...

ok I give up for lack of time and itnerest, if anyone knows the answer please write a comment.