Wednesday, December 22, 2010

XSL Refresh 10g

It is always good practice to have all XSD outside the BPEL and ESB project and refer them via http url (or oramds in 11g). All XSL remains in the BPEL or ESB, and changes to XSL requires redeployment.

We have lot of logic in XSL especially in AIA, and lot of XSL can be reused. We thought of exploring the option of doing real time changes to XSL.

Option 1: XSL embedded in BPEL process
If XSL is embedded in BPEL process, the XSL is cached inside the transformation engine. Fortunately, XSL function used by BPEl and ESB provides ways to initialize the cache. com.collaxa.cube.xml.xpath.functions.xml.GetElementFromXSLTFunction provide initializeCache function. So if you deploy a Java class in the same JVM as BPEL RT, then it can call this method and reinit the XSL cache. I did the same, created a Java class which calls GetElementFromXSLTFunction initializeCache and then exposed that piece of code as a WebService.

Here are detailed steps:
  • (one time) Deploy the the XSL Refresh web service (download) to same container as BPEL
  • Change the XSL from $ORACLE_HOME/bpel/domains/domain-name/tmp/.bpel.../.. as your need
  • go to: http://host:port/XSLTRefresh/RefreshXSLTPoolSoapHttpPort and hit invoke
This will ensure that new XSL changes will be in effect immediately. This approach came quite handy during development phase as I could avoid redeploying AIA processes for XSL changes and could have better turn around. Option 2: XSL on Apache Server I think cleaner way would be to Putting XSLs outside the BPEL project and deploy them separately from the BPEL and ESB deployment. E.g.
<from expression="ora:processXSLT('http://host:7777/xsl/Transform_IP_OP_Sample.xsl',bpws:getVariableData('inputVariable','payload'))"/>


BPEL XSL engine doesn't cache the XSL handle if it is http based, but you can use the xsl refresh webservice if you see any issue depending on BPEL version you are using.

Tuesday, December 21, 2010

IE8 with Oracle ESB 10g

We were having issue with ESB console when we upgraded from IE6 to IE8 browser. BPELConsole/AIA/OWSM Console just worked fine with IE8. If you use 10.1.3.5+, I think this issue is fixed, but for lower version of Oracle ESB you can use following to make it compatible with IE8 browser.

For ESB Console:

- Modify following files:

esb-dt-container\applications\esb-dt\esb_console\esb\widgets\InstancesView.js and
esb-dt-container\applications\esb-dt\esb_console\picasso\widgets\widgets.Perspective.js

- In these files look for a line this.myEvents = [""] and comment this line out with "//"

Wednesday, December 15, 2010

How to check JDBC driver version

Oracle Support Note: 396187.1 provides instructions on how to install a sample web application to test the database driver. It works great, and it is pretty simple process as shown below:

1) download drvtest.ear from the Oracle support
2) Deploy it desired container
3) Goto http://:/drvtest/dbdetails.jsp
enter username/password/url
it provide information like below:

JDBC Driver details
=============
JDBC Driver Name is ........ Oracle JDBC driver
JDBC Driver Version is ..... 10.1.0.5.0
JDBC Driver Major Version is 10
JDBC Driver Minor Version is 1
=============
Database Details
=============
Database Product Name is ... Oracle
Database Product Version is Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options



I found couple of issues with drvtest.ear file which forced me to write another sample app:
1. This application opens connection and doesn't close
2. This application is struts based and causes problem when you deploy oc4j_soa container (at least in 10.1.3.3.x). It works fine on other container
3. Some time you want to use data source instead of direct connection

I decompiled the code and modified for my need, and it was very easy to expose that piece of java code as web service and provide two separate operations:

InitialContext initialContext = new InitialContext();
DataSource dataSource = (DataSource) initialContext.lookup(dataSourceName);
connection = dataSource.getConnection();
DatabaseMetaData meta = connection.getMetaData();



1. You can deploy the CustomDriverTest.ear to any oc4j container
2. Goto http://host:port/CustomDriverTest/DriverCheckService?WSDL or http://host:port/CustomDriverTest/DriverCheckService
it provides both operation - test by direct database connection or test by data source.
3. It certainly closes connection after providing db information

JDBC Driver Upgrade for SOA/AIA 10g

Oracle SOA suite comes with 10.1.0.5 version of JDBC driver, which is pretty old I believe. If you are using newer version of database, it is worth upgrading the JDBC driver of SOA Suite or AIA to the database version you are using.

If you are using 11g database, then 11g version of database driver does cause some problem with AIA console and EBS WF_Event complex payload, but as long as 10g version is concerned it is quite easy migration.

For instance, we were using 10.2.0.5 version of database and wanted to upgrade to 10.2.0.5 JDBC drivers:

1. Download 10.2.0.5 specific JDBC drivers from below
http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html

2. Copy all jar files to $ORACLE_HOME/JDBC10205/lib directory

3. Add following to $ORACLE_HOME/j2ee/CONTAINER_NAME/config/server.xml:

    <shared-library name="oracle.jdbc" version="10.2.0.5">
<code-source path="/aiaapp/oracle/product/10.1.3.1/OracleAS_1/JDBC10205/lib/classes12.jar"/>
<code-source path="/aiaapp/oracle/product/10.1.3.1/OracleAS_1/JDBC10205/lib/classes12_g.jar"/>
<code-source path="/aiaapp/oracle/product/10.1.3.1/OracleAS_1/JDBC10205/lib/classes12dms.jar"/>
<code-source path="/aiaapp/oracle/product/10.1.3.1/OracleAS_1/JDBC10205/lib/classes12dms_g.jar"/>
<code-source path="/aiaapp/oracle/product/10.1.3.1/OracleAS_1/JDBC10205/lib/ojdbc14.jar"/>
<code-source path="/aiaapp/oracle/product/10.1.3.1/OracleAS_1/JDBC10205/lib/ojdbc14_g.jar"/>
<code-source path="/aiaapp/oracle/product/10.1.3.1/OracleAS_1/JDBC10205/lib/ojdbc14dms.jar"/>
<code-source path="/aiaapp/oracle/product/10.1.3.1/OracleAS_1/JDBC10205/lib/ojdbc14dms_g.jar"/>
<code-source path="/aiaapp/oracle/product/10.1.3.1/OracleAS_1/j2ee/home/lib/ojms-provider.jar"/>
<code-source path="/aiaapp/oracle/product/10.1.3.1/OracleAS_1/jdbc/lib/ocrs12.jar"/>
<code-source path="/aiaapp/oracle/product/10.1.3.1/OracleAS_1/opmn/lib/ons.jar"/>
<code-source path="/aiaapp/oracle/product/10.1.3.1/OracleAS_1/rdbms/jlib/aqapi.jar"/>
<import-shared-library name="oracle.dms"/>
<import-shared-library name="oracle.gdk"/>
</shared-library>


4. Change $ORACLE_HOME/j2ee/CONTAINER_NAME/config/system-application.xml file:
(add : min-version="10.2.0.5)
    <import-shared-library name="oracle.jdbc" min-version="10.2.0.5"/>



5. bounce the server

6. check the driver version (http://chintanblog.blogspot.com/2010/12/how-to-check-jdbc-driver-version.html)

Thursday, December 2, 2010

OPMN Ping timeouts

I did this exercise quite a while ago and thought of posting as I encountered this issue again. Basically, opmn manages all containers and does health check. It can restart the container if container doesn't respond in timely fashion. In opmn log file, it shows up as : [libopmnoc4j] Forcefully Terminating Process. During heavy load or temporary network failure, this is not desired behavior so it is better to control and fine tune such parameters.

It is pretty scattered documentation on different parameters, so thought of putting them together. OPMN algorithm documentation can be found at :

By default opmn just comes with stop/start and restart timeout, which are used just during start/stop and restart as name suggest, but the run time algorithm uses different ping parameters:

Different ping option from OPMN
1. OS Process Check: Every 2 seconds OPMN queries the OS with the managed process id to see if it has terminated.
2. Forward Ping: Periodically, 20 seconds by default, OPMN sends a ping message to the managed process and expects a result within 20 seconds.
3. Reverse Ping: Every 20 seconds managed process sends OPMN a ping notification.

Forward ping can be fine tuned with ping attribute in opmn.xml
Reverse ping can be set using "reverseping" parameters in opmn.xml

Wednesday, November 24, 2010

BAM 11g JVM Filter/Sort

I was working with BAM 11g and saw that I was not able to apply filter or sort when creating chart.



No error in log file makes even hard to troubleshoot. Finally, one of the metalink note (1077533.1) helped me out. Downgrading BAM JVM to jdk160_14_XXXX resolved the issue. You can either just change the JDK version of BAM or change it for whole domain by changing $DOMAIN_HOME/bin/setDomainEnv.sh.

Wednesday, September 29, 2010

BPEL Fault Generation - adapter framework

Recently we had to dig into how BPEL was generating Runtime or Binding Fault. E.g. we were calling BRM adaper and based on BRM logs we could see, it was returning and error code. On BPEL console, we saw that error code was prefixed with BRM-. We had no idea what part was doing this conversion and that brought us to the point to analyze BPEL and Adapter code to figure out how it works with EIS system and how EIS fault gets converted to BPEL fault. It should be generic across all the adapter, as BPEL PM would be just calling the adapter and getting generic exception.

It was quite obvious that BRM- would be somewhere in the BRM adapter and that exception would be converted to Fault XML, but we wanted to find exact place where it would happen. Upon analyzing multiple files, we ended up with following findings.

Summary
  • oracle.tip.adapter.brm.BRMInteraction had hard coded BRM- when it was throwing PCResourceException
  • com.collaxa.cube.ws.WSIFInvocationHandler.WSIFInvocationHandler is getting this exception and converting this in to Fault XML message which is seen in the BPELConsole
Details
  • Each adapter entry point would be Interaction, and all adapter will implement that interface
  • com.collaxa.cube.ws.WSIFInvocationHandler.WSIFInvocationHandler.invoke seems to be the master piece which calls all the adapters via WSIF - especially you can see invokeRequestHeaderHandlers and invokeLocalService calls here
  • invokeLocalService converts adapter level exception (PCResourceException) to WSIFException
  • invoke constructs SOAP fault XML message based on WSIFException

Monday, September 27, 2010

AIA deployment error: Please set the ORACLE_HOME environment variable

When you deploy AIA project from Jdeveloper (10.1.3.x release), you usually get an error: Please set the ORACLE_HOME environment variable. Easiest way to solve is to setup dummy Oracle and AIA home on your machine. You don't need to install entire SOA or AIA suite but need to setup the directory structure as below and copy the appropriate directory content from actual AIA installation. It comes to be about 40 to 50 MB.



Once it is setup, you can setup following environment variables:

  1. AIA_HOME D:\Profiles\DummyHomes\DummyAIAHome
  2. ORACLE_HOME D:\Profiles\DummyHomes\DummyOracleHome
  3. BPEL_HOME D:\Profiles\DummyHomes\DummyOracleHome\bpel

Once Jdeveloper is restarted, this error should go away.

Note: it was quite obvious that something else will fail as soon as I hard code my ORACLE_HOME. It didn't take long me to find, my Oracle XE stopped working after my work station restart. I think it is good practice to not set ORACLE_HOME and set only when you need to do critical AIA deployment.

As another work around, you can only try to set AIA_HOME and BPEL_HOME, and based on build.xml file, it might just work fine, that way it doesn't cause problem with existing SOA or ORACLE DB installation on your machine.

How to install & get list of AIA patches

To get list of all the patches installed in Oracle Application Server (10g release), you can run following command to get all patches:

To list patches installed in Oracle Home
set ORACLE_HOME=
cd $ORACLE_HOME/OPatch
opatch lsinventory

For AIA, there is separate OPATCH to install and to get list of patches. Here are the steps:
  • Download latest version of AIA Opatch from metalink (p5912518_111000_GENERIC.zip)
  • Set following homes
export ORACLE_HOME= (e.g. /home/oracle/product/10.1.3.1/OracleAS_1)
export AIA_HOME= (e.g. /home/oracle/aiahome )
export SOA_HOME= (e.g. /home/oracle/product/10.1.3.1/OracleAS_1)
export PATH= (e.g. /home/oracle/5912518/OPatch:$PATH)

Note: Make sure AIA Opatch is in the path and it is the first entry or prior to any other OPATCH entry.

Now you can run following command to get list of AIA patch or install AIA patch

List of AIA patch
  • opatch lsinventory -invPtrLoc $AIA_HOME/oraInst.loc -oh $AIA_HOME -jre $SOA_HOME/jdk/jre

Install AIA patch
  • Go to the directory where patch is unzipped and run:
  • opatch apply -invPtrLoc $AIA_HOME/oraInst.loc -oh $AIA_HOME -jre $SOA_HOME/jdk/jre

Thursday, September 23, 2010

Removing WSSE Headers in OWSM

Recently had chance to work with WSSE headers in OWSM. WSSE information is stored in SOAP Header. When we were getting WSSE security information in SOAP envelope (header), and we were using "Verify Signature" to verify signature. Verify Signature has step to remove the WSSE header so that this signature doesn't get propagated to BPEL, otherwise BPEL will throw exception. E.g.



If you install entire SOASuite in one container (oc4j_soa) and use above option to remove Security headers, it works great. When SOA suite is installed as per Enterprise Deployment Guide where gateway and policy manager are in separate container than oc4j_soa, OWSM doesn't remove the header even with this option.

Quick resolution to this issue is to use XSL and remove the header completely. Earlier we used following XSL to remove entire SOAP header.


We faced the problem with XSL as it removes entire SOAP header. We can use following XSL which can just remove WSSE header from entire SOAP envelope, so if there are custom element in SOAP header, it doesn't get removed.

Thursday, September 16, 2010

Non intrusive set title for BPEL, AIA

If you check my blog http://chintanblog.blogspot.com/2010/03/bpel-set-title.html you can see how to configure set title for BPEL process and why it is almost absolutely necessary for enterprise implementation. It also makes search in BPEL console quite useful http://chintanblog.blogspot.com/2010/03/bpel-title-wildcard-search_01.html.

We did encounter multiple issues which forced us to think non intrusive approach of setting title of BPEL process
  • We had to change title of more than 80 processes and writing logic and changing each process was very cumbersome (it had to go through un-necessary QA cycles)
  • Lot of process were already deployed and had lot of instances, we couldn't go back in time and set the title for them
  • Due to business requirement, if we plan to change the title, we have to go through this cycle again
  • We didn't want to touch OOTB process which comes with PIP, but we needed our custom title for those

Here is what I came up with:



Implementation Steps
  1. EJB 3.0 timer which polls for new instances in BPEL DB
  2. Via JDBC, extract Audit Information and Audit Trail (it would be configurable how much data to extract)
  3. Once payload is available, apply XPath (based on configuration) to extract the title for a particular process
  4. Update the title of the BPEL process

It sounded pretty complicated and resource exhaustive, but when I implemented and ran on the huge amount of data. I could see that we could set title of individual process in just 0.03 seconds, which was quite acceptable. It runs in separate JVM and doesn't talk with BPEL Runtime Engine so it doesn't increase any load on BPEL. It does increase some load on database but it is just select and update, there is no heavy processing going inside the database.

With this approach, we could achieve following
  • Centralized approach to configure and set the titles
  • We could change title of OOTB processes without touching the code
  • We could set the title of old instances (even stale instances)
  • Changing title was just matter of configuration and pure XPath. I also increased the size to title from 50 to 256, so you could put more data in title (e.g. order number, organization id, etc...)

Sunday, September 12, 2010

Oracle AIA SOA - Multi JVM - Vertical Scaling

It is pretty old concept and I tried earlier couple of times but this time I had much more time to do through analysis of Oracle Application Server with multi JVM container and see how it works out with SOA and AIA in general.

Configuration of multi JVM is fairly straight forward. All you need to do is change number of JVM for container from EM or change numprocs from opmn.xml for a particular container. You can get more information from http://mike-lehmann.blogspot.com/2006/09/scaling-oracleas-with-multiple-jvms.html

(Note: Although you can not change number of JVM for the container where EM is running, so if you install basic SOA suite, adding JVM would cause problem with EM.)

So we added 2 JVM to OC4J_SOA container and tried couple of test cases:

1) Test case: Make sure load is distributed evenly
I believe it is due to mod_oc4j config or default option, but load was distributed in exactly round robin fashion as per log file.

2) Functionality testing
Well, I was not involved much into functional stuff, but seems like functional stuff worked like a charm. We didn't see any issue with BPEL or ESB communication.

At this point we were pretty satisfied with results and about to move forward and then we thought of checking couple of configuration and deployment stuff for AIA and things started looking pretty disappointing:

3) AIA Configuration change
Test case: Changing AIA configuration file and using AIA console to reload the configuration. Expected output would be to have new configuration in both JVM.
Result: Only one JVM loads the AIA Configuration. I tried loading multiple times using UI, it still loads only on one JVM. May be http connection had some static stuff with OC4J. Removing caching or trying from different machine might fix this issue but I would still consider it as failure scenario.
Note: Restarting server certainly forces both JVM to load new AIA configuration file.

4) BPEL Configuration change
Test case: Changing BPEL configuration (e.g. audit level or logging level) from BPEL console. Expected output would be to have new configuration in both JVM.
Result: Only one JVM loads the BPEL configuration.
Note: Restarting server certainly forces both JVM to load new BPEL configuration

5) BPEL deployment
Test case: Redeploying BPEL process with same version with minor code change. Expected output would be to have new BPEL code in both JVM.
Result: Only one JVM picks up new BPEL deployed suitcase. Second JVM was still running with old BPEL code.
Note: Restarting server forces both JVM to load latest version of BPEL suitcase.

6) ESB Configuration and Deployment testing.
I was really hoping this test to work smooth due to ESB-DT and ESB-RT concept. So as long as ESB-DT is in separate container with only one JVM and ESB RT (may be in OC4J_SOA) can have multiple JVM and deployment and configuration change would still work fine. Unfortunately I didn't have access to correct environment where ESBDT and ESBRT were database persisted, and ESBDT in separate container.

With ESB-RT and ESB-DT in same container (oc4j_soa) and having them in-memory topics caused the similar effect as BPEL during configuration chagne and deployment.



In future, I might publish results on ESB with DB persisted topics and some interesting stuff I saw on Java based application (webapp and webservices).

Friday, September 10, 2010

CAVS Configuration

I have been using CAVS for quite a while but didn't see lot of documentation on how to configure it so just thought blogging about it. I have also been using iTKO Lisa for a long time which is much richer in functionality than CAVS, and maybe I will write an article about it someday.

Brief Summary

CAVS (Composite Application Validation System) is mainly used for simulating your integration points for composite testing. It can basically mimic the end system and validate your request and send valid response upon successful validation.

Technical details

  • It is a servlet. URL (http://host:port/AIAValidationSystemServlet/syncresponsesimulator). You can configure multiple simulator instances and it get recognized by simid parameter.
  • It is part of AIAApplication ($CONTAINER_HOME/applications/AIAApplication/ValidationSystemServlet.war)
  • Execution logs can be found at ($CONTAINER_HOME/application-deployments/AIAApplication/oc4j_soa_default_group_1/application.log)


How to use:

Scenario:
Let's say we have simple Echo service, which returns upper case data back. We want to validate the request that, it has input and return the static response back.




Configuration steps:

  • Login to AIA console (http://host:port/AIA)
  • Click on Validation System (GO)
  • Click on Create Simulator

  • Enter the request and response as below (Make sure to include namespace for both request and response and don't remove CAVS namespace)
  • Click Next


  • Click on Request and Generate XPath (this will generate xpath for all possible combinations)

  • Make changes to validation as necessary. E.g. I made one nodekey (which is required) and just changed "equal to" to "is valid" operation for input.

  • Click on Save and record simulator id number
  • Now it is ready to tested with SOAP UI and end point would be http://host:port/AIAValidationSystemServlet/syncresponsesimulator?simid=<<>> or http://host:port/AIAValidationSystemServlet/syncresponsesimulator (generic). If you use generic one, it will compare against all simulator to get exact match


AIA Configuration

  • Out of the box always have support for real or CAVS endpoint for any partnerlink. If you are implementing custom code make sure you use dynamic parterlink for AIA so that it has CAVS support (more information at: http://chintanblog.blogspot.com/2010/03/aia-bpel-dynamic-partnerlink-lookup.html)
  • In AIAHome/config/AIAConfigurationProperties.xml file, make following changes:

Tuesday, August 3, 2010

AIA Error Codes

I was working on AIA error handling and found very weird thing about how AIA was handling its error codes and description. Error codes are pretty much sporadic in .bpel or .xsl files, and aia:getErrorMessage is used to get error description for the error code.

AIA gets error messages from following file:
$oracle_home/bpel/system/classes/oracle/apps/aia/core/eh/i18n/EHResourceBundle.class


Error Code

Error Message

AIA_ERR_AIAINF_1001 Input log level for IsLoggingEnabled function is incorrect
AIA_ERR_AIAINF_1002 No corrective action string specified for the given corrective action code
AIA_ERR_AIAINF_1003 No error message has been specified for the input key
AIA_ERR_AIACOMBMPI_0001 Maxitems requested is less than the Threshold/Number of records returned from the billing system
AIA_ERR_AIACOMBMPI_0002 Account/Billing Profile being sent is not synced to the billing system
AIA_ERR_AIACOMCMPI_0001 EBMHeader/Sender/ID is required
AIA_ERR_AIACOMCMPI_0002 EBMHeader/Target/ID is required
AIA_ERR_AIACOMCMPI_0003 Account Sequence Error: Pay-From Accounts and Billing Profiles must appear before dependent/subordinate Accounts and Billing Profiles
AIA_ERR_AIACOMCMPI_0004 Subordinate account cannot have multiple parent accounts
AIA_ERR_AIACOMCMPI_0005 Ambiguous subordinate bill profile update: There are multiple distinct Pay-From-Party Billing Profile references associated with a single Prior Pay-From-Party Billing Profile reference
AIA_ERR_AIACOMCMPI_0006 All existing subordinate bill profiles are not included in the move account request
AIA_ERR_AIAINF_2001 Error message for getErrorMessage XPath verification
AIA_ERR_AIAO2C2_1001 Timeout while waiting for a response from the InterfaceCustomerToFulfillmentEBF service.
AIA_ERR_AIAO2C2_1002 Timeout while waiting for a response from the InterfaceSalesOrderToCustomerEBFV2 service.
AIA_ERR_AIAO2C2_1003 Timeout while waiting for a response from the CreateSalesOrder EBS service operation.
AIA_ERR_AIAO2C2_1004 Timeout while waiting for a response from the UpdateSalesOrder EBS service operation.
AIA_ERR_AIAO2C2_1005 This order has already been synced.
AIA_ERR_AIAO2C2_1006 Account could not be queried. Please make sure the Account exists in the system
AIA_ERR_AIAO2C2_1007 Timeout while waiting for a response from the SyncCustomerPartyList EBS service operation.
AIA_ERR_AIAO2C2_1008 Credit Check failed. Please contact your System Administrator.
AIA_ERR_AIAMDM_1001 Timeout while waiting for a response from the SyncCustomerPartyList EBS service operation.
AIA_ERR_AIAMDM_1002 Timeout while waiting for a response from the FetchCustomerPartyEBF service.
AIA_ERR_AIAMDM_1003 Invalid QueryCode. Valid values are: MATCH_PERSON or MATCH_ORGANIZATION.
AIA_ERR_AIAMDM_1004 Invalid QueryCode. Valid values are: FETCH_PERSON or FETCH_ORGANIZATION.
AIA_ERR_AIAMDM_1005 Cross-Reference ID lookup failed or returned no associated IDs
AIA_ERR_AIARTL2PSFT_1001 Invalid Requesting System; Requesting Systems must be RESA
AIA_ERR_AIARTL2PSFT_1002 Invalid Set Of Books Id; Set Of Books Id must in BUSINESS_UNIT DVM
AIA_ERR_AIARTL2PSFT_1003 Invalid Currency Conversion Type Code; Currency Conversion Type Code is not in CURRENCYEXCHANGE_CONVERSIONTYPECODE DVM
AIA_ERR_AIACOMOMPI_0001 Dates Validation Falied : Either one of the Purchase Date/Cycle Start Date/ Usage Start Date should be set to future
AIA_ERR_AIACOMOMPI_0002 Date Validation Falied : Purchase Date should be set to future
AIA_ERR_AIACOMOMPI_0003 Purchased promotion instance does not exist for a promotion that was previously purchased.\240\240 A data upgrade script was not run.
AIA_ERR_AIACOMOFMPI_0001 Data Insufficient for Trouble Ticket Creation. Order Originating System Code not available
AIA_ERR_AIACOMOFMPI_0002 Data Insufficient for Trouble Ticket Creation. Order ID not available
AIA_ERR_AIAAGILEJDEE1_0001 For additional information go to /agile/ais/fileResult and review the following file:
AIA_ERR_AIAAGILEJDEE1_0002 There are branch plants in the input message that do not have a mapped value in the AGILE_TARGET_SITE_MAPPING DVM
AIA_ERR_AIAAGILEJDEE1_0003 None of the items selected have been integrated
AIA_ERR_AIAAGILEJDEE1_0004 None of the engineering change orders selected have been integrated
AIA_ERR_AIAAGILEJDEE1_0005 Unable to find a Agile Site to branch plant mapping. Ensure all of the sites for the items on the Change are properly mapped or a default is set in AGILE_SITE_TARGET_MAPPING DVM
AIA_ERR_AIAAGILEJDEE1_0006 Invalid Batch Quantity: All Bill of Materials Batch Quantity must be equal to Zero.
AIA_ERR_AIAAGILEJDEE1_0007 Invalid Bill Of Materials Type: All Bill of Materials Type must be equal to 'DEFAULT_BOM_TYPE' AIA Configuration Property value.
AIA_ERR_AIAAGILEJDEE1_0008 Invalid Bill Of Materials Input: Multiple Bill of Materials for the same Parent Item is not allowed when 'MULTISITE_ENABLED' property is set to 'FALSE'.
AIA_ERR_AIAAGILEJDEE1_0009 Invalid Bill Of Materials Input: Bill Of Materials Components with 'Non-Stock' Stocking type is not allowed when 'MULTISITE_ENABLED' property is set to 'TRUE'.
AIA_ERR_AIAAGILEJDEE1_0010 Failed
AIA_ERR_AIAAGILEJDEE1_0011 Release ECO SDK Execution Failed:
AIA_ERR_AIAAGILEJDEE1_0012 Could not find Change Order workflow:
AIA_ERR_AIAAGILEJDEE1_0013 File does not exist:
AIA_ERR_AIAAGILEJDEE1_0014 None of the Items selected have associated Branch Plants
AIA_ERR_AIAAGILEJDEE1_0015 The Change Order Not found -
AIA_ERR_AIAAGILEJDEE1_0016 Invalid Item Revision Level: Make sure 'ITEM_REVISION_LEVEL' Property in AIA Configuration Properties is not Blank
AIA_ERR_AIAEBSI_0001 Failed to fetch the Sales Representative Resource ID. Please make sure the Sales Representative email addresses are identical in both systems


It was quite disappointing to see that all error codes and error messages are defined in a Java class instead of a property file. if someone needs to change error message or add new error code and error message, it is impossible unless you hack the Java code and recompile it.

It does makes sense to create a custom framework to store all your error codes and error messages so that you don’t get bound to the AIA boundaries.

Wednesday, July 7, 2010

Siebel Web Service with SoapUI

I was working with Siebel webservices for Query Customer and found that it was working fine from BPEL but when I try from soapUI, it returns junk characters. Upon intercepting both traffic using tcpmon, we found the issue was in one of the HTTP header. Basically "Accept-Encoding: gzip,deflate" which was sent from SoapUI was causing the problem.

In soapUI, you can disable this particular header via following option. Once the option is enabled, you can invoke Siebel web service doesn't return junk data and returns valid XML data.

Wednesday, June 30, 2010

Java forever

Not related with Oracle SOA. It was just fun to watch this after a long busy day .. Java forever

Wednesday, June 16, 2010

BPEL Version Redirect

I was working with the client and we had situation were multiple BPEL process versions were deployed with one of them being the default version (e.g. 1.0, 2.0*, 3.0). If client is using is version agnostic WSDL and end point URL, (as below), then it is not major concern because BPEL will route it to default version and everything will work like a charm.

http://host:port/orabpel/<domain>/<process>/<process>?wsdl

http://host:port/orabpel/<domain>/<process>

That was not the case we had. One of the client was using version specific URL, and we didn’t have time and control over the client to change their URL right away. Of course, the long term solution would be use version agnostic URL, gateway or UDDI, but here is quick and dirty way if we just want to route old version request to new version using Apache redirect rule.


This basically routes the request from old-version to new-version for WSDL or End-Point request. If we want to make it generalize, to redirect all versions to a specific version (doesn't matter if that is default or not), it would be following. This can come pretty handy if version management goes out of hand..


After making it generalized, I thought of taking this approach to the next level. As all of us know that to utilize ESB->BPEL native binding (which is highly recommended by Oracle, especially in AIA world), we have to configure routing rules to point to specific version of BPEL process. Every time new version of BPEL is deployed it causes routing rule to change. I thought may be I can fool ESB with this redirect even if it is using native binding, but this trick but didn’t work out with native binding.

Monday, May 3, 2010

XSLT Troubleshooting

May be it is just based on my experience, but I feel in general XSLT doesn’t have lot of troubleshooting support. E.g. in Java, no matter what JVM you use, you can pretty much get stack trace (even in NPE errors). In XSLT, based on XML parser you use, sometime you get line numbers and some time you don’t, plus it doesn't provide lot of details in log. Moreover there are not really any good tools to do much troubleshooting. In AIA world, it gets even crazier. Most of the XSLT functions come with AIA just runs only on server side, so you are hopeless and helpless when you want to do some troubleshooting on your local box. It gets even worse, when you get FOTY0001 type errors. Sometime you get more details in log file when there is FOTY0001, and sometime you don't.

Here are couples of ideas which can make your life easier.

1) XSL comment
You can put XSL comment in your code, so it will show up when XSLT is completed. It does help a lot when you are trying to just print values of variables. Pretty much all credit goes to Mahesh Narayanaswamy (absolute XSL genius) for this suggestion.

2) XSL out
This was very cool idea came out of disucssion with Amol Vaidya. XSL comment didn’t help much when XSLT was completely breaking and we were unable to get the line number or the root cause. All we needed is the similar capability like System.out inside the XSL, so we know how far in XSL we went and what are the variables. We just want to get all information before the point of failure. A custom XSLT log function came pretty handy for putting trace log in your XSLT. This way we can get as much information about the XSLT before the point of failure.
We wrote custom XSL function called XSLTLog, and registered that function in BPEL RT and ESB XSL Library.

3) Java code
I also wrote a Java code which can take XML input and execute the XSL. We have to register this Java code to the server as lot of AIA XSL functions relies on server side components. We also took it further to find exact line number in XSL using binary search approach.

Wednesday, April 28, 2010

BPEL ReadOnly Console

It was my first blog which I wrote almost three years ago. http://chintanblog.blogspot.com/2007/12/i-saw-numerous-people-asking-about-bpel_290.html Since then, pretty much all my clients and a lot of other companies used this approach. I also saw many other blogs copied this idea or put enhancement to it. Anyways, one of my client pointed out this metalink article: 852840.1. Metalink had reference to my blog!! Wow, it certainly makes me feel good when multi billion dollar organization put reference to my tiny little site.




On a smaller scale, but it still reminds what Margaret said: "Never doubt that a small group of thoughtful, committed citizens can change the world. Indeed, it is the only thing that ever has"

Thursday, April 8, 2010

TCP Tunnel - Java Port Forwarding - TCP kill

You know, sometime you just get amazed when you find an absolutely simple solution for a overly complicated problem. I was working with one client remotely and banging my head against the wall to get the access to their valuable servers. After a so much frustration I could get access to one or two servers via ssh, and that's pretty much it. I could ping to everywhere from that UNIX box but can not connect anything from my local laptop.

To make long story short, I tried using SSH tunnel, hacked routing tables of UNIX/windows but nothing came as handy as a simple Socket program which basically listens on a port and make socket connection to remote client. It is very much like TcpMon or Obtunnel but it is just bare bone version of it. Pretty much 99% of my laptop traffic was going through this tiny unix box and never had to beg for access.

java -jar springportforward.jar com.springsoa.socket.Forward localport remotehost remoteport &

Now as this become the absolutely life savor, I thought I can I can leverage something more out of it. I think we potentially can use this for tcpkill workaround. Basically try to forward all traffic through portforward, and kill the portforward to achieve same effect as tcpkill.

Wednesday, March 31, 2010

BPEL Set Title

BPEL titles are extremely important for troubleshooting anything from BPELConsole. It is basically providing title-name to BPEL instance. I also wrote blog on how to do wildcard search on those BPEL titles (http://chintanblog.blogspot.com/2010/03/bpel-title-wildcard-search_01.html).

Now the part comes is how to set titles. I am still working on implementing non-intrusive way of setting titles without ever changing BPEL code, but for now let's talk about how it is done Out of the Box:

Recommended Approach is:



I didn't like the idea of Java embed, just as it conflicts with other best practices Oracle has and it creates an additional workItem overhead for BPEL RT. Correct way of doing this would be to write BPEL function to do this. I wrote BPEL function as below:

ora:setProcessTitle()

This function sets the title of BPEL process
The signature of this function is : ora:setProcessTitle ('title', 'auditTrail'?)
auditTrail: true/false, it is optional and default value is true.

With this, you can set the title as native assign operation:


It doesn't reduce the code footprint that much, but still provides neater BPEL code and centralized way of handling Audit.

AIA BPEL Dynamic Partnerlink Lookup

BPEL dynamic partnerlink lookup concept is quite old and been there since 10.1.2 and it works great. AIA took that concept little far and forced the design pattern. E.g. all endpoint URLs should be strictly in AIAConfigurationProperties.xml file.

Example would be:

Step 1: put the endpoint URL in AIAConfigurationProperties.xml file:



Step 2: Change the BPEL code to look up this URL at run time using Java Embed.



Step 3: Follow the same old rule for BPEL dynamic partner-link once we have the right endpoint URL.



So far so good, but the problem is 20 lines of "non reusable" java embed code in my BPEL. If you talk with any decent Oracle SOA guru, they will ask you to avoid Java Embed as much as possible. AIA design pattern didn't stop here, they have recommended not to put EndPoint (or Partner-link) name directly in your Java Embed. Reason seems to quite obvious, you just specify the partner-link name, and based on SystemID or CAVS parameter, we can route it to any place without doing any code change. At the end your Java Embed looks something like this:

AIAConfigurationProperties.xml:


Java Embed:





Functional point of view it looks great, but technically - holy crap! 93 lines of non reusable code copied for every partner-link and every BPEL process.


I took initiative to eliminate the code for and obviously the best option was to use Oracle BPEL XPath Function. Initial functionality didn't take long time to develope BPEL function and register them to BPEL RT engine, but making addAuditTrailEntry working in my custom function was an amazing experience. Rather than going too much into details, would just go with final product. I created two separate bpel functions:

1) ora:getSimpleDynamicURL (simpler version)

This function gets dynamic URL from AIAConfigurationProperties.xml.
The signature of this function is : ora:getSimpleDynamicURL ('serviceName', 'partnerlinkName', 'auditTrail'?)
auditTrail: true/false, it is optional and default value is true.


2) ora:getDynamicURL (richer version)

This function gets dynamic URL from AIAConfigurationProperties.xml.
The signature of this function is : ora:getDynamicURL ('serviceName', 'partnerlinkName', 'ebmMsgBpelVariableName', 'ebmMsgPartName', 'auditTrail'?)
auditTrail: true/false, it is optional and default value is true.


If I look at my BPEL process now, it looks like the way it supposed to. I can get TargetEndpointLocation from AIAConfigurationProperties.xml based on parameters, and hallelujah!



It just reminds me the most basic programming tip which my friend told me: "Don't do copy and paste, just do cut and paste.

Thursday, March 4, 2010

Namespace agnostic XPath/XQuery

Problem Description

I have two different type of XML files, both have multiple namespaces in it. First one contains prefixes along with namespaces, where second one doesn't. The question is how do I find title (Organization->Person->title) using XPath or XQuery?



Solution - 1 (Aware of Namespace)

The standard way (which I don't recommend) of doing this would be to create XPath resolver and register all the namespaces with it. I created external properties file with all the namespace like below (Note: Namespace prefix doesn't have to match between XPath and XML Input Payload (e.g. org to org1). Only namespaces has to match.):


Now, I started writing a method which does Xpath resolution.

For this method, I had to create a class for Namespace resolution. I wrote a class which resolves namespaces based on property file:


That's it, now if you provide /org1:Organization/person1:Person/person1:title as XPath to this program, it can evaluate it as "Engineer"! I was not too impressed with this approach because everytime payload comes up with change/addition in namespace, I have to maintain my property file. In small organization it might workout OK, but in rapidly changing world I can not imagine it would work at all.



Solution - 2 (Namespace Agnostic XPath/XQuery)

For this, I wrote method which doesn't require any Namespace Context. E.g.


Now the trick is in the XPath, I wrote XPath: /*[contains(name(),'Organization')]/*[contains(name(),'Person')]/*[contains(name(),'title')]. This XPath resolves to "Engineer" given XML payload and it doesn't require any namespace. Correct way of writing this XPath would be to [name()='Organization' or ends-with(name(),':Organization')], but unfortunately ends-with is not supported with Oracle XML parser, but I don't see any huge issue with current Xpath.


Test

Finally I just wrote test case to test this out, e.g.


Ran the test, and I could not be more happier after looking at the results:




FYI, just found two more approaches to write name space agnostic XPath:
a) /*[local-name()='Organization']/*[local-name()='Person']/*[local-name()='title']
b) //*[local-name()='title']

Wednesday, March 3, 2010

JAZN Security - Hacked

I guess pretty much everybody in Oracle community knows that Oracle supports indirect password (for data-sources.xml) via file based security system (Jazn). All the container passwords e.g. oc4jadmin, bpeladmin are also stored in Jazn. File name is $ORACLE_HOME/j2ee/<<container_name>>/config/system-jazn-data.xml

There are multiple ways to implement indirect password, and you can go through http://download.oracle.com/docs/cd/B31017_01/web.1013/b28957/deploysimple.htm#BABCCIFH if you really using it first time.
- You can use EM to use indirect password
- You can change data-sources.xml and put ! infront of password.
- You can put "->USERNAME" and create that USERNAME in Jazn with indirect password using EM

Anyways, back to the main problem, passwords are stored in encrypted form in system-jazn-data.xml, so people who has access to the file system would not know clear text password. The encryption algorithm used was way too weak to break. I would avoid putting the solution on my blog just to avoid hacking encouragement.

I would assume the person who wrote encryption algorithm for Jazn was either too lazy or didn't want to implement it correctly, because I believe an average Java programmer can decrypt system-jazn-data.xml in less than 30 minutes.

Tuesday, March 2, 2010

ESB Interceptor

I guess I am pretty late on this blog, I had this working 2 years ago, and implemented it for more than 2 clients over last two years and now probably does not value that much. I still thought to share it and it is a little bit documented in http://download.oracle.com/docs/cd/E12524_01/relnotes.1013/e12523/esb.htm as well.

Basically, implementing IEsbMessageInterceptor interface, which looks something like this (You probably have to tweak it little bit as IEsbMessageInterceptor has been changed from 10.1.3.4 to 10.1.3.5).

public class CustomESBInterceptor implements IEsbMessageInterceptor {
public CustomESBInterceptor() {
System.out.println("Initializing Custome Interceptor");
}

public void invoke(FlowId pFlowId, String pInstanceId, Element pPayload, Element pHeader, String pServiceName, String pSystemName, boolean isOutbound) {
System.out.println("----------------------------------------");
System.out.println("Custom Interceptor ");
System.out.println("FlowId: " + pFlowId + " subflowid: " + pFlowId.getSubFlowId() );
System.out.println("instanceid: " + pInstanceId);
System.out.println("Header: " + XMLHelper.toXML(pHeader));
System.out.println("payload: " + XMLHelper.toXML(pPayload));
System.out.println("Service: " + pServiceName);
System.out.println("System: " + pSystemName);
System.out.println("----------------------------------------");
}
}

Once we compile this class, we can put the class in bpel/system/classes directory and add following to $ORALCE_HOME/integration/esb/config/esb_config.ini file:

inboundMessageInterceptor = CustomESBInterceptor
outboundMessageInterceptor = CustomESBInterceptor

Just to clarify, just like any other interceptor this is extreamly dangerous point. We should keep following things in mind:
  • Call from ESB runtime to this interceptor is made in synchronous fashion, so if CustomESBInterceptor.invoke errors out, then entire ESB RT will have issues.
  • Another issue is if we are doing any heavy processing in CustomESBInterceptor.invoke, that will affect performance of entire ESB RT. The code in invoke should be absolutely error free and as quick as possible. We should use AQ or another JMS implementation to avoid real time processing if needed.
  • You can possibly change the payload and header values if you want to (it should be avoided for best practices)

BPELConsole Timeout Issue



In 10.1.3.5 Oracle SOA Suite we realized that BPELConsole to load the flow page, often timeouts. It gets worse if you are accessing the BPELConsole remotely or from different country. Error seems something like: failed to load resource: xmlGetAuditTrail.jsp?referenceId=bpel%3A//localhost/<<domain-name>>/<<process-name>>%7E1.15/431669&id3j0son2=1

After doing extensive digging in the JSP code a little bit, I found that one of the Java Script which was making server call had 20 second timeout!! After bumping up that to higher number, I was able to resolve that issue. Here is the fix:

$ORACLE_HOME\j2ee\oc4j_soa\applications\orabpel\console\ui\util2\1001.js
(search for rInfo.timeout)
increase timeout from 20 to 200

Monday, March 1, 2010

BPEL Title WildCard Search

I probably would be blogging on setting title for BPEL processes in non-intrusive way, but have to get through couple of hurdles before I get there. It is quite common practice to set Titles for BPEL process so that you can search from BPELConsole.

e.g. setTitle("Title = " + title); //in embedded Java (you can also look at http://blogs.oracle.com/pt/2009/02/searching_bpel_process_instanc_1.html if you are interested on how to use title in intrusive way)

The problem people complain is that BPEL title search doesn't support wild card search. It only supports exact search. While looking through BPELConsole JSP, I found this was quite easy change it from exact search to wild card search. The query was getting generated as part of $ORACLE_HOME/j2ee/oc4j_soa/applications/orabpel/console/ngInstanceList.jsp. To change exact title search to wild card search, here is the change required:

- In $ORACLE_HOME/j2ee/oc4j_soa/applications/orabpel/console/ngInstanceList.jsp, search for keyword called instanceTitle, you should see something like:

String instanceTitleQ = request.getParameter( "instanceTitle" );
if ( instanceTitleQ != null && instanceTitleQ.length( ) != 0 )
{
buf.setLength( 0 );
tmpWhere.setClause( buf.append( n++ > 0 ? " AND " : "" )
.append( SQLDefs.AL_ci_title )
.append( " = ? " )
.toString() );
tmpWhere.setString( 1, instanceTitleQ );
where.append( tmpWhere );
}

You can change it to:

String instanceTitleQ = request.getParameter( "instanceTitle" );
if ( instanceTitleQ != null && instanceTitleQ.length( ) != 0 )
{
buf.setLength( 0 );
tmpWhere.setClause( buf.append( n++ > 0 ? " AND " : "" )
.append( SQLDefs.AL_ci_title )
.append( " LIKE ? " )
.toString() );
tmpWhere.setString( 1, instanceTitleQ );
where.append( tmpWhere );
}


Once it is changed, you can search for Title in BPELConsole using % as wild card character.