I had the privilege of speaking at the Mule Summit in Chicago a few weeks ago. During my presentation, I covered some key Mule ESB features we leverage at Express Scripts: Component Bindings and Custom Configuration Patterns. Few conference attendees were familiar with these features, so we thought blog posts would help share information about these features with a broader audience. In this post, I’ll focus on Component Bindings. A future post will cover Custom Configuration Patterns.
Component Bindings provides a mechanism for Java components hosted in a Mule Flow or Service to make outbound calls to the ESB without needing to integrate with proprietary MuleSoft interfaces. With Component Bindings, you can define a Java interface that meets your requirements and your Java component is written to integrate with that interface. A Component Binding can be used to make a Mule outbound-endpoint the “implementation” for the interface, allowing you to write fully portable (and testable) Java components which can leverage the ESB without being “aware” of the ESB. Figure 1 shows the call flow when using a Component Binding.
Figure 1: Component Binding Call Flow
Using Component Bindings, you can easily create a clean separation of duties where Java code handles business logic and orchestrations, essentially acting as a “controller”, while the ESB handles inbound and outbound integration concerns (transports, transformations, security, transactions, etc). Here are a few benefits of this approach:
- Since it creates a clean separation of duties, it can be easier to debug an implementation.
- Because Java code is used for flow control instead of the ESB, it reduces the learning curve of Mule, while still getting the benefits of it for integration concerns. For large organizations, like Express Scripts, that need to make new developers effective quickly, this can be significant.
- It makes it easier to test business logic and orchestrations using standard tools that many developers are familiar with, like JUnit.
- It allows the Java code to be hosted outside of Mule, if need be.
Let’s take a look at an example. The sample project that I created for this post was inspired by a NPR story that I recently heard about the potential role that social media can play as a data point in predicting stock performance. It’s an intriguing idea for sure, but I won’t be making portfolio changes anytime soon based solely on Twitter.
The sample project exposes a RESTful API, using Mule’s Jersey Module, for fetching stock stats including both financial and social data. The diagram below shows the architecture. The API client provides a stock symbol and an as-of date. The implementation first fetches the financial information using the Stocklytics API. Next, the implementation gets up to 1000 tweets from Twitter using Twitter’s relatively new $ “cashtag” for stocks. The Twitter integration uses Mule’s Twitter Cloud Connector. Finally, the implementation batches all tweets and determines the sentiment for each of them by making a single call to the Sentiment140 API.
Figure 2: Sample Project Overview
Figure 3: Sample Project Request/Response
The heart of the sample project is in the stockstats.impl.StockStatsResourceImpl Java class which contains all of the business logic and orchestration code. (See the unit test for this class in StockStatsResourceImplTest.java.) This class integrates with three Java interfaces: StockService, TwitterService and SentimentService. The StockService and SentimentService interfaces have implementations that integrate with the Stocklytics and Sentiment140 APIs respectively. These implementations are injected into the StockStatsResourceImpl class using Spring Framework. A Component Binding is used to implement the TwitterService interface and inject it into the StockStatsResourceImpl class.
Figure 4: Component Binding Example
The snippet from the StockStats.mflow file shown in Figure 4 provides an example of creating the Component Binding for the TwitterService interface. In this example, we define a Component which is tied to a Spring bean called “stockStatsResource” which is an instance of stockstats.impl.StockStatsResourceImpl and is defined earlier in the file. The “binding” node tells Mule to create a Component Binding for the TwitterService interface and inject it into the stockStatsResource bean. Mule will forward any calls to the TwitterService.search method to the outbound-endpoint specified. In this example, the VM outbound-endpoint delegates to another flow which then uses Mule’s Twitter Cloud Connector to integrate with the Twitter API. Figure 5 shows the call flow at runtime.
Figure 5: TwitterService Binding Call Flow
There are a few noteworthy items about Component Bindings:
- Component Bindings are not yet supported by Mule Studio, so you’ll need to edit the Flow XML directly in order to use them.
- It is important that exceptions that occur downstream of the Component Binding are bubbled up into the Java tier. You should test this. Versions of Mule prior to 3.0 may not handle this as you would expect.
- You are limited to injecting bindings into Java Components that Mule knows about, but wouldn’t it be great to have the ability to inject a binding into any Spring bean — even beans that Mule has no direct visibility to? At Express Scripts, we developed a feature that we call “Global Interface Bindings” to do exactly that. Look for this feature to become available, either on Mule Forge or part of the core ESB, in the future.
Complete project can be viewed from Github.
Hopefully this post has demonstrated the potential benefits and technical details of Mule’s Component Bindings feature. The ability to host portable Java code that can leverage the ESB for integration concerns without being tied to proprietary APIs is a key feature for Mule in the ESB space.
This is a guest post from Mule community member Steven Sefton. Steve is a Tech Lead at Express Scripts with over 14 years of IT experience. He has been a proponent of Mule since 2009. Thank you Steve. You bagged yourself a cool T-Shirt. If anyone else in the Mule community would like to write a guest post, please email us.