Sign In/My Account | View Cart  
advertisement


Listen Print Discuss

Web Services Integration Patterns, Part 2
by Massimiliano Bigatti | Pages: 1, 2, 3, 4, 5

Data Logger

Input and output from the service is logged in a database table

Logging is one of the most used techniques to identify bugs in the software, but when it comes to the seb services, a simple text file isn't sufficient.

Usually the developer starts logging some key information about the process, to identify specific problems. Quickly, it became necessary to have the request and response XML message in the logs. But one problem is that often the services have many input and output, resulting in long log files.

Text files are also difficult to read and, although logging packages like log4j have nice formatting options, they don't directly support XML.

When debugging a web service it's useful to have the request and the response for a single call in front of each other. The multithreaded and parallel architecture of a J2EE container doesn't guarantee that the information is mantained in a contiguous way, so you'll end struggling in finding the correct response for a specific call.

The situation is worse in production, where many users use the system, performing many calls to the services and generating huge logging data. This amount is so huge that sometimes it overhelms the available storage and CPU in the production machines.

For these reasons, it's useful to log the data flow in a database table, so the input and output of the same call are always coupled. The table could use a pair of CLOB columns, one for the request and the other for the response.

The Logger incorporates all the logic required to store the XML documents in the database table. The Abstract Service implements a common base for services that are aware of the logging capabilities of the framework.

The client invokes the service as usual, but the code contained in the Abstract Service class passes the request (i.e. the SOAP request Envelope) to the Logger, which in turns stores it to the database, obtaining a lock on the row just created. When the response arrives, it is stored in the same row of the request.

Sample code

The following code is an example implementation of an AbstractService class; it implements the call to the service using a channel object. After initialization, the AbstractService gets the request XML from the channel. The data is stored by the logger object, which returns a numeric token, used to identify the running session, so it can distinguish concurrent calls.

After the Channel.call(), the response XML is fetched from the channel object and passed over the logger, with the token previously obtained; the logger then store the response on the database.


public abstract class AbstractService implements Service {
  Channel channel;
  Logger logger;
  
  public void call() throws ServiceException {
    channel.init();
    
    String request = channel.getRequest();
    int token = logger.storeRequest( request );
    
    channel.call();
    
    String response = channel.getResponse();
    logger.storeResponse( token, response );
  }
}

Pages: 1, 2, 3, 4, 5

Next Pagearrow