Wednesday, August 29, 2012

JSP - Database Access

http://www.tutorialspoint.com/jsp/jsp_database_access.htm

This tutorial assumes you have good understanding on how JDBC application works. Before starting with database access through a JSP, make sure you have proper JDBC environment setup along with a database.
For more detail on how to access database using JDBC and its environment setup you can go through our JDBC Tutorial.
To start with basic concept, let us create a simple table and create few records in that table as follows:

Create Table

To create the Employees table in EMP database, use the following steps:

Step 1:

Open a Command Prompt and change to the installation directory as follows:
C:\>
C:\>cd Program Files\MySQL\bin
C:\Program Files\MySQL\bin>

Step 2:

Login to database as follows
C:\Program Files\MySQL\bin>mysql -u root -p
Enter password: ********
mysql>

Step 3:

Create the table Employee in TEST database as follows:
mysql> use TEST;
mysql> create table Employees
    (
     id int not null,
     age int not null,
     first varchar (255),
     last varchar (255)
    );
Query OK, 0 rows affected (0.08 sec)
mysql>

Create Data Records

Finally you create few records in Employee table as follows:
mysql> INSERT INTO Employees VALUES (100, 18, 'Zara', 'Ali');
Query OK, 1 row affected (0.05 sec)
 
mysql> INSERT INTO Employees VALUES (101, 25, 'Mahnaz', 'Fatma');
Query OK, 1 row affected (0.00 sec)
 
mysql> INSERT INTO Employees VALUES (102, 30, 'Zaid', 'Khan');
Query OK, 1 row affected (0.00 sec)
 
mysql> INSERT INTO Employees VALUES (103, 28, 'Sumit', 'Mittal');
Query OK, 1 row affected (0.00 sec)
 
mysql>

SELECT Operation:

Following example shows how we can execute SQL SELECT statement using JTSL in JSP programming:
<%@ page import="java.io.*,java.util.*,java.sql.*"%>
<%@ page import="javax.servlet.http.*,javax.servlet.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
 
<html>
<head>
<title>SELECT Operation</title>
</head>
<body>
 
<sql:setDataSource var="snapshot" driver="com.mysql.jdbc.Driver"
     url="jdbc:mysql://localhost/TEST"
     user="root"  password="pass123"/>
 
<sql:query dataSource="${snapshot}" var="result">
SELECT * from Employees;
</sql:query>
 
<table border="1" width="100%">
<tr>
   <th>Emp ID</th>
   <th>First Name</th>
   <th>Last Name</th>
   <th>Age</th>
</tr>
<c:forEach var="row" items="${result.rows}">
<tr>
   <td><c:out value="${row.id}"/></td>
   <td><c:out value="${row.first}"/></td>
   <td><c:out value="${row.last}"/></td>
   <td><c:out value="${row.age}"/></td>
</tr>
</c:forEach>
</table>
 
</body>
</html>
Now try to access above JSP, which should display the following result:
Emp ID First Name Last Name Age
100 Zara Ali 18
101 Mahnaz Fatma 25
102 Zaid Khan 30
103 Sumit Mittal 28

INSERT Operation:

Following example shows how we can execute SQL INSERT statement using JTSL in JSP programming:
<%@ page import="java.io.*,java.util.*,java.sql.*"%>
<%@ page import="javax.servlet.http.*,javax.servlet.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
 
<html>
<head>
<title>JINSERT Operation</title>
</head>
<body>
 
<sql:setDataSource var="snapshot" driver="com.mysql.jdbc.Driver"
     url="jdbc:mysql://localhost/TEST"
     user="root"  password="pass123"/>


<sql:query dataSource="${snapshot}" var="result">
INSERT INTO Employees VALUES (104, 2, 'Nuha', 'Ali');
</sql:query>
 
<sql:query dataSource="${snapshot}" var="result">
SELECT * from Employees;
</sql:query>
 
<table border="1" width="100%">
<tr>
   <th>Emp ID</th>
   <th>First Name</th>
   <th>Last Name</th>
   <th>Age</th>
</tr>
<c:forEach var="row" items="${result.rows}">
<tr>
   <td><c:out value="${row.id}"/></td>
   <td><c:out value="${row.first}"/></td>
   <td><c:out value="${row.last}"/></td>
   <td><c:out value="${row.age}"/></td>
</tr>
</c:forEach>
</table>
 
</body>
</html>
Now try to access above JSP, which should display the following result:
Emp ID First Name Last Name Age
100 Zara Ali 18
101 Mahnaz Fatma 25
102 Zaid Khan 30
103 Sumit Mittal 28
104 Nuha Ali 2

DELETE Operation:

Following example shows how we can execute SQL DELETE statement using JTSL in JSP programming:
<%@ page import="java.io.*,java.util.*,java.sql.*"%>
<%@ page import="javax.servlet.http.*,javax.servlet.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
 
<html>
<head>
<title>DELETE Operation</title>
</head>
<body>
 
<sql:setDataSource var="snapshot" driver="com.mysql.jdbc.Driver"
     url="jdbc:mysql://localhost/TEST"
     user="root"  password="pass123"/>
 
<c:set var="empId" value="103"/>
 
<sql:update dataSource="${snapshot}" var="count">
  DELETE FROM Employees WHERE Id = ?
  <sql:param value="${empId}" />
</sql:update>
 
<sql:query dataSource="${snapshot}" var="result">
   SELECT * from Employees;
</sql:query>
 
<table border="1" width="100%">
<tr>
   <th>Emp ID</th>
   <th>First Name</th>
   <th>Last Name</th>
   <th>Age</th>
</tr>
<c:forEach var="row" items="${result.rows}">
<tr>
   <td><c:out value="${row.id}"/></td>
   <td><c:out value="${row.first}"/></td>
   <td><c:out value="${row.last}"/></td>
   <td><c:out value="${row.age}"/></td>
</tr>
</c:forEach>
</table>
 
</body>
</html>
Now try to access above JSP, which should display the following result:
Emp ID First Name Last Name Age
100 Zara Ali 18
101 Mahnaz Fatma 25
102 Zaid Khan 30

UPDATE Operation:

Following example shows how we can execute SQL UPDATE statement using JTSL in JSP programming:
<%@ page import="java.io.*,java.util.*,java.sql.*"%>
<%@ page import="javax.servlet.http.*,javax.servlet.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
 
<html>
<head>
<title>DELETE Operation</title>
</head>
<body>
 
<sql:setDataSource var="snapshot" driver="com.mysql.jdbc.Driver"
     url="jdbc:mysql://localhost/TEST"
     user="root"  password="pass123"/>
 
<c:set var="empId" value="102"/>
 
<sql:update dataSource="${snapshot}" var="count">
  UPDATE Employees SET last = 'Ali'
  <sql:param value="${empId}" />
</sql:update>
 
<sql:query dataSource="${snapshot}" var="result">
   SELECT * from Employees;
</sql:query>
 
<table border="1" width="100%">
<tr>
   <th>Emp ID</th>
   <th>First Name</th>
   <th>Last Name</th>
   <th>Age</th>
</tr>
<c:forEach var="row" items="${result.rows}">
<tr>
   <td><c:out value="${row.id}"/></td>
   <td><c:out value="${row.first}"/></td>
   <td><c:out value="${row.last}"/></td>
   <td><c:out value="${row.age}"/></td>
</tr>
</c:forEach>
</table>
 
</body>
</html>
Now try to access above JSP, which should display the following result:
Emp ID First Name Last Name Age
100 Zara Ali 18
101 Mahnaz Fatma 25
102 Zaid Ali 30


Tuesday, August 28, 2012

hibernate example

http://www.roseindia.net/hibernate/firstexample.shtml
http://www.roseindia.net/hibernate/runninge-xample.shtml


with little modification of code as below:

public static void main(String[] args) {
        Session session = null;
        Transaction t = null;
        try{
            // This step will read hibernate.cfg.xml and prepare hibernate for use
            SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
             session =sessionFactory.openSession();
                //Create new instance of Contact and set values in it by reading them from form object
                 System.out.println("Inserting Record");
                 t = session.beginTransaction();
                 session.beginTransaction();
                Contact contact = new Contact();
                contact.setId(0);
                contact.setFirstName("Deepak");
                contact.setLastName("Kumar");
                contact.setEmail("deepak_38@yahoo.com");
                session.save(contact);               
                t.commit();
                System.out.println("Done");
        }catch(Exception e){
            t.rollback();
            System.out.println(e.getMessage());
        }finally{
            // Actual contact insertion will happen at this step
                
            session.flush();
            session.close();

            }


we need to begin and commit transaction to push the data into table.

Monday, August 27, 2012

Hibernate Architecture

In this lesson you will learn the architecture of Hibernate.  The following diagram describes the high level architecture of hibernate:
The above diagram shows that Hibernate is using the database and configuration data to provide persistence services (and persistent objects) to the application.
To use Hibernate, it is required to create Java classes that represents the table in the database and then map the instance variable in the class with the columns in the database. Then Hibernate can be used to perform operations on the database like select, insert, update and delete the records in the table. Hibernate automatically creates the query to perform these operations.
Hibernate architecture has three main components:
  • Connection Management
    Hibernate Connection management service provide efficient management of the database connections. Database connection is the most expensive part of interacting with the database as it requires a lot of resources of open and close the database connection.  
  • Transaction management:
    Transaction management service provide the ability to the user to execute more than one database statements at a time.
  • Object relational mapping:
    Object relational mapping is technique of mapping the data representation from an object model to a relational data model. This part of the hibernate is used to select, insert, update and delete the records form the underlying table. When we pass an object to a Session.save() method, Hibernate reads the state of the variables of that object and executes the necessary query.
Hibernate is very good tool as far as object relational mapping is concern, but in terms of connection management and transaction management, it is lacking in performance and capabilities. So usually hibernate is being used with other connection management and transaction management tools. For example apache DBCP is used for connection pooling with the Hibernate.
Hibernate provides a lot of flexibility in use. It is called "Lite" architecture when we only uses the object relational mapping component. While in "Full Cream" architecture all the three component Object Relational mapping, Connection Management and Transaction Management) are used.

Wednesday, August 15, 2012

Eclipse debug options

http://www.vogella.com/articles/EclipseDebugging/article.html

For debugging we will create an example project. Create a Java project with the name de.vogella.combug.first and add the package de.vogella.combug.first. Also create the following classes.

package de.vogella.combug.first;

public class Counter {
  private int result = 0;

  public int getResult() {
    return result;
  }

  public void count() {
    for (int i = 0; i < 100; i++) {
      result += i + 1;
    }
  }
} 


package de.vogella.combug.first;

public class Main {
  
/** * @param args */
public static void main(String[] args) { Counter counter = new Counter(); counter.count(); System.out.println("We have counted " + counter.getResult()); } }

4. Debug

4.1. Setting Breakpoints

To set breakpoints right click in the small left margin in your source code editor and select "Toggle Breakpoint". Or you can double-click on this position.

Setting a breakpoint

For example in the following screenshot we set an breakpoint on the line Counter counter = new Counter();.

Showing a defined breakpoint

4.2. Starting the Debugger

To debug your application, select a Java file which contains a main method, right click on it and select Debug AsJava Application.

Start the debugger

If you have not defined any breakpoints, this will run your program as normal. To debug the program you need to define breakpoints.
If you start the debugger the first time, Eclipse asks you if you want to switch to the debug perspective. Answer "yes". You should then see a perspective similar to the following.

Switch to perspective

You can use F5 / F6, F7 and F8 to step through your coding. The meaning of these keys is explained in the following table.
Table 1. Debugging Key bindings
Command Description
F5 Goes to the next step in your program. If the next step is a method / function this command will jump into the associated code.
F6 F6 will step over the call, i.e. it will call a method / function without entering the associated code.
F7 F7 will go to the caller of the method/ function. This will leave the current code and go to the calling code.
F8 Use F8 to go to the next breakpoint. If no further breakpoint is encountered the program will run normally.


These commands are also available in the toolbar of Eclipse. The following picture displays the buttons and their related keyboard shortcuts.

Debug Shortcuts

4.3. Stack

The call stack show the parts of the program which are currently executed and how they relate to each other. The current stack is displayed in the "Debug" View.

Showing the stack view

4.4. Evaluating variables

The Variables Ciew displays fields and local variables from the current stack. Please note you need to run the debugger to see the variables in this View.

Variables View

Use the drop-down menu to display static variables.

Drop-down menu for static variables

Via the drop-down menu you can also customize the displayed columns. For example, you can show the actual type of each variable declaration. For this select LayoutSelect Columns...Type.

Showing the actual type of the variables

Another nice feature is the "New Detail Formatter" in which you can define how a variable is displayed. For example the toString() method in our Counter class shows something meaningless, e.g. de.vogella.combug.first.Counter@587c94. Right mouse on the variableand select "New Detail Formater".

New Detail Formater Screenshot

Add the following code to get the current value of result variable in the Counter class of this example.

Detailer formater example

5. Advanced Debugging

The following section shows advanced options for debugging. It is not based on the example introduced previously.

5.1. Skip all breakpoints

If you want to temporary de-activate all your breakpoints you can press the button "Skip all breakpoints". This button is visible, if you select the "Breakpoints" tab.
If you press this button again, your breakpoints will be reactivated.

De-activating all breakpoints

5.2. Breakpoint Properties

After setting a breakpoint you can select the properties of the breakpoint, via right-clickBreakpoint Properties. You can define a condition that restricts when the breakpoint will become active.
For example, specify that the breakpoint should only be active after it has been reached 12 or more times (Hit Count).
Or, you can put in a conditional expression (which you can also use for logging). Execution will stop at the breakpoint, if the condition evaluates to true.

Breakpoint Properties


Breakpoint Properties

5.3. Watchpoint

A watchpoint is a breakpoint set on a field. The debugger will stop whenever that field is read or changed.
You can set a watchpoint by double-clicking on the left margin, next to the field declaration. In the properties of a watchpoint you can define if the execution should stop during read access (Field Access) and during write access (Field Modification).

Watchpoint

5.4. Exception Breakpoint

You can also set breakpoints which are triggered when exceptioins are thrown. To define an exception breakpoint click on the "Add Java Exception Breakpoint" icon in the "Breakpoints" View toolbar.

Exception Breakpoint

You can define if you want to stop for caught and / or uncaught exceptions.

5.5. Method Breakpoint

A method breakpoint is defined by double-clicking in the left margin of the editor next to the method header.
You can define if you want to stop the program before entering or after leaving the method.

Method Breakpoint

5.6. Class Load Breakpoint

A Class Load Breakpoint will stop when the class is loaded.
To set a class load breakpoint, right-click on a class in the Outline View and choose "Toggle Class Load Breakpoint".

Toogle class load breakpoint

5.7. Hit Count

For every breakpoint you can define a hit count in it's properties. The application is stopped once the breakpoint is reached the number of times defined in the hit count.

5.8. Drop to frame

Eclipse allows you to select any level (frame) in the call stack during debugging and set the JVM to restart from that point.
This allows you to rerun a part of your program. Be aware that variables which have been modified by code that already run will remain modified.
Changes made to variables or external data, e.g. files, databases, will not be reset when you drop to a previous frame.
To use this feature, select a level in your stack and press the "Drop to Frame" button in the toolbar of the "Debug" View.
For example you can restart your "for" loop. The field "result" will not be reseted in this case.


Tuesday, August 7, 2012

web service reliable messaging with sandesha

http://wso2.org/library/3429

However, specifications do not provide a reliable programming interface like JMS (Java Messaging Service). It specifies just a wire format for SOAP messages intended to be sent reliably. Read this article to find out how Sandesha2/C implements reliable messaging. Damitha Kumarage explains.

Introduction

Axis2/C is a Web services engine that is gaining popularity as a robust, feature rich Web services engine and is implemented in C. Sandesha2/C provides reliability for SOAP messages sent using Axis2/C by implementing the WS-Reliable Messaging specification. It plugs into Axis2/C as a standard module with two handler implementations within it, fitting into the Axis2/C in/out handler chains as specified by the module configuration. They provide implementation for RMSource and RMDestination specified in the specification. This implementation support both RM 1.0 and 1.1 specifications. It is interoperable with Microsoft .NET and Sandesha2/Java implementations.

Table of Contents

Reliability provided by Sandesha2/C

Underlying transport for sending SOAP messages could be any valid transport supported by the SOAP engine. It could be http, https, smtp, xmpp etc. We can't always expect the underlying transport to be reliable. Infact, http - the most widely used transport for SOAP is inherently unreliable. Also, we can't always expect that SOAP messages we send goes from a client to a service node. There could be many intermediaries between which the message hops, before it reaches it's final destination. We cannot predict whether the transport between any two intermediaries is reliable or not.
There are several aspects to reliability when transmitting SOAP messages. First, the sender of messages need to know whether he intends to know if the sent messages are actually received by the recipient. In that case, he needs to be acknowledged by the receiver. If the sender is not acknowledged within a predefined time frame then the sender should be able to resend the message until he receives an acknowledgment. The application environment that's sending out the message could be unreliable due to several reasons. The network could be broken, the server could be shutdown etc etc. This level of reliability is required from the specification and is provided by Sandesha2/C.
Second, there may exist the need for delivery assurance that the application message hits the target service exactly once. Although this is not required by the specification, it could be provided by a SOAP engine and Sandesha2/C do that for Axis2/C.
Thirdly, there may also exist the need for assurance that the messages are fed into the target service in the order they were intended to by the sender. Again, this is not required by the specification but the server could provide for it. This is in the TODO task list for Sandesha2/C.
Forth, suppose that the server shuts down before a sequence is completed. If the SOAP engine's reliability implementation provides a permanent storage mechanism to store the information related to the sequence(specifically at RMDestination), the sequence could be revoked when the server come back up. This level of reliability is not mandated by the reliable messaging specification. But Sandesha2/C has gone a step forward and implements this.
Finally, again, although not mandated by the specification, transaction support integration is deemed as necessary for certain business requirements. Sandesha2/C has no plans to support this yet.

Let's do it with Sandesha2/C

Before installing Sandesha2/C, you need Axis2/C installed and configured in your system. For further information on installing and configuring Axis2/C see here. After installing Axis2/C make sure that AXIS2C_HOME environment variable is set pointing to the Axis2/C installation folder(repository). You can download Sandesha2/C from here. After downloading do
./configure --prefix=${AXIS2C_HOME} --enable-static=no
--with-axis2=${AXIS2C_HOME}/include/axis2-1.3.0
make
make install
This will install Sandesha2/C into Axis2/C repository. After installing you will find following in AXIS2C_HOME repository.
$AXIS2C_HOME/modules/sandesha2
$AXIS2C_HOME/services/RMSampleService
$AXIS2C_HOME/lib/libsandesha2_client.so
$AXIS2C_HOME/bin/samples/sandesha2
For Windows operating system the instructions for installing is as follows:
  1. Unzip the source zip file and go into the extracted folder's build\win32 subfolder.
  2. Edit the configure.in with your binary locations.
  3. To set necessary environment variables on your cmd.exe run vcvars32.bat file.
  4. Run
    nmake dist
    command. This will build the Sandesha2/C binary and samples to a directory \build\sandesha2
  5. Now copy \build\sandesha2\Sandesha2 directory to your <AXIS2C_HOME>\modules directory
  6. Copy \build\sandesha2\bin\samples\RMSampleService to <AXIS2C_HOME>\services directory
Additionally, both on Linux and Windows platforms, you need to make sure that you add the RMPhase to the flows in axis2.xml in your repository directory pointed to by AXIS2C_HOME; environment varible. To do this add the following entry into inflow, outflow INfaultflow and Outfaultflow.
<phase name="RMPhase"/>
For more information on installing Sandesha2/C see Sandesha2/C documentation.
Note: If you download WSF/C then you need not worry downloading and installing separate packages for Axis2/C and Sandesha2/C and then integrating them. WSF/C is an integrated Web services platform which provides the user many Web services specific facilities in one package.
RMSampleService is an Axis2/C service engaged with Sandesha2/C for demonstration purposes. Engaging Sandesha2/C to a service is done by adding following line to services.xml.
<module ref="sandesha2"/>
If there is a need to engage Sandesha2/C to every service in the repository, you need to put this entry into Axis2/C main configuration file(axis2.xml).
There are two Reliable Messaging specifications released so far from W3C. They are WS-Reliable messaging version 1.0 and version 1.1. Sandesha2/C is designed to support both of these versions.
When sending SOAP messages, there are basically four message exchange patterns(MEP) possible. In-Only, In-Out, Out-Only, Out-In. These falls into two broader categories namely a request-response(two way) pattern, and a one-way pattern, which a communication protocol wishing to establish a communication channel is required to support. Currently, Sandesha2/C supports only SOAP over HTTP transport protocol. Usually, a service client using Axis2/C client API can send messages in several ways. He can use one of the following AXIS2/C client API functions to send messages:
axis2_svc_client_fire_and_forget()
axis2_svc_client_send_robust()
axis2_svc_client_send_receive()
axis2_svc_client_send_receive_non_blocking().
The first two falls into one-way pattern and the last two to two-way pattern. The difference between the first and second, is that in the second pattern, if the server triggers a SOAP fault this function would report an error back to the caller.
The request-response messages could be further categorized into synchronous and asynchronous. In synchronous mode the sender is blocked for a response from the server, whereas in the asynchronous mode the user is not. The third function above is synchronous and the fourth asynchronous.
Keeping those things about Axis2/C service client API in mind, let's now turn into sending messages reliably using Sandesha2/C. For an existing client which is not reliable, adding reliability is simple. You need to make sure addressing is enabled by:
axis2_svc_client_engage_module(svc_client, env,
AXIS2_MODULE_ADDRESSING);
and you need to add a line to engage Sandesha2/C to the client by.
axis2_svc_client_engage_module(svc_client, env, "sandesha2");
Today, SOAP over HTTP protocol is dominant for sending/receiving SOAP messages. However, doing two-way messaging using SOAP over HTTP posesses interesting issues. We don't have a contactable URI in some situations, like when sitting behind a firewall. In that case, there is a replay model implemented for Sandesha2/C, that could be used to do two-way messaging which uses the HTTP back channel to send messages from the server.
Now, let's go into detail with each of these.

One way

Once we engage a service and a client with Sandesha2/C as described above, the client and server exchanges messages reliably. While we proceed further, we will get clarified of certain elements pertaining to reliable messaging. Sequence is an element embedded into messages to make it identify as belonging to a certain sequence of messages. It has a SequenceID element to uniquely identify the sequence. RMSource and RMDestination are the words defined by RM Specification for sequence client and server. Here, sequence client means the one who initiated the sequence. RMSource and RMDestination should not be interchanged for the application client/requester and server/service. In two way reliable messaging, for the response sequence RMSource actually resides in the application server side and RMDestination actually resides in the application client side.

Once the message is sent by the client application, it is intercepted by the Sandesha2/C out handler that sits in the RMPhase of the outflow. It would temporarily hold this application message until registering a sequence with the server. Registering a sequence means sending a RM specific message called CreateSequence to the server with an AcksTo element and receiving from server a CreateSequenceResponse message which contain a SequenceID. AcksTo element contains an endpoint URL to which the acknowledgment messages must be sent from server. Thereafter all the application messages sent from client should contain this sequence id to mark that the message belongs to an established sequence between client and server until the client specifically terminate the sequence. In addition, each application message belonging to a sequence should have a MessageNumber element to mark the order of the message within the sequence. There could be any number of application messages associated with a sequence. Once the client receive the CreateSequenceResponse message it can send the temporarily held application message marked with the sequence id. Server could send an acknowledgment for this message to the specified URL in AcksTo element. In HTTP if the AcksTo URL is anonymous as it happen in most cases then the acknowledgment messages is sent in the HTTP back channel.
It is not required to send an acknowledgment for each application message from the server. Server can send one acknowledgment message containing an AcknowledgementRange element. AcknowledgementRange element contain the message numbers for all the messages so far received by the server. However a client could specifically request an acknowledgment request element in the sending message which should be promptly responded with an acknowledgment by the server.
When the client know that it has sent all the application messages intended for the server it can inform the server so by sending an application TerminateSequence message. In the RM 1.1 this will be responded by a TerminateSequenceResponse message.
It should be noted that all the strong typed words in the above paragraphs belongs to the WSRM namespace defined by the specification. You can define to which Reliable messaging version(1.0 or 1.1) this namespace should belong to by adding following code to the client application
property = axutil_property_create_with_args(env, 3, 0, 0,
SANDESHA2_SPEC_VERSION_1_0);
if(property)
{
    axis2_options_set_property(options, env,
    SANDESHA2_CLIENT_RM_SPEC_VERSION, property);
}
So far I have explained the all good scenario where nothing goes wrong between RM source and RM destination. What happens if network is broken and your second message in the sequence is not received by the destination?. Well the sever does not acknowledge for the second message you would say. yes that's correct. Then what will RM source do when it does not receive acknowledgment for the second message?. It will simply resend the application message number 2. But for how many times?. If the connection is broken indefinitely what happen?. In this case the client will resend the application message for a predefined number of times. The number of resends in such cases are determined by the RM Policy. Also the delay between sends is determined by the RetransmissionInterval by the Policy. Policy related xml configuration in the server or client repository should be edited before deployment to change the default values. Also there is a policy parameter called InactivityTimeout in Policy which is used to determine sequence timeout.

Two way dual channel

Two way messaging is basically understood as two one-way scenarios described above. One from client to server and other from server to client. All the request application messages from client to server belong to the sequence initiated by the client. All the response application messages from server to client belongs to the sequence initiated by the server. It should be understood that in the client there is both RMSource and RMDestination and so in the server side.

Two way single channel

Adding reliablity to a set of related application messages should not be a burden to the original sender or a receiver. If we increase RM specific messages such as CreateSequence, CreateSequenceResponse, Acknowledgement messages etc it would greatly reduce network efficiency. So if we reduce such RM specific messages to a minimum it would be a great way of providing reliability for the applications. One such mechanism is SequenceOffer element you can incorporate into your CreateSequence message. This element containa a RMSource generated sequence id, which would be offered to the RMDestination for acceptance. If the destination accept this by responding with an Accept element included in its CreateSequeceResponse message, then it does not need to specially send a CreateSequence message from server to client because response sequence id is already established by accepting the sequence id offered from the source.
This feature opens way for an application who has only single http channel to communicate in request/response pattern. For example, when we are behind a firewall and need to do two way messaging with our server reliably. Of course if there is no reliability, we can use the http back channel to send response messages synchronously. When reliability is on, we can still use the back channel to send response messages and acknowledgments in the http back channel. But how the server send us a CreateSequence message to establish a sequence to send response messages from server?\ We don't have a contactable URL behind our firewall to do that. You have the answer in sequence offer concept described above, because we can use SequenceOffer element in our CreateSequence message sent from client and avoid a CreateSequence message from server.
There is another method which could be used to do reliable messaging in a two way single channel using MakeConnection specification. In this method once the sequence is established Sandesha2/C starts a new thread for sending a new message called MakeConnection. This message body contains nothing more than an identifier element containing the sequence id offered for response sequence. HTTP back channel for this message provides a channel for response messages from server. For example, all application response messages from server and a terminate message from server are communicated through this back channel. The frequency of sending the MakeConnection message is determined by the PollingWaitTime Policy paramter.

Enhanced Reliability

Although not mandated by the specification Sandesha2/C provides a persistant storage mechanism to store sequence information in an sqlite embedded database. Because of this even in a server crash and recovery scenario the on going sequences can continue because sequence information are stored in a database. Sandesha2/C also provides 'exactly once' feature by dropping duplicate messages received by the destination.

Future

As explained earlier on, reducing the number of RM-specific messages greatly improves the network performance, when reliable messaging is engaged. As a future direction, it is planned to support AckRequested element, using which, we can configure to get Acknowledgement messages only when requested by the client.
Additionally, server could be configured to send acknowledgment messages only for missing messages. It does so by sending a Nack element to the sender that contains missing message numbers. This is intended as a future enhancement for Sandesha2/C. Also, it is planned to support Policy integration and security integration in to Sandesha2/C. The message ordering will also be supported by future versions.
More, there is plans to incorporate a sequence message monitoring mechanism tool into Sandesha2/C, so that one could easily track sequence messages from a database.

Summary

Sandesha2/C is the reliable messaging implementation for Axis2/C Web services engine. It could be easily integrated into your existing application written using Axis2/C to provide reliability with minimum effort. Sandesha2/C currently supports HTTP transport and has future plans to support other transports (supported by Axis2/C). It supports both one-way and two-way message exchange patterns. In addition, it provides a mechanisms to do two-way messaging using a single http channel between a client and a server both for RM 1.0 and RM 1.1. Sandesha2/C also features a persistant storage mechanism to support server shutdowns during a sequence progress.

Thursday, August 2, 2012

Perfect tutorial - Web Services Reliable Messaging

An Introduction to Web Services Reliable Messaging

Sections
Enterprise Architecture
Topics
WS-Reliable Messaging ,
WS Standards ,
WSO2 ,
Messaging ,
Web Services ,
SOA Platforms ,
SOA ,
Architecture ,
Enterprise Architecture

Introduction

The OASIS WS-RX Technical Committee recently released the Web Services Reliable Messaging 1.1 specification for public review. As one of the two co-chairs of the committee, this seemed like a really good time to provide an introduction to WSRM and an overview of the specification. This article provides an introduction to the specification and talks about how it might be used in real systems. It is based on the WSRM 1.1 Committee Draft 4 which is available for public review.
Web Services Reliable Messaging (WSRM) is a specification that allows two systems to send messages between each other reliably. The aim of this is to ensure that messages are transferred properly from the sender to the receiver. Reliable Messaging is a complex thing to define, but you can think about WSRM as providing a similar level of guarantee for XML messaging that a JMS system provides in the Java world. There is one key difference though - JMS is a standard API or programming model, with lots of different implementations and wire-protocols underneath it. WSRM is the opposite - a standard wire-protocol with no API or programming model of its own. Instead it composes with existing SOAP-based systems. Later in the article I will address the exact meaning of reliability and what sort of guarantees the specification offers.

Agents

Before I explain the wire protocol, I'd like to explain the way it fits into an existing SOAP interaction. Unlike a queue-based system, WSRM is almost transparent to the existing applications. In a queue-based system, there is an explicit third party (the queue) where messages the sender must put messages and the receiver get messages from. In RM, there are handlers or agents that sit inside the client's and server's SOAP processing engines and transfer messages, handle retries and do delivery. These agents aren't necessarily visible at the application level, they simply ensure that the messages get re-transmitted if lost or undelivered. So if, for example, you have set up a SOAP/JMS system to do reliable SOAP messaging, you will have had to define queues, and change the URLs and endpoints of the service to use those queues. In WSRM that isn't necessary, because it fits into the existing HTTP (or other) naming scheme and URLs.
In WSRM there are logically two of these agents - the RM Source (RMS) and the RM Destination (RMD). They may be implemented by one or more handlers in any given SOAP stack.
The RM Source:
  • Requests creation and termination of the reliability contract
  • Adds reliability headers into messages
  • Resends messages if necessary
The RM Destination:
  • Responds to requests to create and terminate a reliability contract
  • Accepts and acknowledges messages
  • (Optionally) drops duplicate messages
  • (Optionally) holds back out-of-order messages until missing messages arrive
It is important not to confuse the Source and Destination with the "service client/requester" and "service server/provider". In a two-way reliable scenario (where both requests and responses are delivered reliably) there will be an RMS and an RMD in the client, and the same in the server.

Wire Protocol

The main concept in WSRM is that of a Sequence. A sequence can be thought of as the "reliability contract" under which the RMS and RMD agree to reliably transfer messages from the sender to the receiver. Each sequence has a lifetime, which could range from being very short (I create a sequence, deliver a few messages, and terminate) to very long. In fact the default maximum number of messages in a sequence is 2^63, which is equivalent to sending 1000 messages a second for the next 292 million years!
A Sequence is created using a CreateSequence interaction, and terminated when finished with a TerminateSequence interaction.
Example of a CreateSequence message:
<soap:body>
  <wsrm:createsequence>
    <wsrm:acksto>
      <wsa:address>http://Business456.com/serviceA/789</wsa:address>
    </wsrm:acksto>   
  </wsrm:createsequence>
</soap:body>
      
Each message in a sequence has a message number, which starts at one and increments by one for each message.
Example of a Sequence Header and message number:
<soap:header>
  <wsrm:sequence>
    <wsrm:identifier>http://Business456.com/RM/ABC</wsrm:identifier>
    <wsrm:messagenumber>1</wsrm:messagenumber>
  </wsrm:sequence>
</soap:header> 
The message number is used to Acknowledge the message in an SequenceAcknowledgement header.
Example of a SequenceAcknowledgement Header:
<soap:header>
  <wsrm:sequenceacknowledgement>
    <wsrm:identifier>http://Business456.com/RM/ABC</wsrm:identifier>
    <wsrm:acknowledgementrange lower="1" upper="1" />
    <wsrm:acknowledgementrange lower="3" upper="3" />    
  </wsrm:sequenceacknowledgement>
</soap:header>

Example One-Way Scenario

Let's walk through a simple example. For simplicity we will add reliability to a one-way interaction so in this case there is just an RMS in the client and just an RMD in the server. After this I'll talk through some of the options.
  • The client wants to send an application message, so the the RMS first sends a CreateSequence message to the same URL as the application messages go to, and
  • The RMD intercepts the message and responds with a CreateSequenceResponse. This includes the all important SequenceID which is the identifier by which this sequence will be known
  • The RMS now adds a Sequence header into the original application message. This has the SequenceID and the message number (in this case it will be 1).
  • The RMS continues to add incrementing Sequence headers into application messages.
  • The RMD delivers these messages to the server application, maintaining any guarantees that it offers, such as exactly-once and in-order
  • According to its timing policy, at some point the RMD will send SequenceAcknowledgements back to the RMS. When an RMS creates a sequence, it passes an address for acknowledgements (the AcksTo address) to the RMD. In this particular scenario, we will assume that the AcksTo address is the WS-A anonymous URI - which implies you use the transport backchannel. In this case the RMD will send the acknowledgement on the HTTP response channel. Because this is a one-way interaction, there is no SOAP envelope flowing back to the client, so the RMD will create an empty SOAP envelope, add the header, and return it on the HTTP response. The RMS will pick this up before it gets to the client application.
    Note that the acknowledgement isn't just for one message, it acknowledges all the messages successfully received by the RMD.
  • If there are any missing messages, the RMS will resend those
  • Once the RMS has had all the messages that it has sent acknowledged, it can terminate the sequence. To do this is sends a TerminateSequence message to the RMD.
  • The RMD responds to the RMS with a TerminateSequenceResponse, and
  • That's all folks!
Actually, spelt out in that level of detail it seems like quite a lot, but if we recap, there were two extra service calls (Create and Terminate), and then a few extra headers floating around. I don't think that is unnecessary overhead. At one point an early draft of the spec had an inline or implicit CreateSequence. Unfortunately, that left the first message in doubt. The current design means that once you have successfully created a sequence, you have a "contract" with the other end to deliver messages. In most implementations, if no TerminateSequence is sent the sequence will be timed out automatically. And of course, you do get extra message flows if messages are lost, as in that case they will have to be resent.
So what could have gone differently? In other words, what options are there?
Well firstly, the acknowledgements don't have to use the backchannel. The RMS can open up its own HTTP port (or other endpoint) to receive acknowledgements on. This is specified in the AcksTo address. If the AcksTo address is the same as the WS-Addressing ReplyTo address, the RMD may piggyback acknowledgements in response messages flowing back to the client in some circumstances.
Secondly, the RMD doesn't have to acknowledge the messages it has received. Instead, if it is missing just one message in a million, it can Nack just the missing message. This is like a prompt to the RMS saying, I'd really like this missing message. Thirdly, the RMS could have requested an acknowledgement. Suppose the RMD is set to only acknowledge rarely (minimizing extra bandwidth), but the RMS wants to clean up its store of messages, then it can ask for an acknowledgement by adding an AckRequested header. The RMD will respond immediately with a SequenceAcknowledgement.

Closing a sequence

The other thing that could have been different is that maybe for some reason the RMS might decide to shut down the sequence before all messages are delivered. Why? Maybe my server is being closed down and I want to clean up in an orderly manner, or maybe there is one message that In this case, its tricky. Once I terminate the sequence, I can't ask for an acknowledgement, because the RMD will have cleared its state. If I ask for an acknowledgement first and then terminate, I might not get a true picture - maybe some extra messages might end up being delivered after I receive the SequenceAcknowledgement but before the Terminate happens. Arggg.
Well, we thought of this. So, we added the ability to Close a sequence. This basically is an extra interaction that allows the RMS to say that it won't be delivering any more messages. The RMD then responds with a Final sequence acknowledgement showing the ultimate state of delivered messages. After that its ok to terminate the sequence.

Request/Response

In the case of request response, there is very little difference, except that there is a sequence in each direction. The sequences are independent - so there is no linkage between transmission of the messages on one sequence with transmission of the messages on the other sequence. The only "linkage" is that you can optimize the creation of the two sequences by sending an Offer of a return sequence in the outgoing CreateSequence.
Imagine you are a client and it is clear that there will be a two-way reliable connection. In that case the client can create a sequence and Offer it to the server for responses. Effectively this lets you create two sequences in one message exchange. However, after that the sequences are independent: for example you can terminate one and still use the other.

Firewall crossing

Most internet users can't just start up an HTTP server on their machines and have other systems connect in. The problem doesn't come with running an HTTP server - that's simple. The real problem comes with getting the packets to your machine. For example, many home users have a broadband router/firewall that performs Network Address Translation. Without complex configuration these will drop all inbound packets. Similarly if I walk into a coffee shop and use the wireless LAN, I have the same problem - my IP address isn't globally accessible. Why do we care? Well, if I just want to do one-way reliable, then this doesn't matter. In fact, in the example above we showed how it works. By piggybacking the acks on the HTTP response flow, everything works just fine. But if I have a request-response flow, things change.
Suppose a response goes missing. The server wants to resend that message to the client. But the client isn't addressable. There is no open connection to resend the message on, and no way of the server opening one. Help!!!

MakeConnection to the rescue

MakeConnection is a simple one-way message that logically flows from the client to the server. By opening up an HTTP connection, this allows the server to respond with any "queued" or waiting messages that need to be transmitted to the client. Effectively the client "polls" the server every once in a while for any waiting messages. If you think about this carefully, you will see that this message flows from the RMD to the RMS, because it is designed for the return (response) path. Effectively the client's RMD is asking the server's RMS if there are any messages waiting. Of course, the client has to identify itself to make this happen. There are two options in MakeConnection. One is to modify the WS-Addressing headers to use a special URI that includes a unique ID. This is really there for complex scenarios. For simpler scenarios, the following approach works well:
  • Client creates a sequence and offer's a sequence at the same time
  • Client sends requests, ideally receives response on the backchannel
  • For some reason, some responses are timed out or connections lost
  • Client initiates MakeConnection, passing the Sequence identifier of the offered sequence
  • Server responds with missing message, plus a flag to indicate if more are waiting
  • Once no more messages are waiting the client can terminate the sequences

Security

In many ways RM just plugs in with whatever other security model is already in place. However, there are some issues that need watching out for. In particular, there is the possibility of a "sequence attack". In this model, imagine there are two valid "clients" each with a sequence. Both are authorized at the service level, but one of the clients is actually a maverick, and he wants to attack the other sequence. If he can guess (or sniff) the sequence identifier, then he can start a Denial of Service attack, by for example, terminating the sequence. So the RM spec addresses how to associate the sequence with a particular credential or security session. This means that the RM agent can protect against this kind of attack. This is particularly important with MakeConnection, because otherwise an unauthorized user could retrieve messages destined for another system.

WSRM Policy

As well as the core spec, the TC has published a Policy Assertion Language for WSRM that can be used with the WS-Policy Framework model. In the previous spec (1.0) the policy model was fairly complex. There were a number of timing parameters that were published in WSRMP. Firstly the TC decided a number of these were "unhelpful" as they tied the parties to using static timing models instead of dynamically adjusting them. Secondly, it was felt that it would be better to have any remaining timing agreed during the CreateSequence. This means that WSRM can be used very successfully without needing to use WS-Policy. Now WS-Policy is simply used to signal whether WSRM is optional or required on a given endpoint. So what does Reliability mean anyway?
Are you still reading? Congratulations on making it this far! Well we've covered the protocol in a reasonable amount of depth. Now let's step back and see what it actually gives us! The first question that challenges people about WSRM is: "What level of reliability do I get?". And the answer isn't that simple, unfortunately. WSRM was designed as a wire protocol not as an end-to-end application level protocol. There are two reasons for this. One is that the Web Services standards (WS-*) are generally designed to cover the externally visible view of a service and not the implementation, to promote the concept of loose-coupling. The second reason is composability: to provide end-to-end reliability you need to have some kind of transaction manager associated with the application. Because there are other WS-* specifications that cover transactions, and different ways of implementing transactions, it doesn't make sense for this specification to cover that aspect. This is a thorny issue that comes up every time I discuss WSRM with customers or potential users, who are looking for much more of a plug-in replacement for existing messaging systems that tightly integrate with transactional applications.
The guarantee that WSRM - by itself - offers, is simply that the message was successfully transferred from the RMS to the RMD and that the RMD acknowledged it. Different implementations can have different guarantees behind this. For example, Apache Sandesha2, an open source implementation of WSRM, has a pluggable storage manager. This means that you can have a persistent store behind the RMD, so the acknowledgement is only sent when the message has been written to disk. This means that Sandesha can support server failure and restart. The WSO2 Tungsten server supports this model of operation.
The previous specification (WSRM 1.0) specifically talked about delivery assurances such as AtLeastOnce, AtMostOnce, ExactlyOnce and InOrder. However, these assurances are really guarantees between the RMD and the application, not across the wire. So as a committee, we removed these from the specification. We still expect implementations to offer these levels of assurance, but they are part of the implementation not the wire protocol.

Programming model and implications

If you are a JMS or messaging developer, you will be used to learning a programming model (PM) for reliable messaging, such as JMS. So WSRM might come as a shock to you, because it can be used without any new programming model. Of course its hard to generalize, because each implementation can have its own approach, but the core spec doesn't imply any particular PM. For example, Sandesha allows you to turn on RM. If there is no sequence in place, it automatically creates one, and then when no more messages are being sent, it times out and terminates the sequence. The fact that the RMS and RMD are just "handlers" in the chain of processing also means that there are no new "visible entities" such as queues that need to be configured or that show up in the client code - the RM infrastructure can share the same URIs that the existing Web Service uses. So WSRM can be added into an existing Web Services interaction with no extra application code. (By the way, Sandesha also has a full programming API that gives access to sequences if users wish to hand-code the RM behaviour).
Despite this transparentness, it is worth thinking about the implications on coding. Many recent Web Service stacks and APIs, including Microsoft WCF (Indigo), JAX-WS, and Apache Axis2, offer the ability to call a Web service asynchronously (non-blocking). In this model, instead of the client blocking until the response comes back, the client passes a callback object in when it makes the outbound call. Processing then continues on the client thread, and when the response comes back a separate thread handles passes the response to the callback handler.
This style of programming is very important for WSRM, because it means that even if the server goes down, RM can resend the request and response messages until the response is received. With a blocking call, at some point the client would timeout, leaving the reliable response "orphaned" - properly delivered back to the client but without any code available to process it. So in general, if you think you might use RM, it makes sense to write clients using this non-blocking approach. (Its actually good practice anyway: imagine a web application server that is making calls out to a third-party using Web services; if too many requests are blocking waiting for responses the server's thread pool would end up exhausted and the server couldn't handle incoming requests).

History and differences from the existing 1.0 specification

WS ReliableMessaging dates all the way back to March 2003, when it was originally published. In June 2005 the 1.0 specification was submitted to OASIS for standardization. The current draft reflects a number of changes from the 1.0 spec. Without listing all of them I can summarize the main changes:
  • Namespace changes Since the specifications have significant changes they are not compatible at the wire-level. The 1.1 spec has a different set of namespaces reflecting the ownership by OASIS
  • Cleanup The TC really worked through the specification with a fine-toothed comb, and found many small issues ranging from potential errors to potential problems interoperating.
  • Addition of CloseSequence As discussed above, there are cases where it is necessary to close an incomplete sequence, and CloseSequence allows that to happen cleanly
  • Removal of LastMessage The 1.0 spec had a marker on a message to indicate it was the last message, which was largely superfluous.
  • Improved security composition The original spec had very specific composition with WS-Security/WS-SecureConversation. The 1.1 spec has a much more flexible approach that also supports composition with SSL/TLS based security sessions.
  • Updated to use the W3C WS-Addressing Recommendation The 1.1 spec uses the recommended version of WS-Addressing from the W3C.
  • Simplification of WSRM-Policy The published policy assertion is much simpler - basically is RM on or optional. The previous spec had a number of timing parameters which would not allow for dynamic adjustment of the protocol, so they were removed, or moved into the CreateSequence.
  • Support for two-way reliability with firewall crossing The MakeConnection support was added in the 1.1 spec

Implementations

There are a number of implementations of the existing WSRM 1.0 specification, including Microsoft WCF (formerly known as Indigo), and Apache Sandesha2. The OASIS WSRX TC hosted an interop based on the last Committee Draft earlier in 2006, and 5 companies turned up with implementations. Although the interop didn't produce 100% coverage, three companies managed to interop fully between their implementations in all scenarios. The TC is hosting a second interop during the public review period, to fully test the implementations on the latest specification. We are also expecting more companies to take part this time.

Summary

In this article we've covered a lot of ground, from the overall model down to the main elements of the wire protocol. There are more complicated scenarios I haven't covered, and I encourage you to read the spec itself to understand the nuances, but I hope its been useful. I'd like to finish off by looking at some of the potential uses I see for WSRM, and some of the ideas that customers have talked to me about.
  • B2B messaging A number of people see WSRM playing a key part in business to business links. Many companies are looking for a low-cost simple way of ensuring that orders, invoices, etc. are reliably and securely transmitted over the Internet to partners. WSRM is an ideal technology to provide the reliability for those links.
  • Internal department-to-department or server-to-server links WSRM is also a very useful protocol inside the enterprise. More and more companies are developing and using Web services and XML communications internally, and as those links become "line-of-business" WSRM will become a key technology to ensure reliability.
  • JMS replacement Some companies are looking at WSRM as a long-term replacement for existing proprietary JMS systems. The next release of Windows, Vista, will include WSRM support built-in. That makes it tempting if companies have currently got to install proprietary JMS clients on many workstations.
  • JMS bridge You could use WSRM as a standard protocol to bridge between two different JMS implementations. The Apache Synapse open source project is designed to help you do this, amongst other things.
  • Browser-based scenarios and notifications As AJAX applications get more interesting, the idea of doing reliable messaging directly from a browser becomes pretty exciting, especially if you were building, for example, an AJAX trading application. At least one effort is creating a plug-in for the Firefox browser that supports a SOAP-based AJAX model. RM support is coming and will make it very simple to create reliable AJAX applications. Since AJAX already uses a non-blocking asynchronous approach it is ideally suited to being composed with WSRM. The ability to cross firewalls using the MakeConnection facility also means that RM can be used without the client needing to open ports. This approach can also be used to support subscriptions, where the browser makes a single request (subscribe) and receives multiple responses (notifications) back using MakeConnection.
All in all, I see a bright future for WSRM. Its taken a while to pull together all the companies and the technology into a single approach, but we are making good progress, and the public review of the specification is a major milestone on that path