Monday, December 31, 2007

BPEL Client API

I had chance to work on both BPEL and ESB client APIs, and I found very little documentation on BPEL Client API, that made me write this BLOG entry.

BPEL Client API:

Everything we can do in BPELConsole, we can do through BPEL client API as well. BPEL client API is JAR file shipped with SOASuite, I imporeted that JAR file and I could manage my BPEL domain using stand alone Java program which calls this client APIs. Here is the usecase we had to implement: Activating and Deactivating a BPEL process using stand-alone Java program or Servlet.

Here is what I started with:

Here we can see the establishConnection, which takes oc4j server name, port, username and port to connect with BPEL server. I have couple of test service to list all domains, list all services in a domain. I have high-lighted startService and endService which has logic for activating and deactivating the service.

I had to include all libraries from, bpel/lib, opmn/lib and j2ee/home/lib. Once I included these libraries, I was able to run this Java program and activate/deactivate the process successfully.

BPEL Client API source code can be downloaded from here.

ESB Client API:

I found ESB Client API are extreamly well explained and documented, so I avoided repeating that information.

Oracle BPEL Header Interceptor

I saw that BPEL interceptor has been only documented as header handler, I found it can do much more than just handling Headers. It is perfect interceptor and works just like Servlet Filter. It is sensitive part of code, because interceptor is called synchronously from main BPEL process. Any uncatched exception or time consuming delays in interceptor code will be propagated to main BPEL process.

OK, let's look at how to implement it:

We can register two different interceptor, one for request and one for response. I pretty much copied the initial part from documentation and enhance it for 10.1.3.x SOASuite. I created CustomHeaderHandler which implements HeaderHandler, and then I created two different classes InboundHandler and OutboundHandler which extends CustomHeaderHandler.

CustomHeaderHandler:

Here we can see invoke operation with Parternlink, Header, CallProperties. I have also written dumpProperties method which will dump all the properties from Map.

Here is InBound and OutBound interceptor which merely just calls CustomHedaerHandler's invoke method:

InboundHandler

OutboundHandler

I compiled all three classes and put it in bpel/system/classes directory and restarted SOASuite. I created couple of BPEL Processes to test my interceptors, I put following lines of code in bpel.xml to activate the interceptors:
Now if I look into soasuite/opmn/log/default_group~oc4j_soa~default_group~1.log, I can see the intercepted log:
Source code can be downloaded at here.

Thursday, December 27, 2007

It is all about JMX

It is all about JMX

I worked on JMX stuff on OC4J lately, and found information are scattered at many places. Thought of writing blog to combine information which might be useful.

- Simple MBean registered in Stand-Alone JVM, and monitered using JConsole

- Simple MBean registration to stand-alone OC4J, Stand-Alone OC4J MBean Browser, Stand-Alone OC4J MBean Client

- Simple MBean registration to cluster OC4J, OC4J Cluster MBean Browser, Cluster OC4J MBean Client

- Monitor OC4J MBeans using JConsole

1. Stand-Alone JVM

As per MBean spec, we need to define interface which is suffixed by MBean. I created interface called HelloServiceMBean and implemented called HelloService.

Here getMessage and setMessage will expose my message as an attribute to the MBean and printMessage will be exposed as an operation to MBean. To register this MBean in stand-alone JVM, I wrote another class which register this MBean in JVM and I could manage it using JConsole MBean Browser.
I compiled those classes using JDeveloper and executed through following command line:

cd D:projectsJMXSamplesSampleJMXclasses

java -Dcom.sun.management.jmxremote jmx.trial.SimpleAgent

On second window, I started JConsole using: %JAVA_HOME%jdkbinJConsole, and I can see my MBean with Attributes and Operations. I can invoke any operation but I am not able to change any attribute using JConsole. Not sure why I am not able to change any attribute value using JConsole, it works just fine with OC4J MBean Browser.

2. MBean with Stand-Alone OC4J

There are two options we can try, Registering JAR (static registration) file to OC4J using deployment descriptor, and registering MBean from servlet (dyanmic registration). For current Blog entry, I will use deploying through descriptor.

I used the same project which I used for Stand-Alone JVM. I created 3 artifacts in my JDeveloper project:

- Created EJB-JAR deployment profile for jar file called: helloservicejar.deploy

- Created EAR deployment profile: helloservice.deploy (had dependency on helloservicejar.deploy)

- Created OC4J deployment descriptor called - orien-application.xml

I deployed this ear file in stand-alone OC4J, I can see my application and MBean Browser right in EM console. (We can also register this Jar file in j2ee/config/application.xml file then we don't need to have orien-application.xml and ear file.)

Here I can change attribute values and invoke operation without any issues. I used java client to test MBeans deployed on OC4J.

Here getMBeanConnection method is pretty generic, it will get us connection based on the URL specified. printAllMBeans will iterate through all available MBeans and prints all MBeans. The testStandAlone() method does, invocation of method, get attribute and set attribute.

I had to put following libraries in my classpath in order to execute my client:

J2EE
j2eehomelibjmx_remote_api.jar
j2eehomelibjmxcluster.jar
j2eehomelibjmxri.jar
j2eehomelibadminclient.jar
j2eehomeoc4jclient.jar
opmnlib all six jar files.

3. MBean with Cluster OC4J

Registration as JAR: Registration through JAR in Cluster is pretty much similar as registering in Stand-Alone. I use JDeveloper to deploy my EAR file in Cluster Group. I created a group called default_group and registered all my OC4J instances in that group.

Dynamic Registration: Through servlet or POJO residing in container, I could register only to specific container. It looks like, all instances has to do the same to achieve cluster level MBeans deployment.

For testing purpose, I manually deployed a JAR on OC4J group. Here is little introduction about Cluster MBean:

Cluster MBean is actually a proxy to the OC4J group. Client (Java/Browser) can get hold on Cluster MBean, and pass the specific MBean and it's method/attribute as paraemter. Cluster MBean takes care of invoking those method across cluster. Cluster MBean knows about all OC4J instances through OC4J group configured in EM. For each OC4J group there will be one Cluster MBean proxy.

OC4J Cluster MBean Browser: following are the screen shots which explains how did I use cluster MBean browser for getAttribute, I can use it for setAttribute or invoke operation exactly the same way.

Upon invoking the operation I get following return values.

Now to test through Java code, it is pretty much the same concept:

We can see that I got access to Cluster MBean which is "ias:j2eeType=J2EEServerGroup,name=default_group', and after that I am just invoking method of that proxy same as MBean browser. Here tricky part is method signatures, OC4J MBean browser is able to know all those signature through reflection but in my code I had to provide those signature before hand.

4. Monitor OC4J MBeans using JConsole

Basically by adding few libraries to JConsole, you can use it to browse OC4J MBeans. Here is the thing I used to start my JConsole:

set ORACLE_HOME=d:soasuite

jconsole -J-Dcom.sun.management.jmxremote.ssl=false -J-Dcom.sun.management.jmxremote.authenticate=true -J-Djmx.remote.protocol.provider.pkgs=oracle.oc4j.admin.jmx.remote -J-Djava.class.path=;%JAVA_HOME%libjconsole.jar;%JAVA_HOME%libtools.jar;%ORACLE_HOME%j2eehomelibadminclient.jar;%ORACLE_HOME%j2eehomeoc4jclient.jar;%ORACLE_HOME%j2eehomelibjavax77.jar

Upon the window, I added the same URLs which I used in my Java program, I can use any of the following URLs:

STAND_ALONE_OC4J_URL (service:jmx:rmi://localhost:23791/oc4j)
SOASUITE_HOME_URL (service:jmx:rmi:///opmn://mycomputer:6003/home)
SOASUITE_OC4J_SOA_URL (service:jmx:rmi:///opmn://mycomputer:6003/oc4j_soa)
SOASUITE_CLUSTER_URL (service:jmx:rmi:///opmn://localhost:6003/cluster)

And it works great except one weird exception on DOS prompt.

Source code for all can be downloaded over here.

Sunday, December 23, 2007

Insert/Extract SOAP Headers in BPEL

It has been very common topic to insert and extract SOAP headers with BPEL. Lately, I was working with extracting WSSE headers in BPEL, I had to apply some tricks that made me write this BLOG entry.

Inserting Headers in BPEL Outbound:

I will try to enter three different types of headers:

1) Complex XSD element

2) Simple XSD element

3) WSSE headers - which comes out-of-box with BPEL

- First of all I defined XSD element which I want to insert in SOAP headers, e.g.

Here I have created ComplexCredentialElement as XSD Complex element and and Username and Password with XSD simple type. Here namespace is extremely important, I will insert all elements in SOAP header with "http://xmlns.oracle.com/InsertHeaderVariables" namespace. A target process will need to know namespace while extracting Headers, that's why namespace is very important in this case.
Now, in BPEL process I created variable and assigned those variable with some dummy values. You can see my BPEL process as well as source code in following figure:
Here I created variable of the header elements, and assigned dummy values to them. Now when I invoke the partnerlink, I need to specify those variable as bpelx:inputHeaderVariable, and BPEL PM will take care of inserting them when creating SOAP envelope. I believe if you have to insert some SOAP headers for enterprise wide, you can use OWSM client agent to do so, and if you haven't bought OWSM product then writing custom BPEL partnerlink interceptor would be an awesome choice rather than putting header in each partner link. Stay tuned for my blog on intercepting/hacking BPEL partnerlink!
The last one is to insert some WSSE headers through partnerlink, from security aspect I have separate blog entry for this thread: http://chintanblog.blogspot.com/2007/12/have-been-playing-around-with-ws-basic.html but here I am more interested in inserting and extracting headers using BPEL partnerlink.
I deployed this BPEL process and changed my partnerlink URL port to 1234 to test using obtunnel.bat. I started soasuite/bpel/bin/obtunnel.bat and kick-off the BPEL process, here is the intercepted request payload:
I can see my custom headers as well as wsse headers in my SOAP envelope Header, therefore it is working great!!!

Extracting Headers in BPEL in-bound:

I will try to extract three different types of headers:

1) Complex XSD element

2) Simple XSD element

3) WSSE headers

To extract headers I need to define elements which I need to extract, I created following XSD file which represent my simple and complex XSD header elements.

I also need to define wsse headers. Ideally I should download the XSD defined by OASIS for WSSE (http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd) in my project and create variable of the elements already defined in this XSD. Upon loading this XSD project, I got numourous issues so left that approach and created my own XSD element for reprsenting WSSE security header as shown below.
Now I created three variables and pass them to receive activity. BPEL PM takes care of populating them from SOAP headers...
I just deployed this process and I could see both my custom headers and wsse headers are populated nicely...
Source code can be downloaded from this link.

Saturday, December 22, 2007

HTTP and WS-BASIC authentication

Have been playing around with WS-BASIC authentication and HTTP authentication. I just created HelloBPEL project and secured it using OWSM gateway. I defined following policy steps in OWSM for HTTP basic authentication:

Extract credentials I specified HTTP credentials and for File Authenticate I created username/password file using md5 utilies, here is details of the steps:

To test if my policies are defined fine, I tested using Tools -> test page feature.
Everything works great so far. I tried to test it using BPEL. I provided gateway URL to BPEL partnerlink. I had to specify following additional partnerlink properties so that BPEL passes correct header information for HTTP authentication.
Cool... It worked great.
Similar way for WS-BASIC authentication. I changed Extract Credential step in OWSM policy:

And now to test using BPEL, I had to provide following Partnerlink properties:

You can see in above image that you can use httpBasicUsername and httpBasicPassword as well. I found that httpUsername and httpPassword were supported in 10.1.2 but they are deprecated in 10.1.3 as per http://download-uk.oracle.com/docs/cd/B31017_01/integrate.1013/b28982/security.htm , therefore httpBasicUsername and basicUsername are our only choice for 10.1.3.3 SOASuite.

Source code can be downloaded at this link.

Wednesday, December 19, 2007

WSIF with EJB 2.0, 2.1 and 3.0

Although WSIF seems to be hack to plug-in native protocol in web services framework, I absolutely love WSIF.

My understanding of WSIF is standard way of representing service contract (which is WSDL) for any type of service. E.g. if you have servlet, java program, .Net code or JCA operation, you can represent all of them as standard WSDL. Now for WSDL consumer (e.g. BPEL) it is just any other WSDL operation and WSIF provider will know how to interact with this service. My belief is Oracle BPEL uses open source Apache WSIF provider in BPEL engine. I did play with HTTP WSIF Binding and Java Binding. I probably will post on HTTP binding once I figure out how to pass dynamic URL (e.g. calling servlet with dynamic parameters) but now it is time to play with some EJB WSIF.

I created sample EJB 2.0, EJB 2.1 and EJB 3.0 Session Façade using Jdeveloper and deployed to my SOASuite oc4j. I deployed in different container than OC4J_SOA just to make sure Remote interface are being used. I will start with EJB 2.1 because that is the easiest one, EJB 3.0 and EJB 2.0 WSIF binding needs lot of hack and/or custom coding.

Technology Used: JDeveloper 10.1.3.3, Oracle SOASuite 10.1.3.3


EJB 2.1 WSIF: Created a sample EJB 2.1 Session Façade, one business method called demoHelloMethod as shown below:

Once you right click your EJB icon, it let’s you create stand-alone Java client for EJB pointing to Remote Application Server as shown below:

We can see that the client uses opmn URL to connect with remote EJB: “opmn:ormi://localhost:6003:home/demosessionejb21”. I found WSIF doesn’t like this URL so I tested my client with ormi url “ormi://localhost:12402/demosessionejb21”. We probably want to note down some information from this client, e.g.

Provider URL: ormi://localhost:12402/demosessionejb21

Initial Context Factory: oracle.j2ee.rmi.RMIInitialContextFactory

EJB name: DemoSessionEJB21

Now it is time to create WSDL, which can represent this EJB operation. We can Jdeveloper wizard to create such such wsdl. Once we right click on EJB we can see “create J2EE web service” option, it lets you create web-service for your EJB. Remember we are just going to use this to create WSDL but not web-service. I took backup of my project, created web-service, took wsdl and then restored my old project, as I am not interested in web-service. I just followed the wizard as shown below.

In Step 2. Please remember to select RPC Lit otherwise some extra effort will be required on XSD side.
In Step 6, this values I took from EJB Client code which was generated using JDeveloper.
Just click on Finish and Look at generated WSDL file:
We can take this wsif and restore the project from earlier backup. We can see both WSIF and HTTP binding in this WSDL. Now as this is not deployed as web-service, I commented out the http part and also put the partner-link so that BPEL doesn’t create extra ref file. The final WSDL file look something like this:
EJB 2.1 WSIF Testing through BPEL Project
I created sample BPEL project and copied this wsdl file in bpel directory. I created partnerlink and selected the binding wsdl. I am almost done, I just need to pass extra information required by EJB RMI client. Seems like these extra information (e.g. username, password) are not part of WSIF spec, but BPEL supports it very well. I provided these entries in bpel.xml:

Because it is native call, BPEL engine will need all classes for EJB client. I copied the classes from EJB session facade project to bpel/system/classes directory.

Deployed the project … and hulala… things working great.



EJB 2.0 WSIF: It is very well supported by Oracle BPEL PM, but not through JDeveloer. Overuse of Wizards and drag-drop kinda makes us handicapped!! Anyways, time to get hand dirty. Created EJB 2.0 session façade, a sample business method and deployed to Application Server. I also created EJB 2.0 Java Client the same way as described in EJB 2.1.

We can see the “Create J2EE Web Service option”. Upon clicking this option it just create web service code and wsdl file with name called “MyWebService1” without showing any prompt… I double click on MyWebService1 so I could at least change the name of WS to DemoSessionEJB20. The initial WSDL looks something like:

There is no WSIF information at all. I hand coded the part of WSDL as shown below. I copied most of the part from EJB 2.1 WSIF wsdl and just changed the stuff as required.

I created sample BPEL project and imported WSIF WSDL. I also put username and password in bpel.xml as described in EJB 2.1 and copied required EJB classes in bpel/system/classes directory. Deployed the project and things went pretty smooth…




EJB 3.0: Personally I believe EJB 3.0 made life much easier in J2EE development. It is really very nice concept eliminating need of EJB 2.x crap, lot of XMLs (like Spring) and extensive use of annotations. Ok, let’s get back to WSIF part.

I created sample EJB 3.0 Session Façade, Java Client, as EJB 2.x. JDeveloper doesn’t display “Create J2EE webservice” option for EJB 3.0 Session Façade, but there is Annotation to create WSIF bindings.

During the creation of EJB 3.0, please expose them to WebService interfacce as well as shown in above figure. That creates Doc-Lit service without any WSIF binding. I believe we need to do schemac if we stick with Doc-Lit. I changed webservice interface (DemoSessionEJB30WebService.java) as shown below to create RPC Lit service with WSIF bindings using annotations.

Now when I deploy this service using deployment profile, Oracle AS creates very nice WSDL:

I created BPEL project, imported this WSDL. After importing this WSDL file I still had to make couple of changes. I had to add partner link to avoid Ref file, remove soap bindings for safety and I also had to add more parameter in ejb:address e.g. className, jndiName and providerURL. The final WSDL with changes looks something like:

As usual, I provided username and password in bpel.xml and copied required classes in bpel/system/classes directory, and things started rocking!!!


Source code can be downloaded at this link.

I will try to update my log when JDeveloper has support for creating wsif WSDL through wizard for EJB 2.0 and EJB 3.0.