Looking at example from alternative integration framework

As part of my interrest with integration and Apache Camel, and yes my employment, I keep an eye on Camel alternatives, once in a while.

Recently my twitter search revealed this tweet. Which takes you to a SI Example. Do yourself the favor and check out this example, and return back to this blog post.

Maybe, like me, you started at the sea of XML to try to figure out what the example is trying to tell you? Only by click on the provided diagram to see the larger image, and stare back at the XML for some time you may be able to understand a bit what is happening. Now imagine if there was no image at all, would you be able to understand the integration flow in the example?

If you have Camel experience, wouldn't you think the example could be much simpler and easier to understand, by using Camel? In fact I would say that the Camel DSL would make it out for that image. The Camel DSL would be simple and intuitiv to understand the message flow.

It would be something like this in Camel DSL. Let's pick the XML variation as well.

  <-- this route has 2 inputs -->
  <from uri="jms:queue:foo"/>
  <from uri="file:somefolder"/>
  <-- validate message -->
  <to uri="bean:validateService"/>
  <-- split message ... -->
    <-- ... using a method call -->
    <method bean="enrichmentService"/>
    <-- process splitted message -->
    <to uri="bean:processService"/>
    <-- notify splitted message -->
    <to uri="bean:notificationService"/>

Maybe the code comments in the XML is not needed? Can you understand the Camel XML route without the code comments? If so its only 10 lines of XML to define the integration flow.


Christian Schneider said...

After looking at the two xml examples I think the main difference is that there is a standard flow from one processor to the next in camel. In SI the processors are only connected by the name of the channels. Interesting how such a little difference in design has such a big impact on usability.
Even the diagram is much more confusing than a similar diagram you would have for camel (also because of the default flow).

Btw. when looking at your comments for the xml it would perhaps be a good idea to integrate comments into the dsl. So the comments could even be displayed by toolings.

Claus Ibsen said...

The Spring DSL has a description attribute you can use, so you can do:

But yeah the SI example requires that you would have to apply some best practice how you structure the XML to have it somewhat readable. Its really confusing when all you have to "link" together the integration flow is attribute id's on a bunch of XML tags.

Claus Ibsen said...

Ups comments cant show xml tags, what you can do in Camel DSL is

to uri="bean:validationService" description="The message is being validated"

Mark Fisher said...

Actually, Spring Integration provides a <chain> element for those cases where you do not need or want to explicitly define any channels between components.

SpringSource Tool Suite also provides a visual editor for Spring Integration flows with full round-trip support side-by-side with XML.

Just wanted to point those out to hopefully get a more apples-to-apples perspective here.


Claus Ibsen said...

Thanks Mark.

Are you Mark Fisher by any chance? If so why not go by your name?

The example is still a lot of XML which are poorly structured in terms of revealing an integration flow.

The end user who look at the XML would have to look at 3rd party diagrams or STS tooling to better "see" the flow.

The powerful DSL in Camel allows you to write integration flows which is much better structured and the end user don't have to use 3rd party diagram or tooling.

However on the tooling side. FuseSource is also building an IDE for Eclipse.

Mark Fisher said...

Yes, this is Mark Fisher. Sorry, I was not trying to avoid the full name; it just came from the account settings. I actually try to avoid flame wars between framework developers, since we're obviously more biased than anyone. Besides, I don't know Camel well enough and you don't know Spring Integration well enough to do any truly objective comparison even if we tried in good faith. However, I should just point out that the XML would be virtually identical if using <chain>. There are optional attributes, but only "ref" would be required. Also, Spring Integration flows can be created completely via annotations as well, so in those cases no XML is needed at all (and it works well with @Bean style configuration, something we are extending to a point that will be more DSL-like as well). As far as structure, I typically view it as component-centric (in Spring Integration) as opposed to flow-centric (in Camel). And, there's probably a lot that could be discussed about that, but I doubt if it's very productive for us to debate it considering the bias, as I mentioned above.


Claus Ibsen said...

This blog is no attempt on any flame work or the like.

Just an observation from an SI example, created by an end user. Eg its not created by a SpringSource employee.

That's the interesting fact, the end user, ends up with a poorly structured example, that is hard to understand without any additional help from diagrams, or for example using STS tooling, and maybe sprinkle some more comments in the XML file.

Either that end user was unlucky and didn't use better best practices with SI (maybe using as you mention), or there could be other end users out there creating similar poorly structured applications. Which over time is harder to maintain for the next guy.

Frankly my first read of that example, I thought it was an old example from an early version of SI. Not the latest 2.0. So it took me a bit by surprise.

Glad to know that SI have better solutions. Competition is good. And end users should have choices.


Maybe we can meet up in TSSJS? James and I are going there as well.

Mark Fisher said...

Well, I've got to give you credit... your passive-aggressiveness makes it pretty hard to drop the discussion ;)

I think you and I have very different views about "poor structure". For example, I feel strongly that conditional logic (when/otherwise) and try/catch elements do not belong in XML. Instead, I prefer a clearer distinction between the declarative (config) and imperative (logic) elements of an application. Also, if you have to indent the fluent API elements to understand the control logic, then it's the wrong tool for the job in my opinion (again mixing declarative and imperative). Every Camel example I have seen either has conditional logic in XML or complex fluent API chains that use method invocations as control structures. Both feel wrong to me, but I'll be the first to admit that's subjective.

Spring Integration puts the Message Channel front and center, considering it to be the most important component of EIP and the primary enabler of loose coupling. Obviously, "loose coupling" by definition means everything is not jammed together, but our 'chain' offers a way to create a simple flow for those cases where explicit Message Channels are not needed between components. Because there are so many situations where having explicit channels *is* crucial, I have absolutely no regrets about that design choice.

Finally, as one of the contributors to enabling alternatives to XML-based configuration in the Spring Framework itself, I am very excited about the work we have in progress to do even more of that for Spring Integration applications.

I am looking forward to meeting you at TSSJS. Maybe we can grab a beer and even find something to talk about other than our frameworks ;)


Claus Ibsen said...

Hi Mark

I would like to apologize for using the word "poorly structured". It may seem a bit harsh. Let me rephrase that I think the example is "not good" in terms of maintenance; By that I mean when the next engineer comes by he would have to resort to visual diagrams or special tooling to better understand what it does. Even the original author may have to resort to that if he comes back 6 months later. For the trained SI eyes the example may seem good.

However you can just as easily structure "poorly" Camel applications. In fact it's a generic problem.

I am pointing fingers at the business problem. I am sure the example solves the problem and when you run the application it does that well.

I am only looking at this from the non trained SI eyes and the average engineer who will have to take over or maintain that application.

The good think is that as you said that SI have alternative or other approaches to structure the solution which would improve the example. So maintaining the example would be easier. For someone picking up SI, I would take a look at the examples you ship with the project. And if I want to go further, I would suggest to pickup any of the two SI books, currently in writing.

I share your point of view that SI is component oriented, where as Camel is more integration flow (route) oriented. It's just two different principles for solving the same business problems, using the concepts and patterns from EIPs.

I think one of the key differentiator between the two projects is that Camel is more pragmatic; where as SI is more "theoretical correct" and has a very good and clean design. In fact SpringSource has always been very good at designing APIs which are similar across the products and makes it easier for end users to leverage it. Kudo to Spring for that.

The founders of Camel has a more pragmatic approach. For example the imperative DSL in Camel allows more easily for new users to pickup and be successful with Camel. Their mindset, coming from a Java background, is highly imperative minded.

As error handling is hard, we had end users in the community, asking how to do X in Camel, where they gave a Java example. For that reason we designed to add the try .. catch equivalent into the DSL. I agree from a design principle I would like to separate the integration flows from that. And that's why you can configure error handlers and/or exception clauses, and not "clutter" that into your flows. But that said, sometimes its often easier and faster for users to mimic what they already know from Java, such as the try .. catch.

You can say the same for the condition logic, which is the Content Based Router EIP. I would say it would be confusing for users to force them to use a different mindset for using that pattern, if they can't express the conditions in the flows. At least when using pure Java or XML as the DSL. More advanced languages such as Groovy or Scala (at least for DSL) may allow a more "functional language" declaration for that given pattern.

Continued in next comment ...

Claus Ibsen said...

Continued ...

In terms of "indent" then that's fundamental to nearly all programming languages. Developers use indents, despite the compiler would be able to parse the code without. So structuring the DSL would therefore also use indent. Many imperative programming languages have been very successful and the average engineer understand this logic and structure the code using indents. Why shouldn't he be able to do that in a integration oriented DSL such as Camel?

In fact this is a often a key factor why people who get started with Camel love it, because they can easily transition from regular programming to the DSL. For example if you read this article (15 min): http://architects.dzone.com/articles/apache-camel-integration
Then the new user would be off to a good start with Camel.

In the end its great there is room for different projects in the same space. Choices for end users is always good. And both project are successful and have a great future ahead.

Okay I think its time we end this conversation. Sorry for writing this long comment. I had to break it when it was larger than 4096 chars :)

Yeah lets have a beer at TSSJS. I have been told that its St. Patricks day while we are in town. There should be plenty of topics to talk which is not "our framework" related. Such as writing a book, living as a open source developer, conferences, sports and whatnot.

Claus Ibsen said...

Hmmm I cannot edit my own comment. There is a mistake in this

I am pointing fingers at the business problem. I am sure the example solves the problem and when you run the application it does that well.

It should be

I am *not* pointing fingers at the business problem. I am sure the example solves the problem and when you run the application it does that well.

Mark Fisher said...

Thanks Claus.

IMO, this turned out to be an interesting discussion. It's actually refreshing to see this amount of detail in contrast to the Tweet-sized framework "comparisons" that are all too common despite their inability to provide any degree of meaningful information. I appreciate the fact that even here you exceeded the limit ;)

See you at TSS.