Wednesday, June 30, 2010

Oracle MFL tutorial

All the documentation is here:
http://download.oracle.com/docs/cd/E13160_01/wli/docs10gr3/pdf/fbhelp.pdf

Some examples here:
http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/userguide/testing.html#wp1041203

Excellent tutorial here

http://biemond.blogspot.com/2008/12/flat-file-to-xml-with-oracle-service.html


In a OSB Project, do New, Other, Oracle Service Bus, MFL. Enter a name, like MQFeedParser.
You get this:




GEOMQFeed is the "Message Format", i.e. the "Root Element".

From here you can either insert a Group or a Field. A Group can contain other Groups and/or Fields.
A Group can be OPTIONAL or REQUIRED
A Group can repeat itself
You can define a Group once and use Group References to instantiate it multiple times.

"Choice of Children" means that only one of the fields specified is allowed.

Group Occurrence is self-explanatory.

A TAGGED GROUP is a Group whose start is preceded by a specific value, like NEWGROUP:ACME (the tag being NEWGROUP: and the group name being ACME)


________________________________


A good way to test the MFL is to write a File Transport PS with MFL input

For instance this:

<?xml version='1.0' encoding='windows-1252'?>
<!DOCTYPE MessageFormat SYSTEM 'mfl.dtd'>
<!--   Enter description of the message format here.   -->
<MessageFormat name='SampleMFL' version='2.02'>
    <StructFormat name='Employees' delimOptional='y' repeat='*'>
        <FieldFormat name='Name' type='String' delimOptional='y' length='12' strlenInChars='n' codepage='windows-1252'/>
        <FieldFormat name='Age' type='String' delimOptional='y' length='3' strlenInChars='n' codepage='windows-1252'/>
    </StructFormat>
</MessageFormat>

when your input is this
Pierre01 345Pierre02 346

should return you

<?xml version="1.0" encoding="UTF-8"?>
<SampleMFL>
  <Employees>
    <Name>Pierre01</Name>
    <Age>345</Age>
  </Employees>
  <Employees>
    <Name>Pierre01</Name>
    <Age>345</Age>
  </Employees>
</SampleMFL> 
 
 



If the input data doesn't match the MFL you get:

com.bea.wli.sb.sources.TransformException: Failed to transform MFL content from binary to XML

Caused By: <MFLException>
<ErrorMessage>Did not completely process all input data.</ErrorMessage>
<Details>
<Detail>
<Name>ErrorCode</Name>
<Value>-3</Value>
</Detail>
<Detail>
<Name>DataOffset</Name>
<Value>15</Value>
</Detail>
</Details>
</MFLException>
at com.bea.nonxml.common.MFLException.create(MFLException.java:221)
at com.bea.nonxml.common.MFLException.create(MFLException.java:337)
at com.bea.nonxml.readers.NonXMLReaderVisitor.nextToken(NonXMLReaderVisitor.java:155)
at com.bea.nonxml.readers.TokenNonXMLReader.nextToken(TokenNonXMLReader.java:44)
at com.bea.binxml.v2.readers.SaxTokenReader$ExtendedTokenReaderWrapper.nextToken(SaxTokenReader.java:335)
at com.bea.binxml.v2.readers.SaxTokenReader.process(SaxTokenReader.java:189)
at com.bea.binxml.v2.readers.SaxTokenReader.process(SaxTokenReader.java:154)
at com.bea.wli.common.mfl.MflExecutor.executeXmlObject(MflExecutor.java:126)
at com.bea.wli.sb.resources.mfl.MflExecutor.executeXmlObject(MflExecutor.java:98)
at com.bea.wli.sb.stages.transform.MflTransformImpl.executeXmlObject(MflTransformImpl.java:84)
at com.bea.wli.sb.sources.MFLSource.getInstance(MFLSource.java:113)
at com.bea.wli.sb.sources.MFLTransformer.transform(MFLTransformer.java:75)
at com.bea.wli.sb.sources.MetaTransformer.doTransform(MetaTransformer.java:138)
at com.bea.wli.sb.sources.MetaTransformer.transform(MetaTransformer.java:89)




This http://forums.oracle.com/forums/thread.jspa?threadID=945164 should help,
"try to change the message type from text to binary"

Here
C:\bea11\Oracle_OSB11\lib\modules\com.bea.alsb.resources.mfl.jar

is the MflExecutor


There is this tool WLXT

http://download.oracle.com/docs/cd/E13214_01/wli/docs70/classdocs/com/bea/wlxt/WLXT.html

to unittest MFL.
You should include in the CLASSPATH : com.bea.wli.transform.fbruntime_1.1.0.0.jar and weblogic.jar


File binaryfile = new File("c:/geodata.dat");
WLXT wlxt = new WLXT();
URL mflDocumentName = new URL("file:c:/geodata.mfl");
FileInputStream in = new FileInputStream(mybinaryfile);
Document doc = wlxt.parse(mflDocumentName, in, null);
String xml = WLXT.getXMLText(doc, 0, 2);
System.out.println(xml);


MFL and Excel

I don't think anybody in his right state of mind would actually use the Format Builder graphical tool to write MFL files.

In fact the MFL file is a simple XML file, I found it very convenient to stick the structure of my binary message in an Excel file, and generate the XML using simple Excel formulas.

Most of the time you use only a few MFL options so it's pretty trivial to generate automatically the XML file.

I wish I had the time to develop some sort of DSL or something.... the MFL.DTD is here

http://download.oracle.com/docs/cd/E13182_01/elink/elinkii/v10/usergd/appendb.htm

Here I generated the equivalent XSD:

http://javatoolsforweblogic.googlecode.com/svn/trunk/MFL/MFL.xsd

Sunday, June 27, 2010

Representing Collections in WSDL and XSDs

Some people like to represent a Collection of elements as a sequence, without an aggregation element. For instance, if I want to return an array of Location object, I return you this:

<getLocations>
   <Location>Roma</Location>
   <Location>New York</Location>
   <Location>Ouagadougou</Location>
<getLocations>

being getLocation the operation name.

I think this sucks, big time.

I would much rather have:

<getLocations>
  <Locations>
      <Location>Roma</Location>
      <Location>New York</Location>
      <Location>Ouagadougou</Location>
   </Locations>
<getLocations>

It makes the XML a lot more readable and easier to manipulate.
You can add extra info by keeping it hierarchically separated from the collection.
Besides, this is the way the default unmarshaling mechanism from Java (EJB) to OSB works for any type of Java Collection - Sets, Lists, Arrays.

Wednesday, June 23, 2010

This project is not associated with an Oracle Service Bus Configuration.

Let's face it, the Eclipse Plugin for OSB in 11g has still some problems.
Closing and opening a Configuration and its Projects doesn't bring you back to the initial state: you get a nice

This project is not associated with an Oracle Service Bus Configuration.

error.

What to do? I have tried several hacks, including restarting Eclipse,
finally the only solution was to create a new configuration and drag the project inside.

Saturday, June 19, 2010

Enhancing your blog with proper code formatting

Today Luciano told me my blog is a mess, at least I should properly format my code. He is right.
I have followed these instructions:

http://concise-software.blogspot.com/2010/03/enabling-syntaxhighlighter-in-blogger.html



I am testing now:
this is done with the xml brush:

Using <pre name="code" class="brush: xml"> :

<?xml version="1.0" encoding="UTF-8"?>
<Employee>
 <name>Pierre</name><age>33</age>
</Employee>


this is done with the java brush:

Using <pre name="code" class="brush: java"> :

public class XMLLoaderTest {
 @Test
 public void testname() throws Exception {
  XMLLoader<Employee> loader = new XMLLoader<Employee>();
  Employee emp = loader.getObjectFromXMLFile(Employee.class, "testResources/Employees.xml");
  System.out.println(emp.getName() + " " + emp.getAge());
 }
}



import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.File;

/**
 * Helper class to load Java Objects from an XML document
 * See test methods for usage  
 * @author pierre
 *
 * @param <T>
 */
public class XMLLoader <T> {
 /**
  * Loads an object from a XML file
  * @param theClass
  * @param fileName
  * @return
  * @throws JAXBException
  */
 public T getObjectFromXMLFile(Class theClass, String fileName) throws JAXBException {
  T result = null;
  JAXBContext jc = JAXBContext.newInstance(theClass);
  Unmarshaller unmarshaller = jc.createUnmarshaller();
  result = (T)unmarshaller.unmarshal(new File(fileName));
  return result;
 }
}


It works!
Make sure that you include the BrushXyz.js file when you use the "brush: xyz"


Also, I had to load some additional js (you can copy them from my HTML source) to make it look really pretty.

I have the impression that this beauty comes with a cost: the page is slower to load.


I have now copied the .js and .css files to my google site,  it seems much faster!

Yesterday...

This is too funny... who said that IT people have no artistic sense?



Wednesday, June 16, 2010

JRockit Flight Recording failing with "Could not download recording"

Running a Flight Recording with JRockit Mission Control 4.0 I get this error message:

Could not download recording for lassi3.
  java.io.FileNotFoundException: No chunks

Googling around there is absolutely nothing on this topic....

Even running the recording with a local JRMC console gives the same error.
I had to restart WebLogic to make it work again... no error message in the logs... strange indeed.

OSB, closing a Project belonging to a Configuration will fail deployment

I find this feature a bit irritating:
you create configuration AConf,
you create inside two projects:
AProj
BProj


Now you close BProj and you deploy AConf to the server from Eclipse.

You will get an error message reminding you that BProj is closed.
I would expect that, since I am deploying only AProj, the state of BProj doesn't really matter.

Workaround: either keep the BProj open, or move it to another configuration.

I like to keep open only the projects I am currently working on, to improve Eclipse performance issues and avoid getting confused while I click around.


I would also strongly discourage renaming projects, I have the impression the old name still hangs around in some configuration file, and when you deploy you get an error message:

Resource '/yourProjectName' does not exist.

after I have renamed yourProjectName intosomething else.


In fact you can go into ConfigurationProject/.setting/com.bea.alsb.core.prefs
and there is a property
container.referenced.projects=yourProjectName1|yourProjectName2|

Just remove the one you don't need... it's a hack but it works.

Remember to refresh the ConfigProject in Eclipse afterwards, close the ConfigProject and reopen it.

The big ball of mud

just allow me to pay an homage to my favorite article on IT:
brilliantly written a long time ago, still absolutely actual. A must read.
http://www.laputan.org/mud/


A picture evoking SPAGHETTI CODE:



the lady must be one of those managers who still believe that the number of lines produced is a valid metric of productivity. There must still be one or two around.

Monday, June 14, 2010

OSB and EJB: the secret to get some result back from the EJB

I use a BS to expose an EJB in OSB.

As long as I was returning simple data types (String, Long), no problem.

When you return a POJO (Java Bean), you must know that:

a) the POJO must implement Serializable - this makes perfectly sense

b) the attributes that you expect back in OSB MUST be accompanied by getter AND setter - a getter is not enough

c) the namespace of the response incorporates as namespace the package of the Response class:



<m:getMessageResponse xmlns:m="http://www.openuri.org/">
<m:return>
<java:Message xmlns:java="java:com.acme.geoosb.ejb">hello this is Pierre</java:Message>
<java:Age xmlns:java="java:com.acme.geoosb.ejb">13</java:Age>
</m:return>
</m:getMessageResponse>

(com.acme.geoosb.ejb.HelloMessage is the Class name of my return parameter)

and the POJO I am returning has attributes

String message;
int age;

Sunday, June 13, 2010

JRockit: jps and jstat

Good to know utilities:

C:\bea11\jrockit_160_17_R28.0.0-679\bin>jps
5552 Jps
5632 org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar

C:\bea11\jrockit_160_17_R28.0.0-679\bin>jstat
invalid argument count
Usage: jstat -help|-options
jstat -

OSB and Coherence, a real life scenario with performance data


Here http://javatoolsforweblogic.googlecode.com/svn/trunk/OSBArtifacts/OSBCachingTests.jar you have a sample project that you can explore and play with. I also log if the cache was hit or missed.


Make sure you enable Caching in OSB: "Operations/Global Settings/Enable Result Caching".

You can configure caching only at Business Service level:


and make sure you extract the Cache Token (a unique ID for the request) from the payload.

Make sure you read this:

in order to test result caching, do not invoke the business service directly from the test console

You should then create a PS with a routing node pointing to the BS, and using inbound operation for outbound.

The configuration is:

GeoOsbServicePS is the actual service
GeoOsbServiceBS is the BS with caching enabled, and pointing to GeoOsbServicePS
GeoOsbServiceWithCachePS is simply a facade to expose the GeoOsbServiceBS

Test with cache:



Test without cache:






Using SoapUI I am injecting a 5 Threads load, first on the GeoOsbServicePS Proxy Service (no cache) and then on the GeoOsbServiceWithCachePS. These are the average response times measured:

GeoOsbServicePS : 47 ms
GeoOsbServiceWithCachePS : 13 ms

I was requesting over and over the same data.... for a more realistic test we should try requesting a variety of data.... the improvement of course will heavily depend on the hit/miss ratio.... if the overhead introduced by the extra PS and the caching layer is not justified by the percentage of hits, then performance will be deteriorated...


It is particurarly fascinating to observe the outbound message to the BS:

cache token in this case is the unique identifier extracted from the payload, and the TTL in cache is set to 30 minutes


<tran:cache-token xmlns:tran="http://www.bea.com/wli/sb/transports">2</tran:cache-token>
<tran:cache-ttl xmlns:tran="http://www.bea.com/wli/sb/transports">PT30M</tran:cache-ttl>

the outbound response contains:

<tran:cache-originated xmlns:tran="http://www.bea.com/wli/sb/transports">false</tran:cache-originated>

the first time, and for subsequent invocations it becomes true.


Which Cache Token Expression are you allowed to use? Not any user defined expression, but only one dependent on:
$body, $header, $operation or $metadata.

otherwise you will get a OSB Kernel BEA-398311 error
Cache Token expression is using invalid variable variableName.

The good thing is that you can use a single BS to cache the result of multiple operations on an external service, since the actual token used in Coherence will be made by your Cache Token + Operation + BS Identifier, so there is no chance that two different operations conflict with each other because they provide the same token.





When you start your OSB server, you should find this:


<13-06-2010 16:05:25 CEST> <Info> <Coherence> <BEA-000000> <Oracle Coherence 3.5.3/465p2 (member=n/a): Loaded operational configuration from resource "zip:C:/bea11/coherence_3.5/lib/coherence.jar!/tangosol-coherence.xml">

<13-06-2010 16:05:25 CEST> <Info> <Coherence> <BEA-000000> <Oracle Coherence 3.5.3/465p2 (member=n/a): Loaded operational overrides from resource "zip:C:/bea11/coherence_3.5/lib/coherence.jar!/tangosol-coherence-override-dev.xml">

<13-06-2010 16:05:25 CEST> <Info> <Coherence> <BEA-000000> <Oracle Coherence 3.5.3/465p2 (member=n/a): Loaded operational overrides from resource "zip:C:/bea11/user_projects/domains/osbdomain/servers/AdminServer/tmp/_WL_user/ALSB Coherence Cache Provider/sm027g/APP-INF/lib/com.bea.alsb.coherence-impl.jar!/tangosol-coherence-override.xml">

<13-06-2010 16:05:25 CEST> <Info> <Coherence> <BEA-000000> <Oracle Coherence 3.5.3/465p2 (member=n/a): Loaded operational overrides from resource "file:/C:/bea11/user_projects/domains/osbdomain/config/osb/coherence/osb-coherence-override.xml">

<13-06-2010 16:05:26 CEST> <Warning> <Coherence> <BEA-000000> <Oracle Coherence 3.5.3/465p2 (member=n/a): Local address "127.0.0.1
" is a loopback address; this cluster node will not connect to nodes located on different machines>

<13-06-2010 16:05:29 CEST> <Info> <Coherence> <BEA-000000> <Oracle Coherence 3.5.3/465p2 (member=n/a): Created a new cluster "OSB-
cluster" with Member(Id=1, Timestamp=2010-06-13 16:05:26.258, Address=127.0.0.1:7890, MachineId=50080, Location=machine:localhost,
process:4468, Role=OSB-node, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=2) UID=0x7F0000010000012931A11172C3A0
1ED2>
<13-06-2010 16:05:30 CEST> <Info> <OSB Coherence WebLogic> <BEA-2032482> <The OSB Coherence Cache Provider has been initialized wi
th com.bea.alsb.coherence.impl.CoherenceProvider: SafeCluster: Name=OSB-cluster

WellKnownAddressList(Size=1,
WKA{Address=127.0.0.1, Port=7890}
)

MasterMemberSet
(
ThisMember=Member(Id=1, Timestamp=2010-06-13 16:05:26.258, Address=127.0.0.1:7890, MachineId=50080, Location=machine:localhost,p
rocess:4468, Role=OSB-node)
OldestMember=Member(Id=1, Timestamp=2010-06-13 16:05:26.258, Address=127.0.0.1:7890, MachineId=50080, Location=machine:localhost
,process:4468, Role=OSB-node)
ActualMemberSet=MemberSet(Size=1, BitSetCount=2
Member(Id=1, Timestamp=2010-06-13 16:05:26.258, Address=127.0.0.1:7890, MachineId=50080, Location=machine:localhost,process:44
68, Role=OSB-node)
)
RecycleMillis=120000
RecycleSet=MemberSet(Size=0, BitSetCount=0
)
)

Services
(
TcpRing{TcpSocketAccepter{State=STATE_OPEN, ServerSocket=127.0.0.1:7890}, Connections=[]}
ClusterService{Name=Cluster, State=(SERVICE_STARTED, STATE_JOINED), Id=0, Version=3.5, OldestMemberId=1}
InvocationService{Name=Management, State=(SERVICE_STARTED), Id=1, Version=3.1, OldestMemberId=1}
).>



Never again without JMX

Simple tutorial to get started with exposing a Bean with JMX:
http://www.devdaily.com/blog/post/java/source-code-java-jmx-hello-world-application

and here
http://javatoolsforweblogic.googlecode.com/svn/trunk/JMXTest/

the Eclipse project in SVN (remember to set the JVM arguments as specified in the SimpleAgent javadoc)

Run SimpleAgent in Eclipse, run JConsole, connect to SimpleAgent and you can invoke the methods and inspect the attributes via JMX... fabulous!


It's great HtmlAdaptorServer to implement the solution depicted here.

To download the JDMK HtmlAdaptorServer go here: http://java.sun.com/products/jdmk/

JMeter and testing Web Services

I add a Sampler "WebService(SOAP) Request", enter a perfectly working WSDL url (tested also in the browser)... click on "Load WSDL"... nothing happens, the Web Methods drop down doesn't get populated and nothing is logged on the JMeter console.

http://jakarta.apache.org/jmeter/usermanual/build-ws-test-plan.html

If the WSDL file was loaded correctly, the "Web Methods" drop down should be populated. If the drop down remains blank, it means there was a problem getting the WSDL. 

Pardon me for being so old fashioned, but in the old days programmers used to LOG what the problem was... I look also in the jmeter.log file in the bin directory (a log file in the bin directory????) and nothing...

JMeter would be a great tool if only it had been better coded....

So I am using SOAPUI (great great tool):
http://soapui.com/Functional-Testing/structuring-and-running-tests.html

an forget JMeter, its UI anyway is pretty bad, they need someone who knows how to do Swing.


Saturday, June 12, 2010

JRockit R28 Flight Recorder (ex JRA)

Official documentation here:


http://download.oracle.com/docs/cd/E15289_01/doc.40/e15070/usingjfr.htm
entire PDF:
http://download.oracle.com/docs/cd/E15289_01/doc.40/e15070.pdf

interesting reading
http://blogs.oracle.com/jrockit/2010/04/jrockit_r28_ropsten_released.html


C:\bea11\user_projects\domains\osbdomain>jrcmd
576 jrockit.tools.jrcmd.JrCmd

3356 org.apache.derby.drda.NetworkServerControl start

1908 weblogic.Server



C:\bea11\user_projects\domains\osbdomain>jrcmd 1908 help
1908:
The following commands are available:
kill_management_server
start_management_server
print_object_summary
memleakserver
print_class_summary
print_codeblocks
dump_codelayout
dump_codelist
dump_codemap
print_codegenlist
print_vm_state
print_utf8pool
check_flightrecording
dump_flightrecording
stop_flightrecording
start_flightrecording
print_properties
hprofdump
print_threads
datadump_request
runsystemgc
runfinalization
heap_diagnostics
oom_diagnostics
print_exceptions
version
timestamp
command_line
sanity
verbosity
set_filename
help
print_memusage
set_vmflag
list_vmflags
For more information about a specific command use 'help '.
Parameters to commands are optional unless otherwise stated.







C:\bea11\user_projects\domains\osbdomain>jrcmd 1908 start_management_server
1908:


C:\bea11\user_projects\domains\osbdomain>jrcmd 1908 help start_flightrecording
1908:
Starts a JFR recording
name - Name of recording (string)
settings - Settings file or preset (string)
defaultrecording - Starts default recording (bool, false)
delay - Delay recording start (time, 0s)
duration - Duration of recording (time, 0s)
filename - Resulting recording filename (string)
compress - GZip-compress the resulting recording file (bool,
false)
maxage - Maximum age of buffer data (time, 0s)
maxsize - Maximum size of buffers in bytes (long, 0)




C:\bea11\user_projects\domains\osbdomain>jrcmd 1908 start_flightrecording duration=2m name=myfirstgeoosbrecording
1908:
Started recording 2



C:\bea11\user_projects\domains\osbdomain>jrcmd 1908 start_flightrecording duration=2m name=myfirstgeoosbrecording2
1908:
Started recording 3


C:\bea11\user_projects\domains\osbdomain>jrcmd 1908 check_flightrecording
1908:
Recording : id=1 name="WLDFDiagnosticImageRecording_osbdomain_AdminServer_" duration=0s dest="C:\bea11\user_projects\domains\osbdomain\servers\AdminSe
rver\logs\diagnostic_images\__tmp847859670567686703.jfr" compress=false (running)
Recording : id=2 name="myfirstgeoosbrecording" duration=120s (stopped)
Recording : id=3 name="myfirstgeoosbrecording2" duration=120s (stopped)


C:\bea11\user_projects\domains\osbdomain>jrcmd 1908 help dump_flightrecording
1908:
Copies contents of a JFR recording to file
name - Recording name (string)
recording - Recording id (long, -1)
copy_to_file - Copy recording data to file (string)
compress_copy - GZip-compress "copy_to_file" destination (bool, false)



C:\bea11\user_projects\domains\osbdomain>jrcmd 1908 dump_flightrecording name=myfirstgeoosbrecording recording=2 copy_to_file=myfirstgeoosbrecordingf
ile.jfr compress_copy=true
1908:


C:\bea11\user_projects\domains\osbdomain>dir

Directory of C:\bea11\user_projects\domains\osbdomain
......
12-06-2010 16:53 206.158 myfirstgeoosbrecordingfile.jfr

......


Now you can open the file with JRockit Mission Control


To dump on OutOfMemoryException:
-XX:+FlightRecordingDumpOnUnhandledException

To specify a settings file (more than 1 is possible):
-XX:FlightRecorderOptions=settings=s1.jfs,settings=s2.jfs



To start recording:
jrcmd start_flightrecording settings=filename.jfs

In JROCKIT_HOME\jre\lib\jfr\default.jfs you find an example of settings.

Non-Persistent (profiling data are kept im memory only) is the default storage mode. Typically max 1 minute of history.


REMEMBER TO ENABLE THE "DIAGNOSTIC VOLUME" setting (to Low, Medium or High, but not Off) on your WebLogic server configuration, otherwise Hot Methods will not work!




axis2 EndpointReference

To point your Axis2 client stub to any server:

    private static final String SERVER_NAME = "localhost:7001";

    private static final String TARGET_ENDPOINT = "http://" + SERVER_NAME + "//GEO_OSB_Portal/PS/GeoOsbServicePS";



    /**
     * Return a valid instance of a Stub, ready to invoke methods
     * @return
     * @throws AxisFault
     */
    private GeoOsbServiceStub getStub() throws AxisFault {
        GeoOsbServiceStub stub = new GeoOsbServiceStub();
        EndpointReference targetEpr = new EndpointReference(TARGET_ENDPOINT);
        stub._getServiceClient().setTargetEPR(targetEpr );
        return stub;
    }

Problem invoking WLST : IOError: Not enough storage is available to process this command

Problem invoking WLST - Traceback (innermost last):
  (no code object) at line 0
IOError: Not enough storage is available to process this command



Ok, I understand this error is not originated from WLST, but rather inside Windows XP.... yet it would be ncie to know what WLST was doing when this occurred.

Windows Explorer Open a Command Prompt

Here

http://javatoolsforweblogic.googlecode.com/svn/trunk/windowsTricks/dosprompt.reg


the registry entry to create the command in Windows Explorer.
I was tired of googling for it every time I work on a new computer.

Friday, June 11, 2010

WebLogic 11 clientgen and Java Client for a WebLogic Web Service

after having added tons of JARs to the classpath, I still get this error message:

java.lang.IllegalAccessError: tried to access class weblogic/wsee/jaxws/WLSContainer$WLSContainerResolver$1 from class weblogic/wsee/jaxws/WLSContainer$WLSContainerResolver

I give up hopes on clientgen.  I will simply use Axis2 libraries.


http://ws.apache.org/axis2/1_1_1/userguide-creatingclients.html

to get the xmlbeans data binding just run:

cd C:\apps\axis2-1.5.1\bin
wsdl2java.bat -d xmlbeans -uri C:/temp/GEOOSBService.WSDL

Remember first to set AXIS2_HOME to C:\apps\axis2-1.5.1

actually the advantage of using Axis databinding option (no -d xmlbeans, use the default) is that you have only 2 Java files to use:
GeoOsbServiceCallbackHandler.java and
GeoOsbServiceStub.java

I like simplicity!

Thursday, June 10, 2010

WSDL Parser

Since I am not a monkey (well, I am, but with some value added),
I don't like to type what I can generate.

It happens often to have to generate the same kind of artifacts for each operation in a WSDL.
It becomes then very important to be able to parse the WSLD and find out all its components.

Good candidates containing a WSDLDocument class are:
C:\bea11\oracle_common\modules\oracle.webservices_11.1.1\orawsdl.jar
C:\bea11\Oracle_OSB11\lib\modules\com.bea.alsb.resources.wsdl.jar
C:\bea11\Oracle_OSB11\lib\modules\com.bea.alsb.ws.schemas.wsdl.jar

Also

C:\bea11\jdk160_18\lib\tools.jar
or C:\bea11\jrockit_160_17_R28.0.0-679\lib\tools.jar
C:\bea11\modules\glassfish.jaxws.tools_1.0.0.0_2-1-5.jar
C:\bea11\oepe_11gR1PS2\plugins\org.apache.wsil4j_1.0.0.v200901211807.jar
C:\bea11\oepe_11gR1PS2\plugins\org.eclipse.wst.wsdl.validation_1.1.402.v200911251542.jar
C:\bea11\oepe_11gR1PS2\plugins\org.eclipse.wst.wsi_1.0.305.v200902181431.jar
C:\bea11\oracle_common\modules\oracle.webservices_11.1.1\oracle.webservices.standalone.client.jar

C:\bea11\oracle_common\modules\sun.tools_1.6.0.jar
C:\bea11\Oracle_OSB11\lib\sb-kernel-resources.jar


I have tried some of them but could not make them work.


This http://oracled.wordpress.com/2009/02/04/parse-wsdl-effectively/ gives some clues.

Oracle WSDL parser: you get it by installing JDeveloper, it's in C:\beajdev11\jdeveloper\webservices\lib\wsdl.jar

Apache Woden http://ws.apache.org/woden/userguide.html

JWSDL http://wsdl4j.sourceforge.net/


Javadoc of Oracle WSDL parser is at
http://download-uk.oracle.com/docs/cd/A97688_16/generic.903/q20234/index.html


Using the Oracle WSDL parser, I get a


Exception in thread "Main Thread" oracle.wsdl.internal.WSDLException: oracle.xml.parser.v2.XMLParseException: Start of root element expected.
    at oracle.wsdl.WSDLDocument.getDefinitions(WSDLDocument.java:105)
    at com.acme.wsdl.WSDLParser.execute(WSDLParser.java:21)
    at com.acme.wsdl.WSDLParser.main(WSDLParser.java:16)


I give up.

I try Woden and I get:

WSDLException: faultCode=INVALID_WSDL: Fatal WSDL error:
0:0,WSDL501,Expected a "{http://www.w3.org/ns/wsdl}description" element, but found a "{http://schemas.xmlsoap.org/wsdl/}definitions" element instead.:


Googling around I discover that this means that my WSDL is a 1.1 while Woden processes only 2.0.

You can find here http://www.w3.org/2006/02/wsdl11to20.xsl a XSL converter from 1.1 to 2.0
Once converted 1.1 into 2.0 format, Woden manages to parse the WSDL but I get a warning:

The targetNamespace 'http://www.acme.com/NGP3Geo/2010/06/10/GeoOsbService' is not dereferencable.

which means (I think) that a URL connection open to retrieve the resource http://www.acme.com/NGP3Geo/2010/06/10/GeoOsbService gets a "connection refused" (to dereference= to access).

This is a piece of code to print all operations declared in a WSDL:


package com.acme.wsdl;

import org.apache.woden.WSDLException;
import org.apache.woden.WSDLFactory;
import org.apache.woden.WSDLReader;
import org.apache.woden.wsdl20.Description;
import org.apache.woden.wsdl20.xml.BindingElement;
import org.apache.woden.wsdl20.xml.DescriptionElement;
import org.apache.woden.wsdl20.xml.InterfaceElement;
import org.apache.woden.wsdl20.xml.InterfaceOperationElement;
import org.apache.woden.wsdl20.xml.ServiceElement;



public class WSDLParserApache {
public static void main(String[] args) throws WSDLException {
    WSDLParserApache wsdlParserApache = new WSDLParserApache();
     wsdlParserApache.execute();
}

public void execute() throws WSDLException {

String filename1 = "C:/bea11/user_projects/workshops/default/GEO_OSB_Portal/WSDL/GEOOSBService20.WSDL";

WSDLFactory factory = WSDLFactory.newInstance();

WSDLReader reader = factory.newWSDLReader();

reader.setFeature(WSDLReader.FEATURE_VALIDATION, true);

String wsdlurl = filename1;

DescriptionElement descElem = (DescriptionElement) reader.readWSDL(wsdlurl);

InterfaceElement[] interfaces = descElem.getInterfaceElements();

// getting all operations
for (InterfaceElement iface : interfaces) {
   for (InterfaceOperationElement ioe : iface.getInterfaceOperationElements()) {
       System.out.println(ioe.getName().getLocalPart());
   }
}

}
}

OSB: how to use properly fn-bea:execute-sql

Full documentation is here
http://download.oracle.com/docs/cd/E14571_01/doc.1111/e15867/xquery.htm#OSBAG451

This statement:

assign "fn-bea:execute-sql('geo_osb_ds',
     xs:QName('Location'),
     'select SITENAME, LATITUDE, LONGITUDE from GEO_SITE where SITEID > 0')" to sites

will NOT work, only 1 element will be returned.

Bear in mind that bea:execute-sql returns a element()* (with an *), which means that the XML-Fragment returned by the function NEEDS A CONTAINER NODE.

If you want the entire result set to be returned, provide a container node:

<locations>
{fn-bea:execute-sql('geo_osb_ds',
     xs:QName('Location'),
     'select SITENAME, LATITUDE, LONGITUDE from GEO_SITE where SITEID > 0')
}     </locations>   


One more thing:
this

fn-bea:execute-sql('geo_osb_ds',xs:QName('Location'),
'select SITENAME, LATITUDE, LONGITUDE from GEO_SITE where SITEID = $sideId')

will NOT work, the binding of $siteId will not happen. You must use this syntax:

fn-bea:execute-sql('geo_osb_ds',xs:QName('Location'),
'select SITENAME, LATITUDE, LONGITUDE from GEO_SITE where SITEID = ?', $sideId)


Besides, there is no way you can assign a namespace to the result of the query,
the namespace will always be empty:

<java:Location>
<SITEID xmlns="">1.0</SITEID>
<SITENAME xmlns="">Suresh</SITENAME>
<STATEID xmlns="">345.0</STATEID>
<COUNTRYID xmlns="">23.0</COUNTRYID>
</java:Location>


so when you acces it with XPath you should do something like:

declare namespace empty = "";

let $countryId = $item/empty:COUNTRYID/text()


Also, even if you provide a column name in lowercase, as in
select SITEID as siteid...
fn-bea:execute-sql will convert the element name in UPPERCASE.
This is a major pain in the neck, it means that you still need to map this element into whatever case you need.



As for using the SQL IN clause, forget to be able to do it using bind variable "?" in the SQL statement, and passing a XQuery string like 'element1, element2' : it will simply not work, I have tried everything. I don't know which SQL Statement is exactly generated, I should activate the SQL DEbug flag....
A workaround is forget the fn-bea:execute-sql ? bind variable mechanism and build your SQL query dynamically: 



let $sqlStat := fn:concat('select bla from bla where bla in "', $myListOfMatches, "'")
fn-bea:execute-sql('geo_osb20_ds', xs:QName('ns1:Location'), $sqlStat)

Dirty trick but it works.

OSB: trouble publishing projects from Eclipse Plugin to Server

this happens whenever you REMOVE a project.

I have the impression that deleting everything from the OSB Server, performing a clean (Servers tab) and republishing again fixes the issue.

See also here
http://forums.oracle.com/forums/thread.jspa?messageID=4314236&tstart=0


eclipse.buildId=unknown
java.version=1.6.0_17
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=en_US
Command-line arguments:  -os win32 -ws win32 -arch x86




Error
Thu Jun 10 11:07:34 CEST 2010
Runtime exception occurred during publish. The publish is aborted. Please report the bug with the stack trace. The stack can be found on the log and the Error Log view.


java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at com.bea.alsb.server.publish.internal.ALSBModuleFactory.getDeletedContainerModules(Unknown Source)
at com.bea.alsb.server.publish.ALSBPublishOperation.execute(Unknown Source)
at oracle.eclipse.tools.weblogic.server.internal.WeblogicServerBehaviour.performTasks(WeblogicServerBehaviour.java:1253)
at oracle.eclipse.tools.weblogic.server.internal.WeblogicServerBehaviour.publishToServer(WeblogicServerBehaviour.java:804)
at oracle.eclipse.tools.weblogic.server.internal.WeblogicServerBehaviour.publishOnce(WeblogicServerBehaviour.java:660)
at oracle.eclipse.tools.weblogic.server.internal.WeblogicServerBehaviour.publish(WeblogicServerBehaviour.java:526)
at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publish(ServerBehaviourDelegate.java:708)
at org.eclipse.wst.server.core.internal.Server.publishImpl(Server.java:2731)
at org.eclipse.wst.server.core.internal.Server$PublishJob.run(Server.java:278)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

Wednesday, June 9, 2010

OSB JEJB, exposing a OSB Proxy Service Message Flow as a EJB

Manual is here
http://download.oracle.com/docs/cd/E14571_01/doc.1111/e15866/jejb.htm#OSBDV1036

Further elaboration on this topic is available here:

http://biemond.blogspot.com/2010/06/jejb-transport-and-manipulating-java.html

If you create a Proxy Service as "Transport Typed Service", your only option is JEJB.

With Business Service you have EJB, JEJB and FLOW.

You should write the Interface:

package com.acme.jejb;

public interface EmployeeService {
    EmployeeResponse fireEmployee(Employee emp);
}


and the Employee and EmployeeResponse classes (omitted for clarity).
You package this in a Client Jar and use it in the definition of the PS. No implementation is required, since the Service will be the OSB Message Flow itself.

The nasty surprise it that you cannot test the PS from the Console, it says "the service is not testable since all its operations require Java arguments".

Yet if you go to the WebLogic Console, Deployments, you will see a new EJB module
_JEJB_ALSB_1276103248594 deployed in a EAR:

C:\ bea11\ user_projects\ domains\ osbdomain\ sbgen\ alsb_jejb_transport\ _JEJB_ALSB_1276103248594\ build\ dist\ _JEJB_ALSB_1276103248594. ear

with a Deployment Plan

C:\ bea11\ user_projects\ domains\ osbdomain\ osb\ config\ plan\ Plan-_JEJB_ALSB_1276103248594. ear. xml

and inside the EAR you have a Jar containing the Interface you specified in the service.

Inside you find also the Stateless Session Bean generated for you by OSB:



import com.bea.wli.sb.transports.jejb.gen.inb.BaseInboundEJBHelper;


import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.ejb.TransactionAttributeType;
import javax.ejb.Remote;


@Stateless(mappedName="EMPPS")
@Remote
@TransactionManagement(value=TransactionManagementType.CONTAINER)
public class CoherenceEJBProject_EMPPSBean extends BaseInboundEJBHelper implements com.acme.jejb.EmployeeService{


private final String targetNS = "http://www.openuri.org/";


@TransactionAttribute(value=TransactionAttributeType.SUPPORTS)
public com.acme.jejb.EmployeeResponse fireEmployee(
com.acme.jejb.Employee arg0 )
{
Object[] paramValues = new Object[1];
Class[] paramClasses = new Class[1];
String[] paramNames = new String[1];
// copy parameter values and classes into their arrays
paramValues[0] = arg0;
paramClasses[0] = com.acme.jejb.Employee.class;
paramNames[0] = "arg0";
// call the pipeline
try {
return (com.acme.jejb.EmployeeResponse) callPipeline("ProxyService$CoherenceEJBProject$EMPPS", "Archive$CoherenceEJBProject$employee", "fireEmployee", paramClasses,
paramValues, paramNames, true, targetNS, "com.acme.jejb.EmployeeResponse",
"Supports", true,
false);


} catch (Error e) {
throw e;
} catch (RuntimeException e) {
throw e;
} catch (java.lang.reflect.InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t instanceof Error) throw ((Error) t);
if (t instanceof RuntimeException) throw ((RuntimeException) t);
// check each declared exception
// obscure checked exception thrown as wrapped - ERROR!
throw new RuntimeException("Unsupported checked exception thrown wrapped", t);
}
} // end fireEmployee method definition
} // end CoherenceEJBProject_EMPPS class definition


Incidentally, com.bea.wli.sb.transports.jejb.gen.inb.BaseInboundEJBHelper is in
C:\bea11\Oracle_OSB11\lib\transports\jejb_transport.jar


Besides, some configuration is made available in

C:\bea11\user_projects\domains\osbdomain\osb\config\core\YOUR_OSB_PROJECT

in an XML fragment which contains the configuration of the PS (nothing particularly exciting).


At this point most likely you will notice the exception:

java.lang.NoClassDefFoundError: com/bea/wli/sb/transports/jejb/gen/inb/BaseInboundEJBHelper

YET the component seems to be deployed OK.


The JNDI Tree will contain these entries:

_JEJB_ALSB_1276103248594CoherenceEJBProject_EMPPS_jarCoherenceEJBProject_EMPPSEJB_EmployeeService

and

_JEJB_ALSB_1276103248594CoherenceEJBProject_EMPPS_jarCoherenceEJBProject_EMPPSEJB_Home


weblogic.ejb.container.internal.StatelessEJBHomeImpl_1033_WLStub

and now how shall I cast the JNDI lookup and make a remote call? I don't have the Remote interfaces here...

WIP

HelloWorld WSDL

Need a quick WSDL to make a dummy Web Service? Here you are:




  
    
      
        
          
            
          
        
      
      
        
          
            
          
        
      
    
  
  
    
  
  
    
  
  
    
      
      
    
  
  
    
    
      
      
        
      
      
        
      
    
  
  
    
      
    
  
 



Tuesday, June 8, 2010

Eclipse sucks

Well, let's say it could be more reliable.

I have a EJB Project, where I depend on some libraries developed by a colleague.
My colleague changes package of class from a.b.MyClass to acme.a.b.MyClass and gives me the new libraries.
I correct my code, do a clean build, export the EAR and deploy. At activation, I get a ClassNotFoundException a.b.MyClass.   WTF??? I am sure I have refactored everything!

I shutdown Eclipse and restart... I repeat the clean build, I delete the tmp, stage and cache directories on the WebLogic server, I even create a new domain.... always the same problem.

At last, I create a new EJB project and copy into it the EJB classes. This time it works.

So my guess it that even a CLEAN build doesn't really clean everything...
the message is: when you see something weird in Eclipse, don't think of something wrong that YOU might have done.... think first that Eclipse might be playing some trick on you.

I am seriously wishing that Oracle embraces NetBeans.... in a previous life I have used IntelliJ Idea, never been happier.

OSB, WebLogic and Derby Database Console with NetBeans

After installation of OSB11, we get by default a DataSource connecting to this database:

jdbc:derby://localhost:1527/osbexamples;create=true;ServerName=localhost;databaseName=osbexamples

with driver
org.apache.derby.jdbc.ClientDriver

user=DEV_SOAINFRA

To connect a Console with NetBeans 6.8 do this:

Window/Services

open the Databases tab

there should be already a jdbc:derby .../samples

you can edit it (or create a new one) with these properties:

URL: jdbc:derby://localhost:1527/osbexamples
Driver: org.apache.derby.jdbc.ClientDriver
Schema: APP
User: DEV_SOAINFRA

in the schema DEV_SOAINFRA
you can open the table

WL_LLR_ADMINSERVER which contains:

XIDSTR    POOLNAMESTR    RECORDSTR
JDBC LLR Domain//Server    JDBC LLR Domain//Server    osbdomain//AdminServer
JDBC LLR Version    JDBC LLR Version    1.0

where osbdomain is your domain name, and AdminServer your admin server name.

So if you have multiple Weblogic Domains on the same machine, but only one instance of Derby running, you can create a new schema for a new user, and make sure that the second domain uses as a JDBC Pool user this new user, and update the "JDBC LLR Domain//Server" record with the name of your domain/adminserver.

This shold fix the infamous exception:


java.sql.SQLException: JDBC LLR, table verify failed for table 'WL_LLR_ADMINSERVER', row 
'JDBC LLR Domain//Server' record had unexpected value 'my_domain2//AdminServer' expected 
'my_domain//AdminServer'
 
 
An easier solution is to change (Wl Console : AdminServer/General/advanced options/JDBC LLR Table Name) the table name to use in LLR: the default is 
WL_LLR_ADMINSERVER but you can change it to something else)


Monday, June 7, 2010

java.lang.NoClassDefFoundError: weblogic/kernel/KernelStatus

This saved my life:

http://blogs.oracle.com/jamesbayer/2008/08/workshop_for_weblogic_103_jee.html

In the classpath tab, be sure to add the wlclient.jar file located here \wlserver_10.3\server\lib to the User Entries section and remove the WebLogic System Libraries from the Bootstrap Entries section.  If you forget to remove the WebLogic System Libraries, you will get a stack like this: Exception in thread "Main Thread" java.lang.NoClassDefFoundError: weblogic/kernel/KernelStatus

Sunday, June 6, 2010

Mockito vs Easymock

In my project they plan to use EasyMock, I am more in favour of Mockito,but I must be able to explain why...

You might read this http://xunitpatterns.com/index.html  before you start, to get familiar with terminology like Test Double, Test Spy etc.

Mockito presentation here (audio is awful):


http://www.youtube.com/v/rOcuSPUpuXs
http://www.youtube.com/v/fisGZtYRIso

http://www.youtube.com/v/UIjQ4zQ5oGA

remember that the SUT is the Controller, not the Service! You mock the Service to test the Controller. The audience has a real problem with that...


here the presentation slides
http://www.slideshare.net/rapaul/mockito-presentation


Mockito is about INTERACTION testing, not STATE testing.

Here a very good conceptual document:
http://szczepiq.files.wordpress.com/2008/08/dont-give-up-on-mocking.pdf

Some other slides here

http://www.slideshare.net/carrja99/mockito

here Mockito Javadoc:
http://mockito.googlecode.com/svn/tags/1.8.1-rc1/javadoc/index.html?index-all.html

WIP....

Weekend readings...

http://en.wikipedia.org/wiki/Agile_enterprise

you want to know what T-1 means? Read this:
http://en.wikipedia.org/wiki/Straight_Through_Processing

amazing guy, I want to read his Pattern Language - even if it's applied to urbanistic:
http://en.wikipedia.org/wiki/Christopher_Alexander

http://en.wikipedia.org/wiki/Donald_Knuth


very interesting, it reminds me of Peter's Law and Murphy's law:
http://en.wikipedia.org/wiki/Conway%27s_Law


http://en.wikipedia.org/wiki/Event-driven_architecture

Saturday, June 5, 2010

OSB dynamic routing to JRules

We want to provide a generic proxy to invoke JRules.

We provide a routing table in a jrulesEndpointLookupTable XQuery:

<operations>
<operation>
<name>checkemployee</name>
<endpoint>http://localhost:8080/DecisionService/ws/PV01_RuleApp/1.0/PV01_RuleProject/1.0</endpoint>
</operation>

<operation>
<name>checkcompany</name>
<endpoint>http://localhost:8080/DecisionService/ws/PV01_RuleApp/1.0/PV01_RuleProjectCompany/1.0</endpoint>
</operation>


</operations>


where we identify each Ruleset with an identifier (checkemployee).
The Request payload will specify this identifier (jrulesOperation), together with the JRules payload:

<xsd:element name="DecisionServiceRequest">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:element name="jrulesOperation" type="xsd:string"/>
            <xsd:element name="jrulesPayload" type="xsd:anyType"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>


This is a sample payload:

<dec:DecisionServiceRequest xmlns:dec="http://www.ilog.com/rules/DecisionService">
    <dec:jrulesOperation>checkemployee</dec:jrulesOperation>
    <dec:jrulesPayload>
        <par:employeeRequest xmlns:par="http://www.ilog.com/rules/param" xmlns:emp="http://www.acme.com/Employee">
            <emp:EmployeeRequest>
                <emp:SSN>1234-56-7890</emp:SSN>
                <emp:name>Pierre</emp:name>
                <emp:dateOfBirth>1961-02-11</emp:dateOfBirth>
                <emp:employeeType>none</emp:employeeType>
                <emp:salary>20</emp:salary>
            </emp:EmployeeRequest>
        </par:employeeRequest>
    </dec:jrulesPayload>
</dec:DecisionServiceRequest>

where par:employeeRequest is the verbalization of the input parameter in JRules.

The OSB proxy service must:

- extract the jrulesOperation (checkemployee) and payload:

$body/dec:DecisionServiceRequest/dec:jrulesOperation/text()
$body/dec:DecisionServiceRequest/dec:jrulesPayload/node()

- do a lookup on the jrulesEndpointLookupTable to determine the endpoint:

$jrulesEndpointTable/operation[name=$jrulesOperation]/endpoint/text()

- do a Service Callout by using the Routing Option element to set the URI


- return as a body the response from JRules:

replace . in variable body with variable jrulesResponse

WLST script to change target to all deployments in a domain

instead of AdminServer write the name of your target server.

#Script to change target of all modules in a WL domain
#@Author Pierluigi Vernetto
#@Date 2010-06-04

connect('weblogic', 'weblogic0', 't3://localhost:7001')
edit()
startEdit()

cd('AppDeployments')
y=ls(returnMap='true')

for i in y :
  print i
  cd(i)
  print(cmo)
  set('Targets',jarray.array([ObjectName('com.bea:Name=AdminServer,Type=Server')], ObjectName)) 
  cd('..')


save()
activate()



Wednesday, June 2, 2010

JaboWS

JaBoWS is an acronym for "Just a Bunch of Web Services", a software architectural antipattern designating a Service Oriented Architecture solution which doesn't have a governance.

(I had created this entry in Wikipedia but, as usual, they have deleted it.... I am frankly giving up on trying to contribute to Wikipedia, they are simply too totalitarian for my taste).

Tuesday, June 1, 2010

JRules: deploying a Ruleset as a Web Service

Something cool is "Import-Rule Studio Samples and Tutorials", a nice one is webdecisionservice. unfortunately it looks like the example is in Java binding, and not XML binding.... If I want to expose the Ruleset as a Web Service I need to use XML binding (is this true?).
XML handling is done with IlrXmlDataDriver.


1)
Create a Java Project, call it PV01_JRulesResources, create a folder xsds and put inside this file:

http://sites.google.com/site/javamonamour/xsds/Employee.xsd?attredirects=0&d=1




2)
New, Rule Project with a BOM, call it PV01_RuleProject
no JAVA XOM
specify the Employee XSD as XML XOM:


3)
Add the Employee and EmployeeResponse XSDs as a parameter to the Ruleset (right click on PV01_RuleProject, properties, Ruleset Parameters, add employee as a IN parameter and verbalization employee, add employeeResponse as an OUT parameter and verbalization employeeResponse)
Don't forget to set the default value of the response to
new com.acme.employee.EmployeeResponse()

otherwise you will get a Null Pointer Exception when accessing it.

4) Code this business rule


if the name of employeeRequest is "Pierre" then
 set the fired of employeeResponse to "TRUE";

else set the fired of employeeResponse to "FALSE";



5) Create a Rule App project, add to it the RuleSet Project

6) Export the RuleApp project to a JAR, open the console http://localhost:8080/res and do "Deploy RuleApp Archive" and install the Rules.

7) click on "Get HTDS WSDL for this ruleset version", copy the WLSD link, go to SOAP UI and create a new Web Services Client project using the WSDL URL

8) you are now ready to test your rule from SOAP-UI! Time to celebrate.



In our case, we will get this SOAP message for test:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dec="http://www.ilog.com/rules/DecisionService" xmlns:par="http://www.ilog.com/rules/param" xmlns:emp="http://www.acme.com/Employee">
<soapenv:Header/>
<soapenv:Body>
<dec:DecisionServiceRequest>
<par:employeeRequest>
<emp:EmployeeRequest>
<emp:SSN>1234-56-7890</emp:SSN>
<emp:name>Pierre</emp:name>
<emp:dateOfBirth>1961-02-11</emp:dateOfBirth>
<emp:employeeType>none</emp:employeeType>
<emp:salary>20</emp:salary>
</emp:EmployeeRequest>
</par:employeeRequest>
</dec:DecisionServiceRequest>
</soapenv:Body>
</soapenv:Envelope>


We can see that we have a operation DecisionServiceRequest which contains a node par:employeeRequest which contains the value EmployeeRequest.

The generic request will be:


<soapenv:Body>
<dec:DecisionServiceRequest>
<par:parameter1Name>

</par:parameter1Name><par:parameter2Name>


</par:parameter2Name>
</dec:DecisionServiceRequest>
</soapenv:Body>


you should get this response:


<?xml version="1.0" encoding="UTF-8"?>
<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></ilog.rules.outputString>
<ilog.rules.firedRulesCount>1</ilog.rules.firedRulesCount>
<employeeResponse xmlns="http://www.ilog.com/rules/param"><EmployeeResponse xmlns="http://www.acme.com/Employee" xmlns:ns0="http://www.acme.com/Employee">
<fired xmlns="http://www.acme.com/Employee">TRUE</fired>
</EmployeeResponse>
</employeeResponse>
</DecisionServiceResponse>
</soapenv:Body>
</soapenv:Envelope>


and the WSDL is here:

http://sites.google.com/site/javamonamour/xsds/rulesetwsdl.wsdl?attredirects=0&d=1


In case of fault, you get this:

<soapenv:Fault>
 <faultcode>soapenv:Server</faultcode>
 <faultstring>Error when executing the ruleset /PV01_RuleApp/1.0/PV01_RuleProject/1.0</faultstring>
 <faultactor>http://www.ilog.com/rules/DecisionService</faultactor>
 <detail>
    <ds:DecisionServiceException>
       <ds:exception>ilog.rules.res.decisionservice.IlrDecisionServiceException: Error when executing the ruleset /PV01_RuleApp/1.0/PV01_RuleProject/1.0
at ilog.rules.res.decisionservice.web.IlrDecisionServiceController.executeRuleset(IlrDecisionServiceController.java:125)