Jesper Boeg on Priming Kanban
In this interview, Jesper Boeg, author of the new InfoQ book – Priming Kanban, discusses the keys to using Kanban effectively, and how to get started if you are currently using other approaches.
The content has been bookmarked!
There was an error bookmarking this content! Please retry.

Posted by David Dossot on Aug 25, 2009
Over the past couple of years, the REST style of software architecture has gained in popularity, mainly because it typically gets reified in systems that require less moving parts, exhibit loose coupling and are more resilient.
Having more REST resources available in the enterprise landscape increases the chance that orchestrating them in some way will be needed. For example, a business activity will typically consist of creation of a resource followed by subsequent lookups and creations of other resources.
In essence, interacting with RESTful services is pretty simple: we need to form and send proper requests (headers and entity) and analyze the responses we get back (headers and entity again). For this, no special tools or frameworks are needed, besides a good HTTP client library. Besides, as the different entities involved in RESTful interactions are defined by so-called micro-formats, the capacity to parse or output these entities easily can also be very helpful.
Orchestrating the interactions with several resources becomes slightly more involved. We need to define the orchestration, handle errors and retries properly and our system must behave gracefully under load. As an integration framework Mule provides all of this (and much more).
Let's consider an example, a merchant system where the processing of a new order implies the following orchestration:
In this article, we will detail the interactions for each of these steps and will consider what particular Mule moving parts and Groovy features we have used to achieve such an interaction.
The overall orchestration will consist in a chain of Mule services connected with specific routers, filters and in-memory message queues (aka VM queues). You can learn more about routing messages in Mule by reading reading a recent InfoQ article on this subject.
REST support in Mule
Mule provides a simple, yet extremely powerful way to interact with RESTFul services using Mule RESTPack.
The Mule RESTPack provides a comprehensive set of connectors and guidance that help you create new RESTful applications. As of this writing, this pack offers three transports based on popular REST-related frameworks: Abdera, Jersey and Restlet. This is very handy for exposing new resources but what about integrating existing REST resources?
The good news is that with Mule's stock HTTP transport spiced up with Groovy support from Mule's standard scripting module, you get all you need for successfully interacting with RESTful services.
POSTing with Mule
Let's get started with the first interaction. An order is created by HTTP-posting an XML entity to a specific resource, as shown in these excerpts:
POST /orders HTTP 1.1 ... <order xmlns='urn:acme:order:3:1'> <customerId>123456</customerId> <productId>P987C</productId> <quantity>2</quantity> </order>
To which the server replies in case of success:
201 Created Location: http://acme.com/order/O13579 ... <order id='O13579' />
This interaction is achieved in Mule with a simple HTTP outbound endpoint. Note that the interaction itself is triggered by sending a map containing the required values (customer and product IDs, quantity) to the order creation service. So what does this service look like? Here it is:
<service name="OrderCreationService">
<inbound>
<inbound-endpoint ref="OrderCreationQueue" />
</inbound>
<outbound>
<chaining-router>
<http:outbound-endpoint synchronous="true"
responseTimeout="15" method="POST"
host="${acme.order.hostname}"
port="${acme.order.port}" path="orders"
user="${acme.order.username}"
password="${acme.order.password}"
contentType="application/vnd.acme+xml" encoding="UTF-8">
<transformers>
<transformer ref="OrderMapToMicroformat" />
</transformers>
<response-transformers>
<message-properties-transformer>
<add-message-property key="OrderPlaced"
value="#[groovy:message.getStringProperty('http.status','ERR')=='201']" />
<add-message-property
key="OrderResourceLocation"
value="#[groovy:message.getStringProperty('Location','')]" />
</message-properties-transformer>
<object-to-string-transformer />
</response-transformers>
</http:outbound-endpoint>
<outbound-endpoint ref="OrderCreationResultQueue" />
</chaining-router>
</outbound>
</service>
That's rather dense XML so let's look closer at what we've got here:
Groovy's MarkupBuilder Goodness
The heavy lifting in this service is really done by the OrderMapToMicroformat transformer, itself powered by Groovy's MarkupBuilder. The MarkupBuilder API offers a natural way to produce XML entities compliant to our particular microformat:
<scripting:transformer name="OrderMapToMicroformat">
<scripting:script engine="groovy"> <![CDATA[
def writer = new StringWriter()
def xml = new groovy.xml.MarkupBuilder(writer)
xml.order(xmlns: 'urn:acme:order:3:1') {
customerId(payload.clientId)
productId(payload.productCode)
quantity(payload.quantity)
}
result = writer.toString() ]]>
</scripting:script>
</scripting:transformer>
Notice how the values from the map payload are used to populate the XML elements: some of the naming convention mismatches are resolved here (for example, clientId becomes customerId).
As desired, this transformer produces this kind of output:
<order xmlns='urn:acme:order:3:1'> <customerId>123456</customerId> <productId>P987C</productId> <quantity>2</quantity> </order>
And, alongside the right content type, it is all what the order RESTful service was expecting for creating a new resource.
Analyze this
Let's now look at the service in charge of asynchronously analyzing the outcome of the order creation and deciding if it is worth going further with the orchestration:
<service name="OrderCreationResultProcessor">
<inbound>
<inbound-endpoint ref="OrderCreationResultQueue" />
<selective-consumer-router>
<message-property-filter pattern="OrderPlaced=true" />
</selective-consumer-router>
<logging-catch-all-strategy />
</inbound>
<outbound>
<pass-through-router>
<outbound-endpoint ref="SuccessfulOrderQueue" />
</pass-through-router>
</outbound>
</service>
We use a selective consumer to accept only messages that bears a header confirming that the order was successfully placed. If this header is true, we then route, via an in-memory queue named SuccessfulOrderQueue, the message to a third and final service dedicated to handle successful order creation messages. Note that, in this example, we simply log non-compliant messages but in reality we would send error messages to a dedicated queue either for later forensics or for immediate feedback to the application.
GETting with Mule
The final service that composes our orchestration takes care of HTTP-getting the newly created order that contains extra values needed to form a valid message for the email gateway. Here is a sample interaction:
GET /order/O13579 HTTP 1.1 200 OK Content-Type: application/vnd.acme+xml ... <order xmlns='urn:acme:order:3:1'> <customerId>123456</customerId> <productId>P987C</productId> <quantity>2</quantity> <customerEmail>foo@bar.baz</customerEmail> <estimatedShipping>2009-31-12T00:00:00Z</estimatedShipping> </order>
The good news is that Mule's stock HTTP transport contains a component (named rest-servicecomponent) that facilitates the interacting with REST resources from within a service. Thanks to this component, we do not need to chain the result of the GET operation to a subsequent service but can perform everything within a single service. Moreover, it supports the usage of expressions in its configuration, which enables connectivity with dynamically built URLs.
Here is how this last service looks like:
<service name="SuccessfulOrderProcessor">
<inbound>
<inbound-endpoint ref="SuccessfulOrderQueue" />
</inbound>
<http:rest-service-component httpMethod="GET"
serviceUrl="#[header:OrderResourceLocation]" />
<outbound>
<pass-through-router>
<outbound-endpoint ref="EmailGatewayQueue">
<transformers>
<object-to-string-transformer />
<transformer ref="OrderMicroformatToEmailMap" />
</transformers>
</outbound-endpoint>
</pass-through-router>
</outbound>
</service>
After receiving a successful order message, this service uses the REST service component to generate an HTTP GET request to the URL that has been previously stored in a property (aka header) named OrderResourceLocation. Note how we use the Mule expression evaluation framework (with the #[...] syntax) to inject a dynamic URL in this component.
Right before passing the response of the GET request to the service in charge of communicating with the e-mail gateway, we perform two transformations on the XML order entity:
Groovy's XmlSlurper Happiness
Groovy's XmlSlurper is a dream tool for parsing XML microformats, thanks to its DSL-like API.
Here is what is inside the OrderMicroformatToEmailMap transformer:
<scripting:transformer name="OrderMicroformatToEmailMap">
<scripting:script engine="groovy"><![CDATA[
def order = new XmlSlurper().parseText(payload)
.declareNamespace(acme: 'urn:acme:order:3:1')
result = [emailId:'OrderConfirmation',
emailAddress:order.'acme:customerEmail'.text(),
orderId:order.@id.text()]
]]>
</scripting:script>
</scripting:transformer>
Yes, that's two lines of Groovy and we have a namespace-aware XML parser and a map builder. It's almost too good to be true! But that's all we needed to create the map that the email gateway service is expecting.
Finally RESTing
In this article, we have followed a pretty much pre-defined orchestration path, with the new order resource URL being the only dynamic bit. It's not hard to imagine how one could leverage the demonstrated transformers and expressions to support more dynamic interactions, as you could get if you decide to walk the HATEOAS path. If that would be the case, other Mule's smart router would become handy, like the one allowing you to create idempotent receivers. You've seen how Groovy's capacities and conciseness combined with Mule's communicating abilities greatly simplify interacting with RESTfull services. Both Mule's expressions and tiny Groovy scripts are efficient ways to dynamize your Mule configuration. As an added bonus, the fact we use asynchronous VM queues to chain the different steps of our orchestration allows our solution to gracefully degrade under peak loads, thanks to the intrinsic SEDA architecture of Mule.
With all these power tools in hand, integrating REST resources will surely not make you restless.
Enjoy!
The full configuration and related test resources are available as a standalone Maven project that you can get here: http://dossot.net/datastore/mule-groovy-rest.tar.gz
The title of this article is misleading: Mule's RESTpack hasn't been used here.
D.
The title has now been fixed
Hi, I really would like to see the full configs. If you can please fix the download link: dossot.net/datastore/mule-groovy-rest.tar.gz
Thank you
Sorry about that, the link is now back online.
D.
The article is good. But I am looking for the following details.
"I have an external REST webservice, which takes three headers Content-Type, Content-Length and Authorization."
Now I would like to understand
1. How to configure the external REST webservice in Mule.
2. How to get the Header's information. so that I can use those headers for an another purpose. that means I should be able to access those headers in a Custom class.
3. If we call Mule ESB's url, which class will be having all the request information.
In this interview, Jesper Boeg, author of the new InfoQ book – Priming Kanban, discusses the keys to using Kanban effectively, and how to get started if you are currently using other approaches.
John Hugg discusses high volume transaction processing applications with high and low frequency profiles, and how VoltDB can be used for that purpose.
Kevlin Henney examines code samples to see what can be learned from them starting from the premise that one won’t write great code unless he knows how to read it.
Jason Ayers share the observations he made watching a team of developers collaborating in real time on the same code base, pushing XP, pair programming and continuous integration to their extremes.
Michael Snoyman presents Yesod, a web framework written in Haskell and containing a web server, templating, ORM, libraries (templating, gravatar, etc.).
Richard Kreuter and Kyle Banker on how to avoid classical RDBMS transactional systems by using compensation mechanisms, transactional messaging or transactional procedures.
Attila Szegedi talks about performance tuning Java and Scala programs at Twitter: how to approach GC problems, the importance of asynchronous I/O, when to use MySQL/Cassandra/Redis, and much more.
One category of risk that project teams need to ensure they address is business value failure – delivering a product that fails to provide value for the business investor.
5 comments
Watch Thread Reply