Welcome to JoshLong.com, home of my personal blog
<< Last | Next >>
July 17, 2010

Spring Integration at OSCON!

Whew! Time sure flies!

I've been working 'round the clock of late with my fellow authors Daniel Rubio and Gary Mak to wrap up the writing for Spring Recipes, 2nd Edition (more on that as it goes to press). This book's going to be second to none, folks. Spring Roo, Grails, Spring Integration, Spring Batch, Flex, REST and many (16, in fact!) other awesome chapters to bring you to the wide world of Spring 3. As a user of the Spring framework first and an author second, just trust me when I say I'd be very, very interested in buying this book if I wasn't already entitled to a free copy as an author. I digress. The book - all consuming though it is - isn't even why I'm writing this post!

Mark Fisher - lead of the Spring Integration project and all around nice guy (I'm going to throw in brilliant, as well, just in case you haven't had a chance to scour the code behind Spring Integration and come to that conclusion yourself) has been kind enough to let me contribute some adapters to the Spring Integration project - these adapters are centered around bridging communication between systems normally used by humans and automated systems. We have built support for XMPP and Twitter thus far. More's most assuredly coming, too! Looking into the crystal ball, I see ATOM and RSS playing a big part along with IRC. These adapters round out the support already provided for user-facing services like e-mail.

There's a lot of power and promise here. First, in a system with variable states, XMPP is a very promising technology because - besides being a good way for diffent entities to exchange messages (it is, after all, the backing protocol behind Google Talk and Facebook chat) - it lets you add the notion of availability to actors in your system. Imagine a game, with users joining and leaving the game, or a chat room, or a grid of grid-nodes that may be taken off-line. XMPP provides a natural way of representing availability, which is increasingly important in a system with many fluctuating agents and states.

Twitter, ATOM/RSS and others are important because they let you consume human-synthesized events. Trends, volume, etc, are all interesting metrics that can be very valuable to your business. I can see a lot of power in having a Twitter account that responds to queries or commands - in much the same way as the Smarter Child IM bot work (-s,-ed).

In some sense, these adapters are only the beginning. They let your application drink from the proverbial firehose of events, but what to do with them once you have them? Graph them? Send them to Splunk? Send them through a message broker (and, depending on the volume, which one?)? Why not send them through a complex event processing (CEP) engine like Esper using this fantastic third party Spring Integration adapter for Esper? There, you can can process and analyze these events, and synthesize more interesting, complex events.

If this all sounds interesting to you (and why wouldn't it?), you should check out OSCON next week in Portland, OR. I'll be there giving a talk called the "The Social Enterprise Service Bus." I'll be with some colleagues and friends from Shopzilla, too. If you'd like to grab a beer, ping me on Twitter (@starbuxman) and we'll see what we can do! This is my first time presenting at OSCON, so I'm looking forward to attending some of the other talks almost as much as I am about getting a chance to talk to you guys. Hope to see you there!

July 16, 2010

Is This Thing On?

Hello, world! Nothing to see here, simply conducting a few tests of the software. Move along...

May 4, 2010

Idempotent Queues With HornetQ (or: the 'Last Value Header')

Often times, a message queue is used as a way to publish "events" to other services in the enterprise. The publish/subscribe architecture decouples clients from the senders and alleviates the publisher from specific knowledge of the consumers of the messages. This, plus the asynchronous nature of a message queue - the publisher does not block while clients consume the events - makes it ideal for publishing events to keep other systems aware of the state of a given system.

Now, let's establish the use case: we want to consume events in a very busy system. In our case, it's possible to receive multiple events. Or, perhaps in your system you've positioned the message queue as a way to deliver commands - "pings" - using the "command bus" pattern. It may - and quite often is - be acceptable to ignore duplicate requests in architectures like these. For example, a "command" message notifying a system that it can being processing a batch of data for the day only needs to be handled once per day, not 10 times, even if 10 different events are published. It'd be ghastly and inefficient to process the load 10x a day. What's required is some way to make message submission idempotent for certain messages - to make them indifferent to duplicate message submission.

Backstory: I've been playing with JBoss' HornetQ a lot recently. It's a very fast message queue: it recently bested ActiveMQ in the SpecJMS2007 benchmark by more than 300%!. It is able to perform these feats because it uses a native, asynchronous IO layer on Linux centered around the kernel's libaio functionality. On all other platforms, it's just gosh darned fast, regardless, but doesn't benefit from the native code acceleration.

So, imagine my surprise when I found out that HornetQ supports something it calls a Last-Value Header - a well known message header that - when the value is duplicated by other messages - causes the submitted message to override the existing message: the latest message with a duplicate header wins.

Here's how code submission to the queue looks using Spring's JmsTemplate functionality:

 
this.jmsTemplate.send (this.destination, new MessageCreator () { 
    public Message createMessage (final Session session) throws JMSException { 
        TextMessage textMessage = session.createTextMessage ( ... ); 
        textMessage.setStringProperty ("_HQ_LVQ_NAME", 
someUniqueStringThatYouSpecify);  
        return textMessage; 
    } 
}); 

So, it's often easy to find a business value that can be used to derive a semantically correct, unique key to identify duplicate events. Processing a customer's order with 3 items in the shopping cart at 12:30:30s PM? Build a key combining the 30 second window, the customer ID, the count of items, and the order ID. This provides a service-level mechanism to prevent nasty double submit issues, for example.

You need to enable this characteristic on the queue itself in the configuration files.

In HornetQ there are a few files under the $HORNETQ/config/ folder that you need to be aware of to configure HornetQ: hornrtq-jms.xml, hornetq-configuration.xml, and hornetq-users.xml. In this scenario, we need to only modify the hornetq-configuration.xml.

For a queue configured in hornetq-jms.xml

 
   <queue name="dupesQueue"> 
        <entry name="/queue/dupesQueue"/> 
        <durable>true</durable> 
    </queue> 

... you'll need to make the following changes to hornetq-configuration.xml:

 
  <address-setting match="jms.queue.dupesQueue"> 
          
<last-value-queue>true</last-value-queue> 
        </address-setting> 

Simple, right? So, go ahead, send all the messages you want - only one will remain (unless of course that message is consumed. This only guards against duplicate submissions assuming the messages haven't been delivered yet. Enjoy!

April 26, 2010

A New Post on Artima.com Called 'SOA, 5 Years In'

I've just posted a blog on Artima.com called SOA, 5 Years In. In it, I talk about some of the core value principals behind Thomas Erl's excellent Service Oriented Architecture: Concepts, Technology, and Design. Check it out!

March 20, 2010

The ServerSide Java Symposium 2010 Recap

I'm in my hotel room thinking about the last 3 days here at The ServerSide Java Symposium. I've had a fantastic time. I gave and/or participated in two talks: one was a talk on jBPM and Spring, the other was participation (representing Spring Integration) in a panel with Jeff Genender (representing ServiceMix) and Ross Mason (representing Mule) on ESBs. I enjoyed that process and enjoyed talking to Jeff and Ross gentlemen to the last. The 400+ people in the audience were invigorating too. Im pretty sure anybody would tell you this year was a welcome, marked improvement over previous years, especially in attendance numbers. It also heralded the introduction of a new editorial lineup, with Cameron Mckenzie taking the lead-editors position. Hes got his work cut out for him, but Im confident hes up to the task.

Rod Johnson gave a "zepo" (zero-powerpoint) Spring / Roo keynote, which was very impressive until it seemed to have failed him at the end. A post mortem revealed that the demo was fine, just a simple error. It was interesting to note that he misplaced his wedding ring and still gave a 99% performance without slides in front of 400+ people! Well done! Spring Roo seemed to garner a lot of attention from the audience and the Twitterati. Matt Raible and James Wards talk on Flex vs. GWT was fun, as expected. Jeff Genender and Keath Hesler both turned in good talks on ServiceMix. Ted Neward and Scott Davis gave their talks to great reception, as usual. Finally, my old friends Reza Rahman, Kito Mann, etc., did very well too. I missed some of the JBoss crowd (Emmanuel Bernard and Dan Allen, notably) this year, however.

It was nice meeting James Gosling, too. Can't help but feel a little in-awe. The final treat was partaking in the festivities, libations, etc., with my colleagues at Shopzilla. Tim Morrow, Senior Architect at Shopzilla, gave a very well received talk about the scale story at Shopzilla.

February 17, 2010

A Month's Gap And No Explanation

Hello, world! I've been utterly and completely drowned in lake-busy these last few months. Updates may be a little slow for the next month, too. I've started working as an editor for Infoq.com's Java Queue. Work is progressing apace on my next Spring book, and some exciting things are happening in my personal life pretty soon. Plus, I'm working on an opensource side-project that'll unveil hopefully pretty soon here. Anyway, check out my updates on Infoq.com if you want good old fashioned news, and on Twitter if you want commentary in 140 character chunks. Sorry I can't say more, but I will when I can! If you're going to The Server SIde Java Symposium next month (March 17-19), don't forget to say hi, and attend my sessions!

January 13, 2010

A Very Interesting Technique For Cross-Domain AJAX Requests

I read a very good article on breaking the crossdomain wall for Ajax requests. It's presented here, as an entry on http://www.wait-till-i.com. In it, Chris Heilmann talks about using a Yahoo service and JSON-P requests with Ajax to load any site's contents. You should most certainly read his article - it's fantastic. I post here the most salient bit (for me) since it genuinely knocked my socks off. To re-use this in your own code, copy the parts I've highlighted in bold. You can use your own version of jQuery, naturally, as the most interesting aspect is the bits inside the ajax function (which itself is pretty trivial. I created the wrapper function so that the code could be stashed away and re-used more readily). I demonstrate its use in the script fragment below that, where I load the HTML for this very site.

 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
"http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
  <title> ZOMG! </title> 
  <link rel="stylesheet" href="styles.css" type="text/css"> 
</head> 
<body> 
 
<script src="http://code.jquery.com/jquery-latest.pack.js"></script> 
<script language="javascript"> 
function ajax ( url, cb){ 
 var yqlUrl =  "http://query.yahooapis.com/v1/public/yql?"+ 
            "q=select%20*%20from%20html%20where%20url%3D%22"+ 
              encodeURIComponent (url)+ 
            "%22&format=xml'&callback=?" ; 
 $.getJSON ( yqlUrl,  cb ); 
} 
</script> 
 
<script language="javascript"> 
$ (document).ready (function (){ 
 ajax ( 'http://www.joshlong.com', function (data){ 
  alert ( data.results[0] +'' ) ; 
 }); 
}); 
</script> 
</body> 
</html> 

January 11, 2010

Modeling

I can't tell you how powerful overcoming the leap-before-looking temptation is when building a system. Have an object model? Model it using UML or ERD. Have a workflow? Draw a workflow diagram (an activity diagram). Have a webflow? Draw a webflow diagram (looks like a state diagram, or in more sophisticated scenarios, like an activity diagram). Have a site map? Map the site using a site planning tool like Denim. All of these tools facilitate VISUAL feedback. They are cognitive, high level disciplines, and for good reason! Your mind interprets things visually differently than it does when coding from the left brain - it is able to "see" associations between related concepts when it's fed ideas through feedback that ends up in the right brain.

I've mentioned this before, I think, but check out Neal Ford's On the Lam From The Software Police for more.

Even if you don't check it out, invest in trying the modeling tools associated with the task you're attempting to solve. Even if you feel - after giving the technology a REALLY good-faith effort - that you've gained nothing, I'm willing to bet your product will still be more "consistent" than if you had developed it from scatch, unable to see the big picture.

January 6, 2010

Spring BlazeDS and your RIA/Thick/Thin/Fat client

How are you handling messaging in your thin client, thick client, fat client, RIA, or mobile client?

BlazeDS provides the ability to proxy messages from a JMS destination. Your AIR / Flex client can subscribe to it and provide a callback, very much like a Message Driven EJB or Spring's Message Driven POJOs.

Traditionally, reacting to an event on a bus in a client (which very well could exist outside the firewall) means polling some service or setting up a specialized proxy or perhaps having separate DMZ-safe JMS destination where you forward client-bound messages.

Suffice it to say, all of this is tedious and imposes an unecessary burden on the architecture and the developers. When it comes to messaging and remoting based services, there is definitely an extra burden on the developer of a RIA to secure or handle that requirement where this burden simply does not exist with traditional web applications. It is too frequently glossed over when architecting a system and then becomes a pain point.

There are some tools...

If you are using AJAX for your RIA, then you will have mastered tools like comet for push-based messaging. Even here, though, the burden of connecting and configuring comet is on you, the developer. For example, DWR - which is fantastic - doesn't have a way of proxying a JMS destination that I know of. It can be done, of course.

David Dossot showed me a very interersting, albeit specific, solution that solves the problem for Ajax using ActiveMQ's JavaScript client.

So, back to the question at hand - how are you solving the problem? Do you just avoid building systems that have the problem? You truly can't think of at least one or two or a millino problems that would be better served by messaging?

To me, the most complete solution appears to be Flex partnered with Spring and BlazeDS. If this post sounds like that of a gushing fan boy, you'll forgive me. It's true, unbounded enthusiasm. This technology is liberating, enabling! It reduces a real problem to a half hour of configuration - relegating the architectural burden back to the "gloss over" column, if you're using Flex. The Spring - BlazeDS integration is more than just a lot of "could"s. It provides out-of-the box support for connecting to JMS, and if you use the excellent Spring/BlazeDS solution, then you can do all of this with aplomb, and you can hook up any flex client to any channel on your Spring Integration bus with a minimum of fuss.

Naturally, all of that will all be covered in Spring Web Recipes, so stay tuned!

So: how are you talking to your messaging middleware? Remember - messaging is even MORE important in the wild Web 2.0 / cloud world than the client-server applications of yesteryear. Temporal decoupling brings scalability.

December 31, 2009

PostgreSQL 8.4 and Bitronix XA

I use PostgreSQL 8.3 - highly recommended by the way - and I just updated an application to 8.4. The application is built principally using Spring, Hibernate, and JMS. Naturally, some level of cooperation among transactions is required, so I use an XA provider - Bitronix. Everything was working swimmingly with PostgreSQL 8.3, but the application buckled on startup with errors when I upgrade PostgreSQL to 8.4:

Dec 30, 2009 11:25:50 PM 
bitronix.tm.twopc.AbstractPhaseEngine logFailedResources 
SEVERE: resource xasql failed on a Bitronix XID [737072696E672D62746D2D- 
73656E64657200000125E3A04B9900000038 : 737072696E672D62746D2D73656E6465720- 
0000125E3A04BA40000003A] 
org.postgresql.xa.PGXAException: Error preparing transaction 
at org.postgresql.xa.PGXAConnection.prepare (PGXAConnection.java:254) 
at bitronix.tm.twopc.Preparer$PrepareJob.run (Preparer.java:134) 
at bitronix.tm.twopc.executor.SyncExecutor.submit (SyncExecutor.java:12) 
at bitronix.tm.twopc.AbstractPhaseEngine.runJobsForPosition (AbstractPhaseEngine.java:109) 
at bitronix.tm.twopc.AbstractPhaseEngine.executePhase (AbstractPhaseEngine.java:71) 
at bitronix.tm.twopc.Preparer.prepare (Preparer.java:68) 
at bitronix.tm.BitronixTransaction.commit (BitronixTransaction.java:176) 
at bitronix.tm.BitronixTransactionManager.commit (BitronixTransactionManager.java:95) 
at org.springframework.transaction.jta.JtaTransactionManager.doCommit (JtaTransactionManager.java:1009) 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit (AbstractPlatformTransactionManager.java:754) 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit (AbstractPlatformTransactionManager.java:723) 
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning (TransactionAspectSupport.java:394) 
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke (TransactionInterceptor.java:117) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:172) 
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke (ExposeInvocationInterceptor.java:89) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:172) 
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke (JdkDynamicAopProxy.java:202) 
... 
Caused by: org.postgresql.util.PSQLException: ERROR: prepared 
transactions are disabled 
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse (QueryExecutorImpl.java:1592) 
at org.postgresql.core.v3.QueryExecutorImpl.processResults (QueryExecutorImpl.java:1327) 
at org.postgresql.core.v3.QueryExecutorImpl.execute (QueryExecutorImpl.java:192) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute (AbstractJdbc2Statement.java:451 

If you're in my situation, the immediate cure is to uncomment and set the max_prepared_transactions attribute in data/postgresql.conf. A safe value seems to be 10, though your mileage may vary. There must be a reason they've disabled this in 8.4, so further investigation is required. In the meantime, though, everything seems performant and works as it did before.

<< Last | Next >>