Wednesday, April 23, 2008

Legacy Application Rejuvenation Example

Badis recently asked a good question regarding ways of exposing functions which are implemented by existing applications as part of an SOA:

...I am new to SOA and I work for a group who owns 5 different large web applications. These applications, although, all Java-based, use different technologies. Some are implemented with EJB, others with Spring or home grown frameworks. What is the least-invasive approach to expose these functions as services in your experience.

Before answering this question, there are a number of things that need to be explored. Firstly, I want to just raise a flag regarding terminology here. We do not expose functions within an application as services. A service in the context of SOA is considerably more coarsely grained than a single function within an application. Usually we will find entire applications sitting behind service boundaries.

Before considering how to expose functions in an existing application as part of an SOA, we first need to define our services. Services should be designed from the outside in, not the inside out. That is, we need to understand the service's place in the world before figuring out what goes inside. We want to try and stay clear of a bottom-up Web services integration approach, where services are defined based solely around our existing applications.

Each service should support one or more cohesive business processes. Usually, existing applications do no such thing. They usually embody a number of loosely related business processes that were all brought together to serve a particular purpose at the time the application was built.

Our services need to be identified and defined such that they are aligned with the business. This is the only way we are going to get high cohesion within services and loose coupling between them. Once we have defined our services, then we can then determine to which of these service(s) each of our Web applications belong.

We may find that all five Web applications actually are concerned with the same single service (although this would be unlikely). For example, we may have five different CRM applications for dealing with different types of customers. In this case, all five applications would belong to a single Customer Management service. Although we wouldn't really have an SOA until we added more services. A single tree doesn't make a forest.

When defining our services, we'll very likely be making heavy use of publish-subscribe messaging. In this case, we will update and/or integrate with the existing Web applications not to expose functions as such, but rather to publish events and process event messages when they are received.

We need to evaluate the semantic/functionality gap between our service contracts and the Web application(s) inside each service boundary. Where the gap is very wide and/or we don't want to or can't directly modify the source code of the Web application(s), then we would consider using some kind of EAI tool. Where the gap is very narrow and we are happy to modify the application source code, we can update the application(s) to sit directly on the service bus.

When updating an application directly, which is the situation Badis asked about, we implement a "service interface layer" as part of the application. This layer sits on top of the "application service layer". The application service layer is shared by both the service interface layer and your UI logic (i.e. your controllers in the case of MVC). This allows us to expose the same logic via the UI as well as to other services.

Note that an application service is very different from a service in the context of SOA. I've spoken in the past about how horribly overloaded the term "service" is in IT architecture - this is yet another example.

The service interface layer consists of a number of message handler classes (one for each type of message the application must process) as well as event classes (one for each type of event message the application publishes). This layer would be implemented using the same technology as the rest of the application (EJB/spring/custom).

The application needs some means of receiving messages off the service bus. In essence, the message handlers need to be hosted somewhere. They could be hosted in a Web server (if we are using the HTTP transport), or alternatively you could host your message handlers directly inside an ESB.

In essence, each message handler will be invoked by the infrastructure once the appropriate message is received. The message handler takes over from there.

2 comments:

Blake Caraway said...

Bill,

I'm directing more and more people to your blog for further reading as the posts here clearly communicate the very issues I'm encountering in the wild.

Nice job in this post of describing a common scenario among many businesses today. Agility is a much discussed and sought after thing right now. Doing so can require a break-up of typical LOB-like applications into true services and this is something most technology teams/architects need help with. The information here can really help teams accomplish this.

Good work.

Blake C.

Bill said...

Hi Blake,

It's always great to hear that people are finding the blog useful and relevant.

Cheers!

Bill