|
9.1. Software Buses and the Service BusPeople often use the term software bus to refer to the technical infrastructure of the distributed environment. We consider a software bus to be analogous to the well-known concept of a hardware bus. Much as a hardware bus enables the integration of hardware parts from different vendors, for example when assembling a desktop computer, a software bus is the standardized way of hooking together any software components. 9.1.1. BASIC CONCEPTS OF A REAL-WORLD SERVICE BUSThe most widely known software bus is OMG's CORBA, essentially a communication infrastructure for individual object instances. The CORBA infrastructure enables an object to locate any other object on the bus and invoke any of that object's operations. The CORBA model does not make a strict distinction between clients and servers and is essentially a symmetrical bus. CORBA is a very mature technology, but unfortunately, its underlying concept leans itself to a very fine-grained communication infrastructure that created a history of maintenance and performance problems in many projects. Whereas CORBA is very generic bus technology with a focus on object orientation, another concept of a software bus recently emerged called the Enterprise Service Bus [DC2004]. Although as of this writing, it cannot be considered anywhere near a standard, its main elements are a coarse-grained XML communication protocol together with a message-oriented middleware core to perform the actual message delivery. A number of other software buses are on the market, among them the Enterprise Java Beans as part of the J2EE specification, Microsoft's .NET, and various messaging products, including IBM MQSeries and Tibco Rendezvous. All these buses require standardization on a single interaction and communication model, as shown in Figure 9-1. For example, CORBA and EJB promote synchronous object-oriented communication, whereas messaging products such as MQSeries support asynchronous document-oriented communication. Figure 9-1. Ideal software bus that supports a single communication model. All applications must conform to the same standard, such as CORBA or MQSeries.In a real enterprise application landscape, a single communication model will hardly suffice. Instead, you will need various communication models based on the requirements of the individual application. Vendors have long understood this point, and they provide environments that support multiple communication models at the same time. The J2EE environment, for example, supports various communication types, as shown in Figure 9-2. EJBs provide synchronous object-oriented communication, the Java Message Service (JMS) provides messaging, the system supports communication using email and SOAP, and the Servlet specification provides general support for HTTP applications. Figure 9-2. A software bus that supports various communication models at the same time, such as synchronous, asynchronous, or file-based communication.In the real world, the situation is usually even more complicated because products from different vendors that support similar communication models are often in use at the same time. This situation can arise when different departments of the company introduce competing technology or when a new technology enters the environment as the result of a merger or acquisition. A typical enterprise "software bus" will usually look like that depicted in Figure 9-3. Figure 9-3. The infrastructure of a real-world enterprise will normally consist of various products that support similar communication models.Of course, single applications might use various communication models when communicating with each other. For example, an application might call another one using a synchronous technology if an immediate answer is required and might use an asynchronous communication model if it requires guaranteed and reliable delivery. However, no matter what technology you use, an enterprise SOA infrastructure must conform to certain standards across the board in order to achieve certain goals, such as security and auditing that is independent of the product or the network protocol. In this respect, a service bus is not like a general software bus. An enterprise must create a higher-level entity, some kind of Über bus or Meta bus that endorses all the various products and technologies of the enterprise.
This is why most of the products available on the market cannot be considered service buses in their own right. Instead, they fall into oneor bothof two categories: communication frameworks and execution containers. Communication frameworks are essentially infrastructures that only facilitate communication without many additional infrastructure services. Practically all communication frameworks are built around the concept of a stub and a dispatcher. Typical communication frameworks are MOM products and plain remote method invocation frameworks. Execution containers provide much more sophisticated infrastructure support, including support for transactions and security. Typical execution containers are CORBA and the EJB container. However, do not develop this meta bus in isolation from concrete application projects. Avoid keeping the concepts too abstract; do not build too many technical features into it initially. Chapter 12, "The Organizational SOA Roadmap," describes how and why you should develop an SOA infrastructure gradually, hand-in-hand with concrete business application projects. Chapter 16, "Credit Suisse Case Study," discusses a case study, outlining how a company introduced a synchronous Information Bus (CSIB), an asynchronous Event Bus Infrastructure (EBI), and a file transfer-based Bulk Integration Infrastructure (BII), all driven by the demand from application projects, which in turn were driven by concrete business demands. 9.1.2. SERVICE STUB AND DISPATCHERA service stub is a piece of software that is located at the client side of a service (see Figure 9-4). It provides a local API that presents a convenient access method for the remote service. The service stub encapsulates technical functionality such as handling of the network and application protocol, marshalling and unmarshalling of data, and standard security mechanisms. Figure 9-4. A service stub represents the service for a client. It provides a convenient API that the client developer can easily use. The service stub encapsulates the complexity of the technical access of the service such as network protocol, marshalling and unmarshalling of data, standard security mechanisms, etc.The service dispatcher is the counterpart of the service stub. It receives incoming network requests that are generated by the service stub. The service dispatcher analyzes these requests technically and invokes the requested operation with the appropriate data. 9.1.2.1 Code GenerationCode generation is a powerful technique that can be applied to SOA projects in an efficient manner. In such a scenario, the code generator encapsulates all technical knowledge regarding distribution and service invocation. The application developers can focus on the business aspects of interface definition, while the code generator covers technical issues. Code generation decouples the functional code from the technical code. It provides support for different programming languages, various network and application protocols, and different operating systems with a single code base. Code generation can be used to generate test clients and test serversa handy feature that can prove beneficial for the overall development process. Last but not least, code generation typically increases the quality of the technical code. Contrary to handcrafted code, the generated code will be uniform. Improvements in generated code (e.g., better marshalling or connection management) can be made without causing an impact on current applications if the changes are restricted to the inside of the API of the generated code. Projects that do not use code generation often suffer from a cut-and-paste syndrome. In this scenario, developers of business functionality integrate one functioning version of the technical code into their implementation of the business logic. This code will be repeatedly reused, while slight changes to that code can lead to many different implementations of the same technical functionality.
Basically, you can use code generation in a top-down or bottom-up fashion. Whereas top-down code generation is based on formal interface definitions such as IDL or WSDL, the bottom-up approach analyzes the source code of the service implementation. A typical candidate for top-down code generation is CORBA, where stubs and skeletons are generated from IDL interface definitions. Many modern Web service frameworks, such as .NET or J2EE application servers, support bottom-up mapping of existing APIs (e.g., Java classes) to Web service interfaces (WSDL), often using a combination of internal code generation and reflection. 9.1.2.2 Top-Down ApproachThe precondition for top-down code generation is the usage of a formal interface definition language such as IDL or WSDL. Using a formal interface definition language has a great impact on the development process. It decouples the formal description of interfaces from the actual coding. As illustrated in Figure 9-5, this decoupling enables development teams to simplify the coordination of the service programmers and their clients. Figure 9-5. Code generation is a powerful mechanism to increase development productivity and quality. The code generator encapsulates the technical complexity of the communication between client and service. This enables the developers of both client and service to focus on the functional code.9.1.2.3 Bottom-Up ApproachCode generation can also be performed using low-level implementation APIs (e.g., Java classes or CICS transaction programs) rather than from abstract, implementation-independent interface definitions (see Figure 9-6). Figure 9-6. Bottom-up code generation is based on the service implementation. It is therefore dependent on a specific programming language and the details of its runtime environment and implementation technique. The code generator can use a service description language such as WSDL as an intermediate representation.This technique is particularly useful when transforming legacy applications into services. If existing code must be exposed as a service, the generation of the service interface can save a lot of development time. The caveat is that we get service interfaces that are programming language-specific, technology-focused, and very fine-grained. This is particularly true for the transformation of the traditional application with terminal-based user interfaces such as VT3270. The user screens, which are the natural structural elements of these applications, might be of an inappropriate granularity for a service interface. The bottom-up approach can also be applied to the development of new applications. Although there is no explicit representation of the interface in a formal document, the careful design of the interface is still pivotal and cannot be omitted. With the bottom-up approach comes the danger of ad-hoc design, although there are also benefits to this approach. For example, no additional development tools are required for the design of the service. The developer of the service can use the preferred development environment and modeling tools that are used for the development and design of the original code. If the code generator is integrated into this environment, you can achieve very short turn-around times. The bottom-up approach leverages a development model that is driven by the implementation of the services. Very efficient development environments exist that support the bottom-up approach such as Microsoft's Visual Studio .NET. The downside of such efficiency is a high degree of technical dependencies that could result in a technology lock-in that jeopardizes all the flexibility that should have been leveraged using the SOA approach. Therefore, you should take care when deciding whether to employ a bottom-up or top-down strategy.
9.1.2.4 Code Generation With MDAModel Driven Architecture (MDA) is a contemporary approach to managing technology-independent service specifications, and implementing and managing "SOA meta-bus" architectures, as described in Section 9.1.1. MDA is the umbrella-term for a number of specifications that are currently standardized by the Object Management Group (OMG), including UML, XMI, and MOF. MDA leverages UML to specify Platform Independent Models (PIMs) and Platform Specific Models (PSMs). In MDA terms, a PIM is the formal specification of the technology-neutral structure and function of a system, while a PSM adds the technical details which are needed for the concrete implementation of a software component. The Meta-Object Facility (MOF) is at the heart of the MDA concept. MOF-based meta-models allow the implementation of model repositories, the exchange of models (via XMI), and the transformation between different models, e.g. from a PIM to a PSM. While not limited to code generation techniques, MDA is well suited to using these techniques by generating the mapping from an abstract model to a concrete model implementation. MOF is particularly well suited to define and implement model transformations. A number of tools and standards support the transformation of MOF meta-data, e.g. transformation of UML models into XML, CORBA IDL, Java, and lately into WSDL. This allows for the implementation of very sophisticated code generators, which can generate highly targeted code, as shown in Figure 9-7. Figure 9-7. MDA can be a good basis for the "SOA meta-bus," providing platform-independent service definition and model transformations that support a wide range of middleware and SOA infrastructure platforms.In the light of our discussion on "top-down" versus "bottom-up" code generation (refer to the previous section), technology-independent service definitions would be usually defined in a top-down fashion as a PIM, representing only business functionality. MDA tools can then be used to generate platform specific service interfaces, e.g. in CORBA IDL or WSDL. In many cases, MDA tools will be used in combination with existing code generators, e.g. CORBA IDL compilers or WSDL compilers. However, most MDA tools go beyond the generation of service stubs by supporting the generation of prototypical service implementations, GUI descriptors, SQL code, etc. While MDA is a very powerful concept, it is clearly not a "silver bullet": Like any other technology, MDA depends on a specific set of standards and tools. However, with its focus on model transformation, MDA in combination with SOA could help especially those enterprises which are suffering particularly badly from application and middleware heterogeneity. 9.1.3. EXECUTION CONTAINERSThe execution container is the runtime environment for the service implementation. Most runtime environments for enterprise software also provide appropriate containers for services, mainly because they can provide guidanceand sometimes solutionswhen catering for the technical challenges that we describe in this chapter. Although the formal definition of container was coined with the emergence of the Enterprise Java Beans (EJB) standard, many older application platforms provide similar features for efficient, secure, and transactional execution of service requests. These include transaction monitors such as CICS, distributed object systems such as CORBA, Web application servers (Servlets), and database management systems (stored procedures). The following summarizes the generic feature set of an execution container:
In Sections 9.2 to 9.4, we discuss some of the aforementioned aspects in more detail. 9.1.3.1 Cross-Container IntegrationIndividual execution containers often provide a rich out-of-the-box functionality that makes the development, deployment, and management of individual services reasonably straightforward. However, almost all enterprises suffer from "middleware overload." They must deal not only with a multitude of incompatible applications but also with the existence of many different application platforms and communication middleware systems. In most enterprises, many different types of execution containers can be found, ranging from modern .NET, Java Servlets, and EJB containers to mainframe transaction managers such as CICS and IMS. The key challenge of an enterprise SOA is to define an architecture that enables applications to use different services independently of their container. Although simple service interoperability can be achieved relatively easily through interoperable messaging protocols such as IIOP or SOAP, the challenge is to connect services that reside in different containers beyond simple request/response interoperability, including security and transactionality. Figure 9-8 provides an example of a customer and flight booking system deployed across multiple service platforms. Figure 9-8. In a system where services are implemented on incompatible execution containers, one must introduce a horizontal infrastructure layer that manages technical cross-container integration of services. If this cannot be deployed as a technology layer, it is necessary to incorporate appropriate design principles and procedures to each container in order to address the related problems.In some cases, the introduction of an external horizontal infrastructure layer can automate some of the tasks of integration services across container boundaries at the technical level. However, this is often impossible, and more flexible solutions must be incorporated into the system. In particular, the problem of data and process integrity across container boundaries is a difficult one. Although technologies such as X/Open-based transaction monitors can enable transaction processing across multiple distributed and heterogeneous systems, these technologies are often impracticable due to the many technical and organizational limitations (see Chapter 8, "Managing Process Integrity"). |
|