Introduction: Process Configuration and Flexibility Trends
The need for process flexibility is not a new trend. The trend has
been evident for the last two decades. The Internet, Web, and mobile
computing came along and enabled a global productivity boom, resulting
in technology innovations that are constantly laying the foundation for
renovating industrial-age processes.
These solutions are built primarily on proprietary or system-based
messaging platforms aimed at providing a platform for integration and
communication between various business components. The typical method
for accessing these systems is through a wide assortment of pre-built
adapters that provide a bi-directional connectivity to many types of
application processes. Rather than explicitly declaring how systems will
interact through low-level protocols and object-oriented architectures,
Service-Oriented Architecture (SOA) makes it possible to provide an
abstract interface through which processes or services can interact. It
can be imagined as an interconnected process-based enterprise that
exposes a set of loosely coupled, coarse-grained services.
What Is Service-Oriented Architecture?
SOA is the aggregation of components that satisfy a business need. It
comprises components, services, and processes. Components are binaries
that have a defined interface (usually only one), and a service is a
grouping of components (executable programs) to get the job done. This
higher level of application development provides a strategic advantage,
facilitating more focus on the business requirement.
SOA isn't a new approach to software design; some of the notions
behind SOA have been around for years. Jess Thompson, a research
director at Gartner, argues that the underlying concepts date back to
the early 1970s, when researchers started drawing boundaries around
software and providing access to that software only through well-defined
interfaces.
A service is generally implemented as a coarse-grained, discoverable
software entity that exists as a single instance and interacts with
applications and other services through a loosely coupled (often
asynchronous), message-based communication model.
The most important aspect of SOA is that it separates the service's
implementation from its interface. Service consumers view a service
simply as a communication endpoint supporting a particular request
format or contract. How service executes service requested by consumers
is irrelevant; the only mandatory requirement is that the service sends
the response back to the consumer in the agreed format, specified in
contract.
SOA Entities
SOA consists of various entities configured together to support the
find, bind, and execute paradigm as shown in
Figure 1.
Figure 1. SOA explained
Service Consumer
The service consumer is an application, service, or some other type
of software module that requires a service. It is the entity that
initiates the locating of the service in the service registry, binding
to the service over a transport, and executing the service function. The
service consumer executes the service by sending it a request formatted
according to the contract.
Service Provider
The service provider is the network-addressable entity that accepts
and executes requests from consumers. It can be a mainframe system, a
component, or some other type of software system that executes the
service request. The service provider publishes its contract in the
service registry for access by service consumers.
Service Registry
A service registry is a network-based directory that contains
available services. It is an entity that accepts and stores contracts
from service providers and provides those contracts to interested
service consumers.
Service Contract
A contract is a specification of the way a consumer of a service will
interact with the service provider. It specifies the format of the
request and response from the service. A service contract may require a
set of preconditions and post conditions. The preconditions and post
conditions specify the state that the service must be in to execute a
particular function. The contract may also specify quality of service
(QoS) levels, specifications for the nonfunctional aspects of the
service.
Service Lease
The lease (the time for which the state may be maintained), which the
service registry grants the service consumer, is necessary for services
to maintain state information about the binding between the consumer
and provider. It enforces loose coupling between the service consumer
and the service provider, by limiting the amount of time consumers and
providers may be bound. Without a lease, a consumer could bind to a
service forever and never rebind to its contract again.
Discoverability and Dynamic Binding: Messaging in SOA
SOA supports the concept of dynamic service discovery. The service
consumer queries the "service registry for a service, and the service
registry returns a list of all service providers that support the
requested service. The consumer selects the cost-effective service
provider from the list, and binds to the provider using a pointer from
the service registry entry.
The consumer formats a request message based on the contract
specifications, and binds the message to a communications channel that
the service supports. The service provider executes the service and
returns a message that conforms to the message definition in service
contract.
The only dependency between provider and consumer is the contract,
which the third-party service registry provides. The dependency is a
runtime dependency and not a compile-time dependency. All the
information the consumer needs about the service is obtained and used at
runtime. The service interfaces are discovered dynamically, and
messages are constructed dynamically. The service consumer does not know
the format of the request message or response message or the location
of the service until the service is actually needed.
The ability to transform messages has the benefit of allowing
applications to be much more decoupled from each other. Messaging
underpins SOA; we don't have SOA without messaging.
Messaging Patterns Catalogue Within SOA Context
Messaging patterns exist at different levels of abstraction with the
SOA. Some patterns are used to represent the message itself, or
attributes of a messaging transport system. Others are used to represent
creation of message content or change the information content of a
message. Patterns are also used to discuss complex mechanisms to direct
messages. SOA messaging patterns can be divided into the following
categories:
- Message type patterns. Describe different varieties of messages that can be used in SOA.
- Message channel patterns. Describe the fundamental attributes of a messaging transport system.
- Routing patterns. Describe mechanisms to direct messages between Service Provider and Service Consumer.
- Service consumer patterns. Describe the behavior of messaging system clients.
- Contract patterns. Illustrates the behavioral specification to maintain a smooth communication between Service Provider and Consumer.
- Message construction patterns. Describes the creation of message content that travel across the messaging system.
- Transformation patterns. Change the information content of a message within the enterprise level messaging.
These patterns are shown in
Figure 2.
Figure 2. Messaging patterns catalogue within SOA context
Message Type Patterns
The message itself is simply some sort of data structure—such as a
string, a byte array, a record, or an object. It can be interpreted
simply as data, as the description of a command to be invoked on the
receiver, or as the description of an event that occurred in the sender.
Sender can send a
Command Message, specifying a function or method on the receiver that the sender wishes to invoke. It can send a
Document Message, enabling the sender to transmit one of its data structures to the receiver. Or it can send an
Event Message, notifying the receiver of a change in the sender.
The following message type patterns can commonly be used in SOA.
Command Message
Problem:
How to invoke a procedure in another application?
Solution: Use a command message to reliably invoke a procedure in another application as shown in
Figure 3.
Figure 3. Command message
Interactions:
A
command message controls another application, or a series
of other applications, by sending a specially formatted message to that
system. A command message includes intelligent instructions to perform a
specific action, either through headers and attributes, or as part of
the message payload. The recipient performs the appropriate action when
the message is received. Command messages are closely related to the
Command pattern [9].
A
command message is simply a regular message that happens
to contain a command. A Simple Object Access Protocol (SOAP) request is a
command message.
Command messages are usually sent on a point-to-point channel so that each command will only be consumed and invoked once.
Document Message
Problem:
How can you transfer data between services?
Solutions:
Use a
document message to reliably transfer a data structure between applications. See
Figure 4.
Figure 4. Document message
Interactions:
A
document message is just a single unit of information, a
single object or data structure that may decompose into smaller units.
The important part of a
document message is its content; the document. This content is retrieved by un-marshalling / or de-serializing data.
Document messages are usually sent using a point-to-point channel. In request-reply scenarios, the reply is usually a
document message where the result value is the document.
A
document message can be any kind of message in the messaging system. A Simple Object Access Protocol (SOAP) reply message is a document message.
Event Message
Problem:
Several applications would like to use event notification to
coordinate their actions, and would like to use messaging to communicate
those events. How can messaging be used to transmit events from one
service to another?
Solutions:
Use an
event message for reliable, asynchronous event notification between applications. See
Figure 5.
Figure 5. Event message
Interactions:
An event message extends the Observer model to a set of distributed
applications. Event messages can be sent from one service to another to
provide notification of lifecycle events within a service-oriented
enterprise, or to announce the status of particular activities.
Applications for this pattern include enterprise monitoring and
centralized logging.
An important characteristic of event messages is that they do not require a reply.
An
event message can be any kind of message in the messaging system. An event can be an object or data such as an XML document.
"If a message says that the Stock price for certain symbol has
changed, that's an event. If the message provided information about the
symbol, including its new price, that's a document."
Request-Reply Message
Problem:
Messages travel into a message channel in one direction, from the
sender to the receiver. This asynchronous transmission makes the
delivery more reliable and decouples the sender from the receiver. The
problem is that communication between components often needs to be
two-way. When one component notifies another of a change, it may want to
receive an acknowledgement.
How can messaging be two-way?
Solutions:
Send a pair of request-reply messages, each on its own channel.
See Figure 6.
Figure 6. Request reply message
Interactions:
Request-Reply has two participants:
- Requester (Service Consumer). Sends a request message and waits for a reply message.
- Replier (Service Provider). Receives the request message and responds with a reply message.
The request channel can be a point-to-point channel or a
publish-subscribe channel.
The difference is whether the request should be broadcast to all
interested parties or should only be processed by a single consumer. The
reply channel, on the other hand, is almost always point-to-point,
because it usually makes no sense to broadcast replies.
The request is like a method call. As such, the reply is one of three possibilities:
- Void
- Result value
- Exception
The request should contain a return address to tell the replier where
to send the reply. The reply should contain a correlation identifier
that specifies which request this reply is for.
Messaging Channel Patterns
Channels, also known as queues, are logical pathways to transport
messages. A channel behaves like a collection or array of messages, but
one that is magically shared across multiple computers and can be used
concurrently by multiple applications.
A service provider is a program that sends a message by writing the
message to a channel. A consumer receives a message from a channel.
There are different kinds of messaging channels available.
Point-to-Point Channel
Problem:
The sender dispatches a message to a messaging system, which is
responsible for relaying the message to a particular recipient. The
messaging system might proactively deliver the message (by contacting
the recipient directly), or hold the message until the recipient
connects to retrieve it.
How can you ensure that exactly one consumer will receive the message?
Solution:
Send the message on a
point-to-point channel, which ensures that only one receiver will receive a particular message. See
Figure 7.
Figure 7. Point-to-point channel
Interactions:
A
point-to-point channel ensures that only one consumer
consumes any given message. If the channel has multiple receivers, only
one of them can successfully consume a particular message. If multiple
receivers try to consume a single message, the channel ensures that only
one of them succeeds, so the receivers do not have to coordinate with
each other. The channel can still have multiple consumers to consume
multiple messages concurrently, but only a single receiver consumes any
one message.
Publish-Subscribe Channel
Problem:
The service provider broadcasts an event once, to all interested consumers.
Solution:
Send the event on a publish-subscribe channel, which delivers a copy of a particular event to each receiver. See
Figure 8.
Figure 8. Publish-subscribe channel
Interactions:
A
publish-subscribe channel that is developed based on
Observer pattern [9], and describes a single input channel that splits
into multiple output channels—one for each subscriber. After publishing
an event into the
publish-subscribe channel, the same message
is delivered to each of the output channels. Each output channel is
configured on one-to-one topology to allow only one consumer to consume a
message. The event is considered consumed only when all of the
consumers have been notified.
A
publish-subscribe channel can be a useful for systems management, error debugging and different level of testing.
Datatype Channel
Problem:
The receiver must know what type of messages it is receiving, or it
won't know how to process them. For example, a sender might send
different objects such as purchase orders, price quotes, and queries,
but a receiver will probably take different steps to process each of
these, so it has to know which is which.
Solution:
Use a separate
datatype channel for each data type, so that all data on a particular channel is of the same type. See
Figure 9.
Figure 9. Datatype channel
Interactions:
In any messaging system there are several separate
datatype channels
for each type of data. All of the messages on a given channel will
contain the same type of data. Based on data type, the service provider
sends the data to the channel and the consumer receives data from the
appropriate
datatype channel.
Dead Letter Channel
Problem:
There are a number of reasons for message delivery to fail. Issues
might be message channel configuration problem, a problem with
consumers, or message expiration.
Solution:
When there is any delivery issue with the message, it can be moved to a different messaging channel called a
dead letter channel. See
Figure 10.
Figure 10. Dead letter channel
Interactions:
A
dead letter channel is a separate channel dedicated for
bad messages or invalid messages. From this channel messages can be
rerouted to the mainstream channel or even in separate channel for
special processing of the message.
Guaranteed Delivery
Problem:
One of the main advantages of asynchronous messaging over RPC is that
the participants don't need to be online at the same time. While the
network is unavailable, the messaging system has to use a store and
forward mechanism to ensure message durability. By default, the messages
are stored in memory until they can be successfully forwarded to the
next contract point. This mechanism works well when the messaging system
is running reliably, but if the messaging system crashes, all of the
stored messages are lost. As a preventative measure, applications use
persistent media like files and databases to ensure recovery from system
crashes.
Solution:
Use a
guaranteed delivery mechanism to make messages persistent. See
Figure 11.
Figure 11. Guaranteed delivery
Interactions:
With
guaranteed delivery, the messaging system uses a
built-in data store (local storage disk space in a participant computer)
to persist messages in each participant computer on which the messaging
system is installed. The message is safely stored until it is
successfully delivered. In this way, it ensures guaranteed delivery.
This guaranteed delivery mechanism increases system reliability, but
at the expense of performance as it involves considerable numbers of I/O
and consumes a large amount of disk space. Therefore if performance or
debugging/testing is the priority try to avoid using
guaranteed delivery.
Message Bus
Problem:
An enterprise consists of various independent applications
communicating with each other in a unified manner.We need an integration
/service architecture that enables those applications to coordinate in a
loosely coupled fashioned.
Solution:
Structure the connecting middleware between these applications as a
message bus that enables them to work together using messaging as shown in
Figure 12.
Figure 12. Message bus
Interactions:
A
message bus is a combination of a common data model, a
common command set, and a messaging infrastructure to allow different
heterogeneous systems to communicate through a shared set of interfaces.
A
message bus can be considered as a universal connector
between the various enterprise systems, and as a universal interface for
client applications that wish to communicate with each other. A message
bus requires that all of the applications should use the same canonical
data model. Applications adding messages to the bus may need to depend
on message routers to route the messages to the appropriate final
destinations.
Message Routing Patterns
Almost all messaging system uses built in router as well as
customized routing. Message Routers are very important building blocks
for any good integration architecture. As opposed to the different
message routing design patterns, this pattern describes a hub-and-spoke
architectural style with few specially embedded routing logic.
In Search of the Right Router
An important decision for an architect is to choose the appropriate
routing mechanism. Patterns that will help you make the right decision
are:
- Pipes and filter
- Content-based router
- Content aggregator
Pipes and Filter
Problem:
How can you divide a larger processing task into a sequence of smaller, independent processing steps?
Solution:
Use the
pipes and filters pattern to divide a larger
processing task into a sequence of smaller, independent processing steps
(filters) that are connected by channels (pipes). See
Figure 13.
Figure 13. Pipes and filter
Interactions:
Each filter exposes a very simple interface: it receives messages on
the inbound pipe, processes the message, performs business
transformations, and publishes the results to the outbound pipe. The
pipe connects one filter to the next, sending output messages from one
filter to the next. It's very similar to execution of a method call
through passing parameters and getting a return value. It follows 'chain
of responsibility' [11] pattern. Because all components use the same
external interface they can be composed into different solutions by
connecting the components to different pipes. The connection between
filter and pipe is sometimes called port. In the basic form, each filter
component has one input port and one output port.
The
pipes and filters pattern uses abstract pipes to
decouple components from each other. The pipe allows one component to
send a message into the pipe so that it can be consumed later by another
process that is unknown to the component. One of the potential
downsides of pipes and filters architecture is the larger number of
required channels that consume memory and CPU cycles. Also, publishing a
message to a channel involves a certain amount of overhead because the
data has to be translated from the application-internal format into the
messaging infrastructure's own format.
Using
pipes and filters also improves module-wise unit
testing ability. It can help to prepare a testing framework. It is more
efficient to test and debug each core function in isolation because we
can tailor the test mechanism to the specific function.
Content-Based Router
Problem:
The routing can be based on a number of criteria such as existence of fields, specific field values, and so on.
Solution:
Use a content-based router to route each message to correct consumer based on message content. See
Figure 14.
Figure 14. Content-based router
Interactions:
The
content-based router examines the message content and
routes the message onto a different channel based on message data
content. When implementing a
content-based router, special
caution should be taken to make easily maintainable routing logic. In
more sophisticated integration scenarios, the content-based router can
be implemented as a configurable rules engine that computes the
destination channel based on a set of configurable rules.
Content Aggregator
Problem:
The messaging system exchanges messages between a variety of sources.
The messages have similar content but different formats, which can
complicate the processing of combined messages. It would be better
processing decision if we assigned different components with different
responsibilities [11]. For example, if we want to select all of the
transactions of a particular customer from different business zones for a
particular quarter. This method is called event linking and sequencing.
Solution:
Use a stateful
content aggregator, to collect and store individual messages and combine those related messages to publish a single aggregated message. See
Figure 15.
Figure 15. Content aggregator
Interactions:
A
content aggregator is a special filter that receives a
stream of messages and correlates related messages. When a complete set
of messages has been received, the aggregator collects information from
each correlated message and publishes a single, aggregated message to
the output channel for further processing. Therefore, aggregator has to
be stateful, because it needs to save the message state with processing
state until the complete formation of the aggregation.
When designing an aggregator, we need to specify the following items:
- Correlation ID. An identifier that indicates messages internal relationship
- End condition. The condition that determines when to stop processing
- Aggregation algorithm. The algorithm used to combine the received messages into a single output message
Every time the
content aggregator receives a new message, it
checks whether the message is a part of already existing aggregate or a
new aggregate. After adding the message, the
content aggregator
evaluates the process end condition for the aggregate. If the condition
evaluates to true, a new aggregated message is formed from the
aggregate and published to the output channel. If the process end
condition evaluates to false, no message is published and the
content aggregator continues processing.
Service Consumer Patterns
There are several possible types of Service Consumer. In this pattern catalogue we will present a set of consumer patterns.
Transactional Client
Problem:
Transactions are important part of any messaging system and are
sufficient for any participant to send or receive a single message.
However, a few specific scenarios might need a broader transactional
approach, which in turn may need special transactional coordination.
These cases include (but are not limited to):
- Send-receive message pairs. Receive one message and send another.
- Batch message. Send or receive a group of related messages in a batch mode.
- Message/database coordination. Send or receive a
message combined with database update. For example, when an application
receives and processes a message for ordering a product, the application
will also need to update the product inventory database.
Scenarios like these require a different specification of
transactional boundaries with much more complexities involving more than
just a single message and may involve other transactional stores
besides the messaging system.
How can you solve this kind of transactional problems?
Solution:
Use a
transactional client—make the client's session with
the messaging system transactional and ensure that the client can
specify complex transaction boundaries. See
Figure 16.
Figure 16. Transactional client sequence diagram
Interactions:
Both participants can be transactional. From a sender's point of
view, the message isn't considered added to the channel until the sender
commits the transaction. On the other hand message isn't removed from
the channel until the receiver commits the transaction.
With a transactional receiver, messages can be received without
actual removal of the message from the channel. The advantage of this
approach is that if the application crashed at this point, the message
would still be on the queue after message recovery has been performed;
the message would not be lost. After the message processing is finished,
and on successful transaction commit, the message is removed from the
channel.
Polling Consumer
Problem:
In any messaging system, the consumer needs an indication that
application is ready so that it can consume the message. The best
approach for the consumer is to repeatedly check the channel for message
availability. If any message is available, the consumer consumes it.
This checking is a continuous process known as polling.
Solution:
The application should use a
polling consumer, one that explicitly makes a call when it wants to receive a message. See
Figure 17.
Figure 17. Polling consumer
Interactions:
A polling consumer is a message receiver. A polling consumer
restricts the number of concurrent messages to be consumed by limiting
the number of polling threads. In this way, it prevents the application
from being blocked by having to process too many requests, and keeps any
extra messages queued up until the receiver can process them.
Event-Driven Consumer
Problem:
The problem with polling consumers is that it's a continuous process
involves dedicated threads and consumes process time while polling for
messages.
Solution:
Instead of making the consumer poll for the message, a better idea
might be to use event driven message notifications to indicate message
availability. See
Figure 18 and
Figure 19. The
application should use an event-driven consumer. Event-driven consumers
automatically consume messages as they become available.
Figure 18. Event-driven consumer
Figure 19. Event-driven consumer sequence diagram
Interactions:
An event-driven consumer is invoked by the messaging system at the
time of message arrival on the consumer's channel. The consumer uses
application-specific callback mechanism to pass the message to the
application.
Durable Subscriber
Problem:
In some cases you might require guaranteed message delivery where a
message consumer is not connected to publish-subscribe channel or has
crashed before receiving a message. In this case the messaging system
needs to ensure guaranteed message delivery when the consumer reconnects
to the system.
Solution:
Use a durable subscriber. See
Figure 20 and 21.
Figure 20. Durable subscriber
Figure 21. Durable subscriber sequence diagram
Interactions:
A durable subscription saves messages for an off-line subscriber and
ensures message delivery when the subscriber reconnects. Thus it
prevents published messages from getting lost and ensures guaranteed
delivery. A durable subscription has no effect on the normal behavior of
the online/active subscription mechanism.
Idempotent Receiver
Problem:
For certain scenarios, instead of using Durable Subscription
mechanism, some reliable messaging implementations can produce duplicate
messages to ensure guaranteed, at-least once Delivery. In these cases,
message delivery can generally only be guaranteed by resending the
message until an acknowledgment is returned from the recipient. However,
if the acknowledgment is lost due to an unreliable connection, the
sender may resend a message that the receiver has already received.
We need to ensure that the messaging system is able to safely handle any messages that are received multiple times.
Solution:
Design a receiver to be an idempotent receiver. See
Figure 22.
Figure 22. Duplicate message problem
Interactions:
The term idempotent is originated from mathematics to describe the
ability of a function that produces the same result if it is applied to
itself, i.e. f(x) = f(f(x)). In messaging Environment this concept
ensures safely resent of same message irrespective of receipt of same
message multiple times.
In order to detect and eliminate duplicate messages based on the
message identifier, the message consumer has to maintain a buffer of
already received message identifiers. One of the key design issues is to
decide message persisting timeout. In the simplest case, the service
provider sends one message at a time, awaiting the receiver's
acknowledgment after every message. In this scenario, the consumer
efficiently uses the message identifier to check that the identifiers
are identical. In practice, this style of communication is very
inefficient, especially when significant throughput is required. In
these situations, the sender might want to send a whole set of messages
in a batch mode without awaiting acknowledgment for individual one. This
will necessitate keeping a longer history of identifiers for already
received messages, and the size of the message subscriber's buffer will
grow significantly depending on the number of message the sender can
send without an acknowledgment.
An alternative approach to achieving idempotency is to define the
semantics of a message such that resending the message does not impact
the system. For example, rather than defining a message as variable
equation like 'Add 0.3% commission to the Employee code A1000 having a
base salary of $10000', we could change the message to 'Set the
commission amount $300.00 to the Employee code A1000 having a base
salary of $10000'. Both messages achieve the same result—even if the
current commission is $300. The second message is idempotent because
receiving it twice will not have any effect. So whenever possible, try
to send constants as message and avoid variables in messages. In this
way we can efficiently achieve idempotency.
Service Factory
Problem:
When designing service consumer for multiple styles of communication,
it might seem necessary to define the service for each style, and this
concept can be linked to the Factory Design Pattern [9]. In SOA it's a
challenge to invoke the right services based on the style of
communication.
Solution:
Design a
service factory that connects the messages on the channel to the service being accessed. See
Figure 23.
Figure 23. Service factory
Interactions:
A
service factory may return a simple method call or even a complex remote process invocation. The
service factory invokes the service just like any other method invocation and optionally can create a customized reply message.
Message Facade Pattern
Problem:
Depending on business requirements, you might need to encapsulate business logic flow and complexity behind a standard facade.
Solution:
A message facade can be used asynchronously and maintained
independently. It acts as an interceptor between service consumer and
service provider. See
Figure 24.
Figure 24. Message facade
Interactions:
The client creates a command message and sends it to the message
facade through messaging channel. The facade receives the message (using
a polling consumer or an event-driven consumer) and uses the
information it contains to access business tier code to fulfill a use
case. Optionally, a return message is sent to the client confirming
successful completion of the use case and returning data.
Conclusion
So far we have understood how messaging patterns exist at different
levels of abstraction in SOA. In this paper, which is the first of a
two-part series on messaging patterns in Service-Oriented Architecture,
Message Type patterns were used to describe different varieties of
messages in SOA, Message Channel patterns explained messaging transport
systems, Routing patterns explained mechanisms to route messages between
the Service Provider and Service Consumer, and finally Service Consumer
patterns illustrated the behavior of messaging system clients. In the
next issue of JOURNAL, the final part of this paper will cover Contract
patterns that illustrate the behavioral specifications required to
maintain smooth communications between Service Provider and Service
Consumer and Message Construction patterns that describe creation of
message content that travels across the messaging system.
Copyright Declaration
G Hohpe & B Woolf, Enterprise Integration Patterns, (adapted
material from pages 59-83), (c) 2004 Pearson Education, Inc. Reproduced
by permission of Pearson Education, Inc. Publishing as Pearson Addison
Wesley. All rights reserved.
References
- Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions, Gregor Hohpe and Bobby Woolf, Addison-Wesley, 2004
- Service-oriented architecture: A Primer, Michael S Pallos, EAI Journal, December 2001
- Solving Information Integration Challenges in a Service-Oriented Enterprise, ZapThink Whitepaper, http://www.zapthink.com
- SOA and EAI, De Gamma Website, http://www.2gamma.com/en/produit/soa/eai.asp
- Introduction to Service-Oriented Programming, Guy Bieber and Jeff Carpenter, Project Openwings, Motorola ISD, 2002
- Java Web Services Architecture, James McGovern, Sameer Tyagi, Michael Stevens, and Sunil Mathew, Morgan Kaufman Press, 2003
- Using Service-Oriented Architecture and Component-Based Development to Build Web Service Applications, Alan Brown, Simon Johnston, and Kevin Kelly, IBM, June 2003
- The Modular Structure of Complex Systems, Parnas D and Clements P, IEEE Journal, 1984
- Design Patterns: Elements of Reusable Object-Oriented Software, Gamma E, Helm R, Johnson R, and Vlissides J, Addison-Wesley, 1994
- Computerworld Year-End Special: 2004 Unplugged, Vol. 10, Issue No. 10, 15 December 2003—6 January 2004
- Applying UML and Patterns—An introduction to OOA/D and the Unified Process, Craig Larman, 2001