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
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
The Programmers Guide contains information on how to use JBossESB 4.4 GA.
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.
None.
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.
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: |
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
In addition to this guide, the following guides are available in the JBossESB 4.4 GA documentation set:
JBossESB 4.4 GA Trailblazer Guide: Provides guidance for using the trailblazer example.
JBossESB 4.4 GA Getting Started Guide: Provides a quick start reference to configuring and using the ESB.
JBossESB 4.4 GA Administration Guide: How to manage JBossESB.
JBossESB 4.4 GA Release Notes: Information on the differences between this release and previous releases.
JBossESB 4.4 GA Services Guides: Various documents related to the services available with the ESB.
Questions or comments about JBossESB 4.4 GA should be directed to our support team.
The Enterprise Service Bus
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.
You can learn more about SOA principles and ESB architectures in the SOA Background Concepts document.
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
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:
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.
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.
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.
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.

Services and Messages
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.
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:
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.
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.
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 ();
}
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.
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.
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.
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.
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);
}
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();
}
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.
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.
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:
“get-payload-location”: The location from which to retrieve the message payload.
“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).
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.
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.
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.
Please see details on the LogicalEPR.
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.
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.
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.
Please see details on the LogicalEPR.
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.
Please see details on the LogicalEPR.
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.
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.
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.
in the current release of JBossESB only Java Serialized objects may be attachments. This restriction will be removed in a subsequent release.
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.
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.
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.
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.
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.
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 ();
}
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 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 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).
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">