Wednesday, July 17, 2013

File Adapter in Oracle SOA 11g cluster environment

A couple days ago I had an issue with Oracle SOA Adapter in cluster environment.  File Adapter is used as inbound file reader in the composite. It works fine with the development environment which is single node.  The issue is that the file will be read twice, each time by a File Adapter instance on one cluster node.

From the search for the solution of this issue there are two ways to tackle this problem:

1. Use Singleton property for the inbound endppoint for SOA composite.
To enable this just add singletom property to composite.xml.

 
 <service name="InvoiceXMLReader" ui:wsdlLocation="InvoiceXMLReader.wsdl">

    <interface.wsdl interface="http://xmlns.oracle.com/pcbpel/adapter/file/EInvoiceProcessing/InvoiceXMLReader/InvoiceXMLReader#wsdl.interface(Read_ptt)"/>

    <binding.jca config="InvoiceXMLReader_file.jca">

        <property name="singleton">true</property>

    </binding.jca>

  </service>



2. To use HAFielAdapter for File Adapter.

Thus in the .jca fiel change to use eis/HAFileAdapter instead of eis/FileAdapter.

 
<adapter-config name="InvoiceXMLReader" adapter="File Adapter" wsdlLocation="InvoiceXMLReader.wsdl" xmlns="http://platform.integration.oracle/blocks/adapter/fw/metadata">

 

  <connection-factory UIexcludeWildcard="*.tif;*.lock" location="eis/HAFileAdapter" UIincludeWildcard="*.*"/>

  <endpoint-activation portType="Read_ptt" operation="Read">

    <activation-spec className="oracle.tip.adapter.file.inbound.FileActivationSpec">

      <property name="DeleteFile" value="false"/>

      <property name="MinimumAge" value="0"/>

      <property name="PhysicalDirectory" value="/u01/shared/einvoice"/>

      <property name="Recursive" value="true"/>

      <property name="PollingFrequency" value="10"/>

      <property name="IncludeFiles" value=".*\..*"/>

      <property name="UseHeaders" value="false"/>

      <property name="ExcludeFiles" value=".*\.tif;.*\.lock"/>

    </activation-spec>

  </endpoint-activation>

</adapter-config>


Behind HAFileAdapter is the database used as mutex to ensure the one file is only handled by one instance.  By default it uses jdbc/SOADataSource.   When using HAFileAdapter in OSB this jdbc/SOADataSource should also target the OSB server nodes as well.
This also invovles some configuration changes for File Adapter.  You need to set Deployments->File Adapter->Configuration->Outbound Connection Pools->javax.resource.cci.ConnectionFactory->eisHAFileAdapter->controlDir to some shared localtion.

To my understanding the first way is to force to seralize the inbound file processing, which means only one File Adapter is processing a file at one time.   HAFileAdapter is using some mutex to ensure one file is only processed by one FileAdapter instance.  But the multiple HAFileAdapter can process the different file at the same time.  So this is the real solution for high availability environment.

Monday, July 15, 2013

Comparison of XSLT and XQuery

Recently I am working on one project which gets involved in transforming a large XML document in Oracle SOA Suite 11g.  Initially this transformation is done using XSLT.   We did the end-to-end testing with a large payload and noticed that the XSLT transformation took the most of the message processing time.  Later someone suggests that with large payload XQuery is more efficient than XSLT.   So we decided to implement the same transformation using XQuery.   The comparison result is a bit surprise to me.  
  
<ein:ProcessRequest>
 <ein:DocumentID>4.IPM_013407</ein:DocumentID>
 <ein:InvoiceNumber>12345</ein:InvoiceNumber>
 <ein:InvoiceType>PO</ein:InvoiceType>
 <ein:InvoiceDescription>LYRECO JUN 2013</ein:InvoiceDescription>
 <ein:SupplierName>LYRECO PTY LTD</ein:SupplierName>
 <ein:SupplierSiteName>E-INVOICE</ein:SupplierSiteName>
 <ein:POInvoice>
  <ein:POInvoiceItems>
  <ein:InvoiceNo>2331940908</ein:InvoiceNo>
  <ein:Amount>195.42</ein:Amount>
  <ein:GSTAmount>17.77</ein:GSTAmount>
  <ein:InvoiceDate>2013-05-01</ein:InvoiceDate>
  <ein:Description>Some description text</ein:Description>
  <ein:Quantity>1</ein:Quantity>
  <ein:UnitPrice>195.42</ein:UnitPrice>
  <ein:ExpenseType>STATIONERY</ein:ExpenseType>
  <ein:ProjectNumber>200363</ein:ProjectNumber>
  <ein:TaskNumber>11040</ein:TaskNumber>
  <ein:ExpenditureType>Office Supplies</ein:ExpenditureType>
  </ein:POInvoiceItems>
  
  ............
  
 </ein:POInvoice> 
<ein:ProcessRequest> 

Firstly I tried the transformation of a XML message like the above but with over 2700 <POInvoiceItems> elements using XMLSpy.  The result shows XQuery is much faster than XSLT when transforming this message.   Roughly XQuery is 3~4 times faster. 

Then I put these two transformations into one Oracle SOA application respectively and invoke the application with the same large message payload.   The comparison show that under Oracle Weblogic environment there is no obvious difference between XQuery and XSLT and XSLT is even faster than XQuery.   I am not quite sure what cause the different results using XMLSpy and Oracle Weblogic.  Maybe it is related to the implementation of XQuery and XSLT enegines within XMLSpy and Oracle Weblogic.

BigNumber vs Double

Recently I worked on one project which involved using JAXB to generate XML message fro the excel file.   Some data in the file are financial amount and tax amount.  When it is read from the excel it is represented as the floating number.  However in the generated XML message these data occurs to have something like the below:


       <GSTAmount>26.789999999999999999999999999967899</GSTAmount>


In schema GSTAmount is defined as xsd:decimal and the rounding is done before marshaling by JAXB.  I did some serach using Google and learned some tips when dealing with financial amount in Java.


  1. Use BigDecimal rather than double when defining the financial amount.
  2. When using BigDecimal use its string conductor.
Here is the excellent link which explains this issue very clearly. How to Use Java BigDecimal: A Tutorial