Monday

Resolve "(MARSHAL) Exception" when deploying osb project on web logic through JMX client

Last week we decided to managing deployment of osb project on web logic cluster throw programmatic way. Throw simple JMX client, it's very easy to deploy and change the runtime configuration of the osb project. However the way to development of the simple client for deploying we got some confrontation, and the current post are all about these.
First of all Weblogic(10g R3) JMX implemention classes are no longer exists on weblogic.jar file. Thus, creating new proxy instance for DomainRuntimeServiceMBean might be through java native JMX clasess. However you could use wlfullclient.jar to build all the proxy client, on version 10gR3 oracle transfer all the web logic JMX implemention classes on wlfullclient.jar. Whenever you compile the project successfully and run the client, we found another runtime error related with "(MARSHAL) Exception". The runtime error are as follows:
01.06.2009 13:21:44 com.sun.corba.se.impl.encoding.CDRInputStream_1_0 read_value

WARNING: "IOP00810211: (MARSHAL) Exception from readValue on ValueHandler in CDRInputStream"

org.omg.CORBA.MARSHAL:   vmcid: SUN  minor code: 211 completed: Maybe
at com.sun.corba.se.impl.logging.ORBUtilSystemException.valuehandlerReadException(ORBUti
lSystemException.java:6500)
at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:
1045)
at com.sun.corba.se.impl.encoding.CDRInputStream.read_value(CDRInputStream.java:253)
at com.sun.corba.se.impl.io.IIOPInputStream.inputObjectField(IIOPInputStream.java:1989)
at com.sun.corba.se.impl.io.IIOPInputStream.inputClassFields(IIOPInputStream.java:2213)
at com.sun.corba.se.impl.io.IIOPInputStream.inputObject(IIOPInputStream.java:1221)
at com.sun.corba.se.impl.io.IIOPInputStream.simpleReadObject(IIOPInputStream.java:400)
at com.sun.corba.se.impl.io.ValueHandlerImpl.readValueInternal(ValueHandlerImpl.java:327
)
at com.sun.corba.se.impl.io.ValueHandlerImpl.readValue(ValueHandlerImpl.java:293)
at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:
1034)
at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:
879)
at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_abstract_interface(CDRInputStr
eam_1_0.java:873)
at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_abstract_interface(CDRInputStr
eam_1_0.java:863)
at com.sun.corba.se.impl.encoding.CDRInputStream.read_abstract_interface(CDRInputStream.
java:269)
at com.sun.corba.se.impl.io.IIOPInputStream.readObjectDelegate(IIOPInputStream.java:363)
at com.sun.corba.se.impl.io.IIOPInputStream.readObjectOverride(IIOPInputStream.java:526)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:345)
at java.util.HashMap.readObject(HashMap.java:1030)
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.corba.se.impl.io.IIOPInputStream.invokeObjectReader(IIOPInputStream.java:1694
)
at com.sun.corba.se.impl.io.IIOPInputStream.inputObject(IIOPInputStream.java:1212)
at com.sun.corba.se.impl.io.IIOPInputStream.simpleReadObject(IIOPInputStream.java:400)
at com.sun.corba.se.impl.io.ValueHandlerImpl.readValueInternal(ValueHandlerImpl.java:327
)
at com.sun.corba.se.impl.io.ValueHandlerImpl.readValue(ValueHandlerImpl.java:293)
at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:
1034)
at com.sun.corba.se.impl.encoding.CDRInputStream.read_value(CDRInputStream.java:253)
at com.sun.corba.se.impl.io.IIOPInputStream.inputObjectField(IIOPInputStream.java:1989)
at com.sun.corba.se.impl.io.IIOPInputStream.inputClassFields(IIOPInputStream.java:2213)
at com.sun.corba.se.impl.io.IIOPInputStream.inputObject(IIOPInputStream.java:1221)
at com.sun.corba.se.impl.io.IIOPInputStream.simpleReadObject(IIOPInputStream.java:400)
at com.sun.corba.se.impl.io.ValueHandlerImpl.readValueInternal(ValueHandlerImpl.java:327
)
at com.sun.corba.se.impl.io.ValueHandlerImpl.readValue(ValueHandlerImpl.java:293)
at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:
1034)
at com.sun.corba.se.impl.encoding.CDRInputStream.read_value(CDRInputStream.java:253)
at com.sun.corba.se.impl.io.IIOPInputStream.inputObjectField(IIOPInputStream.java:1989)
at com.sun.corba.se.impl.io.IIOPInputStream.inputClassFields(IIOPInputStream.java:2213)
at com.sun.corba.se.impl.io.IIOPInputStream.inputObject(IIOPInputStream.java:1221)
at com.sun.corba.se.impl.io.IIOPInputStream.simpleReadObject(IIOPInputStream.java:400)
at com.sun.corba.se.impl.io.ValueHandlerImpl.readValueInternal(ValueHandlerImpl.java:327
)
at com.sun.corba.se.impl.io.ValueHandlerImpl.readValue(ValueHandlerImpl.java:293)
at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:
1034)
at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:
879)
at com.sun.corba.se.impl.encoding.CDRInputStream.read_value(CDRInputStream.java:249)
at com.sun.corba.se.impl.corba.TCUtility.unmarshalIn(TCUtility.java:269)
at com.sun.corba.se.impl.corba.AnyImpl.read_value(AnyImpl.java:559)
at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_any(CDRInputStream_1_0.java:73
... 61 more
IOException:CORBA MARSHAL 1398079699 Maybe; nested exception is:
org.omg.CORBA.MARSHAL:   vmcid: SUN  minor code: 211 completed: Maybe

At first i tried to googling on internet and found that, it is JVM bug. On many forums developers suggest to use same version of JVM on both side , client and the server. I have tried a few JVM include Jrockit on both side but all in vain.

After some experiment i discover that, my JMX client uses IIOP implemention of wlclient.jar instead of wlfullclient.jar. Therefore i delete the wlclient.jar from my classpath and vailo. Here are my POM.XML which i use to develop the JMX client.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.fors.weblogic</groupId>
<artifactId>jmxClient</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>jmxClient</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.bea</groupId>
<artifactId>sb-kernel-api</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>D:\Osb10gR3\osb_10.3\lib\sb-kernel-api.jar</systemPath>
</dependency>
<dependency>
<groupId>com.bea.wli</groupId>
<artifactId>sb-kernel-resources</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>D:\Osb10gR3\osb_10.3\lib\sb-kernel-resources.jar</systemPath>    
</dependency>
<dependency>
<groupId>com.bea.wli</groupId>
<artifactId>com.bea.common.configfwk_1.1.0.0</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>D:\Osb10gR3\modules\com.bea.common.configfwk_1.2.0.0.jar</systemPath>
</dependency>
<dependency>
<groupId>weblogic</groupId>
<artifactId>wlfullclient</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>D:\beaWL\wlserver_10.3\server\lib\wlfullclient.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>compile</phase>   
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>java</executable>
<workingDirectory>/target/classes</workingDirectory>
<arguments>
<argument>-classpath</argument>
<classpath/>
<argument>ru.fors.weblogic.JMX.Client</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</project>

Sunday

Setting up Web logic clusters for GWT applications

Inspired by the following post WebLogic Load Balancing for Oracle ADF Applications i have decided to make some agile test for GWT applications.
First we will develop a simple hello world GWT application and configure load balancing cluster. Sample GWT application will be deployed on WebLogic cluster, Load Balancing domain or proxy domain will distribute user requests between cluster members.
1) Develop sample GWT application
It's a hello world web application with one text field and button on a web page. I use maven to develop the application. We can choose any web application to deploy on web logic cluster, any way our aim is to configure web logic cluster and we will go though all over the steps next.
2) Configure cluster domain
It's very easy to setup and configure cluster on web logic. Just start Configuration wizard and select customize installation.

Change port number of the Admin server, in my case it is 7002

On Configure Managed server page add two new managed server and change the port to 7003 and 7004.

Configure cluster by default and we will change the multicast to unicast.

On the next page assign all the managed servers to the cluster.

On the configure machine page add one physical machine and address the listen address to localhost as follows:

On next page apply cluster with manged serves to physical machine:

And finally provide domain name and the location of the domain. In my case i have provide the domain name as cluster_domain.
At this moment cluster is installed and ready to use. Start the cluster domain from program menu, and open the console by following url:
http://localhost:7002/console
Start node manager from the start menu to manage managed servers, go to the console home page->cluster->control and select all the managed servers and click to start. After a few moments states of the servers should be running mode.

Now, it's time to deploy our GWT web application on cluster. Deploy the web application on cluster by web inteface as follows:

3) Set Up the HttpClusterServlet:
Here we will describe how to develop and configure proxy plugin for load balancing. We will use a web logic domain as a proxy plugin and configure HttpClusterServlet on it. To use http cluster servlet, configure it as a default web application on proxy domain. The default web application will only contain a web.xml and weblogic.xml file on WEB-INF directory and nothing more. See the link to more about HttpClusterServlet.
I have used sample web.xml and weblogic.xml available in documentation, just changed WebLogicCluster parameter value to:

localhost:7003|localhost:7004

and build an web application with war archive, name the archive as loadBalancer.war
At this moment we will create another weblogic domain with standard configuration and name the domain as proxy_domain. Deploy the loadBalancer.war on the proxy domain as follows:

4) Test the configuration.
For now we have configured everything to test our web application running on cluster. Address you web applications home page on any browser, in my case it is as follows:
http://localhost:7001/app-name/context-root/HelloGwt.html
One of Managed Servers from Cluster environment will response. Go to the following location to check the output log from the server
\user_projects\domains\cluster_domain\servers\ManagedServer_1\logs\ManagedServer_1.out
In my case server 1 response in this time, if i have opened second session, by pointing to the same 7001 port and it was handled by seconed Managed Server and so on. It was because cluster server was configured with round-robin algorithm.
The above configuration will consider for any web application not just fro GWT application. There are a lot of configuration left behind on httpServlet plugins.
For more information please see following resource:
Load Balancing with a Proxy Plug-in

Tuesday

Implementing DataServices with Oracle data service integrator

DataService: one kind of special service, which expose interface for data stored in sources such as relational databases, CSV files & MS-Excel files. DataServices plays a vital role on IT strategy like SOA. Any organization have to have expose their master data to any enterprise application. Through data services a company enables to have high-quality, consistent data at the right place at the right time.
In practical, data services exposes data, represented as Entity Data Model (EDM) objects, via web services accessed over HTTP. The data can be addressed using a REST-like URI. The Astoria service, when accessed via the HTTP GET method with such a URI, will return the data. The web service can be configured to return the data in either plain XML, JSON or RDF+XML. For more information see the following article about data services.
It's not hard to create and maintain data service on standard way, a lot of ORM framework like hibernate, iBatis, toplink even low level jdbc framework is good enough to built data services. Sometimes it's hard to maintain and governece this type of enterprise application, because life cycle of the development process is vital. For these reason, in this post i will give some overview of tools and frameworks to accelerates application development and deployment by simplifying the complex task of building and maintaining access to and from multiple external data sources.
1) XAware Open Source Data Integration: It provides real-time, bi-directional data integration with a service-oriented flavor. XAware makes other tools and frameworks more productive by hiding data access complexity behind "XML views". XML views span any number of data sources, and can read data, write data, or transfer data between sets of sources, all within a distributed transaction.
2) WSO2 Data Services: With WSO2 Data Services, data can be exposed and accessed in a secure (using WS-Security) and reliable (using WS-ReliableMessaging) manner; data is also made available for mashing-up with other Web services.
3) Native Oracle XML DB Web Services: Oracle 11g Database makes the conversion of existing PL/SQL code into web services easier than ever by providing Native XML DB web services. With some simple configuration, this functionality exposes PL/SQL code code as web services.
4) Oracle Data Service Integrator:It brings a service-oriented architecture (SOA) approach to data access. Data Services Integrator enables organizations to consolidate, integrate, and transform as needed disparate data sources scattered throughout their enterprise, making enterprise data available as an easy-to-access, reusable commodity: a data service.
Next we will implement a simple data service project to see how it's easy to develop on oracle data service integrator.
For study purpose i decided to make the sample project as simple as possible. First we will create a table on Oracle data base and expose this table as a web service through oracle data service integrator. In conclusion you will get more resources links to follows.
Following platforms will get on work:
1) Oracle 10g data base.
2) Oracle data service integrator 10g r3
Download and install products on your local machine. I am going to use user scott to sample purpose.
1) Create a table on user scott as follows:
CREATE TABLE document ( doc_id VARCHAR2(200), doc_type_i VARCHAR2(200), vid_doc VARCHAR2(200), "COMMENT" VARCHAR2(200), num_doc VARCHAR2(200), dat_doc DATE );
Insert some data on it.
2) After installation of data service integrator create one domain, name the domain base_domain.
3) Open the eclipse workshop of oracle data service integrator and create a new server based on domain base_domain.
4) Open admin console, the link should be as follows:
http://localhost:7001/console/console.portal?_nfpb=true&_pageLabel=HomePage1
5) Add a non XA data source on it. Provide all the necessary information as follows:
database name: scott
jndiName:nsiDataSource
hostname:mercury
database username:scott
password:tiger
now we are ready to create data service on workshop.
6) Open the workshop and change the perspective to Oracle data service integrator.
7) Create a dataspace project.
8) Create one physical data service as follows:
Data Source type: Reletional
DataSource: nsiDataSource
DataBase type: Oracle->9->Oracle 9.x and above
Relational data base object: Tables and views
and click next
9) On SQL select source views, select schema Scott and expand it, also select table named "Document".

10) On operation page select check box public and click next button.
11) Put the data service name as getNsiDocument and click finish.
This will create file getNsiDocument.ds and open a overview window as follows:

12) On the above page go to the tab TEST and select operation getNsiDocument and click run. This will show you some result.
13) Now we will create logical data service over physical service. Click new-> New logical service.
DataService Name: getNsiDocument_l
Select logical data service type: Entity data service
and click finish. This will create a new logical service named getNsiDocument_l and now the project has error, don't worry we will make up it very soon.
14) Right click on the overview tab and select add operation. Select it as a public service as a kind of read and name the service as getNsiDocumentL.
15) Click on the tab Query Map. Expand the node getNsiDocument.ds and drag getNsiDocument() to the Query map.
16) Select the getNsiDocument*, press crtl and drag the element over Return box.

17) Right click on the return box and select save and Associate xml type.
18) just change the namespace as ld:Physical/getNsiDocumentL and click ok.
19) For now the project should be valid and we can test the logical data service.
Click tab TEST and click the button run.
20) Now we will add a where clause on our logical service. Click query Map, select getNsiDocument() box and the condition editor will highlighted. Click on add where clause, select element vid_doc and add ="14" in my cause. See the following illustration.

21) Save all the work and test again - now the result should be filtered by where clause.
Here we have done most of the work. Now we will create a web service witch will wrap the logical service.
22) Create new web service map, name nsiDocumantWs and drag the logical service named getNsiDocumentL over the web service map.
Just now we have finished all our work. We have create physical data service and a logical data service over it, at last create a web service map for the logical service.
Now we can test our data service, for these copy the following url and open it on any web browser:
http://localhost.fors.ru:7001/wls_utc/begin.do?
Right click on the nsiDocumentWs.ws and click copy wsdl url. Paste the url on weblogic test client and click on getNsiDocumentL button. You should see some result on page as follows:

In conclusion, we able to understand how easy it is to create data service in oracle data service workshop on declarative way. For more information see following pages:
1) Tutorial.
2) Generate web service from data services.
On the next post i will demonstrate a simple example to use DSP protocol on OSB 10gR3.

Saturday

Solving xcb_xlib.c:50: xcb_xlib_unlock: Assertion 'c->xlib.lock' failed. on fedora 8

Yesterday i decided to upgrade osb 3.0 to OSB 10gr3 on my linux box. During installation i have first locate the famous error "xcb_xlib.c:50: xcb_xlib_unlock: Assertion 'c->xlib.lock' failed.". Through google, i have found a few solution to solve the problem but all the solutions gone in vain.
I have had following configuration:
[recon@localhost home]$ cat /etc/redhat-release
Fedora release 8 (Werewolf)
[recon@localhost home]$ java -version
java version "1.5.0_14"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_14-b03, mixed mode)
[recon@localhost home]$ rpm -q libxcb libX11
libxcb-1.0-3.fc8
libX11-1.1.3-4.fc8
First of all, i have tried to patch the library libmawt.so by sed -i 's/XINERAMA/FAKEEXTN/g' of my current JVM, but it was not help me to run the installer to install OSB 10gR3. Even i installed latest 1.6 JDK and patch the libmawt.so but in vain.
From one of linux forum, i found a suggestion to upgrade libxcb file and try again. Here is my all the step to resolve the problem:
1) upgrade yum install (nothing updated)
2) update libxcb
[recon@localhost home]$ sudo yum update libxcv
[recon@localhost tmp]$ rpm -q libxcb
libxcb-1.1-1.1.fc8
which will upgrade my libxcb to version 1.1
3) patch the libmawt.so for current JVM (it was unnecessary, because i have done it before)
4) run installer and all goes well.
For more information, you can visit the following post on oracle forum.

Sunday

Google Analytics api released

Finally googles long waited analytics api released on last week. Api will help you to write client for gathering and analyze data for your web site. Now through client we could analyze data from our standalone java client and no longer need to logon to our Google Analytics site. Api released with three flavour:
1) Java Script;
2) Java;
3) Http

Along with client libraries there are also reference document and Sample codes to start coding and test api. Also there are brief explanation of account, profile, metrics and dimensions related to google analytics. It will take a couple of minutes to write down your code or just run sample code distributed by google to get the action. The best part: this sophisticated, full-featured web analytics package is free.

For getting started see here.

Tuesday

Upgrade osb project with new advance feature of MTOM support on version 10gR3

Last week we decided to upgrade all our OSB project from OSB3 to OSB10GR3. A few of our project worked with attachment's which failed on new version of OSB. In this post we will explain briefly all the necessary step to upgrade project working with attachments to version 10g release 3.

Assume that, we have a proxy service which will get arbitrary MTOM attachment. First of all, after exporting the project on workspace we must enable mtom support on proxy properties page. When XOP/MTOM Support is enabled, you can further select how to handle binary data in the $header and $body message context variables from among the following options:

* Include Binary Data by Reference: (Default) In an inbound request message, replace xop:Include elements with ctx:binary-content elements when setting up the $header and $body message context variables.
* Include Binary Data by Value: In an inbound request message, replace xop:Include elements with Base64-encoded text versions of corresponding binary data when setting up the $header and $body message context variables.

You can use Include Binary Data by Reference when you need direct access to binary data, for example to pass data to a Java callout or Message Format Language (MFL) transform.

You can use Include Binary Data by Value in the following cases:

* To bridge between MTOM and non-MTOM services. For example, consider an MTOM-enabled proxy service that receives a request that is then routed to a non-MTOM-enabled service. You could use this option to comply with existing standards for sending binary data in XML in Base64-encoded form.
* To validate the contents of the message against an XML schema that requires a base64binary element to be used in place of binary data

Note that if XOP/MTOM Support is enabled for a proxy service, it is not required that every inbound message be in the MTOM format. Instead, this setting specifies that when an MTOM-formatted message arrives, the proxy service should handle it accordingly. Note also that when proxy services not enabled for XOP/MTOM Support receive an MTOM-formatted message, the service rejects the message and issues a runtime error.
When XOP/MTOM support enable on proxy service, the variable $attachment will no longer active. For example on version OSB3 we could define total attachment by following xpath statement as follows:
fn:count($attachment/attachments)
Above frugment of xpath will return 0, because on version 10gR3, MTOM attachment will no longer available in variable $attachment.
When the Binary by Reference option is selected, Oracle Service Bus parses the root of the message checking for the presence of xop:Include tags. These tags, when found, are converted to ctx:binary-content elements with a reference pointing to the corresponding source in binary repository. The resulting document is represented by the $body message context variable.
This means that when pipeline actions access the contents of the $body message context variable, the actions do not encounter xop:Include elements, but instead work with ctx:binary-content elements.
As example:
Guess, from the client side we have sent following soap message with attachment
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:SubmitAttachmentRequestEle xmlns:ns2="http://www.ru.fors.nsi/SOAPwithAttachment/">
<messageId>messageId</messageId>
<senderAppName>fts NSI</senderAppName>
<receiver>rtu-1</receiver>
<department>department</department>
<attaches>
<Attach>
<documentName>test.doc</documentName>
<zipFile>
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:83842c6c-2dbc-459d-98b1-f185f89ce9ec@example.jaxws.sun.com"/>
</zipFile>
<comment>comment</comment>
</Attach>
<Attach>
<documentName>README.txt</documentName>
<zipFile>
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:ea1779f1-4477-46b5-8364-9a525f49c734@example.jaxws.sun.com"/>
</zipFile>
<comment>comment2</comment>
</Attach>
</attaches>
</ns2:SubmitAttachmentRequestEle>
</S:Body>
</S:Envelope>

In Osb $body variable you will get following transformed of code:
<attaches xmlns:ns2="http://www.ru.fors.nsi/SOAPwithAttachment/" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<Attach>
<documentName>test.doc</documentName>
<zipFile>
<con:binary-content ref="cid:1c6b1828:120c78cd5fd:-7fd4" xmlns:con="http://www.bea.com/wli/sb/context"/>
</zipFile>
<comment>comment1</comment>
</Attach>
<Attach>
<documentName>README.txt</documentName>
<zipFile>
<con:binary-content ref="cid:1c6b1828:120c78cd5fd:-7fd3" xmlns:con="http://www.bea.com/wli/sb/context"/>
</zipFile>
<comment>comment2</comment>
</Attach>
</attaches> 

con:binary-content element will hold the reference of the binary data on hash table. We can easily get the content of the binary data and send it to save on file or drive it to ftp or email attachment. For more information see my previous post.
See for detail information.

Wednesday

Send e-mail with attachment through OSB

Oracle Service Bus (OSB) contains a good collection of adapter to integrate with any legacy application, including ftp, email, MQ, tuxedo. However e-mail still recognize as a stable protocol to integrate with any application asynchronously. Send e-mail with attachment is a common task of any business process. Inbound e-mail adapter which, integrated with OSB support attachment but outbound adapter doesn't. This post is all about sending attachment though JavaCallout action.
There are two ways to handle attachment in OSB:
1) Use JavaCallout action to pass the binary data for further manipulation. It means write down a small java library which will get the attachment and send the e-mail.
2) Use integrated outbound e-mail adapter to send attachment, here you have to add a custom variable named attachment and assign the binary data to the body of the attachment variable.
First option is very common and easy to implement through javax.mail api, however a much more developer manage to send the binary attachment by second option but i couldn't figure out it yet.
Here, we are going to describe all the necessary step to implement the first option describe above.
First of all we will develop a small java library to send the mail. Java class will be contain one static method with all the necessary parameter to send mail, including smtp server address and the receptions address, moreover it will have one byte array parameter (byte[]) to get the binary data. The java class is as follows:
package com.blu.nsi.transport;

import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.DataHandler;
import java.io.*;

import javax.mail.Multipart;

public class MailClient {

/**
* public method that will invoked by business service to send mail
* */
public static void  sendMail(String smtpServer,
String from,
String to,
String subject,
String body,
String fileName,
byte[] zipFile) throws Exception
{
java.util.Properties props = System.getProperties();

props.setProperty("mail.smtp.host", smtpServer);
Session session = Session.getInstance(props);
Message message = new MimeMessage(session);
message.setFrom( new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.setSubject(subject);
message.setSentDate(new java.util.Date());
message.setHeader("X-Mailer", "MailClient");

//Set content to the mime body
MimeBodyPart messagePart = new MimeBodyPart();
messagePart.setText(body);
MimeBodyPart messageAttach = new MimeBodyPart();
String fName = fileName.substring(fileName.lastIndexOf("\\")+1);

MailDataSource dataSource = new MailClient.MailDataSource();
dataSource.setContentType("application/x-zip-compressed");
dataSource.setData(zipFile);
dataSource.setName(fName);

messageAttach.setDataHandler(new DataHandler(dataSource));
messageAttach.setFileName(fName);
messageAttach.addHeader("charset", "windows-1251");

// add multipart
Multipart multiPart = new MimeMultipart();
multiPart.addBodyPart(messagePart);
multiPart.addBodyPart(messageAttach);
// add to message
message.setContent(multiPart);

Transport.send(message);

}
static class MailDataSource implements javax.activation.DataSource{
private byte[] data;
private String contentType;
private String name;


public void setContentType(String contentType) {
this.contentType = contentType;
}

public void setData(byte[] data) {
this.data = data;
}

public void setName(String name) {
this.name = name;
}

public String getContentType() {

return contentType;
}

public InputStream getInputStream() throws IOException {

return new java.io.ByteArrayInputStream(data);
}

public String getName() {

return name;
}

public OutputStream getOutputStream() throws IOException {

return null;
}

}
}

Now we are ready to develop project in OSB to send the attachment. First we will create a wsdl to send the soap message with attachment to proxy service. The wsdl file contain only one port and binding will be the style with rpc/literal. Only rpc style could define multipart message. The wsdl file is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.com.blu/SOAPwithAttachment/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
name="SOAPwithAttachment"
targetNamespace="http://www.com.blu/SOAPwithAttachment/">
<wsdl:types>
<xsd:schema targetNamespace="http://www.com.blu/SOAPwithAttachment/">
<xsd:complexType name="SubmitAttachmentResponseType">
<xsd:sequence>
<xsd:element name="response" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="SubmitAttachmentRequestType">
<xsd:sequence>
<xsd:element name="smtpserver" type="xsd:string" />
<xsd:element name="to" type="xsd:string" />
<xsd:element name="from" type="xsd:string" />
<xsd:element name="subject" type="xsd:string" />
<xsd:element name="body" type="xsd:string" />
<xsd:element name="fileName" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
<xsd:element name="submitAttachmentRequest" type="tns:SubmitAttachmentRequestType" />
<xsd:element name="zipFile" type="xsd:base64Binary" />
</xsd:schema>
</wsdl:types>

<wsdl:message name="submitAttachmentRequest">
<wsdl:part name="submitAttachment" type="tns:SubmitAttachmentRequestType"  />
<wsdl:part name="zipFile" type="xsd:base64Binary" />
</wsdl:message>

<wsdl:message name="submitAttachmentResponse">
<wsdl:part name="submitAttachmentResponse" type="tns:SubmitAttachmentResponseType" />
</wsdl:message>
<wsdl:portType name="SOAPwithAttachmentPort">
<wsdl:operation name="submitAttachment">
<wsdl:input message="tns:submitAttachmentRequest" />
<wsdl:output message="tns:submitAttachmentResponse" />
</wsdl:operation>
</wsdl:portType>

<wsdl:binding name="SOAPwithAttachmentSOAP"
type="tns:SOAPwithAttachmentPort">
<soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="submitAttachment">
<soap:operation
soapAction="http://www.com.blu/SOAPwithAttachment/submitAttachment" />
<wsdl:input>
<mime:multipartRelated>
<mime:part>
<soap:body parts="submitAttachment" use="literal" namespace="http://www.com.blu/SOAPwithAttachment/"/>
</mime:part>
<mime:part>
<mime:content part="zipFile" type="application/zip"/>
</mime:part>
</mime:multipartRelated>
</wsdl:input>
<wsdl:output>
<soap:body parts="submitAttachmentResponse" use="literal" namespace="http://www.com.blu/SOAPwithAttachment/"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>

<wsdl:service name="SOAPwithAttachment">
<wsdl:port binding="tns:SOAPwithAttachmentSOAP"
name="SOAPwithAttachmentSOAP">
<soap:address location="http://localhost:7001/SOAPwithAttachment_WS/SOAPwithAttachment" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>


Now we will create a proxy service based on this wsdl file and import the jar file in the project.
Add one pipeline node on the proxy and add one stage node on the request pipeline.
In the stage node add one assign action and set the following xpath expression
$attachments/ctx:attachment/ctx:body/ctx:binary-content
and set the name for variable for example attachData, where $attachments is the variable of the attachment. binary-content element hold the reference of the binary data to hash table. binary-content element looks like this:
<binary-content ref="ccid:2321f-fa-edf21"/>
XML and text attachments are represented as XML and text, respectively, and can be manipulated directly with XQuery or XSLT. Binary attachment data can be manipulated only by passing the binary data to a Javacallout for processing. Remember you should send the content of the binary-content element not its reference id.
Add a JavaCallout action in the stage node and assaign it to the jar file. Fill up all the expression from the $body variable as follows:
$body/soap:submitAttachment/submitAttachment/subject/text()
also set the variable named attachData to byte[] parameter of the java class method.

Add one stage node on the response pipeline and add one replace and delete action. In the response pipleline we will make up the following response:
<ns0:submitAttachmentResponse xmlns:ns0="http://www.alsb.com/SOAPwithAttachment/">
<submitAttachmentResponse>
<response>OK</response>
</submitAttachmentResponse>
</ns0:submitAttachmentResponse>

In the replace action set the variable to the body element and xpath as ./*, also set the above xml fragment. It means we will replace the content of body element with this fragment of xml.
Now in the properties of the delete action, set the attachment variable to delete.

Here, you have just complete the tutorial and are ready to deploy it on the server. After that you have to generate stab or proxy java class from the proxy service wsdl and test the service.
Resources:
See additional information about OSB message context model.

Apply dynamic routing on Oracle service bus

Last year on one of our project we applied oracle enteprise service (SOA suite 10.1.3.1) to integrate with a few legacy system through IBM MQ. This year we have a plan to migrate this integration on OSB (Oracle service bus) previously known Aqua logic service bus from company BEA. Today i simplify one of our integration by using dynamic routing action.

Usecase: We have a few queue predefined on MQ manager to send messages for different purpose. Messages should route by according to their message content.

By using dynamic routing action and routing table we can easily publish messages to proper destination. The input xml file is as follows
<?xml version="1.0" encoding="UTF-8"?>
<TaxDiclaration id="uuid:62fa5eac-3df4-448d-a576-916dd5b432f2">
<destination>
rtu-chanel-2
</destination>
<gtd>
<id>13421</id>
<person>
<type>physical</type>
<name>Jhone</name>
<lastname>dow</lastname>
<tid>co-321478</tid>
<date>01-11-2009</date>
</person>
</gtd>
</TaxDiclaration>

by the content of the destination tag we will route entire message to his physical destination queue. Whole process is as follows:

1) Create three business service according to the destination of MQ.
2) Define the routing table xml as follows:
<routing>
<row>
<logical>rtu-chanel-2</logical>
<physical>rtu_SB/rtu_2_Biz</physical>
</row>
<row>
<logical>rtu-chanel-3</logical>
<physical>rtu_SB/rtu_3_Biz</physical>
</row>
<row>
<logical>rtu-chanel-4</logical>
<physical>rtu_SB/rtu_4_Biz</physical>
</row>
</routing>

where logical name is the name of the service, which will get from the input xml file. Physical tag contain the qualified name of the business services.
3) Create a proxy service with file transport and configure it with proper system folder to receive file.
3.1) Add one pipeline node and two stage node on request pipeline.
3.2) Add one assign action to collect the file from the inbound transport.
3.3) On 2nd stage node, add one assign action and add the routing table xml to the Expression. Give the variable name as routingTable.
3.4) Add one more assign action which will define the destination content from the xml body as follows:
$body/TaxDiclaration/destination/text()
and give the variable name as like logicalDestination.
3.5)Add one more assign action with following xpath:
<ctx:route>
<ctx:service>{$routingTable/row[logical/text()=$logicalDestination]/physical/text()}</ctx:service>
</ctx:route>

name the variable as physicalService.
3.6) Add a route node on the proxy and put a dynamic routing action on it.
3.7.) On expression properties put the following variable named $physicalService.
Now the service bus is ready for dynamic routing. For testing purpose just put some proper xml file with logical destination, service bus will apply dynamic routing according to the content of the entire xml.

Develop your custom resource adapter with maven

The goal of the post is to publish a complete tutorial of developing a resource adapter using maven2. On the web we could found a few complete tutorial about developing resource adapter which will also help to understand the JCA specification. This current post may help the developer to agile development of JCA adapter. On the developing process we are going to use maven2 software managment tool and oc4j container to deploy the adpater and MDB client as consumer of the adapter.
For simlicity, we will going to build a inbound file adapter, which will get file periodically from some drive. An MDB (Message driven bean) will subscribe to the adapter to get file and manipulate the content of the file.
1) Building the resource adapter:
1.1)FileActivationSpec.java
JCA activation specification for the inbound JCA resource adapter. This activation specification contains the following configuration items:
- filePath
- fileExt
- pollingInterval
These configuration items are used at runtime by the JCA resource adapter to connect to the file system. An JCA activation specification must adhere to the JavaBean standards.
package com.blu.jca.file;

import javax.resource.spi.ActivationSpec;
import javax.resource.spi.InvalidPropertyException;
import javax.resource.spi.ResourceAdapter;
import javax.resource.ResourceException;
import java.io.Serializable;
import java.util.logging.Logger;


public class FileActivationSpec implements Serializable, ActivationSpec {
private static Logger logger = Logger.getLogger(FileActivationSpec.class.getName());

private ResourceAdapter resourceAdapter;
private String filePath;
private String fileExt;
private int pollingInterval;

public FileActivationSpec() {
logger.info("[Start] FileActivationSpec");
}

public void validate() throws InvalidPropertyException {
logger.info("[start] validation");
}

public ResourceAdapter getResourceAdapter() {
return resourceAdapter;
}

public void setResourceAdapter(ResourceAdapter resourceAdapter) throws ResourceException {
this.resourceAdapter = resourceAdapter;
}

public String getFilePath() {
return filePath;
}

public void setFilePath(String filePath) {
this.filePath = filePath;
}

public String getFileExt() {
return fileExt;
}

public void setFileExt(String fileExt) {
this.fileExt = fileExt;
}

public int getPollingInterval() {
return pollingInterval;
}

public void setPollingInterval(int pollingInterval) {
this.pollingInterval = pollingInterval;
}
}

1.2)FileResourceAdapter.java: Custom JCA File Resource Adapter implementation.
package com.blu.jca.file;

import javax.resource.spi.ResourceAdapter;
import javax.resource.spi.BootstrapContext;
import javax.resource.spi.ResourceAdapterInternalException;
import javax.resource.spi.ActivationSpec;
import javax.resource.spi.work.WorkManager;
import javax.resource.spi.endpoint.MessageEndpointFactory;
import javax.resource.spi.endpoint.MessageEndpoint;
import javax.resource.ResourceException;
import javax.resource.cci.MessageListener;
import javax.transaction.xa.XAResource;
import java.util.logging.Logger;

public class FileResourceAdapter implements ResourceAdapter {
private static Logger logger = Logger.getLogger(FileResourceAdapter.class.getName());

private WorkManager workManager;
public FileResourceAdapter() {
logger.info("[Start] FileResourceAdapter()");
}

public void start(BootstrapContext bootstrapContext) throws ResourceAdapterInternalException {
logger.info("[Start] start()");
workManager = bootstrapContext.getWorkManager();
}

public void stop() {
logger.info("[stop] stop()");
}

public void endpointActivation(MessageEndpointFactory messageEndpointFactory, ActivationSpec activationSpec) throws ResourceException {
logger.info("[start] endpointActivation");
MessageEndpoint endPoint =  messageEndpointFactory.createEndpoint(null);
if(endPoint instanceof MessageListener){
FileWork fileWork = new FileWork(activationSpec, endPoint);
workManager.scheduleWork(fileWork);
}
}

public void endpointDeactivation(MessageEndpointFactory messageEndpointFactory, ActivationSpec activationSpec) {
logger.info("[start] endpointDeactivation");
}

public XAResource[] getXAResources(ActivationSpec[] activationSpecs) throws ResourceException {
return new XAResource[0];
}
}

1.3)FileWork.java: A Work instance implementation for this JCA resource adapter that would be executed by a WorkManager upon submission.
package com.blu.jca.file;

import com.blu.jca.bean.FileMessageBean;

import javax.resource.spi.work.Work;
import javax.resource.spi.ActivationSpec;
import javax.resource.spi.endpoint.MessageEndpoint;
import javax.resource.cci.MessageListener;
import javax.resource.ResourceException;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.io.*;

public class FileWork implements Work {
private static Logger logger = Logger.getLogger(FileWork.class.getName());

private FileActivationSpec activationSpec;
//private MessageListener messageListener;
private FileMessageListener messageListener;
private boolean released;
public FileWork(ActivationSpec activationSpec, MessageEndpoint messageEndpoint) {
logger.info("[start] FileWork()");
this.activationSpec = (FileActivationSpec) activationSpec;
this.messageListener = (FileMessageListener) messageEndpoint;
this.released = false;
}

public void release() {
this.released = true;                            
}

public boolean isReleased() {
return released;
}

public void run() {
logger.info("[start] run()");
int pollingInterval = activationSpec.getPollingInterval();
//set polling interval in ms
if(pollingInterval < 5){
pollingInterval = 5000;
}else{
pollingInterval *=1000;
}
logger.info("[Set Polling interval in ms:]"+pollingInterval);
while(!isReleased()){
//start read file from directory
try {
logger.info("[Start reading from folder]");
File folder = new File(activationSpec.getFilePath());
if(folder.exists()&& folder.isDirectory()){
File[] files = folder.listFiles();
// process file
for(File file:files){
FileMessageBean fBean = new FileMessageBean();
fBean.setRecordName("Jca Standard file record");
fBean.setFileName("[fileName]:"+file.getName());
fBean.setRecordShortDescription("JCA file record which wrappes the file data");
FileMessage message = new FileMessage();
message.setFileMesssageBean(fBean);
logger.info("Read file data to wrap");
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
BufferedReader bf = new BufferedReader(new InputStreamReader(fis));
String data;
StringBuffer sbuffer = new StringBuffer();
while( (data = bf.readLine())!= null ){
sbuffer.append(data);
}
fBean.setData(sbuffer.toString());
messageListener.onMessage(message);
// sleep
Thread.currentThread().sleep(pollingInterval);
} catch (FileNotFoundException e) {
logger.log(Level.SEVERE,e.getMessage(),e);
throw new RuntimeException("FileNotFoundException:"+e.getMessage());
} catch(IOException e){
logger.log(Level.SEVERE,e.getMessage(),e);
throw new RuntimeException("Error on reading file:"+e.getMessage());
}finally {
try {
fis.close();
} catch (IOException e) {
logger.log(Level.SEVERE,e.getMessage(),e);
throw new RuntimeException("Error on reading file:"+e.getMessage());
}
}
}
}
} catch (InterruptedException e) {
logger.info("[Eroor on Run]"+ e.getMessage());
throw new RuntimeException("error in Run"+e.getMessage());
}
}
}
}
1.4) FileMessageBean: Bean serves as standardized data wrapper for the EIS data. In this case this record wraps a message from a file system.
package com.blu.jca.bean;

public class FileMessageBean {
private String fileName;
private String data;
private String recordName;
private String recordShortDescription;

public String getFileName() {
return fileName;
}

public void setFileName(String fileName) {
this.fileName = fileName;
}

public String getData() {
return data;
}

public void setData(String data) {
this.data = data;
}

public String getRecordName() {
return recordName;
}

public void setRecordName(String recordName) {
this.recordName = recordName;
}

public String getRecordShortDescription() {
return recordShortDescription;
}

public void setRecordShortDescription(String recordShortDescription) {
this.recordShortDescription = recordShortDescription;
}

public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

FileMessageBean that = (FileMessageBean) o;

if (data != null ? !data.equals(that.data) : that.data != null) return false;
if (fileName != null ? !fileName.equals(that.fileName) : that.fileName != null) return false;

return true;
}

public int hashCode() {
int result;
result = (fileName != null ? fileName.hashCode() : 0);
result = 31 * result + (data != null ? data.hashCode() : 0);
return result;
}
}
1.5) FileMessage.java: Also a wrpper bean to FileMessageBean.
package com.blu.jca.file;

import com.blu.jca.bean.FileMessageBean;

public class FileMessage {
private FileMessageBean fileMesssageBean;

public FileMessageBean getFileMesssageBean() {
return fileMesssageBean;
}

public void setFileMesssageBean(FileMessageBean fileMesssageBean) {
this.fileMesssageBean = fileMesssageBean;
}
}
1.6) FileMessageListener.java: It's a message listner for adapter.
package com.blu.jca.file;

import javax.resource.cci.MessageListener;

public interface FileMessageListener extends MessageListener {
void onMessage(FileMessage message);
}
1.7) pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.blu.jca.file</groupId>
<artifactId>jca-adapter</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>jca-adapter</name>
<url>http://maven.apache.org</url>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.resource</groupId>
<artifactId>connector15</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath><BPEL_Home>\lib\connector15.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
1.8) Generate rar file with deployment descriptors: 1.8.1) ra.xml
<?xml version="1.0" encoding="UTF-8"?>
<connector xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd"
version="1.5">
<display-name>File JCA Resource Adapter</display-name>
<vendor-name>Blue mountain international</vendor-name>
<eis-type>File Server</eis-type>
<resourceadapter-version>1.0</resourceadapter-version>
<resourceadapter>
<resourceadapter-class>com.blu.jca.file.FileResourceAdapter</resourceadapter-class>
<inbound-resourceadapter>
<messageadapter>
<messagelistener>
<!--<messagelistener-type>javax.resource.cci.MessageListener</messagelistener-type>-->
<messagelistener-type>com.blu.jca.file.FileMessageListener</messagelistener-type>
<activationspec>
<activationspec-class>com.blu.jca.file.FileActivationSpec</activationspec-class>
<required-config-property>
<config-property-name>filePath</config-property-name>
</required-config-property>
<required-config-property>
<config-property-name>fileExt</config-property-name>
</required-config-property>
<required-config-property>
<config-property-name>pollingInterval</config-property-name>
</required-config-property>
</activationspec>
</messagelistener>
</messageadapter>
</inbound-resourceadapter>
</resourceadapter>
</connector>
1.8.2) oc4j-ra.xml:
<?xml version="1.0" encoding="windows-1252" ?>
<oc4j-connector-factories xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.oracle.com/technology/oracleas/schema/oc4j-connector-factories-10_0.xsd"
schema-major-version="10" schema-minor-version="0">
<!-- When deployed the adapter you must define the name as FileResourceAdapter otherwise client will not found it-->
<connector-factory location="eis/FileResourceAdapter" connector-name="FileResourceAdapter">
<connection-pooling use="none"></connection-pooling>
<security-config use="none"></security-config>
</connector-factory>
</oc4j-connector-factories>
1.8.3) pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.blu.jca.file</groupId>
<artifactId>jca-rar</artifactId>
<packaging>rar</packaging>
<version>1.0</version>
<name>jca-rar</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.blu.jca.file</groupId>
<artifactId>jca-adapter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-rar-plugin</artifactId>
<configuration>
<includeJar>false</includeJar>
<!--<raXmlFile>src/main/resources/ra.xml</raXmlFile>-->
</configuration>
</plugin>
</plugins>
</build>
</project>
2) Deployment: During adapter deployment, the application server creates a new instance of ResourceAdapter and calls the start() method. ResourceAdapter may initialize any resources required for processing later. In the start() method, ResourceAdapter receives the BootStrapContext object, which can be used to retrieve the WorkManager. ResourceAdapter can use WorkManager to submit work, which in turn starts the work thread. The stop() method of ResourceAdapter is invoked when either the application server is shutting down or the resource adapter is being undeployed. following sequence diagram show even during resource adapter deployment. Deployment process is easy in oc4j, through web interface deploy the jca-rar-1.0.rar, during deployment provide resource adapter name as follows FileResourceAdapter. 3) Developing MDB client: 3.1) FileResourceAdapterClientMDBBean.java: EJB 3.0 Message Driven Bean (MDB) that acts as client for the File JCA Resource Adapter.
package com.blu.jca.client;

import oracle.j2ee.ejb.MessageDrivenDeployment;

import javax.resource.cci.MessageListener;
import javax.resource.cci.Record;
import javax.resource.ResourceException;
import javax.ejb.MessageDriven;
import javax.ejb.ActivationConfigProperty;
import java.util.logging.Logger;

import com.blu.jca.file.FileMessageListener;
import com.blu.jca.file.FileMessage;
import com.blu.jca.bean.FileMessageBean;
@MessageDriven(
messageListenerInterface=FileMessageListener.class,
activationConfig = {
@ActivationConfigProperty(
propertyName="filePath", propertyValue="D:\\JcaFolder"),
@ActivationConfigProperty(
propertyName="fileExt", propertyValue="*.*"),
@ActivationConfigProperty(
propertyName="pollingInterval", propertyValue="10")
})
/**
* Resource adapter name during deployment by web
* */
@MessageDrivenDeployment(resourceAdapter = "FileResourceAdapter")
public class FileResourceAdapterClientMDBBean implements  FileMessageListener {
private static Logger logger = Logger.getLogger(FileResourceAdapterClientMDBBean.class.getName());

public FileResourceAdapterClientMDBBean() {
logger.info("[start] FileResourceAdapterClientMDBBean");
}

public Record onMessage(Record record) throws ResourceException {
return record;
}

public void onMessage(FileMessage message) {
logger.info("[start]:File client MDB fileMessage OnMessage");
FileMessageBean fBean = message.getFileMesssageBean();

logger.info("[Record Name]:"+fBean.getRecordName());
logger.info("[Description:]:"+fBean.getRecordShortDescription());
logger.info("[File Name:]:"+fBean.getFileName());
logger.info("[File Data:]:"+fBean.getData());        
logger.info("[End:] On Message");        
}
}
3.2) pom.xml for generate ejb
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.blu.jca.ejb</groupId>
<artifactId>jca-ejb</artifactId>
<packaging>ear</packaging>
<version>1.0-SNAPSHOT</version>
<name>jca-ejb</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.blu.jca.client</groupId>
<artifactId>jca-client</artifactId>
<version>1.0-SNAPSHOT</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>com.blu.jca.file</groupId>
<artifactId>jca-adapter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>jcaEjb-client</finalName>
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<displayName>JCA ejb client</displayName>
<description>Client for JCA file adapter</description>
<!--<version>1.3</version>-->
<modules>
<ejbModule>
<groupId>com.blu.jca.client</groupId>
<artifactId>jca-client</artifactId>
<bundleFileName>jca-client-1.0-SNAPSHOT.jar</bundleFileName>
</ejbModule>
<jarModule>
<groupId>com.blu.jca.file</groupId>
<artifactId>jca-adapter</artifactId>
<!--<bundleFileName>jca-adapter-1.0-SNAPSHOT.jar</bundleFileName>-->
<includeInApplicationXml>false</includeInApplicationXml>
</jarModule>
</modules>
<resourcesDir>${basedir}/target/classes</resourcesDir>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<targetPath>META-INF</targetPath>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
after generating ejb package, we will also deploy it on oc4j container. During deployment of MDB client, if following errors will occure, please check the resource adapter name during deployement and mdb client target adpater name. They must be same. No ResourceAdapterWrapper instance found at the specified resource-adapter() ... 4) Test: Just put any text file on inbound file directory and wait some time. Adapter will collect the file and send it's content to the MDB. All the event will see from the oc4j console. In the conclusion, for further reading see JCA1.5 specification. A much more ideas will get from the follwing resource during writing the post.
  • http://www.oracle.com/technology/pub/articles/luttikhuizen-adapters.doc
  • Have your application call my application, Part 3: The resource adapter
    Geronimo message-driven beans, JCA resource adapters, and e-mail. http://www.ibm.com/developerworks/opensource/edu/os-dw-os-ag-callme1.html?S_TACT=105AGX44&S_CMP=GRNMO

Thursday

Correct dependency configuration for maven-weblogic-plugin to deploy in Weblogic server 10.3.0.0

Mojo weblogic plugin version 2.9.0 is not stable for Weblogic server 10.3.0.0. Configuration which suggest on the mojo documentation is not working for current Weblogic server version and produce some hopeless error. Seems installed weblogic.jar and webservices.jar on local repository is not using properly on plug ins life cycle. However it's easy to fix the error through system scope dependency which i will demonstrate below:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.fors.test.gwt.core</groupId>
<artifactId>core-web</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>core-web</name>
<url>http://www.fors.ru</url>
<parent>
<groupId>ru.fors.test.gwt.core</groupId>
<artifactId>app</artifactId>
<version>1.0</version>
</parent>
<properties>
<weblogic.version>1.0</weblogic.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-servlet</artifactId>
<version>${gwtVersion}</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/gwt-servlet.jar</systemPath>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>${gwtVersion}</version>
<scope>system</scope>
<systemPath>${GWT_HOME}/gwt-user.jar</systemPath>
</dependency>    
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev-windows</artifactId>
<version>${gwtVersion}</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/gwt-dev-windows.jar</systemPath>
</dependency>  
</dependencies>
<build>
<finalName>core-web</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- maven googletoolkit plugin-->
<plugin>
<groupId>com.totsp.gwt</groupId>
<artifactId>maven-googlewebtoolkit2-plugin</artifactId>
<version>2.0-beta6</version>
<configuration>
<extraJvmArgs>-Xmx512m</extraJvmArgs>
<runTarget>HelloGWT.html</runTarget>
<compileTargets>
<param>ru.fors.test.gwt.core.HelloGWT</param>
</compileTargets>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
</configuration>
<executions>
<execution>
<goals>
<goal>mergewebxml</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<webXml>target/web.xml</webXml>
</configuration>
</plugin>
<!-- maven weblogic plugin configuration -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>weblogic-maven-plugin</artifactId>
<version>2.9.0</version>
<configuration>
<adminServerHostName>localhost</adminServerHostName>
<adminServerPort>7001</adminServerPort>
<adminServerProtocol>t3</adminServerProtocol>
<userId>weblogic</userId>
<password>weblogic</password>
<upload>false</upload>
<remote>false</remote>
<verbose>false</verbose>
<debug>false</debug>
<targetNames>AdminServer</targetNames>
<exploded>false</exploded>
</configuration>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.5</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
<dependency>
<groupId>weblogic</groupId>
<artifactId>weblogic</artifactId>
<version>${weblogic.version}</version>
<scope>system</scope>
<systemPath>PATH_TO_LIBRARY/weblogic.jar</systemPath>
</dependency>
<dependency>
<groupId>weblogic</groupId>
<artifactId>webservices</artifactId>
<version>${weblogic.version}</version>
<scope>system</scope>
<systemPath>PATH_TO_LIBRARY/webservices.jar</systemPath>
</dependency>
</dependencies>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.html</include>
<include>**/*.xml</include>
<include>**/*.css</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>

Tuesday

Oracle develop roadshow in Moscow, 4-5 th february

Last week Oracle corporation demonstrated their roadshow in Moscow. The roadshow started with the sparkling presentation of Larry Cable. Within an hour he could manage to demonstrate the Oracle Big Fussion middleware, focused on Oracle WebLogic Server and related (Java based) standards technologies. It was very interesting to listen JAVA/RICH ENTERPRISE APPLICATIONS TRACK and enjoy the ability of Oracle JDeveloper. I always against Oracle strategy to make JDeveloper as a main IDE to develop all the java related technology on Oracle platform, because it's seems all the eggs in one basket. But while Larry go through all the the ADF rich client with some mouse click, i started believe that may be JDeveloper already got maturity to use seriously.
There were three main Track:
DataBase Track and hands on lab;
Java/Rich enterprise Application track and hands on lab;
Service oriented architecture track and hands on lab.

I was very interested on SOA track, specially on BEA products. This track covers all things service-oriented architecture (SOA), from basics to best practices. Also covers architecture role on small and large enterprise application. This track also focused on emerging trends such as business process management (BPM) and event-driven architecture. I love the technical deep drive on BPM suite and BPA suite and the Oracle Business Rules engine. The overview of SCA was very interesting, now Oracle has their own implementation of SCA on their basket.
One of my friend convince me to attend on Database track named "Doing SQL from PL/SQL: Best and Worse Practices", it was wonder full to learn about the new features of PL/SQL and the worst practices.
In the conclusion i can only say that, i was satisfied and be sorry for those who missed the roadshow.

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

Sunday

Agile development of apache tucsany SCA with Ilog jrules decision services

Apache tucsany provides a framework for developing SOA solution that is based on Service Component Architecture (SCA) standard. Tucsany offers following advantages:
1) Provides a model for creating composite applications by defining the services in the fabric and their relationships with one another.
2) Enables service developers to create reusable services that only contain business logic.
3) Existing applications can work with new SCA compositions. This allows for incremental growth towards a more flexible architecture, outsourcing or providing services to others.

Tucsany implemented in java and c++ programming language. For more information visit apache tucsany site.
In the growing uses of business rules in SOA, on the current post i decide to make a laboratory work to show how to use business rules in SCA SOA solution.
For more information to get benifit from business rules please consider my some previous post about Ilog business rules.
On the current tutorial we are going to use following tools and libraries:
1) Maven 2.0.9
2) JAX-WS 2.1.5
3) Tucsany SCA 1.4
4) Ilog Jrules 6.0.7
All the information to download and install of all tools and frameworks should be found on their home site.
For developing the tutorial i preferred to use Intelli Idea 7. But you can use your own IDE because we uses maven to manage the project and you can easily create any particullar project by maven tools.
Create composite service application:
The following shows the composition diagram for the composite service application we are about to create.

The composite stock agent component consist of two services and one decision service. There is Customer agent service, from where you might get all the necessary information of customer by customer id. From the otder service we will get product information and sned all the information to decision service for some validation. If outgoing status approved, then stock agent generate products bill. Actually example used here to only show the jax-ws binding to ilog decision service.
Now we start developing from the scratch by using maven tools. First we will start ilog jrules server and deploy the example decision service provide with the jrules installation. If you deploy it's properly, you should get the wsdl in the folowing location
http://localhost:8080/DecisionService/ws/PreTradeChecksRuleApp/1.0/PreTradeChecks/1.0?WSDL
For more information develop and deploy decesion service on Jrules, please refer to the following post.
Now it's time to create the pom.xml file as follows:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.blu.sca.simple</groupId>
<artifactId>sca-simple</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>sca-simple</name>
<url>http://maven.apache.org</url>
<repositories>
<repository>
<id>apache.incubator</id>
<url>http://people.apache.org/repo/m2-incubating-repository</url>
</repository>
</repositories>    
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-node-api</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-node-impl</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-implementation-java-runtime</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-domain-manager</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-binding-sca</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-binding-sca-axis2</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-host-embedded</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.1.5</version>
</dependency>

</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<!--<phase>process-resources</phase>-->
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<packageName>com.blu.sca.dservice</packageName>
<keep>true</keep>
<sourceDestDir>${basedir}/src/main/java</sourceDestDir>
<wsdlDirectory>${basedir}/src/main/resources</wsdlDirectory>
<wsdlFiles>
<wsdlFile>pretrade.wsdl</wsdlFile>
</wsdlFiles>            
</configuration>
<dependencies>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-tools</artifactId>
<version>2.1.5</version>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.blu.sca.simple.agent.decision</mainClass>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>

First of all we build the project name sca-simple by maven tools and append all the necessary dependency on it. Download the wsdl file to the src\main\resources folder to generate proxy releated class from the decesion service. In the current project i use latest version of JAX-WS which you probably need to download and install manually on the local maven repositories.
Here is the command to install libraries manually on the maven local repositories.
mvn install:install-file -Dfile=D:\Distributors\java\webservice\jax-ws\jaxws-ri\lib\jaxws-rt.jar -DgroupId=com.sun.xml.ws -DartifactId=jaxws-rt -Dversion=2.1.5 -Dpackaging=jar -DgeneratePom=true

Project is now ready to coding. If we will run the following command in console,
$mvn clean compile
the maven will first generate all the stub class from the wsdl and compile the project. This may take a few minutes because maven will download a lot of tuscany modules and files to your local repositories.
For simplicity we will only take a look to the main parts of the project. Anyway the source code the project will be downlodable.
First we will create interface for the decision service as follows:
package com.blu.sca.simple.services;

import org.osoa.sca.annotations.Remotable;
@Remotable
public interface IRulesService {
String lookup(Customer customer, Product product);
}

and also the implemention:
package com.blu.sca.simple.impl;

import com.blu.sca.simple.services.IRulesService;
import com.blu.sca.rules.*;
import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;
import org.osoa.sca.annotations.Reference;
import org.osoa.sca.annotations.AllowsPassByReference;
import org.osoa.sca.annotations.Service;
import org.osoa.sca.ServiceRuntimeException;

import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;

@Service(IRulesService.class)
@AllowsPassByReference
public class RulesService implements IRulesService {
@Reference
protected DecisionServicePreTradeChecks dsrService;

public String lookup(Customer customer, Product product) {
// create request  
DecisionServiceRequest request = new DecisionServiceRequest();
CustomerParameter customarP = new CustomerParameter();

customarP.setCustomer(customer);
OrderParameter orderP = new OrderParameter();

orderP.setOrder(product);

request.setCustomerParameter(customarP);
request.setOrderParameter(orderP);

DecisionServiceResponse response = null;
String str="";
ReportParameter report=null;
try{
response = dsrService.executeDecisionService(request);
report = response.getReportParameter();
str = report.getOrder().getStatus();
}catch(DecisionServiceSoapFault fault){
str = fault.getMessage());
}
return str;
}
}

Finally we will create composite xml file to compose all the component.
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://scadecision"
xmlns:sample="http://scadecision"
name="Decisionservice">

<component name="BookingAgentServiceComponent">
<implementation.java class="com.blu.sca.simple.impl.BookingAgentServiceComponent"/>
<reference name="customerService" target="CustomerServiceComponent" />
<reference name="orderService" target="OrderServiceComponent" />
<reference name="rulesService" target="RulesServiceComponent" />
</component>

<component name="RulesServiceComponent">
<implementation.java class="com.blu.sca.simple.impl.RulesService"/>
<reference name="dsrService">
<binding.ws uri="http://localhost:8080/DecisionService/ws/PreTradeChecksRuleApp/1.0/PreTradeChecks/1.0?WSDL" />
</reference>
</component>

<component name="CustomerServiceComponent">
<implementation.java class="com.blu.sca.simple.impl.CustomerService"/>
</component>

<component name="OrderServiceComponent">
<implementation.java class="com.blu.sca.simple.impl.OrderService"/>
</component>

</composite>

At these moment all the component is ready to compose. You can build and run the program by maven as follows:
$mvn clean compile
$mvn exec:java

Thursday

Simplify developying decision services in Ilog jrules

Ilog Jrules define decision service as a ordinary web service with management capabilities using JMX MBeans. Through protocol SOAP, it's easy to invoke business rules rather than any other protocol like rmi. More information about decision services should find here.
From the view of ilog jrules, there are two types of decision services:
1) Hosted transparent decision services
2) Monitored transparent decision services

All of them drives rule execution and enables users to access Rule Execution Server through a Web service, rather than accessing it directly.
Hosted transparent decision services: Using a hosted transparent decision service, Rule Execution Server automatically exposes any deployed rule set as web services, that uses an XML schema or a Java XOM with simple types. The decision service automatically generates Web Services Description Language (WSDL) file for each deployed ruleset archive and the decision service MBean is able to retrieve execution statistics. These rulesets can be exposed as a Web service without passing through code deployment.
The hosted transparent decision service supports all primitive java type automatically. To use hosted transparent decision service, you should deploy transparent decision service archive in the same server where installed RES.
Now installed business rules with simple data type in RES will automatically exposes as web services. You can access wsdl from the rule set view of the installed business rules.

Whenever user click the link to get wsdl, component transparent decision service automatically generate the web service and a new decision service will found in the navigator.
If rule set contains custom java data types, the xom of the rule set must append to the jrules-bres-ootbds-JBOSS40.ear->jrules-bres-ootbds-JBOSS40.war\WEB-INF\lib directory and redeploy.
Through WSDL it's simple to create java proxy class to test the decision service. Most of the time, i use Xml spy editor to test soap service quickly. XML spy editor has options to create soap request and send it to the server.
Monitored transparent decision services:
Unlike a hosted transparent decision service, a monitored transparent decision service manages rulesets that use an XML schema or any Java XOM with simple types. XML parameters are represented by a String in the WSDL file.
Using the Client Project for RuleApps wizard, you can create the following projects:
1) A monitored transparent decision service project from your RuleApp project. The code generator generates two projects: the decision (or Web) service project, and the client project, which can be used to test the code generated in the decision service project. After the ruleset has been executed by this client, the transparent decision service can be monitored by the Rule Execution Server Console. Note that client generated by wizard is not well generating most of all time, it's better to generate client from the wsdl manually.
2) A Web service project from your rule project. The code generator generates a client project that can be used to test the code generated in the Web service project. This project cannot be detected by the Rule Execution Server management model, so the Rule Execution Server Console does not monitor rulesets executed by the client provided, or any other client.
Monitored transparent decision services created by RuleApps wizard execute rule set archive locally. Actually they never invoke rule set deployed in RES. So there will no execution statistics for the rule set will found in RES.
Generated decision services implements JAX-WS and only support jboss and tomcat.

Another effective way to invoke business rules are creating a web service as client to call business rules through J2EE provider. Here web service is the mediator of the business rules and client, web service encapsulate all the boilerplate code to call business rules in RES.