The main drivers for the creation of composite-services, as defined in Toward a pattern language for Service-Oriented Architecture and Integration, are:
- Usage simplicity. When several business services are used together by multiple consumers, exposing knowledge about all participating services and their coordination rules to every consumer can make consumer implementation more complex. Creation of composite service, both encapsulating participating services and enforcing the rules of their invocation can significantly simplify their usage.
- Improved reusability. New unplanned solutions can often be assembled from available services. Even though they have been designed for the construction of a specific set of solutions, existing business services can be combined in other ways to implement solutions that had not been anticipated. In addition, the availability of services suggests new solutions that might otherwise not be considered. These new solutions can often be created inexpensively and quickly through development or enhancement of relatively few services.
- Solution partitioning, visibility, control and change management. Composite services can serve as a partitioning mechanism for overall solution. Similar to the case of local and remote interfaces in EJBs, introducing composite services and exposing only some of their interfaces to external users allows to control what is visible to the consumer. This supports the ability of underlying software architectures (composite services implementations) to rapidly respond to changing requirements by changing the implementations of its subordinate services, as well as the interconnection between them with minimal or no impact to the consumers.
In this article we will discuss the main approaches to service composition, both from design and implementation point of view.
Composition DesignComposition design is concerned with designing a solution based on a set of existing services. Its role is to specify a list of services involved in a composition, and the way they interact and the composition topology.
Service interactionsThere are two major design approaches to the composition interactions according to "Service–Oriented Composition in BPEL4WS":
- Hierarchical composition.
- Conversational composition.
Figure 1 Hierarchical service composition
This composition approach is a natural fit for implementing systems, based on the hierarchical decomposition. Every level of hierarchy is implemented as an independent composite service, coordinating execution of lower level (composite) services. It is also a common way of modeling high level solutions in workflow systems by composing a series of activities, each of which may correspond to a lower level business process, or a task to be performed by a person or a program. While any composite service may be monitored or interrupted by the outside system using it, it does not support any other functional interactions1 with the service consumer except for an original invocation.
Although the black box composition approach (hierarchical composition) is a very powerful way of dealing with complexities, there are situations when a consumer needs to control execution of the composite service based on the intermediate execution results of service execution. Such an implementation is supported by conversational composition. In this case the implementation of the composite service is also completely opaque to the service consumer, but selected intermediate execution results are exposed (grey box).
This is achieved by supporting an explicit conversation state (see  for distinctions between conversational and execution state) by composite service and exposing multiple interfaces to a service consumer – one for the initial service invocation and others to get intermediate results and control execution based on them (Figure 2)
Figure 2 Conversational service composition
In this type of composition, the interacting consumer and provider are viewed as peers, exchanging data and control signals.
Both interaction styles are viable ways of compositions design. Usage of a strict hierarchy is a useful approach for modeling of complex business processes, as demonstrated by the success of workflow technology. Conversations, on the other hand, have an expressiveness that makes it easy to capture common business interactions – the acts of negotiation, monitoring of results, and so on – through explicitly modeling the message interactions between a consumer and a service.
The design of composite services does not only require the definition of the service interactions, but also a set of components and topologies for their implementation. There are two major design approaches to composite service topologies ("Service–Oriented Composition in BPEL4WS"):
Mediator-based topology (Figure 3) assumes a single service, called the mediator, which has the specialized role of interacting with the service consumer and controlling the execution of the other services (component services) participating in composition.
Figure 3 Mediator-based composition topology
In the case of mediator-based hierarchical services, the mediator implements an orchestration schema that defines invocation sequence of component services in order to achieve a specified goal within specified constraints. Different approaches, including orchestration language/engine, OWL-S compositions, Petri nets, etc. can be used for mediator implementation.
In the case of mediator-based conversational services, the mediator implements service states and states transitions, based on the consumer inputs. A typical implementation of the mediator is based on the transition systems or finite state machines.
In the case of peer-to-peer topology there is no notion of a mediator service. Every participating service (component service) can execute (partial) composite service (Figure 4).
Figure 4 Peer-to-peer composition topology.
A composition, in this case, is defined as a messaging template and component services can be plugged into it. The target behavior is specified as a family of permitted message exchange sequences, which should be realized by the system. Typically this topology is used only for the implementation of the hierarchical services due to the lack of mechanisms required for support of the conversational state (requirement for conversational interactions implementation).
Composition implementation choices
It seems like the simplest way to implement a service mediator is to use a general purpose programming language (Figure 5).
Figure 5 Programmatic implementation of composite service
Unfortunately, this solution suffers from multiple drawbacks:
- It creates a fairly rigid implementation by hard-coding orchestration aspects of the composite service. Any change to composite service requires explicit reprogramming of the service mediator.
- This approach often leads to "services spaghetti" implementations, where services start invoking other services in ad-hoc fashion. "Services spaghetti" usually creates tight coupling between service implementations. The network nature of services invocation and disparate teams, developing different services, typically leads to situations where "services spaghetti" become impossible to maintain.
- Requirements to implement conversational composite service and synchronization of asynchronously invoked services make the overall implementation significantly more complex, requiring threading support in the composite applications. Requirements to support service context usually require creation of a specialized database for every composite service to support service context.
- The composite services implementation requires implementation of some form of transactional support to ensure correct behavior in the case of failures of participating services.
Despite the fact that there are several frameworks for the implementation of composite service (for example, WS-CAF), the programmatic implementation of composite services does not seem to be the right approach.
Another possible approach to the implementation of composite services is event-based composition. This composition implementation is based on event-based service interactions: service consumers publish events to the publish/subscribe intermediary, which delivers them to the actual service consumers (Figure 6).
Figure 6 Service interaction through Pub/Sub
In this case, the pub/sub engine, as any intermediary, provides a decoupling layer between service consumers and providers, which allows for extremely flexible implementation of composite services. The composite service can be implemented as follows (Figure 7):
Figure 7 Implementing composite service using events
The service consumer sends the initiating event that is delivered (through the pub/sub engine) to a set of services that have subscribed to this event. Every service can, in turn, send another message, which will invoke (through the same pub/sub engine) yet another set of services. This sequence of events effectively creates a composite service. The implementation of composite services through pub/sub has the following characteristics:
- It is significantly more flexible, compared to programmatic implementation. By changing a set of services, subscribed to a particular topic, it is possible to completely change implementation of composite services. Alternatively the same can be achieved by changing the topic to which consumer sends the original event.
- Events-based implementation does not provide a well defined place for the composite service context. This makes an implementation of composite services more complex. One of the solutions is to attach the context data to the events content, which usually makes messages larger, which usually leads to increased network usage and performance degradation.
- Events-based implementation does not provide the notion of the composite service instance, which makes it very difficult to coordinate events, implementing a composite services instance.
- This also makes it very difficult to implement any form of transactional support to ensure correct behavior in the case of failures of participating services.
Figure 8 Implementing composite service using orchestration engine
This implementation improves the programmatic implementation by using orchestration language instead of general programming language for composition implementation. This allows programming/maintaining composition logic using visual editors, tailored specifically to simplify this kind of programming. It also allows utilizing the power of orchestration engines providing built-in capabilities for asynchronous invocations, state management, compensation support, etc. Usage of orchestration engines for composite services implementation provides the following advantages:
- An orchestration language is better suited for implementation of the orchestration, which usually simplifies composite service implementation.
- Additional programming simplification can be achieved through usage of a visual editor.
- An orchestration engine natively supports orchestration instances and context, required for implementation of composite services
- Compensation support, implemented in the orchestration languages, makes transactional support implementation significantly simpler.
Based on the above, out of the three discussed approaches, the orchestration-based implementation seems to be the most viable way for creation of the composite services.
Service composition plays a significant role in SOA implementations by providing the following benefits:
- Improved reusability. The composite service provides a natural way of reusing existing services. It allows service providers to add value through service composition.
- Faster time to market. New solutions can be constructed more quickly. The existence of services at many levels (assuming they are composable) along with a mechanism for combining and managing them allows new services and solutions to be constructed with less time and effort. In particular, operating prototypes can be assembled quickly from existing production quality services.
- Improved security and auditability. The composite service represents a single point of access to the set of underlying services. This single point of access provides a simple way of enforcing service invocation contracts, allowing for controlling and metering the access to the component services.
- Lower duplication. Redundancy is reduced or eliminated. Instead of replicating the same business functionality multiple times, a single business service that implements required functionality can be reused in multiple compositions.
- Improved modifiability. Because the same underlying service can be part of many composite services there is a single place for modifications of the functionality throughout the enterprise. Changes to the component service implementation are available to all consumers using this service.
Finally, we recommend usage of orchestration engines for service composition implementation.
About the author
Boris Lublinsky has over 25 years experience in software engineering and technical architecture. For the last several years he focused on Enterprise Architecture, SOA and Process Management. Throughout his career, Dr. Lublinsky has been a frequent technical speaker and author. He has over 40 technical publications in different magazines, including Avtomatika i telemechanica, IEEE Transactions on Automatic Control, Distributed Computing, Nuclear Instruments and Methods, Java Developer’s Journal, XML Journal, Web Services Journal, JavaPro Journal, Enterprise Architect Journal and EAI Journal. Currently Dr. Lublinsky works for the large Insurance Company where his responsibilities include developing and maintaining SOA strategy and frameworks. He can be reached at email@example.com
1. Ali Arsanjani. Toward a pattern language for Service-Oriented Architecture and Integration, Part 2: Service composition. Developworks, December 2005.
2. Richard Hull, Jianwen Su. Tools for Composite Web Services: A Short Overview.
3. Rania Khalaf, Nirmal Mukhi, Sanjiva Weerawarana. Service–Oriented Composition in BPEL4WS.
4. B. Lublinsky. Defining SOA as an architectural style. IBM Developworks, January 2007
5. Web Services Composite Application Framework (WS-CAF)
Link not working
Orchestration and glue code
I wonder what happens, if you use BPEL or any other orchestration technique when you need some glue code inbetween the service calls. Imagine for example a composed service from several navigation services, where some services return a partial route length in miles and some in kilometer. You don't want to introduce a service just for converting length, do you?
I think there is a little mistake in the text ...
"Another possible approach to the implementation of composite services is event-based composition. This composition implementation is based on event-based service interactions: service consumers publish events to the publish/subscribe intermediary, which delivers them to the actual service CONSUMERS (Figure 6)."
Maybe the correct would be :
service consumers publish events to the publish/subscribe intermediary, which delivers them to the actual service PROVIDERS (Figure 6)."
Re: Orchestration and glue code
Hope this helps.
Re: I think there is a little mistake in the text ...
Re: Orchestration and glue code
I must admit, that I just don't un derstand your answer. I think the question is a good one. Just plugging services together "lego block style" seldom works. There is always a little custom work to do. I agree that a single service view should be exposed to the client, encapsulating the end service, but for me this is nothing other than EAI (enterprise application integration), where I produce a new service that so happens to call out to existing services. Is this what you mean?
Re: Orchestration and glue code
Orchestration of business services for building new solutions - topic of this article. In this case I do not care how business service is implemented and the fact that it internally uses multiple integration services is irrelevan at this point.
Implementation of the business service, based on the integrations - the topic of the question.
This two scenarios are quite different and follow different implementation rules.