Chapter 2. Foundation structural patterns
In this chapter
- Patterns dealing with services
- Lightweight containers and DI
- Poison messages
Congratulations, you’re in charge of building your first service—now what? The first thing to do, before getting into advanced topics such as making your service secure and scalable, is to take care of the basics. Where will you deploy your service? How do you ensure your service’s reliability? How do you enable anonymous access? And so on.
In chapter 1 we talked about SOA basics: creating autonomous components that publish and accept messages defined by contracts, delivered at endpoints, and governed by policies to service consumers. In contrast, this chapter deals with some foundation patterns—those that solve some of the more common issues related to all services. These are the patterns you’re most likely to use, even if you have modest requirements for your services. Because they deal with fundamental issues, the patterns in this chapter are relevant to implementing the services themselves (see figure 2.1).
Figure 2.3 shows Microsoft’s implementation of the Service Host pattern, called App-Fabric. You can see that AppFabric (the service host) provides added value on top of hosting the services. You also get the means to control the lifecycle of the hosted services, monitor them, and so on.
In addition to application servers, some Java enterprise service buses (ESBs) provide service host capabilities (see also the discussion of the Service Bus pattern in chapter 7). Figure 2.4 shows the components of Fuse ESB, an open source ESB based on Apache ServiceMix. In the circled area you can see the provisioning, deployment, and admin capabilities (based on Apache Felix—an OSGi implementation).
The Active Service pattern, illustrated in figure 2.6, gets its name from the object-oriented concept of active classes. Active classes, as defined in the official UML specification, represent objects that may execute their own behavior without requiring method invocation. The Active Service pattern implements the active class concept at the service level. As a result, the service creates worker threads to handle cyclic events, such as monthly billing, report generation, and so on. A service can use this pattern, become active, and monitor its own health, handling timeouts in addition to handling requests (the Service Watchdog and Decoupled Invocation patterns in chapter 3 utilize this approach).
How can the Active Service pattern help you solve the problems discussed earlier? Sometimes the best defense is no offense—instead of trying to solve the problem, you can avoid the situation entirely. Instead of calling out to external services with each request to the service, you can actively fetch data from other services and refresh the caches according to an independent schedule. This effectively decouples requests to the service from the connectivity and health of the external services you depend on. Similarly, you can proactively publish your own state changes (see the Inversion of Communication pattern in chapter 5).
When applying the Transactional Service pattern, the transaction you make begins within the server, when the request is received. That’s a distinct and important difference from the other option of initializing the transactions from within the service consumer when the request is made. Although transactions that span services and consumers can help with reliability and consistency when the service consumer fails, they also increase coupling in the system. When you extend a transaction beyond a service boundary and hold internal resources for anything beyond the service trust boundary, you introduce security and performance risks. We’ll examine this in more detail in our discussion of the Transactional Integration antipattern in chapter 8.
Implementing the Transactional Service pattern can be easy if the message transport is transaction-aware. Examples can be found in most ESB software (such as WebSphere ESB and Apache ServiceMix), messaging-oriented middleware such as Microsoft Message Queue (built into.NET), any JMS implementation (such as WebSphere MQ or ActiveMQ), or even SQL Server’s Service Broker. The process is for the service to read a message from the ESB or messaging middleware, process it, send new messages to outgoing destination queues, and then commit the transaction to indicate success. If any of the individual components fails, the entire transaction is rolled back.
The Workflodize pattern, as depicted in figure 2.11, is based on adding a workflow engine to the service to drive business processes. The workflow engine hosts workflow instances. The nominal case is one workflow per request type. Workflows can also become quite complex, handling long-running processes with several entry points, where requests and responses arrive from external services.
This means that a subclass can be used in place of its parent class without breaking the behavior of any users of the base class. Applied to SOA, this means that when changing the internal behavior of a service, you don’t need to create a new version of the contract. The new version of the service should meet the expectations that consumers of the original service have come to expect.
The main idea behind the Edge Component pattern, as demonstrated in figure 2.13, is separation of concerns. The edge component is where you take care of all the cross-cutting features, such as auditing, specific endpoint types and contract version mediation, that aren’t part the service’s business logic. The business logic is then handled in a separate component that focuses solely on the business logic and remains free of other concerns. In a sense, the Edge Component pattern provides a façade, or proxy, to a service implementation.
The Edge Component pattern can be associated with two quality attributes: flexibility and maintainability. When this pattern is implemented, it’s easier to change and enhance the external properties of a service without affecting the business logic.
This chapter was the first to present SOA patterns, and it dealt with the foundation structural patterns used to build services:
The next two chapters discuss patterns that address additional requirements, including scalability, performance, availability, security, and management.
David Chappel, “Introducing Windows Server AppFabric,” Opinari: David Chappell’s Blog (blog entry, May 24, 2010), http://davidchappellopinari.blogspot.ca/2010/05/introducing-windows-server-appfabric.html. This article describes Microsoft’s AppFabric, which is Windows Communication Foundation’s (WCF) implementation of the Service Host pattern.
Restlet engine, www.restlet.org/ RESTlet is a web API framework for building REST style services. RESTlet is mentioned in this book as an example of a framework supportive of the Edge Component pattern.