Over the past several years I’ve become wildly enthusiastic about certain “trends” in software development that promote clean, agile, distributable code. The primary buzzwords I’m referring to are “SOA” (Service Oriented Architecture) and “Dependency Injection”. Heck, I’ll even throw “SOAP” into the mix, even though that’s a more specific protocol.
If I talk to other developers about these things, they look at me funny or they show disinterest or suspicion. I think some people think I’ve gone crazy over some trendy buzzwords (i.e. pointy-haired-manager syndrome) and am just trying to evangelize some lame trend that will come and go. Or there’s the classic “SOAP? Oh yeah, I tried to do something with that and got so confused and just hated it. *shiver*”
(By the way, SOAP may have some hard-to-parse standards, and the WSDL can be daunting and confusing, but it’s really simple: you are taking your XML request and wrapping it in a simple envelope that is often nothing more than a single parent <soap> tag! There are some provisions for allowing messaging meta-data to be added in a header section, but all that stuff is optional. Anyway, if you are one of those people who is afraid of SOAP, take a second look; it’s not all that bad.)
Dependency Injection and Service Oriented Architecture are interesting topics in that they really should be easier to explain. I’ve read so many books and articles, and authors have written a lot of insightful material, but I haven’t run into anyone who has been able to expose the inherent simplicity behind these things. Well, I might my hand at the task someday, but not in this blog posting. My purpose is a bit more specific… to share an insight about Service Component Architecture.
About two years ago I attended a rather nice full-day IBM training event called “BPM in a Day” where they showed their WebSphere Orchestration and ESB solutions. I had just finished my week-long SOA Architect training, so I was rather excited about seeing this sort of thing in practice. I had also spent a lot of time reading about SOAP and wanted to play around with writing some nice simple Web Services and to see how easy it was to wire them up. It’s also worth mentioning that I’ve been fascinated with the idea of writing workflow software that helps people work together in a more efficient, “orchestrated” fashion. So I was interested in seeing the BPM (Business Process Modeling) stuff and less interested in the ESB (Enterprise Service Bus) stuff.
Some of the training focused on IBM’s ESB solutions, and they started talking about SCA (Service Component Architecture) which struck me as strange and confusing. I wanted to get to writing SOAP services and sending messages around between them, and I didn’t want to have to learn another damned technology in order to do this! And since this seemed to be a big IBM push, but not necessarily the universal way that messaging was designed, I pretty much filtered everything out.
About 18 months later I came across the JBoss SwitchYard project. I had been doing a lot with Dependency Injection, which really has saved me from hairy problems that plagued some earlier projects. I love the idea of simply declaring a dependency with a simple @Inject tag and knowing it will be in place at the right time within the right context, and that I don’t have to worry about creation or destruction. (It’s amazing how easy it is to write thread-safe resource pools!) By the way, this is a real motivating excuse for moving to JSF 2 if you haven’t already. Just assume your controllers are going to be available and access them via clean and simple EL expressions!
Then I saw an example of a Web Service been accessed via a simple @Service tag, and I had one of those OMG moments. Rather than worrying about a bunch of JAX-WS code and managing connections, just declare the object (an interface of course, never an implementation!) and call some simple and regular methods. Your code is clean, your functional aspects have been isolated, everything is so much more testable.
After trying to puzzle through Camel or ServiceMix for ESBs, this seemed so much cleaner and more modular. I was so excited, I blogged a little bit about SwitchYard, claiming it was the most innovative thing. Several months later (just a few weeks ago) I was looking at the announcement of the 0.5 release and I saw a familiar diagram… it was an SCA diagram like the ones I saw in my IBM class!
What I find really strange and confusing is that the SwitchYard homepage’s “preamble” does not say “SwitchYard is an eventual JBoss ESB replacement that is based on SCA.” If they said it in so many words, it would have been much easier for technology people (i.e. Solution Architects) to evaluate it. But then again, maybe they found SCA as confusing as I had eighteen months ago, and decided to say what SwitchYard did rather than what it was. (Like I did about SOAP at the top of this blog post.)
Okay, so if you’re reading this, you might be getting mad at me because I’m not offering a description (hypocrisy!) of SCA. I’ll give you a very broad, high-level description, and then someday I’ll write some articles, or maybe I’ll get to publishing my second book….
Anyway, let’s start with SOA and Dependency Injection. These are two sides of the same coin. The idea is that you write your functionality as modularly as possible. Think Lego blocks that you’re assembling one way today, but you just know that someone is going to need the thing to do all sorts of crazy stuff tomorrow. They need to be able to unplug and re-plug in some other fashion. And these blocks are “services” in that they do something. They are part of the controller layer in terms of MVC. In other words, this is primarily about business logic.
With SOA, these services are self-contained entities that may or may not live on the same computer or VM. I think the easiest way of thinking of them are atomic entities that you could put in “the cloud” (buzzword alert!) if you wanted. They don’t care about platform or architecture or physical location. They are made to use and be used by other services without knowing any specifics beyond their contract (interface). In fact, when you use Orchestration (BPM) or an Enterprise Service Bus (ESB), these services really don’t know what other services they are interacting with. The big-ol’ Lego Block Blueprint is kept in some external configuration file.
Dependency Injection is kind of the same thing, but your services and clients (dependencies and dependents) are simple class objects that live within a single VM. They have the same service agnostic quality (they intentionally know nothing about how they are plugged into each other) which enhances reusability. But they don’t try to route everything through messages—that would be insanely inefficient. They are bound together just like any O-O class objects, but the binding is all late binding and it has been done by an overriding framework.
In a way, SOA and DI are like Micro and Macro universes. SOA components will often (although not necessarily) be external to each other. If you make everything use SOA, breaking your pieces down as atomically as possible, you are going to necessarily start creating a whole lot of “chatter” on your localhost TCPIP stack. Some ESB systems (ServiceMix and Mule) solve this by having a sort of virtualized “internal” bus for all the local services and a separate “external” bus for the traffic that has to go through some transport, like JMS or SOAP.
Dependency Injection, on the other hand, has the problem that it doesn’t extend outside the VM. If some functionality is provided by an external service, you have to create the object that handles the communication and any other implementation details. It’s not too hard to do, and fortunately, DI does allow you to keep these details in their own isolated place so as to not contaminate the rest of your code.
Service Component Architecture (SCA) is the marriage of these two things. It essentially recognizes that some of your building blocks are going to be local, others are going to be external, all of them need to be as reusable as possible, and their internal/external exposure may change over time. In other words, it’s a SOA orchestration of services that is a fluid hybrid between the two worlds. Your code will periodically use a @Service tag to declare a service dependency. And some XML configuration file will help map out the ESB-specifics of (a) exposing necessary services or service compositions to the outside and (b) getting access to outside service dependencies that you’ll need.
I think that’s pretty much it. The specification gets a little confusing (I hate the diagrams!) and things get muddled with the terminology of “components” which are (I think) the internal non-SOA-exposed services. But in a nutshell, I think that’s what it is.
Interestingly, I think SCA is best understood by looking at examples. Here the SwitchYard User’s Guide does a pretty great job. Jump to the Bean Services section for the cleanest, simplest example, but then look around at how simple it is to add Camel Services or BPM or BPEL orchestrations… each example is clean and simple and easy.
I’m a little embarrassed that I thought the JBoss people invented SCA. But I still think they are doing a wonderful job of honing it, making it as simple and easy to deploy as possible, and there are a lot of innovations that they can lay credit to. It will be nice to see their new ESB solution be so lightweight and flexible, which is something you definitely can’t say about the current JBoss ESB platform. (Anything that dictates what version of Application Server you use should raise suspicion!) And I’m relieved to know that this stuff is standardized—that anything I do with SwitchYard will be able to work, with minimal translation, with IBM or any other SCA-compliant vendor.