The Role of Middleware in Architecture-Based Software Development
International journal of software engineering and knowledge engineering
Software architectures promote development focused on modular functional building blocks (components), their interconnections (configurations), and their interactions (connectors). Since architecture-level components often contain complex functionality, it is reasonable to expect that their interactions will be complex as well. Middleware technologies such as CORBA, COM, and RMI provide a set of predefined services for enabling component composition and interaction. However, the potential role
... f such services in the implementations of software architectures is not well understood. In practice, middleware can resolve various types of component heterogeneity -across platform and language boundaries, for instance -but also can induce unwanted architectural constraints on application development. We present an approach in which components communicate through architecture-level software connectors that are implemented using middleware. This approach preserves the properties of the architecture-level connectors while leveraging the beneficial capabilities of the underlying middleware. We have implemented this approach in the context of a component-and message-based architectural style called C2 and demonstrated its utility in the context of several diverse applications. We argue that our approach provides a systematic and reasonable way to bridge the gap between architecture-level connectors and implementation-level middleware packages. not only do they implement complex functional parts of the system, they may also be implemented by different organizations, written in different programming languages, run on different platforms, and have divergent expectations about the properties of systems of which they are a part. This leads to the well-known problems of component integration and architectural mismatch. Being able to connect software components in spite of such heterogeneity and then reason about their interconnections is vital for successful system integration. Most software architecture research has focused on modeling and creating systems with explicit software connectors. These connectors are first-class software entities and facilitate the communication among two or more components. At the architectural level, connectors are high level abstractions that prescribe properties of component interconnections. Having these prescriptions available at design time facilitates modeling and analysis of the software system's design. Depending on the nature of the application, software connectors may be simple (a UNIX pipe or a local message bus) or complex (flexible publish/subscribe connectors across machine boundaries). These connectors are often part of a larger architectural style -a set of design constraints and patterns that elicit well-understood, beneficial system properties  . Unfortunately, to date, few approaches to architecture-driven development have explored how to implement connectors that match the architectural properties specified at design-time. Implementation-time connection of heterogeneous software components has traditionally been the domain of middleware  . Different kinds of component heterogeneity can be (partially) resolved by off-the-shelf middleware solutions like CORBA , COM [33, 37] , and JMS  . Middleware can help system integrators and architects to integrate components across platform, language, and machine boundaries. However, using middleware often induces certain architectural constraints on a system that may not be desirable  . For instance, using RPCbased middleware like CORBA implies that all components must communicate using RPC. This can have widespread effects on the design and analysis of any CORBA-based system. The properties of middleware may or may not match the properties of a connector specified in a software system's architecture, leading to mismatch between a software system's implementation and its design. The relationship between architecture and middleware and their respective shortcomings suggest the possibility of coupling architecture modeling and analysis approaches with middleware technologies in order to get "the best of both worlds". Given that architectures are intended to describe systems at a high-level of abstraction, directly refining an architectural model into a design or implementation may not be possible. One reason is that the decision space rapidly expands with the decrease in abstraction levels: at the design level, constructs such as classes with attributes, operations, and associations, instances of objects collaborating in a scenario, and so forth, are identified; the implementation further requires the selection and instantiation of specific data structures and algorithms, interoperation with existing libraries, deployment of modules across process and machine boundaries, The Role of Middleware in Architecture-Based Software Development 369 and so forth. One proposed solution to this problem has been to provide mechanisms for refining an architectural model into its implementation via a sequence of intermediate models [4, 22, 28, 29] . However, the resulting approaches have had to trade off the engineer's confidence in the fidelity of a lower-level model to the higher-level one against the practicality of the adopted technique  . Furthermore, to a large extent, the existing refinement approaches have failed to take advantage of a growing body of existing (implemented) components that may be reusable "as is". This paper pursues another strategy. We view software connectors as pieces of software that provide a service that connects components. This service has welldefined and well-understood properties, as specified at the architectural level. A middleware solution, or a combination of middlewares, can be used to facilitate implementation of this connector. Thus, the connector's properties influence the choice of middleware, rather than the middleware's characteristics affecting the properties of the connector. For example, a connector that uses message-based communication will probably be easier to implement using message-based middleware than using RPC-based middleware (although it is possible to use RPC-based middleware for this purpose, as we will show). The middleware used to implement a connector can also be influenced by other factors such as cost, ease of deployment, and implementation-level concerns like programming languages or platforms. An RPC-based connector that is used to connect Java components suggests that RMI is a better middleware than, say, COM. Thus, we hypothesize that component interconnections can be designed at the architectural level and then facilitated by middleware, rather than having the choice of middleware constrain the connections between components. We have conducted a series of case studies to validate our hypothesis. A specific architectural style, C2, has been used as the basis for this investigation [24, 36] . In evaluating our approach, we learned several valuable lessons about integrating middleware into software connectors. Our results are promising and indicate that a successful marriage of architecture-and middleware-based techniques and technologies is indeed possible. The rest of this paper is organized as follows: Section 2 discusses background material related to connectors and middleware. Section 3 discusses our approach in detail. Section 4 describes the applications we built using our approach and the lessons we learned from building these applications. Section 5 addresses general lessons learned and future directions for this work. Section 6 finishes the paper, covering the conclusions from our work. Background Exploring the relationship between software architecture-level connectors and middleware requires an understanding of existing architectural models for software connectors and the capabilities of modern middleware systems.