Recent Blog Entries

Tuesday, 17 August 2010

DOAG 2010: German User's Group Conference Program Online!

The program of this years DOAG 2010 Conference from Nov 16 to 19,2010 in Nuremberg, Germany is online!
See http://www.doag.org/konferenz/doag/2010/programm (currently German only)
Please don't miss my presentation on day 2 (Nov 17th) about "Oracle BPEL PM - Performance Tuning and Clustering Best Practises".

See you in Nuremberg!

Announcement: Next DOAG Regional Meeting 8.9.2010 covers Enterprise Architecture

The next regional meeting of DOAG in Berlin happens on September 8th in the Oracle Office in Berlin-Tegel. See http://www.doag.org/regio/berlin/i_text for full details.

18:15 - 19:15 Topic 1: Enterprise Architecture
Presenter: Thomas Baumgart, Enterprise Architect / Oracle Germany

19:30 - 20:15 Topic 2: ORACLE Enterprise Content Management
Presenter: Tino Albrecht, Oracle Germany

Monday, 16 August 2010

Web Service Transactions Part 3: Testing Rollback between multiple SOA composites

Overview

The previous sample (Part 2) only contained a call to one web service from a SOA composite. It really gets interesting only when multiple distributed web services join one atomic transaction. To be able to execute this including rollbacks, we will implement 2 web services using SOA composites and the Oracle Database adapter.

Lets assume we have a CRM System (CustomerService) and and Order Fulfillment System (OrderService). The requirement should be that an order is only stored in the Order System if the customer has been stored successfully in the CRM system. Also, if a new order is placed incorrectly, the customer should not be stored in the CRM System.

Please be aware that with a single Weblogic server domain and when not using TcpMon, you will not see any WS-AT transactions because the local optimization kicks in and SOAP will not be used….

Lets design first the CustomerService.  You can find the complete source code here. (Again please click on any image to enlarge)

Create the Database User and Schema

For the 2 services we will need one schema with 2 tables:

create user wstest identified by wstest;

grant connect, resource to wstest;

connect wstest/wstest@XE

create table orders (orderid varchar2(255) primary key, quantity int, description varchar2(20));

create table customers (customerid varchar2(255) primary key, firstname varchar2(20), lastname varchar2(20))

Modify Weblogic Configuration

Create a new data source “jdbc/wstest” in the Weblogic console and enter the connection settings. Be sure to add a target Weblogic server/domain…

image

After that, create a new connection factory in the deployed DBAdapter and point this to the wstest data source:

image

image

Design and test of the CustomerService

First create an new SOA composite named CustomerService with one synchronous BPEL component:

image

Change the CustomerService.xsd to pass customerid, first name and last name as parameters:

<?xml version="1.0" encoding="UTF-8"?>
<schema attributeFormDefault="unqualified"
    elementFormDefault="qualified"
    targetNamespace="
http://xmlns.oracle.com/Test_WS_AT_jws/CustomerService/CustomerService"
    xmlns="http://www.w3.org/2001/XMLSchema">
    <element name="process">
        <complexType>
            <sequence>
                <element name="customerid" type="string"/>
                <element name="firstname" type="string"/>
                <element name="lastname" type="string"/>
            </sequence>
        </complexType>
    </element>
    <element name="processResponse">
        <complexType>
            <sequence>
                <element name="result" type="string"/>
            </sequence>
        </complexType>
    </element>
</schema>

Then create a new Database Adapter on the right hand composite side:

Select the db connection and schema wstest which you have created before and select CUSTOMERS as target. Select Insert or Update as operation. After the DB Adapter wizard, create an Input Variable as inidicated below:

image

Your SOA Composite should now look like:

image

Edit the BPEL Process to insert an Invoke activity to call the newly created Partnerlink:

image

Use a Transform activity before the Invoke to map the input parameters to the variables of the Invoke:

image

You now can deploy and test the CustomerService using the SOA Console Test Page and should see a inserted row in the customers table.

Design and test of the OrderService

Repeat each step of CustomerService to create a similar OrderService. Just select in the DB Adapter Wizard the table ORDERS.

In addition to the CustomerService I have selected the genuid function as input for the orderid variable. So add an additional copy rule in an  Assign activity before the Transform.

This leaves only the Order Item Description as input (for simplicity each time “one “ is assumed for the order amount).

The resulting SOA composite should look like

image

Deploy and the the OrderService using the SOA Console and verify that an Order has been created in the ORDERS table.

Configure TcpMon

Start TcpMon with 8081 as forwarding port and the server:port where you have deployed the CustomerService (i.e. http://localhost:7001) as target.

Testing both webservice in one atomic transaction

Create a new SOA composite CreationService using a synchronous BPEL component which calls both web services – CustomerService and OrderService – sequentially:

Insert 2 web service references in the right side of the SOA composite editor and enter the WSDL URLs of CustomerService and OrderService – but be sure to use the port where TcpMon listens (8081).

image

Edit the XSD of CreationService and modify it to use customerid, firstname, lastname and orderitem as input parameters.

Then edit the BPEL process, insert 2 Invoke activities, calling the Partnerlinks – first for CustomerService, then Orderservice.

Map the variables so that customerid, firstname and lastname are fed into teh input variable for CustomerService and orderitem for OrderService.

image

Last 2 steps are:

Insert bpel.config.transaction=RequiresNew (or Required) in the CreationService BPEL component to start the transaction when the composite is called (see Part 2).

Modify the WS-AT settings to a MANDATORY transaction flow

image

image

Now you can deploy and test the CreationService.

Try first one Order Item (a arbitrary string) with less than 20 characters. This should create a new customer and a new order.

Then try with an Order Item string longer than 20 chars: this results in an SQL exception at the OrderService call and also roll backs the CustomerService as designed:

image

You can verify in TcpMon that the SOAP request used WS-AT.

This concludes the hands-on parts on WS-AtomicTransaction.

Friday, 13 August 2010

Web Service Transactions Part 2: WS-AtomicTransaction with SOA Composite calling EJB-Web Service

In the first part we have looked at web service transactions between JAX-WS web services without any SOA composite/component.

The next scenario where we will look at is a SOA composite calling the web service WsatBankTransferService deployed in part 1. (click on each image to display in full quality):

image

Enable WS-AT on the SOA domain

The installation of the 11.1.1.3 Patch Set of Oracle SOA unfortunately does not update the file policy-accessor-config.xml in the created domain or WLS instance to the required WS-AT settings.

The definition of policy interceptors is however mandatory for WS-AT to work. If you did not configure anything in policy-accessor-config.xml yourself, this means that you will need to replace your version of the file with this version. (The original file can the found here for comparison).

Rename you file to .old and copy the downloaded file to the directory. Restart the Weblogic server.

Design and Deploy the Composite

First start the Weblogic samples server and use a port different than the SOA instance. I use port 8001 for the examples WLS domain and port 7001 for the admin server where the soa domain is deployed.

Then start TcpMon – to be able to monitor the SOAP request lateron and tunnel all request from port 8081 to port 8001:

image

We will create a BPEL based SOA composite with the SOA designer.

Create a new SOA project and a new composite with a BPEL component. Choose a synchronous BPEL process type and name it like you want. 

After that, drop a web service from the resource palette into the right part of the composite editor to create a reference. Fill in the details of the WsatBankTransferService but use the port set with TcpMon. Paste the WSDL URL of the WsatBankTransferService into the form and select MANDATORY and DEFAULT for WS-AT transaction propagation and version

image

Next edit the bpel process to include a Invoke activity for “CreateAccount” using the newly created Partnerlink and pass the input parameter with an Assign activity to the invoke:

image

The result should look like:

image

Now you can deploy and test the composite, right?

No, because at this point, the BPEL component would not automatically start a transaction. To achieve this, edit the composite.xml and insert the bpel.config.transaction property like:

<component name="WSATBPELClient">
  <implementation.bpel src="WSATBPELClient.bpel"/>
  <property name="bpel.config.transaction"
       many="false" type="xs:string">requiresNew</property>
</component>
<reference name="BankAccountService"
           ui:wsdlLocation="http://192.168.56.110:8081/WsatBankTransferService/WsatBankTransferService?WSDL">
  <interface.wsdl interface="http://tempuri.org/#wsdl.interface(WsatBankTransferService)"/>
  <binding.ws port="http://tempuri.org/#wsdl.endpoint(WsatBankTransferService/WSHttpBindingIService)"
              location="http://192.168.56.110:8081/WsatBankTransferService/WsatBankTransferService?WSDL"
              soapVersion="1.1">
    <property name="weblogic.wsee.wsat.transaction.flowOption"
              type="xs:string" many="false">MANDATORY</property>
    <property name="weblogic.wsee.wsat.transaction.version" type="xs:string"
              many="false">DEFAULT</property>
  </binding.ws>
</reference>

At this point it does not matter if you used “RequiresNew” or “Required”, any of the two will start a new transaction because we do not pass any to the inbound “client” partnerlink.

Now you can deploy the composite to the SOA domain.

Testing and Debugging WS-Atomic Transactions

Execute the composite in the EM Test page (http://host:7001/em)

You should see a successfully completed instance and several SOAP or https calls in TcpMon. The latest should be the SOAP request to create the account – with the same WS-Coordination Context as seen in part 1:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
              xmlns:wsa="http://www.w3.org/2005/08/addressing">
  <env:Header>
    <wsa:To>
http://127.0.0.1:8081/WsatBankTransferService/WsatBankTransferService</wsa:To>
    <wsa:Action>
http://tempuri.org/WsatBankTransferService/createAccountRequest</wsa:Action>
    <wsa:MessageID>urn:73432EF0A5E911DFBFAC43B9B866DC33</wsa:MessageID>
    <wsa:RelatesTo>urn:73432EF0A5E911DFBFAC43B9B866DC33</wsa:RelatesTo>
    <wsa:ReplyTo>
      <wsa:Address>
http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
      <wsa:ReferenceParameters>
        <instra:tracking.ecid xmlns:instra="
http://xmlns.oracle.com/sca/tracking/1.0">0000Id_N1rj3n3WjLxZR8A1COuk800001X</instra:tracking.ecid>
        <instra:tracking.conversationId xmlns:instra="
http://xmlns.oracle.com/sca/tracking/1.0">urn:73432EF0A5E911DFBFAC43B9B866DC33</instra:tracking.conversationId>
        <instra:tracking.parentComponentInstanceId xmlns:instra="
http://xmlns.oracle.com/sca/tracking/1.0">reference:50001</instra:tracking.parentComponentInstanceId>
      </wsa:ReferenceParameters>
    </wsa:ReplyTo>
    <ns3:CoordinationContext xmlns:ns3="
http://schemas.xmlsoap.org/ws/2004/10/wscoor"
                             xmlns:ns4="http://schemas.xmlsoap.org/ws/2004/08/addressing"
                             env:mustUnderstand="1">
      <ns3:Identifier>urn:uuid:BEA1-02783739A26FB5C280E1</ns3:Identifier>
      <ns3:Expires>298000</ns3:Expires>
      <ns3:CoordinationType>
http://schemas.xmlsoap.org/ws/2004/10/wsat</ns3:CoordinationType>
      <ns3:RegistrationService>
        <ns4:Address>
http://192.168.56.110:7001/wls-wsat/RegistrationPortTypeRPC</ns4:Address>
        <ns4:ReferenceParameters>
          <wls-wsat:txId xmlns:wls-wsat="
http://weblogic.wsee.wstx.wsat/ws/2008/10/wsat">BEA1-02783739A26FB5C280E1</wls-wsat:txId>
          <wls-wsat:routing xmlns:wls-wsat="
http://weblogic.wsee.wstx.wsat/ws/2008/10/wsat">AdminServer</wls-wsat:routing>
        </ns4:ReferenceParameters>
      </ns3:RegistrationService>
    </ns3:CoordinationContext>
  </env:Header>
  <env:Body>
    <createAccount xmlns="
http://tempuri.org/">wwewe</createAccount>
  </env:Body>
</env:Envelope>

Debugging of all WS-AT related actions on server-side can be switched on with the java command line flag

-Dweblogic.debug.DebugWSAT=true

You will see a lot of 2PC handshake requests like for example:

<WseeWsat> <BEA-224575> <WS-AT transaction id is BEA1-45D0D4EFBBE0B5C280E1 and time to live is 299,000 for transaction Name=…

<WseeWsat> <BEA-224504> <registerOperation entered with …

<WseeWsat> <BEA-224503> <Registering Durable2PC Participant

<WseeWsat> <BEA-224538> <Durable2PC WS-AT Participant created for Address

<WseeWsat> <BEA-224539> <Prepare called for Address

<WseeWsat> <BEA-224603> <Successfully created participant port

<WseeWsat> <BEA-224602> <Durable participant port placed in cache for

<WseeWsat> <BEA-224510> <preparedOperation Xid:

<WseeWsat> <BEA-224511> <preparedOperation exited with Notification

<WseeWsat> <BEA-224546> <Commit called for Address

<WseeWsat> <BEA-224590> <About to send commit for durable participant with Xid

<WseeWsat> <BEA-224518> <committedOperation entered with Notification

<WseeWsat> <BEA-224591> <Commit sent for durable participant with Xid

<WseeWsat> <BEA-224547> <Commit call received reply COMMITTED before wait was entered for Address

<WseeWsat> <BEA-224583> <Durable participant port removed from cache

<WseeWsat> <BEA-224584> <Durable participant XAResource removed from cache

Monitoring and Management

In the SOA Control web administration frontend, you can set or change the WS-AT settings for all endpoints. Right-click on the SOA composite and select “Service/Reference Properties”:

image

In our case, we only see the client-side composite endpoint because we do not have a SOA on the callee side.

Under “Properties” you have access to the Transaction Flow and WS-AT Version settings.

image

For the JAX-WS Webservice published on the Samples Server you can see the settings in the WLS console:

image

Navigate to the webservicesWsatSimpleEar deployment, expand the WsatBankTransferService web service and click on it. You will see the WS-AT setting under “Configuration”, “Ports”:

image

Click on any operation or the whole web service to modify this:

image

You can also verify the WS-AT setting in the WSDL on the web service:

If you look at the WSDL then you see for every binding the attached WS-AT policy:

<operation name="createAccount">
   <wsp:PolicyReference URI="#WSAT10"/>

This scenario was a single operation “CreateAccount”. In the next part we will create a sample using 2 SOA composites being called by another composite in one atomic transactions. Both callees use DBAdapter, so we can play around with rollbacks easily.

Stay tuned!

Troubleshooting

If you receive the following exception when testing the composite, then you did not copy the new policy-accessor-config.xml

Caused by: javax.xml.ws.soap.SOAPFaultException: transaction context is required to be inflowed at oracle.j2ee.ws.client.jaxws.DispatchImpl.throwJAXWSSoapFaultException(DispatchImpl.java:955) at oracle.j2ee.ws.client.jaxws.DispatchImpl.invoke(DispatchImpl.java:750) at oracle.j2ee.ws.client.jaxws.OracleDispatchImpl.synchronousInvocationWithRetry(OracleDispatchImpl.java:234) at ...

Thursday, 12 August 2010

Web Service Transactions Part 1: WS-AtomicTransaction with EJB-based Webservices and WLS 11gR1

To make it clear at first: I am not a fan of web service transactions. They contradict the principle of loose coupling in a SOA. But it is like with XA and 2PC – there are situations where you want to use them or where it is almost mandatory.

In SOA there have been concepts like compensation in BPEL to avoid atomic transactions spanning several SOAP calls (before they were possible and available technically) but some business requirements do not allow to commit at first and undo later on.

Also, Oracle SOA Suite optimizes local calls, so transactions were possible over multiple service invocations if they are on the same application server instance (see optSoapShortcut property in 10g)

To allow web services with SOAP using transactions like in EJB-based distributed applications the following standards have been published by OASIS (http://www.oasis-open.org/specs/):

  • WS-AtomicTransaction v1.2
  • WS-BusinessActivity v1.2
  • WS-Coordination v1.2

    The latest version 1.2 was published in February 2009 and WS-Coordination and WS-AtomicTransaction support started in Weblogic Server 11gR1 (10.3.3) and Oracle Soa Suite 11g PS2 (11.1.1.3). WS-BusinessActivity is for long running business transactions and therefore not covered here.

    With WS-AtomicTransaction (abbreviated WS-AT) it is possible to call another web service (callee) from a web service (caller) within the same transaction. The transaction context is passed to the other web service via soap in a CoordinationContext structure in the SOAP header. Some other components work together as outlined here to let the second web service participate in the transaction.

    Let’s have a look at how you can setup a transaction spanning 2 or more web services.

    The first scenario we will look at is when you have implemented 2 web service based on JAX-WS EJBs in Weblogic and you want to call the one from the other.

    A good startup example for WS-AtomicTransaction is included in the Weblogic Server 11gR1 installation when you select custom install and include the "Server Samples” for installation. Then you can move to %WLS_HOME%\wlserver_10.3\samples\server\examples\src\examples\webservices\jaxws\wsat.

    After setting the examples environment, compiling and deploying with ant you will see the Bank application:

    ws-at-sample

    You can enter for example local account number 100 and remote account number 100 with initial amounts of 100 USD.Then try to transfer 20 USD from local to remote account. This is done in one atomic transaction.

    The application consists of one servlet which makes modifications on the local account and then calls the web service for the remote  located at

    http://host:port/WsatBankTransferService/WsatBankTransferService

    The wsdl is available at

    http://host:port/WsatBankTransferService/WsatBankTransferService?WSDL

    To be able to see the SOAP request to the web service I have put TcpMon  inbetween: change the following lines in WsatBankTransferServlet.java to map the TcpMon port (i.e. 8081):

    public void doPost(HttpServletRequest request,HttpServletResponse response)

               throws ServletException, IOException {

        // define remote Webservice server
        String url = "
    http://localhost:8081";
        URL wsdlURL = new URL(url + "/WsatBankTransferService/WsatBankTransferService");

    The SOAP request looks like follows – the WS-AT specific parts are contained in the CoordinationContext structure:

    <?xml version='1.0' encoding='UTF-8'?>
    <S:Envelope xmlns:S="
    http://schemas.xmlsoap.org/soap/envelope/">
      <S:Header>
        <To xmlns="
    http://www.w3.org/2005/08/addressing">http://localhost:8081/WsatBankTransferService/WsatBankTransferService</To>
        <Action xmlns="
    http://www.w3.org/2005/08/addressing">http://tempuri.org/WsatBankTransferService/createAccountRequest</Action>
        <ReplyTo xmlns="
    http://www.w3.org/2005/08/addressing">
          <Address>
    http://www.w3.org/2005/08/addressing/anonymous</Address>
        </ReplyTo>
        <FaultTo xmlns="
    http://www.w3.org/2005/08/addressing">
          <Address>
    http://www.w3.org/2005/08/addressing/anonymous</Address>
        </FaultTo>
        <MessageID xmlns="
    http://www.w3.org/2005/08/addressing">uuid:a64a702b-0ce6-40fc-9b12-71a494c41520</MessageID>
        <CoordinationContext xmlns:ns3="
    http://schemas.xmlsoap.org/soap/envelope/"
                             xmlns:ns2="http://schemas.xmlsoap.org/ws/2004/08/addressing"
                             xmlns="http://schemas.xmlsoap.org/ws/2004/10/wscoor"
                             ns3:mustUnderstand="1">
          <Identifier>urn:uuid:BEA1-0070D4A7F05CBD76B51F</Identifier>
          <Expires>900000</Expires>
          <CoordinationType>
    http://schemas.xmlsoap.org/ws/2004/10/wsat</CoordinationType>
          <RegistrationService>
            <ns2:Address>
    http://192.168.56.110:7001/wls-wsat/RegistrationPortTypeRPC</ns2:Address>
            <ns2:ReferenceParameters>
              <wls-wsat:txId xmlns:wls-wsat="
    http://weblogic.wsee.wstx.wsat/ws/2008/10/wsat">BEA1-0070D4A7F05CBD76B51F</wls-wsat:txId>
              <wls-wsat:routing xmlns:wls-wsat="
    http://weblogic.wsee.wstx.wsat/ws/2008/10/wsat">examplesServer</wls-wsat:routing>
            </ns2:ReferenceParameters>
          </RegistrationService>
        </CoordinationContext>

      </S:Header>
      <S:Body>
        <ns2:createAccount xmlns:ns2="
    http://tempuri.org/">
          <arg0>222</arg0>
          <arg1>0</arg1>
        </ns2:createAccount>
      </S:Body>
    </S:Envelope>

    More details regarding the implementation:

    The WsatBankTransferService bean contains the following annotations to enable WS-AT:

    @WebService(serviceName = "WsatBankTransferService", targetNamespace = "http://tempuri.org/", portName = "WSHttpBindingIService")
    @Transactional(value=Transactional.TransactionFlowType.MANDATORY,
               version=weblogic.wsee.wstx.wsat.Transactional.Version.WSAT10)

    Each method of the webservice looks up the JTA user transaction (if available):

    ctx = new InitialContext();
    tx = (UserTransaction)ctx.lookup("javax.transaction.UserTransaction");

    The servlet passes the TransactionalFeature to the web service as documented in

    Oracle® Fusion Middleware Programming Advanced Features of JAX-WS Web Services for Oracle WebLogic Server – Chapter 3: Using Web Services Atomic Transactions

    // Passing the TransactionalFeature to the Client
    private WsatBankTransferService getWebService(URL wsdlURL) {
      TransactionalFeature feature = new TransactionalFeature();
      feature.setFlowType(TransactionFlowType.MANDATORY);
            feature.setVersion(Version.WSAT10);
            WsatBankTransferService_Service service =
                    new WsatBankTransferService_Service(wsdlURL,
                        new QName("
    http://tempuri.org/", "WsatBankTransferService"));
      return service.getWSHttpBindingIService(new javax.xml.ws.soap.AddressingFeature(), feature);

    In the next parts we will call the WsatBankTransferService from a SOA Composite and we will span atomic transactions over multiple SOA composites.

  •