Wednesday, February 15, 2012

Getting rolling with drools rules engine server

We are trying out drools as a rules engine and it took me a little while to understand and get drools-server setup in tomcat and interact via soap. So here are my notes for future reference.

0) Documentation can be found here, but it wasn't fully helpful:
http://docs.jboss.org/drools/release/5.3.0.Final/droolsjbpm-integration-docs/html_single/#d0e666

1) Download and install a fresh copy of Tomcat. I used 6.0.35 (not 7). My JRE was 1.6.0_24-b07.

2) Download and unzip the Drools integration project:
http://download.jboss.org/drools/release/5.3.0.Final/droolsjbpm-integration-distribution-5.3.0.Final.zip

 3) Take the "drools-server-app.war" file from the "binaries" directory unpacked above and drop it in your Tomcat webapps directory and fire up tomcat. It will unpack the war file into webapps/drools-server-app directory.

4) Tomcat wouldn't actually deploy my drools-server-app because of the following error:

Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [META-INF/cxf/cxf-extension-jaxrs-binding.xml]; nested exception is java.io.FileNotFoundException: class path resource [META-INF/cxf/cxf-extension-jaxrs-binding.xml] cannot be opened because it does not exist
       at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:349)
       at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
       at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
       at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
       at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(DefaultBeanDefinitionDocumentReader.java:174)
       ... 52 more
Caused by: java.io.FileNotFoundException: class path resource [META-INF/cxf/cxf-extension-jaxrs-binding.xml] cannot be opened because it does not exist
       at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:143)
       at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:336)

I found this:
http://stackoverflow.com/questions/6349424/apache-cxf-rs-extensions-issue-in-2-4-0
so in my webapps/drools-server-app/WEB-INF/classes/camel-server.xml I removed:

 <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"/>
 <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
 <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

which did the trick and I could then restart Tomcat and it would successfully load the drools-server-app.

5) Now I could visit http://localhost:8080/drools-server-app/kservice which gave me a list of available services.

6) I wanted to try interacting via soap, so I clicked on the soap service WSDL link (http://localhost:8080/drools-server-app/kservice/soap?wsdl) but that gave me a soap fault error.

7) I went to my webapps/drools-server-app/WEB-INF/classes/soap.wsdl and edited my binding soap address and made it:

  <wsdl:service name="CommandExecutor">
    <wsdl:port binding="tns:CommandExecutorSoapBinding" name="CommandExecutorPort">
        <soap:address location="http://127.0.0.1:8080/drools-server-app/kservice/soap"/>
    </wsdl:port>
  </wsdl:service>

8) I restarted tomcat and tried again to view the wsdl. That still did not work. I decided to ignore that for now and see if I could still communicate via soap anyway.

 9) I downloaded soapUI:
http://sourceforge.net/projects/soapui/files/soapui/4.0.1/soapui-4.0.1-win32-standalone-bin.zip/download
unzipped it and ran bin/soapui.bat

10) I created a new project in soapui and browsed to my local webapps/drools-server-app/WEB-INF/classes/soap.wsdl file as my initial wsdl since the url wouldn't work for me.

11) I created a soap request message in soapui according to salaboy:
http://salaboy.com/2011/04/05/drools-in-real-life-droolsjbpm5-server-first-steps/
(Thanks!)
like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://soap.jax.drools.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <soap:execute>
    <soap:arg0><![CDATA[

<batch-execution lookup="ksession1">
<insert out-identifier="person1">

 <org.test.Message>
    <text>salaboy</text>
 </org.test.Message>
 </insert>
 <fire-all-rules/>
</batch-execution>
]]>
</soap:arg0>
      </soap:execute>
   </soapenv:Body>
</soapenv:Envelope>

and when I clicked send (green arrow) button, I received:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <ns1:executeResponse xmlns:ns1="http://soap.jax.drools.org/">
         <ns1:return><![CDATA[<?xml version='1.0' encoding='UTF-8'?><execution-results><result identifier="person1"><org.test.Message><text>echo:salaboy</text></org.test.Message></result><fact-handle identifier="person1" external-form="0:2:16823234:1:2:DEFAULT"/></execution-results>]]></ns1:return>
      </ns1:executeResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

12) So it looks like everything is working. I'm very much looking forward to getting into drools now that I have an engine up!