Programmers Guide











JBossESB 4.4 GA

Programmers Guide

JBESB-PG-8/6/08














Legal Notices

The information contained in this documentation is subject to change without notice.

JBoss Inc. makes no warranty of any kind with regard to this material, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. JBoss Inc. shall not be liable for errors contained herein or for incidental or consequential damages in connection with the furnishing, performance, or use of this material.

Java™ and J2EE is a U.S. trademark of Sun Microsystems, Inc. Microsoft® and Windows NT® are registered trademarks of Microsoft Corporation. Oracle® is a registered U.S. trademark and Oracle9™, Oracle9 Server™ Oracle9 Enterprise Edition™ are trademarks of Oracle Corporation. Unix is used here as a generic term covering all versions of the UNIX® operating system. UNIX is a registered trademark in the United States and other countries, licensed exclusively through X/Open Company Limited.

Copyright

JBoss, Home of Professional Open Source Copyright 2006, JBoss Inc., and individual contributors as indicated by the @authors tag. All rights reserved.

See the copyright.txt in the distribution for a full listing of individual contributors. This copyrighted material is made available to anyone wishing to use, modify, copy, or redistribute it subject to the terms and conditions of the GNU General Public License, v. 2.0. This program is distributed in the hope that it will be useful, but WITHOUT A WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details. You should have received a copy of the GNU General Public License, v. 2.0 along with this distribution; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Software Version

JBossESB 4.4 GA

Restricted Rights Legend

Use, duplication, or disclosure is subject to restrictions as set forth in contract subdivision (c)(1)(ii) of the Rights in Technical Data and Computer Software clause 52.227-FAR14.

© Copyright 2008 JBoss Inc.


Contents

Table of Contents

Contents iii


About This Guide 6

What This Guide Contains 6

Audience 6

Prerequisites 6

Organization 6

Documentation Conventions 7

Additional Documentation 7

Contacting Us 8

The Enterprise Service Bus 10

What is an ESB? 10

When would you use JBossESB? 10

JBossESB 14

Rosetta 14

The core of JBossESB in a nutshell 15

Services and Messages 17

Introduction 17

The Service 17

The Message 18

Getting and Setting Data on the Message Body 23

Extensions to Body 23

The Message Header 24

LogicalEPR 26

Default FaultTo 26

Default ReplyTo 26

The Message payload 27

The MessageFactory 27

Message Formats 29

MessageType.JAVA_SERIALIZED 29

MessageType.JBOSS_XML 29

Building and Using Services 30

Listeners, Notifiers/Routers and Actions 30

Listeners 30

Notifiers 30

Actions and Messages 34

Handling responses 35

Error handling when processing actions 35

Meta-data and Filters 36

What is a Service? 37

ServiceInvoker 38

Services and ServiceInvoker 39

InVM Transport 39

InVM Scope 40

Lock-step Delivery 40

Load Balancing 41

Transaction Semantics 41

Pass-by-Reference 41

Other Components 43

Introduction 43

The Message Store 43

Data Transformation 43

Content-based Routing 44

The Registry 44

Example 45

How to use the Message 45

The Message structure 45

The Service 46

Unpicking the payload 47

The Client 48

Hints and Tips 49

Advanced Topics 50

Introduction 50

Fail-over and load-balancing support 50

Services, EPRs, listeners and actions 50

Replicated Services 51

Figure 7-2: Two service instance each on a different node. 51

Protocol Clustering 52

Clustering 52

Channel Fail-over and Load Balancing 53

Message Redelivery 54

Scheduling of Services 54

Simple Schedule 55

Cron Schedule 55

Scheduled Listener 55

Example Configurations 56

Quartz Scheduler Property Configuration 56

Fault-tolerance and Reliability 58

Introduction 58

Failure classification 58

JBossESB and the Fault Models 59

Failure Detectors and Failure Suspectors 60

Reliability guarantees 61

Message loss 62

Suspecting Endpoint Failures 63

Supported Crash Failure Modes 63

Component Specifics 63

Gateways 63

ServiceInvoker 63

JMS Broker 64

Action Pipelining 64

Recommendations 64

Configuration 66

Overview 66

Providers 67

Services 68

Transport Specific Type Implementations 71

JMS Message filter configuration 72

FTP configuration 73

FTP Listener configuration 74

Read-only FTP Listener 75

Read-only FTP Listener Configuration 75

Transitioning From The Old Configuration Model 77

Configuration 77

Web Services Support 79

JBossWS 79

Out-of-the-box Actions 80

Transformers & Converters 80

ByteArrayToString 80

LongToDateConverter 80

ObjectInvoke 81

ObjectToCSVString 81

ObjectToXStream 82

XStreamToObject 83

SmooksTransformer 84

SmooksAction 85

SmooksAction Configuration 85

Message Input Payload 86

XML, EDI, CSV etc Input Payloads 86

Java Input Payload 86

Specifying the Result Type 86

PersistAction 87

Business Process Management 88

jBPM - BpmProcessor 88

Scripting 91

GroovyActionProcessor 91

Services 92

EJBProcessor 92

Routing 93

Aggregator 93

EchoRouter 93

HttpRouter 93

JMSRouter 93

ContentBasedRouter 95

StaticRouter 96

StaticWiretap 97

Notifier 97

Webservices/SOAP 101

SOAPProcessor 101

Dependencies 102

"ESB Message Aware" Webservice Endpoints 102

Webservice Endpoint Deployment 102

Endpoint Publishing 102

SOAPClient 102

Optional Properties 102

SOAP Operation Parameters 103

JAXB Annotation Introductions 105

Action Configuration 105

Quickstarts 105

SOAPClient 106

Endpoint Operation Specification 106

SOAP Request Message Construction 106

SOAP Response Message Consumption 108

Miscellaneous 111

SystemPrintln 111

Developing Custom Actions 112

Configuring Actions Using Properties 113

Connectors and Adapters 115

Introduction 115

The Gateway 115

Gateway Data Mappings 116

How to change the Gateway Data Mappings 117

Connecting via JCA 117

Configuration 118

Appendix A 120

Writing JAXB Annotation Introduction Configurations 120

Appendix B 122

Service Oriented Architecture Overview 122

Why SOA? 124

Basics of SOA 125

Advantages of SOA 126

Interoperability 126

Efficiency 126

Standardization 126

Statefull and Stateless services 127

JBossESB and its relationship with SOA 128

Glossary 129

Index 134




About This Guide

What This Guide Contains

The Programmers Guide contains information on how to use JBossESB 4.4 GA.

Audience

This guide is most relevant to engineers who are responsible for using JBossESB 4.4 GA installations and want to know how it relates to SOA and ESB principles.

Prerequisites

None.

Organization

This guide contains the following chapters:

  • Chapter 1, The ESB: an overview of the ESB concept.

  • Chapter 2, JBossESB: a description of the core components within JBossESB and how they are intended to be used.

  • Chapter 3, Services and Messages: a discussion on the two core concepts within JBossESB.

  • Chapter 4, Building and Using Services: How to use listeners and actions to develop services and consumers.

  • Chapter 5, Other Components: An overview of the other services within JBossESB.

  • Chapter 6, Example: A worked example using some of the principles examined so far.

  • Chapter 7, Advanced Topics: Some advanced concepts available within JBossESB, such as automatic fail-over and scheduling.

  • Chapter 8, Fault-tolerance and Reliability: A discussion of how failures may affect applications developed on an ESB and how JBossESB can help tolerate them.

  • Chapter 9, Configuration: a description of the configuration options within JBossESB.

Documentation Conventions

The following conventions are used in this guide:

Convention

Description

Italic

In paragraph text, italic identifies the titles of documents that are being referenced. When used in conjunction with the Code text described below, italics identify a variable that should be replaced by the user with an actual value.

Bold

Emphasizes items of particular importance.

Code

Text that represents programming code.

Function | Function

A path to a function or dialog box within an interface. For example, “Select File | Open.” indicates that you should select the Open function from the File menu.

( ) and |

Parentheses enclose optional items in command syntax. The vertical bar separates syntax items in a list of choices. For example, any of the following three items can be entered in this syntax:

persistPolicy (Never | OnTimer | OnUpdate | NoMoreOftenThan)

Note:

Caution:

A note highlights important supplemental information.

A caution highlights procedures or information that is necessary to avoid damage to equipment, damage to software, loss of data, or invalid test results.



Table 1 Formatting Conventions

Additional Documentation

In addition to this guide, the following guides are available in the JBossESB 4.4 GA documentation set:

  1. JBossESB 4.4 GA Trailblazer Guide: Provides guidance for using the trailblazer example.

  2. JBossESB 4.4 GA Getting Started Guide: Provides a quick start reference to configuring and using the ESB.

  3. JBossESB 4.4 GA Administration Guide: How to manage JBossESB.

  4. JBossESB 4.4 GA Release Notes: Information on the differences between this release and previous releases.

  5. JBossESB 4.4 GA Services Guides: Various documents related to the services available with the ESB.

Contacting Us

Questions or comments about JBossESB 4.4 GA should be directed to our support team.



The Enterprise Service Bus

What is an ESB?

The ESB is seen as the next generation of EAI – better and without the vendor-lockin characteristics of old. As such, many of the capabilities of a good ESB mirror those of existing EAI offerings. Traditional EAI stacks consist of: Business Process Monitoring, Integrated Development Environment, Human Workflow User Interface, Business Process Management, Connectors, Transaction Manager, Security, Application Container, Messaging Service, Metadata Repository, Naming and Directory Service, Distributed Computing Architecture.

As with EAI systems, ESB is not about business logic – that is left to higher levels. It is about infrastructure logic. Although there are many different definitions of what constitutes an ESB, what everyone agrees on now is that an ESB is part of an SOA infrastructure. However, SOA is not simply a technology or a product: it's a style of design, with many aspects (such as architectural, methodological and organisational) unrelated to the actual technology. But obviously at some point it becomes necessary to map the abstract SOA to a concrete implementation and that's where the ESB comes in to play.

  1. You can learn more about SOA principles and ESB architectures in the SOA Background Concepts document.

When would you use JBossESB?

The figures below illustrate some concrete examples where JBossESB would be useful. Although these examples are specific to interactions between participants using non-interoperable JMS implementations, the principles are general and can be applied to other transports such as FTP and HTTP.

The first diagram shows simple file movement between two systems where messaging queuing is not involved.




The next diagram illustrates how transformation can be injected into the same scenario using JBossESB.






In the next series of examples, we use a queuing system (e.g., a JMS implementation).


The diagram below shows transformation and queuing in the same situation.




JBossESB can be used in more than multi-party scenarios. For example, the diagram below shows basic data transformation via the ESB using the file system.




The final scenario is again a single party example using transformation and a queuing system.




In the following chapters we shall look at the core concepts within JBossESB and how they can be used to develop SOA-based applications.

JBossESB

Rosetta

The core of JBossESB is Rosetta, an ESB that has been in commercial deployment at a mission critical site for over 3 years. The architecture of Rosetta is shown below in Figure 1:

  1. In the diagram, processor classes refer to the Action classes within the core that are responsible for processing on triggered events.






There are many reasons why users may want disparate applications, services and components to interoperate, e.g., leveraging legacy systems in new deployments. Furthermore, such interactions between these entities may occur both synchronously or asynchronously. As with most ESBs, Rosetta was developed to facilitate such deployments, but providing an infrastructure and set of tools that could:

  • Be easily configured to work with a wide variety of transport mechanisms (e.g., email and JMS).

  • Offer a general purpose object repository.

  • Enable pluggable data transformation mechanisms.

  • Support logging of interactions.

To date, Rosetta has been used in mission critical deployments using Oracle Financials. The multi platform environment included an IBM mainframe running z/OS, DB2 and Oracle databases hosted in the mainframe and in smaller servers, with additional Windows and Linux servers and a myriad of third party applications that offered dissimilar entry points for interoperation. It used JMS and MQSeries for asynchronous messaging and Postgress for object storage. Interoperation with third parties outside of the corporation’s IT infrastructure was made possible using IBM MQSeries, FTP servers offering entry points to pick up and deposit files to/from the outside world and attachments in e-mail messages to ‘well known’ e-mail accounts.

As we shall see when examining the JBossESB core, which is based on Rosetta, the challenge was to provide a set of tools and a methodology that would make it simple to isolate business logic from transport and triggering mechanisms, to log business and processing events that flowed through the framework and to allow flexible plug ins of ad hoc business logic and data transformations. Emphasis was placed on ensuring that it possible (and simple) for future users to replace/extend the standard base classes that come with the framework (and are used for the toolset), and to trigger their own ‘action classes’ that can be unaware of transport and triggering mechanisms.

  1. Within JBossESB source we have two trees: org.jboss.internal.soa.esb and org.jboss.soa.esb. You should limit your use of anything within the org.jboss.internal.soa.esb package because the contents are subject to change without notice. Alternatively anything within the org.jboss.soa.esb is covered by our deprecation policy.

      1. The core of JBossESB in a nutshell

Rosetta is built on four core architectural components:

  • Message Listener and Message Filtering code. Message Listeners act as “inbound” message routers that listen for messages (e.g. on a JMS Queue/Topic, or on the filesystem) and present the message to a message processing pipeline that filters the message and routes it (“outbound” router) to another message endpoint.

  • Data transformation via the SmooksAction action processor. See the Message Action Guide for further details.

  • A Content Based Routing Service. See the CBR Guide for further information.

  • A Message Repository, for saving messages/events exchanged within the ESB. See the Message Store Guide for further details.

These capabilities are offered through a set of business classes, adapters and processors, which will be described in detail later. Interactions between clients and services are supported via a range of different approaches, including JMS, flat-file system and email.

A typical JBossESB deployment is shown below. We shall return to this diagram in subsequent sections.

  1. Some of the components in the diagram (e.g., LDAP server) are configuration choices and may not be provided out-of-the-box. Furthermore, the Processor and Action distinction shown in the above diagram is merely an illustrative convenience to show the concepts involved when an incoming event (message) triggers the underlying ESB to invoke higher-level services.




Figure 2: ESB Core components.

In the following chapters we shall look at the various components within JBossESB and show how they interact and can be used to develop SOA-based applications.

Services and Messages

Introduction

In keeping with SOA principles, everything within JBossESB is considered to be either a service or a message. Services encapsulate the business logic or points of integration with legacy systems. Messages are the way in which clients and services communicate with each other.

In the following sections we shall look at how Services and Messages are supported within JBossESB.

The Service

A “Service” in JBossESB is defined a list of “Action” classes that process an ESB Message in a sequential manner (see below). This list of Action classes is referred to as an “Action Pipeline”. A Service can define a list of “Listeners”, which act as inbound routers for the Service, routing messages to the Action Pipeline.

The following is a very simple JBossESB configuration that defines a single Service that simply prints the contents of the ESB Message to the console.

<?xml version = "1.0" encoding = "UTF-8"?>
<jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd">

<services>
    <service category="Retail" name="ShoeStore" description="Acme Shoe Store Service">
        <actions>
            <action name="println" class="org.jboss.soa.esb.actions.SystemPrintln" />
        </actions>
     </service>
</services>

</jbossesb>

As you can see from the above example, a Service has “category” and “name” attributes. When JBossESB deploys the Service, it uses these attributes to register the Service endpoints (listeners) in the Service Registry (see Registry Guide). Clients can invoke the Service using the ServiceInvoker as follows.

ServiceInvoker invoker = new ServiceInvoker(“Retail”, “ShoeStore”);
Message message = MessageFactory.getInstance().getMessage();

message.getBody().add(“Hi there!”);
invoker.deliverAsync(message);

The ServiceInvoker uses the Service Registry (see Registry Guide) to lookup the available Endpoint addresses for the “Retail:ShoeStore” Service. It takes care of all the transport details of getting the message from the Client to one of the available Service Endpoints (JMS, FTP, HTTP etc), hiding all of the lower level details from the Client.

The Endpoint addresses made available to the ServiceInvoker will depend on the list of listeners configured on the Service (JMS, FTP, HTTP etc). No listeners are configured on the Service in the above example. This is perfectly valid. Every Service is, by default, configured with an “InVM” listener, so the ServiceInvoker will always have access to InVM addresses for locally deployed Services (i.e. in the same VM). To add additional Endpoints for the Service, we need to explicitly add listener configurations on the Service. JBossESB supports two forms of listener configuration:

  1. Gateway Listeners: These listener configurations configure a “Gateway” Endpoint. These Endpoint types can be used to get messages onto an ESB bus. It is responsible for “normalizing” the message payload by wrapping it into an ESB Message (see below) before shipping it to the Service's Action Pipeline.

  2. ESB Aware Listeners: These listener configurations configure an “ESB Aware” Endpoint. These Endpoint types are used to exchange ESB Messages (see below) between ESB Aware components i.e. exchanging messages on the bus.

The following is an example of how a JMS Gateway listener can be added to the above ShoeStore Service.

<?xml version = "1.0" encoding = "UTF-8"?>
<jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/
                                       trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd">
<providers>
    <jms-provider name="JBossMQ" connection-factory="ConnectionFactory">
        <jms-bus busid="shoeStoreJMSGateway">
            <jms-message-filter dest-type="QUEUE" dest-name="queue/shoeStoreJMSGateway"/>
        </jms-bus>
    </jms-provider>
</providers>

<services>
    <service category="Retail" name="ShoeStore" description="Acme Shoe Store Service">
<listeners>
    <jms-listener name="shoeStoreJMSGateway" busidref="shoeStoreJMSGateway" 
                  is-gateway="true"/>
</listeners>
        <actions>
            <action name="println" class="org.jboss.soa.esb.actions.SystemPrintln" />
        </actions>
     </service>
</services>

</jbossesb>

In the above configuration, we added a bus <providers> section to the configuration. This is where we configure the transport level details for Endpoints. In this case we added a <jms-provider> section that defines a single <jms-bus> for the Shoe Store JMS Queue. This bus is then referenced in the <jms-listener> defined on the Shoe Store Service. The Shoe Store is now invocable via two Endpoints – the InVM Endpoint and the JMS Gateway Endpoint. The ServiceInvoker will always use a Service's local InVM Endpoint, if available, in preference to other Endpoint types.

The Message

All interactions between clients and services within JBossESB occur through the exchange of Messages. In order to encourage loose coupling we recommend a message-exchange pattern based on one-way messages, i.e., requests and responses are independent messages, correlated where necessary by the infrastructure or application. Applications constructed in this way are less brittle and can be more tolerant of failures, giving developers more flexibility in their deployment and message delivery requirements.

To ensure loose coupling of services and develop SOA applications, it is necessary to:

  • Use one-way message exchanges rather than request-response.

  • Keep the contract definition within the exchanged messages. Try not to define a service interface that exposed back-end implementation choices, because that will make changing the implementation more difficult later.

  • Use an extensible message structure for the message payload so that changes to it can be versioned over time, for backward compatibility.

  • Do not develop fine-grained services: this is not a distributed-object paradigm, which can lead to brittle applications.

In order to use a one-way message delivery pattern with requests and responses, it is obviously necessary to encode information about where responses should be sent. That information may be present in the message body (the payload) and hence dealt with solely by the application, or part of the initial request message and typically dealt with by the ESB infrastructure.

Therefore, central to the ESB is the notion of a message, whose structure is similar to that found in SOAP:

<xs:complexType name="Envelope">
<
xs:attribute ref="Header" use="required"/>
<
xs:attribute ref="Context" use="required"/>
<
xs:attribute ref="Body" use="required"/>
<
xs:attribute ref="Attachment" use="optional"/>
<
xs:attribute ref="Properties" use="optional"/>
<
xs:attribute ref="Fault" use="optional"/>
</xs:complexType>

Pictorially the basic structure of the Message can be represented as shown below. In the rest of this section we shall examine each of these components in more detail.



In UML, the Message structure can be represented as:



Each message is an implementation of the org.jboss.soa.esb.message.Message interface. Within that package are interfaces for the various fields within the Message as shown below:

public interface Message
{
public Header getHeader ();
public Context getContext ();
public Body getBody ();
public Fault getFault ();
public Attachment getAttachment ();
public URI getType ();
public Properties getProperties ();
}

  1. In JBossESB, Attachments and Properties are not treated differently from the Body. The general concepts they embody are currently being re-evaluated and may change significantly in future releases. As such, we recommend developers do not use Attachments.

The Header contains routing and addressing information for this message. As we saw earlier, JBossESB uses an addressing scheme based on the WS-Addressing standard from W3C. We shall discuss the org.jboss.soa.esb.addressing.Call class in the next section.

public interface Header
{
public Call getCall ();
public void setCall (Call call);
}

The Context contains session related information, such as transaction or security contexts.

  1. The 4.x release of JBossESB does not support user-enhanced Contexts. This will be a feature of the 5.0 release.

The Body typically contains the payload of the message. It may contain a list of Objects of arbitrary types. How these objects are serialized to/from the message body when it is transmitted is up to the specific Object type.

  1. You should be extremely careful about sending Serialized objects within the Body: not everything that can be Serialized will necessarily be meaningful at the receiver, e.g., database connections.

public interface Body
{
public static final String DEFAULT_LOCATION = "org.jboss.soa.esb.message.defaultEntry";

public void add (String name, Object value);
public Object get (String name);
public void add (Object value);
public Object get ();
public Object remove (String name);
public void replace (Body b);
public void merge (Body b);
}

A Body can be used to convey arbitrary information types and arbitrary numbers of each type, i.e., it is not necessary to restrict yourself to sending and receiving single data items within a Body.

  1. The byte array component of the Body was deprecated in JBossESB 4.2.1. If you wish to continue using a byte array in conjunction with other data stored in the Body, then simply use add with a unique name. If your clients and services want to agree on a location for a byte array, then you can use the one that JBossESB uses: ByteBody.BYTES_LOCATION.

  2. The default named Object (DEFAULT_LOCATION) should be used with care so that multiple services or Actions do not overwrite each other's data.

The Fault can be used to convey error information. The information is represented within the Body.

public interface Fault
{
public URI getCode ();
public void setCode (URI code);

public String getReason ();
public void setReason (String reason);

public Throwable getCause ();
public void setCause (Throwable ex);
}

  1. In JBossESB, Attachments and Properties are not treated differently from the Body. The general concepts they embody are currently being re-evaluated and may change significantly in future releases. As such, we recommend developers do not use Attachments or Properties.

A set of message properties, which can be used to define additional meta-data for the message.

public interface Properties
{
public Object getProperty(String name);
public Object getProperty(String name, Object defaultVal);

public Object setProperty(String name, Object value);
public Object remove(String name);

public int size();
public String[] getNames();
}

  1. JBossESB does not implement Properties as java.util.Properties for the same reason Web Services stacks do not: it places restrictions on the types of clients and services that can used. If you need to send java.util.Properties then you can embed them within the current abstraction.

Messages may contain attachments that do not appear in the main payload body. For example, imagines, drawings, binary document formats, zip files etc. The Attachment interface supports both named and unnamed attachments.

public interface Attachment
{
Object get(String name);
Object put(String name, Object value);

Object remove(String name);

String[] getNames();

Object itemAt (int index) throws IndexOutOfBoundsException;
Object removeItemAt (
int index) throws IndexOutOfBoundsException
Object replaceItemAt(
int index, Object value)
throws IndexOutOfBoundsException;

void addItem (Object value);
void addItemAt (int index, Object value)
throws IndexOutOfBoundsException;

public int getNamedCount();
}

Attachments may be used for a number of reasons (some of which have been outlined above). At a minimum, they may be used to more logically structure your message and improve performance of large messages, e.g., by streaming the attachments between endpoints.

  1. At present JBossESB does not support specifying other encoding mechanisms for the Message or attachment streaming. This will be added in later releases and where appropriate will be tied in to the SOAP-with-attachments delivery mechanism. Therefore, currently attachments are treated in the same way as named objects within the Body.

Given that there are attachments, properties, and named objects, you may be wondering where should you put your payload? The answer is fairly straightforward:

  • As a service developer, you define the contract that clients use in order to interact with your service. As part of that contract, you will specify both functional and non-functional aspects of the service, e.g., that it is an airline reservation service (functional) and that it is transactional (non-functional). You'll also define the operations (messages) that the service can understand. As part of the message definition, you stipulate the format (e.g., Java Serialized message versus XML) and the content (e.g., transaction context, seat number, customer name etc.) When defining the content, you can specify where in the Message your service will expect to find the payload. That can be in the form of attachments or specific named objects (even the default named object if you so wish). It is entirely up to the service developer to determine. The only restrictions are that objects and attachments must be globally uniquely named, or one service (or Action) may inadvertently pick up a partial payload meant for another if the same Message Body is forwarded across multiple hops.

  • As a service users, you obtain the contract definition about the service (e.g., through UDDI or out-of-band communication) and this will define where in the message the payload must go. Information placed in other locations will likely be ignored and result in incorrect operation of the service.

There is more information about how to define your Message payload in the Message Payload section of this document.

      1. Getting and Setting Data on the Message Body

By default, all JBossESB 4.2.1GA+ components (Actions, Listeners, Gateways, Routers, Notifiers etc) get and set data on the message through the messages “Default Payload Location”.

All ESB components use the MessagePayloadProxy to manage getting and setting of the payload on the message. It handles the default case, as outlined above, but also allows this to be overridden in a uniform manner across all components. It allows the “get” and “set” location for the message payload to be overridden in a uniform way using the following component properties:

  1. get-payload-location”: The location from which to retrieve the message payload.

  2. set-payload-location”: The location on which to set the message payload.

Prior to JBossESB 4.2.1GA there was no default message payload exchange pattern in place. JBossESB 4.2.1GA+ can be configured to exchange payload data according to the pre 4.2.1GA approach (i.e. is backward compatible with) by setting the “use.legacy.message.payload.exchange.patterns” property to “true” in the “core” section/module of the jbossesb-properties.xml file (found in the jbossesb.sar).

Extensions to Body

Although you can manipulate the contents of a Message Body directly in terms of bytes or name/value pairs, it is often more natural to use one of the following predefined Message structures, which are simply different views onto the data contained in the underlying Body.

As well as the basic Body interface, JBossESB supports the following interfaces, which are extensions on the basic Body interface:

  • org.jboss.soa.esb.message.body.content.TextBody: the content of the Body is an arbitrary String, and can be manipulated via the getText and setText methods.

  • org.jboss.soa.esb.message.body.content.ObjectBody: the content of the Body is a Serialized Object, and can be manipulated via the getObject and setObject methods.

  • org.jboss.soa.esb.message.body.content.MapBody: the content of the Body is a Map<String, Serialized), and can be manipulated via the setMap and other methods.

  • org.jboss.soa.esb.message.body.content.BytesBody: the content of the Body is a byte stream that contains arbitrary Java data-types. It can be manipulated using the various setter and getter methods for the data-types. Once created, the BytesMessage should be placed into either a read-only or write-only mode, depending upon how it needs to be manipulated. It is possible to change between these modes (using readMode and writeMode), but each time the mode is changed the buffer pointer will be reset. In order to ensure that all of the updates have been pushed into the Body, it is necessary to call flush when finished.

You can create Messages that have Body implementations based on one of these specific interfaces through the XMLMessageFactory or SerializedMessageFactory classes. The need for two different factories is explained in the section on Message Formats, which is described later in the document.

For each of the various Body types, you will find an associated create method (e.g., createTextBody) that allows you to create and initialize a Message of the specific type. Once created, the Message can be manipulated directly through the raw Body or via the specific interface. If the Message is transmitted to a recipient, then the Body structure will be maintained, e.g., it can be manipulated as a TextBody.

The XMLMessageFactory and SerializedMessageFactory are more convenient ways in which to work with Messages than the MessageFactory and associated classes, which are described in the following sections.

  1. these extensions to the base Body interface are provided in a complimentary manner to the original Body. As such they can be used in conjunction with existing clients and services. Message consumers can remain unaware of these new types if necessary because the underlying data structure within the Message remains unchanged. It is important to realise that these extensions do not store their data in the default location; data should be retrieved using the corresponding getters on the extension instance.

      1. The Message Header

As we saw above, the Header of a Message contains a reference to the org.jboss.soa.esb.addressing.Call class:

public class Call
{
public Call ();
public Call (EPR epr);

public void setTo (EPR epr);
public EPR getTo () throws URISyntaxException;

public void setFrom (EPR from);
public EPR getFrom () throws URISyntaxException;

public void setReplyTo (EPR replyTo);
public EPR getReplyTo () throws URISyntaxException;

public void setFaultTo (EPR uri);
public EPR getFaultTo () throws URISyntaxException;

public void setRelatesTo (URI uri);
public URI getRelatesTo () throws URISyntaxException;

public void setAction (URI uri);
public URI getAction () throws URISyntaxException;

public void setMessageID (URI uri);
public URI getMessageID () throws URISyntaxException;

public void copy (Call from);
}

The properties below support both one way and request reply interaction patterns:

  • [To] : EPR (mandatory). The address of the intended receiver of this message.

  • [From] : endpoint reference (0..1). Reference of the endpoint where the message originated from.

  • [ReplyTo] : endpoint reference (0..1). An endpoint reference that identifies the intended receiver for replies to this message. If a reply is expected, a message must contain a [ReplyTo]. The sender must use the contents of the [ReplyTo] to formulate the reply message. If the [ReplyTo] is absent, the contents of the [From] may be used to formulate a message to the source. This property may be absent if the message has no meaningful reply. If this property is present, the [MessageID] property is required.

  • [FaultTo] : endpoint reference (0..1). An endpoint reference that identifies the intended receiver for faults related to this message. When formulating a fault message the sender must use the contents of the [FaultTo] of the message being replied to to formulate the fault message. If the [FaultTo] is absent, the sender may use the contents of the [ReplyTo] to formulate the fault message. If both the [FaultTo] and [ReplyTo] are absent, the sender may use the contents of the [From] to formulate the fault message. This property may be absent if the sender cannot receive fault messages (e.g., is a one-way application message). If this property is present, the [MessageID] property is required.

  • [Action] : URI (mandatory). An identifier that uniquely (and opaquely) identifies the semantics implied by this message.

  • [MessageID] : URI (0..1). A URI that uniquely identifies this message in time and space. No two messages with a distinct application intent may share a [MessageID] property. A message may be retransmitted for any purpose including communications failure and may use the same [MessageID] property. The value of this property is an opaque URI whose interpretation beyond equivalence is not defined. If a reply is expected, this property must be present.

The relationship between the Header and the various EPRs can be illustrated as follows in UML:



When working with Messages, you should consider the role of the header when developing and using your clients and services. For example, if you require a synchronous interaction pattern based on request/response, you will be expected to set the ReplyTo field, or a default EPR will be used; even with request/response, the response need not go back to the original sender, if you so choose. Likewise, when sending one-way messages (no response), you should not set the ReplyTo field because it will be ignored.

  1. Please see details on the LogicalEPR.

  2. The Message Header is formed in conjunction with the Message by the creator and is immutable once transmitted between endpoints. Although the interfaces allow the recipient to modify the individual values, JBossESB will ignore such modifications. In future releases it is likely that such modifications will be disallowed by the API as well for improved clarity. These rules are laid down in the WS-Addressing standards.

        1. LogicalEPR

A LogicalEPR is an EPR that simply specifies the name and category of an ESB Service/Endpoint. It contains no physical addressing information.

Clients setting the ReplyTo or FaultTo EPRs should always use the LogicalEPR, as opposed to one of the Physical EPRs (JMSEpr etc). The LogicalEPR is the preferred option because it makes no assumptions about the capabilities of the user of the EPR (typically the ESB itself, but not necessarily), or when the EPR will be used i.e. a physical EPR may no longer be valid by the time it gets used. By it's non-Physical nature, a LogicalEPR is also a lot easier to “handle” from a user perspective. The user of the LogicalEPR can use the Service name and category details supplied in the EPR to lookup the physical endpoint details for that Service/Endpoint at the point in time when they intend making the invocation i.e. they will get relevant addressing information. The user will also be able to select an endpoint type that suits it i.e. if it's easier for the user to make the invocation using a file based transport (Vs e.g. JMS), then they can select that type of transport.

        1. Default FaultTo

When sending Messages, it is possible that errors will occur, either during the transmission or reception/processing of the Message. JBossESB will route any faults to the EPR mentioned in the FaultTo field of the incoming message. If this is not set, then it will use the ReplyTo field or, failing that, the From field. If no valid EPR is obtained as a result of checking all of these fields, then the error will be output to the console. If you do not wish to be informed about such faults, such as when sending a one-way message, you may wish to use the DeadLetter Queue Service EPR as your FaultTo. In this way, any faults that do occur will be saved for later processing.

  1. Please see details on the LogicalEPR.

        1. Default ReplyTo

Because the recommended interaction pattern within JBossESB is based on one-way message exchange, responses to messages are not necessarily automatic: it is application dependent as to whether or not a sender expects a response. As such, a reply address (EPR) is an optional part of the header routing information and applications should be setting this value if necessary. However, in the case where a response is required and the reply EPR (ReplyTo EPR) has not been set, JBossESB supports default values for each type of transport. Some of these ReplyTo defaults require system administrators to configure JBossESB correctly.

  • For JMS, it is assumed to be a queue with a name based on the one used to deliver the original request: <request queue name>_reply

  • For JDBC, it is assumed to be a table in the same database with a name based on the one used to deliver the original request: <request table name>_reply_table. The new table needs the same columns as the request table.

  • For files (both local and remote), no administration changes are required: responses will be written into the same directory as the request but with a unique suffix to ensure that only the original sender will pick up the response.

  1. Please see details on the LogicalEPR.

      1. The Message payload

From an application/service perspective the message payload is a combination of the Body and Attachments. In this section we shall give an overview of best practices when constructing and using the message payload.

  1. In JBossESB, Attachments and Properties are not treated differently from the Body. The general concepts they embody are currently being re-evaluated and may change significantly in future releases. As such we shall not be considering the Attachments as part of the payload in the rest of this discussion.

The UML representation of the payload is shown below:



More complex content may be added through the add method, which supports named Objects. Names must be unique on behalf of a given Message or an appropriate exception will be thrown. Using <name, Object> pairs allows for a finer granularity of data access. The type of Objects that can be added to the Body can be arbitrary: they do not need to be Java Serializable. However, in the case where non-Serializable Objects are added, it is necessary to provide JBossESB with the ability to marshal/unmarshal the Message when it flows across the network. See the section of Message Formats for more details.

If no name is supplied to set or get, then the default name defined by DEFAULT_LOCATION will be used.

  1. be careful when using Serialized Java objects in messages because it constrains the service implementations.

In general you will find it easier to work with the Message Body through the named Object approach. You can add, remove and inspect individual data items within the Message payload without having to decode the entire Body. Furthermore, you can combine named Objects within the payload with the byte array.

  1. in the current release of JBossESB only Java Serialized objects may be attachments. This restriction will be removed in a subsequent release.

      1. The MessageFactory

Internally to an ESB component, the message is a collection of Java objects. However, messages need to be serialized for a number of reasons, e.g., transmitted between address spaces (processes) or saved to a persistent datastore for auditing or debugging purposes. The external representation of a message may be influenced by the environment in which the ESB is deployed. Therefore, JBossESB does not impose a specific normalized message format, but supports a range of them.

All implementations of the org.jboss.soa.esb.message.Message interface are obtained from the org.jboss.soa.esb.message.format.MessageFactory class:

public abstract class MessageFactory
{
public abstract Message getMessage ();
public abstract Message getMessage (URI type);

public static MessageFactory getInstance ();
}

Message serialization implementations are uniquely identified by a URI. The type of implementation required may be specified when requesting a new instance, or the configured default implementation may be used. Currently JBossESB provides two implementations, which are defined in the org.jboss.soa.esb.message.format.MessageType class:

  • MessageType.JBOSS_XML: this uses an XML representation of the Message on the wire. The schema for the message is defined in the message.xsd within the schemas directory. The URI is urn:jboss/esb/message/type/JBOSS_XML.

  • MessageType.JAVA_SERIALIZED: this implementation requires that all components of a Message are Serializable. It obviously requires that recipients of this type of Message have sufficient information (the Java classes) to be able to de-serialize the Message. The URI is urn:jboss/esb/message/type/JAVA_SERIALIZED.

  1. You should be wary about using the JAVA_SERIALIZED version of the Message format because it more easily ties your applications to specific service implementations, i.e., it breaks loose coupling.

Other Message implementations may be provided at runtime through the org.jboss.soa.esb.message.format.MessagePlugin:

public interface MessagePlugin
{
public static final String MESSAGE_PLUGIN =
"org.jboss.soa.esb.message.format.plugin";

public Message getMessage ();
public URI getType ();
}

Each plug-in must uniquely identify the type of Message implementation it provides (via getMessage), using the getType method. Plug-in implementations must be identified to the system via the jbossesb-properties.xml file using property names with the org.jboss.soa.esb.message.format.plugin extension.

  1. The default Message type is JBOSS_XML. However, this can be changed by setting the property org.jboss.soa.esb.message.default.uri to the desired URI.

      1. Message Formats

As mentioned previously, JBossESB supports two serialized message formats: MessageType.JBOSS_XML and MessageType.JAVA_SERIALIZED. In the following sections we shall look at each of these formats in more detail.

        1. MessageType.JAVA_SERIALIZED

This implementation requires that all contents are Java Serializable. Any attempt to add a non-Serializable object to the Message will result in a IllegalParameterException being thrown.

        1. MessageType.JBOSS_XML

This implementation uses an XML representation of the Message on the wire. The schema for the message is defined in the message.xsd within the schemas directory. Arbitrary objects may be added to the Message, i.e., they do not have to be Serializable. Therefore, it may be necessary to provide a mechanism to marshal/unmarshal such objects to/from XML when the Message needs to be serialized. This support can be provided through the org.jboss.soa.esb.message.format.xml.marshal.MarshalUnmarshalPlugin:

public interface MarshalUnmarshalPlugin
{
public static final String MARSHAL_UNMARSHAL_PLUGIN =
"org.jboss.soa.esb.message.format.xml.plugin";

public boolean marshal (Element doc, Object param)
throws MarshalException;

public Object unmarshal (Element doc) throws UnmarshalException;

public URI type ();
}

  1. Java Serialized objects are supported by default.

Plug-ins can be registered with the system through the jbossesb- properties.xml configuration file. They should have attribute names that start with the MARSHAL_UNMARSHAL_PLUGIN. When packing objects in XML, JBossESB runs through the list of registered plug-ins until it finds one that can deal with the object type (or faults). When packing, the name (type) of the plug-in that packed the object is also attached to facilitate unpacking at the Message receiver.

Now that we have looked at the concepts behind services and Messages, we shall examine how to construct services using the framework provided by Rosetta in the following Chapter.

Building and Using Services

Listeners, Notifiers/Routers and Actions

Listeners

Listeners encapsulate the endpoints for ESB-aware message reception. Upon receipt of a message, a Listener feeds that message into a “pipeline” of message processors that process the message before routing the result to the “replyTo” endpoint. The action processing that takes place in the pipeline may consist of steps wherein the message gets transformed in one processor, some business logic is applied in the next processor, before the result gets routed to the next step in the pipeline, or to another endpoint.

Notifiers

Notifiers are the way in which success or error information may be propagated to ESB-unaware endpoints. You should not use Notifiers for communicating with ESB-aware endpoints. This may mean that you cannot have ESB-aware and ESB-unaware endpoints listening on the same channel. Consider using Couriers or the ServiceInvoker within your Actions if you want to communicate with ESB-aware endpoints.

Not all ESB-aware transports are supported for Notifiers (and vice versa). Notifiers are deliberately simple in what they allow to be transported: either a byte[] or a String (obtained by calling toString() on the payload).

  1. JMSNotifier was sending the type of JMS message (TextMessage or ObjectMessage) depending upon the type of ESB Message (XML or Serializable, respectively). This was wrong, as the type of ESB Message should not affect the way in which the Notifier sends responses. As of JBossESB 4.2.1CP02, the message type to be used by the Notifier can be set as a property (org.jboss.soa.esb.message.transport.jms.nativeMessageType) on the ESB message. Possible values are NotifyJMS.NativeMessage.text or NotifyJMS.NativeMessage.object. For backward compatibility with previous releases, the default value depends upon the ESB Message type: object for Serializable and text for XML. However, we encourage you not to rely on defaults.

As outlined above, the responsibility of a listener is to act as a message delivery endpoint and to deliver messages to an “Action Processing Pipeline”. Each listener configuration needs to supply information for:

  • the Registry (see service-category, service-name, service-description and EPR-description tag names). If you set the optional remove-old-service tag name to true then the ESB will remove any existing service entry from the Registry prior to adding this new instance. However, this should be used with care, because the entire service will be removed, including all EPRs.

  • instantiation of the listener class (see listenerClass tag name).

  • the EPR that the listener will be servicing. This is transport specific. The following example corresponds to a JMS EPR (see connection-factory, destination-type, destination-name, jndi-type, jndi-URL and message-selector tag names).

  • the “action processing pipeline”. One or more <action> elements each that must contain at least the 'class' tagname that will determine which action class will be instantiated for that step in the processing chain.

<?xml version = "1.0" encoding = "UTF-8"?>

<jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd" parameterReloadSecs="5">


<providers>

<jms-provider name="JBossMQ"

connection-factory="ConnectionFactory"

jndi-URL="jnp://127.0.0.1:1099"

jndi-context-factory="org.jnp.interfaces.NamingContextFactory"

jndi-pkg-prefix="org.jboss.naming:org.jnp.interfaces">

<jms-bus busid="quickstartGwChannel">