Dynamic Interface Adaptability in Service Oriented Software
M. Ketfi and N. Belkhatir
8th International Workshop on Component-Oriented Programming (WCOP'03),
Darmstadt, Germany, July 2003.
Dynamic Interface Adaptability in Service Oriented Software
1. Dynamic Interface Adaptability in Service Oriented Software
Abdelmadjid Ketfi, Noureddine Belkhatir
Adele Team Bat C
LSR-IMAG , 220 rue de la chimie
Domaine Universitaire, BP 53
38041 Grenoble Cedex 9 France
Abstract.
This paper deals with the adaptability in the context of service oriented systems. Static adaptability means
simply the modification of the system constituents in response to new needs or situations. Whereas dynamic
adaptability requires that modifications must be done at run-time without stopping the system and without
affecting its consistency and integrity which is a very complicated task. A dynamic system can be closed or
open; an open system can be either adaptive or self-adaptive. Another comparison criteria between dynamic
systems can be the mechanisms used to support the dynamic adaptability: reflection, reification, mediators,
plugins and so on. It is often said that the different entities composing a service oriented system are
independent, however this is not exactly true because clients need to know at as early as compile-time the
services they have to use. Two main limitations of service oriented systems are discussed in this paper:
syntactic dependencies and the lack of real automated dynamic support. The proposed solution is
implemented for OSGi framework, it enhances the clients/servers independency as well as the dynamic
character of systems.
Keywords: Service oriented programming, Dynamic adaptability, Open systems, Interface compatibility,
OSGi, Connection reification.
1. Introduction
Service oriented programming [1] is one of the evolution facets of object oriented programming. Its
main aim is to focus on the services provided by the different entities that compose a system rather than
focusing on the entities themselves. The innovation is that services can be discovered at run-time and used
to build systems. In general, service oriented systems are based on the use of a service locator mechanism
that constitutes the shared area between service providers and clients. A provider uses the service locator
to explicitly declare the services it takes the responsibility to ensure whereas clients come looking for the
services they need in the service locator.
It is often said that the different entities composing a system are independent, in other words, the
client that uses a service is independent of the server providing it. However this is not exactly true because
clients need to know at as early as compile-time the services they have to use, consequently they are
syntactically and semantically dependent of service providers. Two main limitations of service oriented
systems are discussed in this paper: syntactic dependencies and the lack of real automated dynamic
support. After the illustration by the example of these two limitations, our contribution to provide an
efficient solution is discussed.
First, we explain how it is possible to avoid the syntactic dependencies between the different entities of
a system. Then we show how our solution enhances the dynamic character of systems and resolves
problems like faulty and unavailability of services. This paper is organized as follows: in section 2 we
present the main concepts of service oriented programming and we try to put the light on their
limitations. Section 3 discusses how syntactic dependencies could be avoided between service providers
and clients. The dynamic character of our solution and its automation is presented in section 4 and before
we conclude in section 6 some related work is briefly discussed.
2. Service oriented software
Service oriented programming can be seen as a new emerging programming paradigm for large
distributed and collaborative systems. This paradigm is mainly driven by the networking technologies and
2. aims to reduce software complexity, cost and maintenance. Service oriented paradigm is supported by
many technologies and frameworks like Jini [2], Openwings [3] and OSGi [4]. A complete description of
all these technologies is beyond the scope of this paper, therefore, we will just focus on the main concepts
and mechanisms on which these technologies are based.
Basic concepts
The main concepts related to service oriented programming are:
Components: are the fundamental entities composing a system. Each of them may provide services and
may eventually use services provided by other components.
Contracts: they describe both syntax and semantic of services. A contract shows the way a client could
use a provided service. Two services are semantically compatible if they meet the needs of the same client.
Service Locator: it is responsible of keeping track of all services that are currently available for use.
Service providers willing to offer their services to potential clients must first find the nearby service
locator by means of request message sent to the network.
Figure 1 describes the interaction possibilities between the service provider, locator and user.
Figure 1. Interaction between system entities
Limitations by example
The application example used to illustrate the limitations of service oriented programming addressed in
this paper is composed of two components, a Morse encoder/decoder (MorseED) providing a service
called MorseService and a Morse client (MorseClient). The service defines an operation getCode (respectively
getMessage) to determine the Morse code corresponding to a given message (respectively the message
corresponding to a given Morse code).
Sometimes, some common services can be standardized and their specifications become a shared
knowledge between service developers and users. However this is not always the case and we cannot
imagine the possibility to standardize all services someone may use. This is why service adaptability is
needed to allow a real independence between service developers and users. In our example, suppose that
the client developer does know only that a Morse server may exist and allows to encode and decode
messages but s/he does not know neither the exact name of the service nor the specification of its
operations. Because our solution has been implemented for OSGi, the syntax we will use to describe the
services is Java syntax.
Suppose the client has been developed considering that the Morse service has the following
specification:
1
1
The symbol means that the component MorseClient requires a service called MED_Service.
MED_Service {
public String encode(String message);
public String decode(String code);
}
MorseClient
3. On the other hand, the server developer has designed his server as follows:
2
A natural solution to resolve the incompatibility problem is to either modify the client by using the
MorseService instead of MED_Service or to make the server providing the needed service MED_Service
instead of MorseService. This solution presents many weaknesses:
- The task of modifying any of the components can be very difficult and may be eventual source of
bugs if the number of operations declared within the service is significant.
- This solution is not applicable to the server component if it is already used with its original
definition and not applicable at all in the context of non-stop applications.
Even if the problem of incompatibility is resolved and the client could be connected to the server,
several other problems remain unresolved. For example how to do if the provided service becomes
unavailable. In the next section, we show how our solution deals with these problems.
3. First step towards interface adaptability
We focus in this section on the incompatibility problems between the provided services and the
services effectively expected by clients. The philosophy of our solution is to reify the connections between
clients and servers as explicit connectors. Our reified connectors are very similar to those defined in
ACME [5].
3.1. Reified connectors
Two kinds of connectors can be possible: passive and active connectors. As shown in figure 2, if the
available service matches exactly to the needed one the connector can be passive. In other words the client
is directly connected to the server.
Figure 2. Passive connector
On the other hand, if there is a problem of incompatibility like in our example, the connector must be
active to take in charge the problem of incompatibility. This situation is illustrated in figure 3.
Figure 3. Active connector
3.2. ServiceFinder service
As mentioned above, we have implemented our solution for OSGi. Figure 4 shows the standard
process of searching and using services in OSGi and figure 5 shows how the lookup can be performed via
the ServiceFinder.
2
The symbol means that the component MorseED provides a service called MorseService.
MorseED MorseService {
public char[] getCode(char[] message);
public char[] getMessage(char[] code);
}
MyClient MyServer
MySer MySer
MorseClient MorseED
MED_Service MorseService
4. The ServiceFinder provides a lookup service more powerful than the standard one and is enhanced by
many mapping facilities. It is also responsible to automatically generate the reified connector and to
simulate the exact needed service. By the service mapping, we mean the correspondence between the
service expected by the client and the available service or services. Figures 6-1, 6-2, 6-3 show successive
steps of the run-time mapping related to our application example.
Selecting the replacing service
When the ServiceFinder receives the client query and if the expected service is unavailable, it asks the
user to select one or many services to simulate and replace it. This selection is illustrated in figure 6-1.
Mapping the operations of the old service to those of the new ones
After selecting the replacing services, the user must specify the mapping between operations. To each
original operation, it is possible to associate one or many replacing operations. It is possible to validate
the mapping at this stage if to each operation corresponds just one operation and in each case, the
parameters and the return types of the original and replacing operations are the same. Of course this is
not possible in our example because the parameters and return types do not match.
Service Locator
Client
Server
12
3
Service Locator
Client
Server
12
3
Service
Finder
2’
Figure 4. Standard lookup Figure 5. Lookup via the ServiceFinder
1. Service registration.
2. Service lookup.
2’. Automatic connector generation.
3. Service use.
Figure 6-1. Service selection
1. Compute the replacing
parameters.
2. Call the replacing
operation.
3. Compute the expected
return value.
4. Return the expected value.
Figure 6-2. Mapping of operations
Figure 6-3. Mapping of operations
parameters and return values
Figure 7. Operations call according to
the mapping
5. Mapping the parameters and the return types
If the parameters of the replacing operation are different from those of the expecting one or if the return
types do not match, it is necessary to define explicitly the exact relation between all these information.
On top of the dialog illustrated in figure 6-3 the expected operation is described. The user must specify
to each replacing parameter an expression of the original ones, of course it is possible to use any Java
expression. For example, the first line of the dialog means that the first parameter of the replacing
operation getCode() is equivalent to the expression oldParam_0.toCharArray() where oldParam_0 is the
first parameter of the expected operation. The last line of the dialog concerns the return value. If the
return types of the expected operation and the replacing one are different, it is necessary to specify how
to compute the expected return value starting from the replacing return one. Figure 7 shows how the
mapping can be used when an operation is called.
3.3. Service composition
The example presented in the previous section is just a basic view of the interface adaptability. In
reality the situation becomes more complicated if the expected service cannot be entirely covered by only
one other service. In our example, suppose that there is no service able to guarantee all the functionalities
of MED_Service expected by the client, however, it is noted the availability of four services able all
together to simulate the MED_Service. These services are:
- Message Encoder Service (MES) provided by MessageEncoder: able to replace the message
encoding functionality (operation encode).
- Code Splitter Service (CSS) provided by CodeSplitter: splits a Morse code into many items where
each item corresponds to a letter.
- Letter Decoder Service (LDS) provided by LetterDecoder: takes in parameter a Morse item and
returns the letter corresponding to this item.
- Message Inverter Service (MIS) provided by MessageInverter: allows to invert a message. This
service is necessary if we suppose for example that the Morse codes sent by the client are inverted
for security reasons.
As illustrated in figure 8 the decode operation for example is simulated by three replacing operations.
The user must then specify a script to express how to do when the decode operation is invoked and how to
compute the return value if it is needed. It is important to note that the more complex part of the script is
automatically generated and that the user has to precise only the semantic part. Figure 9 shows a possible
user script for our example.
Figure 8. Multiple operations mapping
Figure 9. User mapping script
6. 4. Dynamic adaptability
This section discusses the dynamic character of our solution. One way to make an application dynamic is
to code all possible modifications and scenarios within the application. This solution implies a very heavy
burden on the developer shoulders. In our solution all the tedious work related to the dynamic adaptation
is separated of the application. It is included in a special service called DynamicAdaptor. This service
provides a unified adaptation interface that allows users to control the application at run-time. For
example thanks to the DynamicAdaptor it is possible to replace a component by another, to transfer the
internal state from the old component to the new one, to passivate or to activate components. Obviously
the functionalities offered by the DynamicAdaptor are closely related to the capabilities of our reified
connectors. For example a connector must at least support the dynamic reconnection towards new target
services. Because they have to deal with unforeseen situations, our connectors are aware of all possible
change at run-time. If for example a target service becomes unavailable the connector may take the
decision to dynamically reconnect to another potential service. It can also take the decision to just inform
the user depending on the adopted adaptation strategy. A dynamic adaptation may be triggered manually
or automatically by sensors that spy the evolution of the execution environment.
It is important to note that the adaptation is performed without stopping the application and especially
that it is transparent to the client. However because the client is not conscious of potential dynamic
adaptation, it continues naturally to send requests even the service to which the requests are sent becomes
unavailable. The connector takes the responsibility of preserving the client requests and guarantees that
these requests will be sent to the new replacing components and of course in the correct order.
5. Related work
Many academic works deal with the problem of interface adaptability and conversion between types. In
[6] the proposed solution is based on transparent adapters and concerns Jini-based systems. The role of an
adapter is to convert a provided service to another service expected by the client. The solution is
materialized by a special service called ‘Adapter Service’ always present in the Jini lookup service and acts
as a repository of adapters. When a component registers a service S1, the Adapter Service is notified and
registers a new service supposed adapting the original service S1. Like our approach, this solution is
flexible insofar as it does not hardly modify the Jini framework. However we think that this solution is less
dynamic because it is necessary to know before launching the client what is the exact service that will be
effectively provided, and to write by hand a kind of wrapper to be plugged in the service locator side.
Also the solution neither it takes in charge the problem of unavailability of services nor it allows to
combine services to obtain the expected one. Another work [7] has tried to address practically the same
problem by clearly separating the semantic of a service of its syntax. The authors have focalized on two
issues: how to identify a service compatible with an expected one and what are the mechanisms to invoke
this service. The semantic equivalence is materialized by a human-mapping between services. The
possibilities of service composition are not considered, also the solution is less transparent because the
client must manage by itself the problem of service compatibility. To the best of our knowledge, many
solutions address the problem of interoperability between incompatible services using mapping and
adapting techniques, however few works were interested in the consistency and the dynamic character of
systems.
6. Conclusion
In spite of their efficiency, service oriented frameworks are based on a strong assumption which is the
interoperation via standardized interfaces. This assumption makes their use much less easy and strongly
rigid. In this paper we proposed a solution to enhance the independence between the application
components and to make it possible to develop applications without the obligation to have standard
interfaces. The aim of the paper is also to demonstrate the possibility to transparently deal with the
problem of interface incompatibility without the awareness of clients and with a minimal participation of a
human-actor for semantic purposes.
7. We have first explained by an application example the general limitations of service oriented frameworks,
namely the syntactic dependencies and the lack of automated dynamic support. Then we have presented a
solution based on the reification of connectors between components. We have shown that taking into
account the connectors at conceptual level allows the control and the adaptation of the application
architecture transparently without the participation of its components.
It is important to note that the adaptability of interfaces is only one facet that dynamic systems must deal
with. A dynamic system must also answer many other requirements like how to transfer the state of a
replaced component into the replacing one(s), how to define this state, how to know and specify the
correspondence especially when the structure of the replacing component is completely different, what is
important to do to affect the adapted system as minimum as possible, how to guarantee its consistency
and integrity, how to evaluate that the adaptation has been correctly performed and how to do if not. In
recent works [8, 9, 10], we have tried to answer most of these questions by a conceptual support
reinforced by many experimentations. Currently we are working on an MDA-like approach to specify the
dynamic character of a system at a meta-level based on many techniques like meta-modeling and
reflection. The main aim is to work at a level independent of a specific component model and a specific
technology in order to validate and to make our research results more general.
Bibliography
[1] Bieber, Guy and Carpenter, Jeff, “Introduction to Service-Oriented rogramming (Rev 2.1)”
http://www.openwings.org/download/specs
[2] K. Arnold, B. O’Sullivan, R. W. Scheifler, J. Waldo, and A. Wollrath. “The Jini Specification”. Addison
Wesley, 1999.
http://www.jini.org
[3] Bieber, Guy and Carpenter, Jeff. “Openwings - A Service-Oriented Component Architecture for Self-Forming,
Self-Healing, Network-Centric Systems (Rev 2.0)”
http://www.openwings.org
[4] OSGi
http://www.osgi.org
[5] The Acme Architectural Description Language
http://www.cs.cmu.edu/~acme
[6] Julien Vayssière, “Transparent Dissemination of Adapters in Jini”, Proceedings of DOA'01, the third
International Symposium on Distributed Objects & Application. Rome, Italy, September 2001.
[7] Shankar R. Ponnekanti and Armando Fox. “Application-Service Interoperation without Standardized
Interfaces”, Proc. IEEE International Conference on Pervasive Computing and Communications
(Percom 2003), Dallas-Fort Worth, TX, March 2003.
[8] A. Ketfi, N. Belkhatir and P.Y. Cunin. “Automatic Adaptation of Component-based Software: Issues and
Experiences”, PDPTA'02, June 2002, Las Vegas, Nevada, USA.
http://www-adele.imag.fr/Les.Publications/intConferences/PDPTA2002Ket.pdf
[9] A. Ketfi, N. Belkhatir and P.Y. Cunin. “Dynamic updating of component-based applications SERP'02”,
June 2002, Las Vegas, Nevada, USA.
http://www-adele.imag.fr/Les.Publications/intConferences/SERP2002Ket.pdf
[10] A. Ketfi, H. Cervantes, R. Hall, D. Donsez. "Composants adaptables au dessus d'OSGi", Journées
Systèmes à Composants Adaptables et extensibles Octobre 2002, Grenoble, France.
http://www-adele.imag.fr/Les.Publications/intConferences/JOURNEES2002Cer.pdf