Developing a distributed WS-AT transaction using an IBM BPM Advanced Integration Service, Part 2: Configuring the transaction support

Leveraging the capabilities of the Advanced Integration Services (AIS) in IBM Business Process Manager V8.0.1 Advanced, this series describes the implementation of a distributed WS-AT scenario involving two databases (Microsoft® SQL Server and IBM® DB2®) installed on two different machines and accessed via two web services. The implementation illustrates the automatic rollback capabilities offered by the SCA-based management in an AIS in collaboration with the WS-AT protocol. In Part 2, you'll configure the transactional support and implement the two transactional web services for the Credit and Charge operations in the example scenario, one in .NET® and the other in JEE.

Carlo Randone (carlo_randone@it.ibm.com), Certified IT Architect , IBM

Carlo Randone photoCarlo Randone is a Certified IBM IT Architect and Open Group Master Certified IT Architect in IBM Global Business Services, Italy. Carlo has a deep knowledge of different development platforms and middleware on heterogeneous environments and operating systems. He worked for several years as a Certified Trainer and Solution Developer for a Microsoft® Certified Partner.

Since joining IBM in 2000, Carlo's main job interests are related to SOA and BPM, and their related software engineering methodologies and enabling platforms, and Enterprise Architecture planning and design. He enjoys collecting documentation and hardware pieces related to the historical development of IT, and to support this hobby he is a member of the Charles Babbage Institute.



Marco Antonioni (marco_antonioni@it.ibm.com), Certified IT Architect, IBM

Marco Antonioni photoMarco Antonioni is a Certified IT Architect and Open Group Master Certified IT Architect in IBM Software Group, Italy. Marco has a deep knowledge of WebSphere platforms (WebSphere Application Server, WebSphere Process Server, IBM Business Process Manager, IBM Operational Decision Manager, IBM Business Monitor, WebSphere Service Registry and Repository, and WebSphere Message Broker). Since joining IBM in 2000, his main role has been as a BPM Solution Architect in IBM Software Services for WebSphere.



18 September 2013

Also available in Chinese

Introduction

Part 2 of this series guides you through the steps to configure the transactional support and to implement the two transactional web services for the Credit and Charge operations in the example scenario: a .NET web service to charge Bank1 on SQL Server on machine A and a JEE web service to credit Bank2 on DB2 on machine B.

We'll cover the following steps:

  1. Configure the security certificates. We'll create a certificate on the Windows .NET machine A and import it to the WebSphere machine B, then create a certificate on the WebSphere machine B and import it to the Windows .NET machine B.
  2. Configure MSDTC and WS-AT on the WebSphere machine A.
  3. Configure the transactional support in WebSphere on the Windows machine B.

Configure the security certificates

As described for example in the IBM developerWorks articles Building transactional Web services with WebSphere Application Server and Microsoft .NET using WS-AtomicTransaction and Microsoft .NET WCF interoperability with a WebSphere ESB service gateway using WS-Atomic transactions (and also on MSDN in Configuring WS-Atomic Transaction Support for the .NET-based part of the solution), the WS-AT protocol service requires the administrator to explicitly authorize individual accounts to participate in distributed transactions. We'll configure both machines A and B in our example scenario to establish a mutual trust relationship by exchanging the right set of certificates, installing them into the appropriate certificate stores, and using the appropriate tools to add each machine's certificate to the other's list of authorized participant certificates. This step is necessary to perform distributed transactions between two machines using WS-AT. WebSphere Application Server supports either secure or non-secure exchange of transaction protocol messages (for example, Register, Prepare, Commit, Rollback). The scenario presented in this article requires the protocol messages to be secured using SSL mutual authentication. This means that you need to configure SSL security and set up certificates before WS-AT can operate across the two platforms.

In a production environment, a certificate from a recognized certificate authority would be used for each participant. However, for the sake of simplicity in this example, we'll produce a self-signed certificate for both Windows .NET and WebSphere.

In this section, we'll put in place a mutual trust between machines A and B. This is a complete configuration, useful for a test environment in which we want to enable the ability of a complete bi-directional transactional context propagation from A to B and vice versa. In the scenario described here, the transactional coordinator is the WebSphere transaction service on the server B, and one of the participants is the Microsoft Distributed Transaction Coordinator (MSDTC) on machine A.

Create a certificate on Windows .NET machine "A" and import to the WebSphere machine "B"

  1. Create a certificate authority for the Windows 7 machine (the .NET machine A) using the command line tool makecert (part of the Windows Software Development Kit), as follows:
    makecert –sk testRootCA –sky signature –sr localmachine –n "CN=RootTrustedCA" 
    –ss TRUST –r RootTrustedCA.cer
  2. Create a certificate based on the certificate authority that can perform key exchange, as follows:
    makecert –sk testServer –ss MY –sky exchange –sr localmachine –n "CN=myW7host" 
    –ic RootTrustedCA.cer –is TRUST myW7host.cer

    When you're finished, you'll have a myW7host.cer certificate, which you can later import to the WebSphere machine B.

  3. First, however, you need to import this certificate into the Windows certificate store of machine A, using the Microsoft Management Console (MMC) snap-in designed to manage the digital certificates. You can skip the first five steps if you have already configured a Certificates management console snap-in:
    1. Select Windows Start.
    2. In the Start search box, type mmc, then select mmc.exe and click Enter.
    3. Select File => Add/Remove Snap-in.
    4. Select Certificates and click Add.
    5. Select Computer Account, then select Next and ensure that Local computer is selected, then click Finish and OK. Figure 1 shows the console with the Certificates snap-in.
      Figure 1. The Management Console with the Certificates snap-in
      The Management Console with the Certificates snap-in

      Click to see larger image

      Figure 1. The Management Console with the Certificates snap-in

      The Management Console with the Certificates snap-in
    6. Right-click Trusted Root Certification Authorities and select All Tasks => Import.
    7. Step through the wizard, selecting the certificate authority file name, such as RootTrustedCA.cer.
    8. Right-click Personal and select All Tasks => Import.
    9. Complete the wizard, selecting the key exchange certificate file name, such as myW7host.cer.
  4. You can now import the Windows machine A certificate into the WebSphere trust store on machine B:
    1. Copy or share the Windows certificate (such as myW7host.cer) to machine B.
    2. Start the WebSphere administrative console (WebSphere Integrated Solutions Console) on the BPM machine B.
    3. Select Security => SSL certificate and key management.
    4. On the right, click Key stores and certificates.
    5. Select NodeDefaultTrustStore.
    6. On the right, click Signer certificates.
    7. Click Add.
    8. Specify a certificate alias such as myW7host and in the File name field, type the full path to the certificate file. Click OK and then Save.

Define a certificate on the WebSphere machine and import it to the Windows .NET machine

Create a self-signed certificate on the WebSphere machine B, using the administrative console as follows:

  1. Select Security => SSL certificate and key management => Key stores and certificates => NodeDefaultKeyStore => Personal certificates => Create a self-signed certificate.
  2. Specify the following, then click OK:
    • Alias = <your_hostname> (for example IBMBPM)
    • Common Name = <your_hostname> (for example IBMBPM)
    • Organization = <your_organization_name>
  3. Click Save Changes to Master Configuration.
  4. To make the newly created certificate the default, select Security => SSL certificate and key management => SSL configurations => NodeDefaultSSLSettings, then select the newly created certificates (for example IBMBPM) for Default server certificate alias and Default client certificate alias, and click OK.
  5. To import the signer certificate into the trust store, select Security => SSL certificate and key management => Key stores and certificates, then select both NodeDefaultKeyStore and NodeDefaultTrustStore and click Exchange signers>.
  6. Select the newly created certificate and add it to the NodeDefaultTrustStore by clicking Add then OK.
  7. Import the WebSphere machine B certificate to the Windows machine A as follows:
    1. Copy or share the WebSphere Application Server key store and trust stores (key.p12 and trust.p12, usually found in %WAS_HOME%\profiles\<your-server>\config\cells\<your-cell>\nodes\<your-node>) to the Windows machine A
    2. To import the WebSphere key store key.p12 into the Windows machine A personal certificates store using MMC, expand Certificates, Personal, then select Action => All Tasks => Import => Next => Browse, and select the key.p12 file from the folder selected in the previous step.
    3. Specify the following:
      • Filename = <the key.p12 file>
      • Password = WebAS (default password for the key store)
      • Place the certificate in the Personal Certificate Authority by selecting Personal as the certificate store.
    4. To import both the WebSphere Application Server key store (key.p12) and trust store (trust.p12) into the Windows Trusted Root Certification Authorities store in MMC, expand Certificates, Trusted Root Certificate Authority, then select Action => All Tasks => Import => Next => Browse, and select the key.p12 file from the folder selected in step a. Specify the following:
      • Filename = <the key.p12 file>
      • Password = WebAS
      • Place the certificate in the Trusted Root Certificate Authority by selecting Trusted Root Certificate Authority as the certificate store.
    5. Still under Certificates, Trusted Root Certificate Authority, then select Action => All Tasks => Import => Next => Browse, and select the trust.p12 file from the folder selected in step a. Specify the following:
      • Filename = <the trust.p12 file>
      • Password = WebAS
      • Place the certificate in the Trusted Root Certificate Authority by selecting Trusted Root Certificate Authority as the certificate store.

Configure MSDTC and WS-AT on the Windows machine

The Microsoft Distributed Transaction Coordinator (MSDTC) must be configured to support the XA-transaction protocol in order to communicate with the WebSphere Application Server, and must also be enabled for the WS-AT protocol. The initial configuration of the MSDTC for XA was described in Enable the MS DTC service for XA transactions in Part 1.

Configuring the MSDTC to support the WS-AT protocol requires the presence of a specific WS-AT tab in the DTC configuration tool, as shown in Figure 2.

Figure 2. Configure WS-AT in MSDTC
Configure WS-AT in MSDTC

If the WS-AT tab is not present in the DTC configuration tool on the Windows system, run the command: regasm.exe /codebase WsatUI.dll. The regasm.exe command is located in C:\Windows\winsxs. WsatUI.dll is part of the Windows Software Development Kit. The installation procedure of WsatUI is described in detail in WS-AtomicTransaction Configuration MMC Snap-in.

To configure the WS-AT support, as illustrated in , do the following:

  1. Check Enable WS-Atomic Transaction network support, and leave the default of 443 for the HTTPS port.
  2. In the Endpoint certificates field, select the newly imported certificate (with your hostname as alias, from the WebSphere machine B), and click OK.
  3. In the Authorized certificates fields, click Select and check the WebSphere certificate and the Windows certificate (myW7host in this demo) and click OK.
  4. Click OK and restart MSDTC as prompted.

Configure the transactional support on the WebSphere machine

Configure the WebSphere transaction service on the WebSphere machine B, by completing the following steps (refer to Figure 3):

  1. In the WebSphere administrative console, select Servers => Server Types => WebSphere application servers => server1 (or the name of your server) => Container Services => Transaction Service. Click the Configuration tab.
  2. Uncheck Enable transaction coordination authorization. This option must be disabled for interoperability. Protocol messages will still be secured using SSL transport-level security, but role-based authorization of received protocol messages is disabled. Role-based authorization of transaction protocol messages is supported only for WebSphere-to-WebSphere interactions. When transaction coordination authorization is enabled, the transaction service verifies the caller is permitted to the administrator role before handling the transaction.
  3. For Default WS-Transaction specification level, select 1.1 (our sample scenario is based on a WS-AT implementation leveraging V1.1 of the WS-AT specification).
  4. Save your changes and stop and restart the BPM WebSphere Application Server. For a standalone scenario, you can restart the server, for a network deployment, you need to restart the whole cell.
Figure 3. Configure the transaction service settings on WebSphere Application Server
Configure the transaction service settings on WebSphere Application Server

Configure the transactional web services

The scenario presented in this series uses a couple of transactional web services to charge an account on the SQL Server database Bank1 and to credit another account on the DB2 database Bank2. The Charge web service is implemented in .NET and IIS (Internet Information Services) on machine A, and the Credit web service is implemented in JAX-WS and WebSphere Application Server on machine B (note that in our scenario, this web service is deployed on the same WebSphere Application Server and on the same machine as the BPM engine, but it could be deployed also on a different WebSphere machine accessible on the network).

Configure the .NET web service to charge Bank1

The first of the two web services involved in this transactional scenario is developed in C# (C-Sharp), one of the .NET languages, using the Microsoft Visual Studio 2010 development environment. The .NET library adopted to implement this web service is the Windows Communication Foundation (WCF), part of the .NET Framework 4. WCF is a runtime and a set of APIs in the .NET framework for building connected, service-oriented applications. There are two main options to implement a web service provider (or consumer) on the Microsoft .NET platform: the legacy ASP.NET approach and the more recent WCF-based approach. In our scenario, considering the requirement to support WS-AT V1.1 and to provide an up-to-date vision and solution design, we've chosen to leverage the new WCF-based approach.

The web service is designed to implement a Charge operation on the SQL Server database. The web service is implemented (WSChargeBank1Soln.zip provided for download in Part 1) in a Visual Studio 2010 solution named WSChargeBank1Soln, in a C# project named WSChargeBank1.

Listing 1 shows the C# implementation of the web service.

Listing 1. The Charge web service (in C#, using .NET WCF)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Data.SqlClient;
using System.Web;
using System.Web.Services;


namespace WSChargeBank1
{
 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
 [ServiceBehavior(TransactionIsolationLevel = System.Transactions.IsolationLevel.Serializable,
     ConcurrencyMode = ConcurrencyMode.Single,
     InstanceContextMode = InstanceContextMode.PerSession,
     ReleaseServiceInstanceOnTransactionComplete = true)]
 public class WSChargeBank1Svc : IWSChargeBank1Svc
 {
     [WebMethod(false, System.EnterpriseServices.TransactionOption.Required)]
     // Use:
     // [TransactionFlow(TransactionFlowOption.Allowed)] to enable discovery and run in a non 
     // transational client
     // [TransactionFlow(TransactionFlowOption.Mandatory)] to allow ONLY transactional clients
     [TransactionFlow(TransactionFlowOption.Mandatory)]
     [OperationBehavior(TransactionAutoComplete = true, TransactionScopeRequired = true)]
     public string Charge(string myConnection, string myTable, string myAccount, int myAmount)
     {
         string strSQL;
         string result = "Result OK from Charge operation";
         int HowManyRows;
         SqlConnection sqlConn=null;
         SqlCommand sqlComm;

         strSQL = "UPDATE " + myTable + " SET Amount = Amount - ";
         strSQL += myAmount.ToString();
         strSQL += " WHERE Description = '" + myAccount + "'";

         try
         {
             sqlConn = new SqlConnection(myConnection);
             sqlComm = new SqlCommand(strSQL, sqlConn);
             sqlConn.Open();
             HowManyRows = sqlComm.ExecuteNonQuery();
             if (HowManyRows != 1)
             {
                 // Invalid account
                 throw new Exception("Exception from Charge (-): Invalid account.");
             }
             sqlComm.Dispose();
             sqlConn.Close();
             return (result);
         }
         catch (Exception ex)
         {
             if (sqlConn != null)
             {
                 if (sqlConn.State == System.Data.ConnectionState.Open)
                 {
                     sqlConn.Close();
                 }
             }
             result = "Exception from Charge (-): myConnection: " + myConnection +"; strSQL: " 
                + strSQL + "; ex.Message: " + ex.Message;
             throw new FaultException(result);
         }
     }

 }
}

The transactional options of the web service are declared and supported in the code and in the configuration file. In the listing above, the attribute [TransactionFlow(TransactionFlowOption.Mandatory)] is used to specify the transaction flow policy for a service operation. With a setting of Mandatory, the transaction must be flowed.

Note that the following statements:

HowManyRows = sqlComm.ExecuteNonQuery();
if (HowManyRows != 1)
{
   // Invalid account
   throw new Exception("Exception from Charge (-): Invalid account.");
}

are used to check whether the execute command does not return any row; for example, when the statement is not executed on any record (typically for the unavailability of the account passed in the myAccount parameter to the Charge operation). In this case, an explicit exception Exception is thrown, with the string Invalid account. Later, this kind of exception, or any other exception (for example an insufficient amount on the account, triggered by the SQL Server database engine) is returned by the FaultException. In a service, you can use the generic FaultException class to create an untyped fault to return to the client. Another option is to design your services to return strongly-typed SOAP faults, using a FaultContractAttribute to declare one or more specific exception conditions that are added to the WSDL description of the service operation as explicit SOAP fault messages returned by the operation.

This web service does not expose any specific SOAP fault, and in the consumer of the service (in this scenario, an SCA mediation module in the BPM AIS) there will be an unmodeled fault management.

The Web.config web service configuration file, shown in Listing 2, contains additional key configurations.

Listing 2. The Charge web service configuration file
<?xml version="1.0"?>
<configuration>
    
  <system.web>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <!-- <add assembly="System.Transactions, Version=4.0.0.0, Culture=neutral, 
PublicKeyToken=B77A5C561934E089"/> -->
      </assemblies>
    </compilation>
    
    <webServices>
      <protocols>
        <add name="AnyHttpSoap"/>
      </protocols>
    </webServices>
    
  </system.web>
  <system.serviceModel>
        
    <!-- Extension for single WSDL with inline schemas, from http://wcfextras.codeplex.com/ -->
    <extensions>
      <behaviorExtensions>
        <add name="wsdlExtensions" type="WCFExtrasPlus.Wsdl.WsdlExtensionsConfig, WCFExtrasPlus" />
      </behaviorExtensions>
    </extensions>
    <!-- -->
    
    <services>
      <service name="WSChargeBank1.WSChargeBank1Svc">
        <endpoint address="" binding="customBinding" 
		bindingConfiguration="customBinding_IWSChargeBank1Svc"
          contract="WSChargeBank1.IWSChargeBank1Svc" 
		behaviorConfiguration="singleFileEndpointBehavior">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>

    
    <bindings>
    
      <customBinding>
        <binding name="customBinding_IWSChargeBank1Svc">
          <textMessageEncoding messageVersion="Soap11" />
          <!-- -->
          <!-- WS-AT 1.0 -->
          <!--
          <transactionFlow transactionProtocol="WSAtomicTransactionOctober2004" />         
          -->
          <!-- WS-AT 1.1 -->
          <transactionFlow transactionProtocol="WSAtomicTransaction11" />
          <!-- -->
          <!-- -->
          <httpTransport />
        </binding>
      </customBinding>

    </bindings>
    
    <behaviors>

      <endpointBehaviors>
        <behavior name="singleFileEndpointBehavior">
          <wsdlExtensions singleFile="True" />
        </behavior>
      </endpointBehaviors>
      
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and 
                  remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value 
                  below to true.  
                  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>
</configuration>

The section:

<extensions>
 <behaviorExtensions>
  <add name="wsdlExtensions" type="WCFExtrasPlus.Wsdl.WsdlExtensionsConfig, 
	WCFExtrasPlus" />
 </behaviorExtensions>
</extensions>

together with the declaration:

<endpointBehaviors>
 <behavior name="singleFileEndpointBehavior">
  <wsdlExtensions singleFile="True" />
 </behavior>
</endpointBehaviors>

enables the use of a free library (named WCFExtras and available at http://wcfextras.codeplex.com/), which is used here to enhance the portability of the WSDL code generated by this web service implementation. In particular, one of the features available in WCFExtras is the ability to simply merge the external types into the WSDL file and produce a single flat WSDL file that contains all the necessary definitions. This configuration is obviously not mandatory, but it's an interesting feature that in .NET/WCF 4.5 is now part of the platform and does not require the adoption of an external library like the WCFExtras (refer to What's New in Windows Communication Foundation 4.5). WCF 4.5 allows you to specify that all WSDL information must be returned in a single document. To request a single WSDL document, append ?singleWSDL to the URI when requesting metadata from the service.

The configuration section:

<customBinding>
        <binding name="customBinding_IWSChargeBank1Svc">
          <textMessageEncoding messageVersion="Soap11" />
          <!-- -->
          <!-- WS-AT 1.0 -->
          <!--
          <transactionFlow transactionProtocol="WSAtomicTransactionOctober2004" />         
          -->
          <!-- WS-AT 1.1 -->
          <transactionFlow transactionProtocol="WSAtomicTransaction11" />
          <!-- -->
          <!-- -->
          <httpTransport />
        </binding>
      </customBinding>

defines a custom binding with SOAP 1.1 and the new WS-AT V1.1 (WSAtomicTransaction11). The commented XML code is related to the old specification 1.0. Our scenario is based on SOAP 1.1 and WS-AT 1.1, and the WebSphere configuration on machine B will be set to WS-AT 1.1. (Note that, in practice, version 1.2 of the WS-AT standard is functionally equivalent to V1.1, but these versions have a significant set of differences compared to 1.0).

The Visual Studio project for this web service is also deployed to the local IIS on the Windows machine A. If, for example, the path of the .NET web service project is C:\Projects\WSChargeBank1Soln\WSChargeBank1, you need to create a new application WSChargeBank1, as shown in Figure 4.

Figure 4. The web service application WSChargeBank1 in IIS
The web service application WSChargeBank1 in IIS

Figure 5 shows the advanced settings for this kind of web application, configured to host the .NET web service.

Figure 5. Configure the web service application on IIS
Configure the web service application on IIS

The exposed web service endpoint is at http://<<machineA>>/WSChargeBank1/WSChargeBank1Svc.svc (considering that <<machine A>> is a placeholder for the real name of the Windows/.NET/SQL Server machine). And the WSDL is exposed at http://<<machineA>>/WSChargeBank1/WSChargeBank1Svc.svc?wsdl.

Configure the JEE web service to credit Bank2 on machine B

The second of the two web services involved in our transactional scenario is developed in Java® with the IBM Integration Designer, which is part of IBM BPM. The web service is implemented using the JAX-WS support offered by Integration Designer and the WebSphere runtime platform. The Java API for XML web services (JAX-WS, JSR-224) is a Java programming language API for creating web services, and is part of the Java EE platform.

JAX-WS is a programming model that simplifies application development through support of a standard, annotation-based model to develop web service applications and clients. JAX-WS defines a model that uses Java annotations to develop web service providers and web service clients. In addition, compared to JAX-RPC, JAX-WS web service clients and web service providers are more portable because no vendor-specific artifacts are necessary. The JAX-WS technology strategically aligns itself with the current industry trend towards a more document-centric messaging model and replaces the remote procedure call programming model as defined by JAX-RPC. The IBM Redbook IBM WebSphere Application Server V7.0 Web Services Guide provides an in-depth description of the methods for developing JAX-WS web services on WebSphere Application Server.

The web service is designed to implement a Credit operation on the DB2 database, and is implemented in a IBM Integration Designer project named WSCreditBank2Project (in WSCreditBank2Project.zip, available for download in Part 1.

Listing 3 shows the Java implementation of the web service.

Listing 3. The Credit web service (in Java using JAX-WS)
package org.tempuri;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;


@javax.jws.WebService (endpointInterface="org.tempuri.IWSCreditBank2Svc", 
targetNamespace="http://tempuri.org/", serviceName="WSCreditBank2Svc", 
portName="CustomBinding_IWSCreditBank2Svc")
public class CustomBinding_IWSCreditBank2SvcImpl{

    public String credit(String myConnection, String myTable, String myAccount, 
        Integer myAmount) throws Exception  
    {
    	String result = "Result OK from Credit operation";
        int HowManyRows;
    
        /**/
        // Credit (+) (on Bank2 DB) operation
        
        Context ctx = null;
        DataSource ds = null;
        Connection  con = null;		
        String strSQL;

        strSQL = "UPDATE " + myTable + " SET Amount = Amount + ";
        strSQL = strSQL + String.valueOf(myAmount);
        strSQL = strSQL + " WHERE Description = '" + myAccount + "'";

      try
      {
          ctx = new InitialContext();
          ds = (DataSource) ctx.lookup(myConnection);
          con = ds.getConnection();
          
          Statement stmt = con.createStatement();
          
          HowManyRows = stmt.executeUpdate(strSQL);
          if (HowManyRows!=1)
          {
                 // Invalid Account
                 throw new Exception("Exception from Credit (+): Invalid account.");
          }
          
      }
      catch(Exception ex)
      {   
             result = "Exception from Credit (+): myConnection: " + myConnection +
             "; strSQL: " + strSQL + "; ex.getMessage(): " + ex.getMessage();
             //ex.printStackTrace();
             throw new Exception(result, ex);
      }
      finally
      {
          if (ctx!=null)
          {
             try {ctx.close();}
             catch(javax.naming.NamingException ex2){}
          }
          try
          {
             if(con!=null && !con.isClosed())
             {
                 con.close();     
             }
          }
          catch (SQLException e)
          {
             // ignore
            
          }
      }         
      /**/
            return(result);
     }

}

The Update operation on the Accounts table is implemented following the traditional JEE execution path to obtain a DataSource by a lookup on the Context, and a Connection by a getConnection on the DataSource, and finally using the createStatement (on the Connection object) and ExecuteUpdate (on the Statement object) methods.

Note that the followings statements:

HowManyRows = stmt.executeUpdate(strSQL);
if (HowManyRows!=1)
{
   // Invalid Account
   throw new Exception("Exception from Credit (+): Invalid account.");
}

are used to check whether the execute command does not return any row; for example, when the statement is not executed on any record (typically for the unavailability of the account passed in the myAccount parameter to the Credit operation). In this case, an exception is thrown, with the string Invalid account. This exception, together with any others, is caught by the catch(Exception ex) catch handler, which re-throws the exceptions to the caller (in this case, the ESB mediation).

This web service exposes a specific SOAP fault (as you can verify by looking at the WSDL), and in the consumer of the service (in our scenario an SCA mediation module in the BPM AIS) there will be a modeled fault management.

The exposed web service endpoint is at http://<<machineB>>:9080/WSCreditBank2Project/WSCreditBank2Sv (considering that <<machine B>> here is a placeholder for the real name of the WebSphere DB2 machine), and the WSDL is at http://<<machineB>>:9080/WSCreditBank2Project/WSCreditBank2Svc?wsdl.


Conclusion

Part 2 of this series covered the configuration of the transactional support and the implementation of the two transactional web services (for the Credit and Charge operations), based on JEE and .NET technologies. In Part 3, you'll learn how to define and implement the BPMN business process using the IBM Process Designer in IBM Business Process Manager Advanced.


Acknowledgements

The authors would like to thank their colleagues Giuseppe Bottura and Simone Chiucchi for their reviews of this article, and their colleagues Stefano Angrisano, Matteo Franciolli, and Daniele Rossi for their contributions. We also want to thank Andrew J. Howes, Billy Lo, Frank I. Toth, Dave Screen, Callum Jackson, Konstantin Luttenberger and Oliver Rebmann for their inspiring and thoughtful developerWorks articles.

Resources

Resources specific to the .NET platform

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Business process management on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Business process management, WebSphere
ArticleID=945121
ArticleTitle=Developing a distributed WS-AT transaction using an IBM BPM Advanced Integration Service, Part 2: Configuring the transaction support
publish-date=09182013