Chapter 6. Gateways and Integrating with External Clients

In previous chapters we have discussed the main concepts of the JBoss Enterprise Service Bus, showing how services can be developed to expose functionality in a loosely coupled manner.

We began the journey by defining the desirable characteristics of a service and explaining why they are advantageous, covered the structure of the messages that pass between the service consumers and service providers, explained how services are addressed through the opaque endpoint references and how service actions, combined with the action pipeline, its lifecycle and its events, are used to construct these services.

By combining these services we are then able to create composite ESB applications that can perform a multitude of tasks and solve many of our problems. Even with these capabilities there still remains one area that we are yet to cover, an area which can be argued is more important than the rest. This is the ability to support the invocation of services from external clients.

Recall from our description of services at the beginning of Chapter 3 that one of their key benefits is the ability to reuse functionality that is exposed by those services. This capability is desirable for both internal clients (those which are aware of the ESB and how to invoke services) and external clients (those which communicate with service endpoints using different, often standards-based, protocols).

By supporting the invocation of ESB services from an external client we are also enabling another silo of applications, namely those that involve the integration of services which may already exist within the organization. This capability will allow the ESB to act as a mediator between external services, augmenting their invocations as and when necessary, with everything driven by the specific business requirements which have been implemented within the ESB services.

This chapter will cover the facilities within JBoss ESB which enable the support and integration of external clients and will cover the following topics:

  • The purpose of a gateway and a notifier
  • The difference between synchronous and asynchronous invocations
  • How message composition works
  • The JMS gateway
  • The File gateway
  • The HTTP gateway
  • The Camel gateway
  • The FTP gateway
  • The UDP gateway
  • The JBoss Remoting gateway
  • The Groovy gateway
  • The SQL gateway
  • The JCA gateway

So let's get on with it...

What is a gateway and a notifier?

A gateway is a service endpoint through which an external client can talk to an ESB-aware service using a protocol that is supported by the external client. It may be that this protocol is based on a standard format, for example web service invocations over HTTP, or that the format is specific to existing applications within an organization, perhaps sent over a transport such as JMS. The gateway acts as a proxy between the two participants, adapting requests from the external client into a message that can be sent over the ESB to the target service.

Some of the gateways provided by JBoss ESB are based on a synchronous protocol, such as HTTP, and are required to handle processing of both requests and responses using the same connection. Other gateways support asynchronous protocols, such as sending messages over JMS or through a file system, and are only required to adapt the incoming request.

In order to handle the responses for the asynchronous gateway it is necessary to make use of another facility offered by JBoss ESB, the notifier. A notifier enables the sending of messages from an ESB-aware service to an external service endpoint and can be considered the inverse of the asynchronous gateway. A notifier not only handles responses, it can also be used to send asynchronous notifications to any external service which can receive them.

The behavior of the gateways and notifiers can be visualized as follows:

What is a gateway and a notifier?

In the above diagram we are showing two different types of external invocations, a synchronous invocation using the HTTP transport, and an asynchronous invocation using the JMS transport. In both instances it is the gateways which are responsible for processing the incoming request, constructing an ESB message and passing it into the ESB to be handled by the target service(s). Where they differ is in the handling of the responses.

The JMS transport, by its nature, allows invocations to be made asynchronously. This allows the gateway to complete its part in the processing of the current request and move on to the next one arriving at the gateway. Any response to the client will come through a notifier, at a later point in time.

The HTTP transport, being a synchronous transport by default, requires any response to be sent back to the client using the same connection through which the request was received. The HTTP gateway must block in these circumstances, waiting for the reply from the ESB service before responding to the external client.

Note

There is no requirement to use the same transport for receiving and responding to asynchronous requests, it is possible to mix the transports should it make sense to the application being developed.

How do we compose messages?

Every gateway must take an incoming request, in the native format, and convert it into a message that can be sent over the ESB to the target service, but how is this done?

Each gateway has a message composer associated with it, responsible for performing the conversion from a native request to an ESB message and, if necessary, vice-versa. By default it will use a composer appropriate for the supported transport, each composer implementing the org.jboss.soa.esb.listeners.message.MessageComposer interface.

The important methods within the interface are:

public Message compose(T messagePayload)
    throws MessageDeliverException;

public Object decompose(Message message,T originalInputMessagePayload)
    throws MessageDeliverException;

The compose method is responsible for taking the incoming request and creating an ESB message representing the payload, returning this to the gateway so that it can be sent to the target ESB service.

The decompose method is responsible for taking the response, if it is necessary, and returning a payload that can then be sent to the external client as a native response. The decompose method also has access to the original request in case it contains information that may be relevant when creating the response.

Simple composer example

The following code snippet shows a simplistic composer for the File gateway:

public class ExampleMessageComposer<T extends File>
  implements MessageComposer<T> {

    public void setConfiguration(final ConfigTree config)
      throws ConfigurationException {
    }

    public Message compose(final T inputFile)
      throws MessageDeliverException {
        final Message message =
          MessageFactory.getInstance().getMessage();
        final byte[] contents ;
        try {
            contents = FileUtil.readFile(inputFile) ;
        } catch (final IOException ioe) {
            throw new MessageDeliverException(
              "Failed to obtain contents", ioe) ;
        }
        message.getBody().add(contents) ;
        return message;
    }

    public Object decompose(Message message, T inputFile)
      throws MessageDeliverException {
        return message.getBody().get() ;
    }
}

The gateway will invoke the compose method, passing in the File instance which identifies the incoming request. The MessageComposer is then responsible for retrieving the contents of this File and creating the message, initializing the content and properties of the message as required.

When the gateway receives a response from the ESB service it will invoke the decompose method in order to obtain the externalized response, passing in the response message from the ESB service, and the File instance which identifies the original request. The MessageComposer is then responsible for retrieving the necessary content from the ESB response message and returning this to the gateway.

This MessageComposer can be applied to the gateway by specifying the composer-class property on the listener, along with any other properties that may be required by the composer. An example configuration for the MessageComposer could be:

<listeners>
  <fs-listener name="example" busidref="examplebus" is-gateway="true"
               schedule-frequency="2">
    <property name="composer-class" value="ExampleMessageComposer"/>
    ...
  </fs-listener>
</listeners>

It is beyond the scope of this book to cover message composition in any further detail, as the default composers are sufficient for most needs, however it is important that their existence is understood.

Now that we have an understanding of the gateway functionalities, let's get started with the fun stuff.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset