dinsdag 22 september 2009

Dynamic endpoints in BPEL

On the Oracle website there is a good document that describes how you can make your BPEL projects to use Dynamic endpoints.

http://www.oracle.com/technology/pub/articles/bpel_cookbook/carey.html

It lacks a few things. One is a link to the WS-Addressing xsd, which you can of course find on http://schemas.xmlsoap.org/ws/2004/08/addressing/addressing.xsd

Also in this example cookbook it is hardcoded, which actually is the way not to do it since that is the whole point of making endpoints dynamic: so that on deployment to another environment your sourcecode does not need to be changed/recompiled. I am using a db adapter now myself with a response time of 69ms. As long as there is a low volume of transactions this should be fine.


Related version: 10.1.3.4.0

maandag 14 september 2009

LOG files

There are multiple locations where you can find log files. See at the bottom of this post how to increase logging.

On the server there is a main directory under which most of the configuration, faultpolicy directory and log files are stored. For a Windows 2003 Server this could be:
c:\product\10.1.3.4\OracleAS\bpel\domains\default\
C:\product\10.1.3.1\OracleAS\bpel\system

Other logs are available here:

Webserver (apache) log:
C:\product\10.1.3.4\OracleAS\Apache\Apache\logs

OC4J log (java container):
C:\product\10.1.3.4\OracleAS\j2ee\oc4j_soa\log\oc4j_soa_default_group_1\oc4j

OPMN log:
C:\product\10.1.3.4\OracleAS\opmn\logs


To increase the logging some options in the BPELConsole can be modified:
Go to the BPELConsole - Configuration - Logging.
Standard almost all logging levels are set to INFO and some are on DEBUG.
DEBUG is the lowest level and produces the most logging information.

PLEASE NOTE Do not put everything on Debug!
If you set all options to DEBUG level you will risk crashing the server because of an extreme amount of logging data.

The most interesting options on which you can(should consider to) increase logging are the following 3:

default.collaxa.cube.activation = incoming queue/fileadapter logging
default.collaxa.cube.ws = outgoing messages when invoking adapters
default.collaxa.cube.xml = pickup messages and convert to xml data

Related version: 10.1.3.4.0

WSDL errors, Cannot figure out operation name. Bad SOAPAction or wsa:Action

If you get error messages like Cannot figure out operation name. Bad SOAPAction or wsa:Action or other strange things after you've changed something related to the WSDL then this might be a solution.
One of the possible error messages:

<env:Fault xmlns="http://xmlns.oracle.com/LeaveBalancePSProvABCSImpl">
  <faultcode xmlns="">null:LeaveBalancePSProvABCSImpl</faultcode>
  <faultstring xmlns="">Cannot figure out operation name. Bad SOAPAction or wsa:Action.</faultstring>
  <faultactor xmlns="">process</faultactor>
</env:Fault>

In our case we had modified the webservice LeaveBalancePSProvABCSImpl, which had 2 operations after a "get" was added next to the "process" operation and then we removed the process operation so we changed it back to only 1 operation (the "get"). The wsdl then is still cached somehow and even cleaning the cache through the BPELConsole does not fully work.

So, go to your DOMAIN directory on the Application Server (standard that is the 'default' domain), for example:
c:\product\10.1.3.4\OracleAS\bpel\domains\default and then under the \tmp\ directory, delete both references to your webservice.
You will need to stop all activities before deleting these temp files is possible (Oracle_AS\opmn\bin\opmnctl\opmnctl stopall)

Related version: 10.1.3.4.0

Available xpath functions

If you want to know the signature of a function, you can take a look at the xpath-functions.xml
This file can be found where your Application Server is installed. This has a list of all available functions and under which namespace each is registered.

For example on an MS Windows 2003 Server it could be C:\product\10.1.3.1\OracleAS\bpel\domains\default\ or under C:\product\10.1.3.4\OracleAS2\bpel\system\config

Change the title of the instances in the BPELConsole

To show a custom title in the BPELConsole it is possible to include in every .bpel process a piece of code.

Example:
<bpelx:exec name="Assign_Title" language="java" version="1.3">
  <![CDATA[java.lang.String titleValue=null;
oracle.xml.parser.v2.XMLElement titleValueElement= (oracle.xml.parser.v2.XMLElement)getVariableData("inputVariable", "payload" , "/client:TesterProcessRequest/client:input");
  titleValue=titleValueElement.getText();
  setTitle("Employee " + titleValue);
  addAuditTrailEntry("Employee " + titleValue);]]>
</bpelx:exec>

This code will result in a title starting with the text Employee followed by (concatenate) the value from the inputVariable, element input. In my case this will be the employee id.

Modifying the setTitle will improve tracebility. By doing a search on the text Employee and the id of the employee you want to find the performed data updates for, will result in a list of all instances with that title. A very useful change that I would advise to include in all BPEL processes as a Best Practice.

Passing XML as parameter to an XSLT transformation, Oracle BPEL

In this document an example is given on how to import an XML parameter into a XSLT tranformation.

Step 1) Define the variable ‘XSLTParams’

Define a variable ‘XSLTParams’, based on the element {http://schemas.oracle.com/service/bpel/common}parameters

This is defined in an external xsd which will have to be imported upon making the variable.

The xsd looks like this:
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="http://schemas.oracle.com/service/bpel/common"
    targetNamespace="http://schemas.oracle.com/service/bpel/common"
    elementFormDefault="qualified">
<xsd:element name="parameters">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="item" minOccurs="1" maxOccurs="unbounded">
      <xsd:complexType>
        <xsd:sequence>
          <xsd:element name="name" type="xsd:string"/>
          <xsd:element name="value" type="xsd:string"/>
        </xsd:sequence>
      </xsd:complexType>
    </xsd:element>
   </xsd:sequence>
  </xsd:complexType>
</xsd:element>
</xsd:schema>


Step 2) Assign the value and name to the XSLTParams:
<assign name="Assign_XSLTParams">
  <copy>
    <from expression="'AssignmentData'"/>
    <to variable="XSLTParams" query="/bpelcommon:parameters/bpelcommon:item/bpelcommon:name"/>
  </copy>
  <copy>
<!-- Replace the variable and namespace ns10 with your variable and namespace -->
    <from expression="ora:getContentAsString(bpws:getVariableData 'Invoke_GetAssignment_OutputVariable','payload','/ns10:EBO_GET_ASSIGNMENT_CIResponse'))"/>
    <to variable="XSLTParams" query="/bpelcommon:parameters/bpelcommon:item/bpelcommon:value"/>
  </copy>
</assign>


Step 3) Call the transformation WITH the property (parameter) XSLTParams:
<assign name="XForm_CombineInputForCheckAddressAndDistance">
  <bpelx:annotation>
    <bpelx:pattern>transformation</bpelx:pattern>
  </bpelx:annotation>
  <copy>
<!-- Replace the variable inputVariable and transformation xslt filename with your variable and file name -->
    <from expression="ora:processXSLT('XForm_CombineInputForCheckAddressAndDistance.xsl',bpws:getVariableData('inputVariable','payload'),bpws:getVariableData('XSLTParams'))"/>
    <to variable="Invoke_CheckAddressAndDistance_initiate_InputVariable" part="payload"/>
  </copy>
</assign>


Step 4) Add the parameter in the transformation:

Put the following code in your transformation, below the namespaces, above the first line of code:
<!-- import the parameter in the xslt transformation -->
<xsl:param name="AssignmentData"></xsl:param> 

<!-- replace ampersands to fix possible later issues in data exchange -->
<xsl:variable name="AmpersandReplacement">&amp;</xsl:variable>
<xsl:variable name="AssignmentData_fixed" select="str:replaceAll(string($AssignmentData),'\u0026(amp;)*+',$AmpersandReplacement)"/>
<xsl:variable name="AssignmentDataEBM"  select="orcl:parseEscapedXML($AssignmentData_fixed)"/>


Step 5) Use XML values from within the fixed parameter:
<eboupreq:ADDRESS>
  <xsl:value-of select="$AssignmentDataEBM/ns0:ADDRESS"/>
</eboupreq:ADDRESS>

Replace the namespaces, variable names, etc, where appropriate.