Friday, October 24, 2008

AMQP back in the radar...

Just learned that Microsoft has joined up with AMQP. This is great news - I was playing with AMQP some time ago but in recent months I got a feeling that there was a lot of sitting on the fence about whether people are going to take up on it or not. There's nothing so sad as taking a great idea with a well thought out standard and seeing it get a lack-lustre take-up. This is just the kind of injection AMQP needed.

As I recall, Apache Camel already has support for AMQP, so that'll be a very nice bridging tool for organizations who want to migrate piecemeal towards an AMQP-based infrastructure.

It'll be nice to see what the full extend of Microsoft's participation will be: are they going to buy in wholesale or are they going to just look nice in the background of wedding photographs, enjoying the party? Will they be actively implementing AMQP brokers, or will they just add some AMQP connectivity options to their existing integration offerings?

Things are getting interesting again for AMQP :)

Wednesday, October 22, 2008

Sneak Preview: my FUSE ESB / ServiceMix screencasts...

Over the last few weeks I've worked on putting some screen casts together on how to get "over the hump" with ServiceMix: you've read all about it, you've downloaded it, and then you wonder: where do I start?

In the screen casts, I show:

  • Three things to make you more productive with ServceMix - see how to set up your development environment to get stuff done faster.

  • How to create a simple flow - from file pickup to JMS queue.

  • How to XSLT transform file data and place on a JMS queue using a pipeline EIP.


  • The screencasts aren't long, 8, 25 & 19 minutes respectively. Use the streamed video below to get an idea of what's going on in the screen casts: if you like them, then let me know and I'll send an FTP link to where you can download the full resolution 800x600 quick-time movies.

    Three things to make you more productive with ServceMix





    How to create a simple flow - from file pickup to JMS queue




    How to XSLT transform file data and place on a JMS queue using a pipeline EIP



    FUSE TV: Andy Warhol may have been right...

    Didn't Warhol say something about in the future everyone will have 15 minutes of fame? I, along with some of my Progress colleagues, have been recorded for FUSE TV. My own slot is 13m 13s, which means that I may have only 1m 47s left. Hmmmm... better use those precious seconds sparingly...

    Wednesday, October 8, 2008

    m2eclipse: developing with ServiceMix / FUSE archetypes has never been so easy

    Hurrah for Cool Tooling!

    Maven archetypes are great: anyone developing with ServiceMix will know and appreciate good archetypes, but will probably grumble disapprovingly at the long command lines they entail. In ServiceMix, the smx-arch command-line short-cut made things easier, but I was always uncomfortable with having to swich from Eclipse to the command-line to create my new projects.

    In the last few days, Guillaume Nodet put in a tiny little script onto the FUSE repository (http://repo.open.iona.com/maven2) that generates an archetypes-catalog.xml file containing all the archetypes. You can import this URL into m2eclipse, and then use the really neat m2eclipse dialogs to create your maven/eclipse projects directly from the catalog.

    I love it so much I added an entry on the FUSE wiki; go there for more details!

    Monday, October 6, 2008

    Carpe springem - community to the rescue?

    I was following a trail on the CXF users list, when Dan Kulp introduced "FreeSpring" (http://www.freespring.org), a community-based effort that has come about to alleviate the effects of the new SpringSource licensing system. Their aim is to solve three key problems for Spring users who do not want to pay SpringSource subscriptions for fixes after the three-month post-release dust-settling period: creating versioned binary distributions, applying community fixes, and, importantly, providing distributions through maven.

    I admire the initiative, but was of course keen to find out how freespring.org plan to keep the lights on... their intent is to get some corporate backing from benevolent organisations (perhaps SpringSource competitors?) and also to sell advertising space. I think the latter may be a go-er: freespring.org has the opportunity to become a hub for open-minded Java developers.

    Thursday, September 25, 2008

    Using AspectJ to diagnose ServiceMix component performance

    An inventive FUSE customer showed me an approach to diagnosing his ServiceMix integration flow by injecting some aspect-oriented code, and it's so cool that I thought it would be worth sharing. The problem is this: given that you have an integration flow, how can you diagnose how long each endpoint in the flow is taking to do its business? The customer in particular was experiencing exceptionally high latency on his integration flow (in the order of 900ms) that just seemed plain wrong: the question was, where in the flow was he incurring the hit? Was it in transformation, EIP, resequencing, or something else?

    I used AspectJ to reproduce my customer's approach, weaving in some diagnosis code into the ServiceMix call stack. You can do this by creating a simple aspect like the one below, which is called whenever a call is made to Flow.send(). The measurePeformance() method does some logging, but also does a simple timer around the message invocation. The result will only be accurate to the millisecond; however, if you're trying to isolate big-elephant-in-the-room bottlenecks then this should be sufficient.


    @Aspect
    public class PerformanceAdvice {

    @Around("execution(* org.apache.servicemix.jbi.nmr.flow.Flow.send(..))")
    public Object measurePerformance(ProceedingJoinPoint thisJoinPoint) {
    Object ret = null;
    try {
    MessageExchange me = (MessageExchange) thisJoinPoint.getArgs()[0];
    System.out.println("send() to " + me.getEndpoint().getServiceName() + "... (status: " + me.getStatus() + ", role: "
    + (me.getRole() == MessageExchange.Role.PROVIDER ? "PROVIDER" : "CONSUMER")
    + ")");
    long startTime = System.currentTimeMillis();
    ret = thisJoinPoint.proceed();
    long endTime = System.currentTimeMillis();
    System.out.println(me.getEndpoint().getServiceName() + " done; elapsed time = " + (endTime - startTime) + " ms.");


    } catch (Throwable e) {
    System.out.println(e.getMessage());
    }
    return ret;
    }
    }



    To weave this code into ServiceMix (I used version 3.3.1.6-fuse from http://open.iona.com) was surprising easily: I added the JARs for aspectj (aspectjlib.jar, aspectjtools.jar, aspectjrt.jar, aspectjweaver.jar) into ServiceMix's lib directory. I also jarred up my PerformanceAdvice class and dropped it into the lib directory too. Finally, I modified the ServiceMix configuration file - conf/servicemix.xml - to create my advice and turn on auto-proxying for AspectJ. First, I added the Spring AOP namespace to the tag:


    xmlns:aop="http://www.springframework.org/schema/aop"


    Then, I added the following elements within the element:


    <!-- Turn on AspectJ auto-proxying -->
    <aop:aspectj-autoproxy/>
    <!-- Create my performance advice aspect -->
    <bean id="performanceAdvice" class="ps.progress.com.PerformanceAdvice">


    And that's it! To test, I ran a simple integration flow that reads from a JMS queue and uses a pipeline to transform the message and send the result to another queue. Here's the output:

    Invoking on {http://progress.com/ps/smx/demo/transformer}Pipeline... (status: Active, role: PROVIDER)
    {http://progress.com/ps/smx/demo/transformer}Pipeline done; elapsed time = 0 ms.
    Invoking on {http://progress.com/ps/smx/demo/transformer}XsltTransformer... (status: Active, role: PROVIDER)
    {http://progress.com/ps/smx/demo/transformer}XsltTransformer done; elapsed time = 1 ms.
    Invoking on {http://progress.com/ps/smx/demo/transformer}XsltTransformer... (status: Active, role: CONSUMER)
    {http://progress.com/ps/smx/demo/transformer}XsltTransformer done; elapsed time = 0 ms.
    Invoking on {http://progress.com/ps/smx/demo/transformer}JmsOutput... (status: Active, role: PROVIDER)
    {http://progress.com/ps/smx/demo/transformer}JmsOutput done; elapsed time = 0 ms.
    Invoking on {http://progress.com/ps/smx/demo/transformer}JmsOutput... (status: Done, role: CONSUMER)
    {http://progress.com/ps/smx/demo/transformer}JmsOutput done; elapsed time = 1 ms.
    Invoking on {http://progress.com/ps/smx/demo/transformer}XsltTransformer... (status: Done, role: PROVIDER)
    {http://progress.com/ps/smx/demo/transformer}XsltTransformer done; elapsed time = 0 ms.
    Invoking on {http://progress.com/ps/smx/demo/transformer}Pipeline... (status: Done, role: CONSUMER)
    {http://progress.com/ps/smx/demo/transformer}Pipeline done; elapsed time = 1 ms.



    You can see that there's lots of messages being sent out - we're most interested in those where the status is Active and the role is PROVIDER (you can modify the PerformanceAdvice class to just print those out if you like). From this, I can see that the call to the XsltTransformer endpoint is taking just 1ms; a nice verification that my XSLT transform is doing anything crazy.

    Using an approach similar to this, my customer was able to show that his bottleneck was actually in one of his own handmade components that invoked on a back-end server using RMI - the hit was in the order of 850ms, using the lion's share of the latency. I'm not sure what he's done since then to minimize this hit, but at least we know where the problem is.

    In summary: Aspect-Oriented Programming is great for weaving in cross-cutting concerns such as logging, security or transactionality into your application code - it's also a nice tool to have for performance diagnosis.

    Friday, September 19, 2008

    CXF, JMS & the risk of acknowledged-but-not-processed messages

    May God speed Christian Schneider and his refactoring of the CXF JMS endpoints to be more configurable. I was looking into the reliability of the JMS implementation in CXF, and (from the code), I see that the JMS acknowledgement mode used by CXF is hard-coded to be Session.AUTO_ACKNOWLEDGE. So, I thought, it's not transactional - but that's ok, right? As long as the message is acknowledged after my CXF implementation code then I'm good... right?

    I wanted to verify that this was the case; so, I modified the jms_queue demo to exit unmercifully in the middle CXF impl code for the greetMe() and greetMeOneWay() methods. I had hoped that this would mean that the incoming message, having been unacknowledged, would be redelivered - however, it appears that the message is not redelivered. It looks like CXF is acknowledging the message before we actually process it. Ouch.

    The implications of this are serious: if you're implementing a listener for one-way (in-only) messages with CXF then there is a possibility that messages delivered just before an emergency server shutdown will have been acknowledged but not processed: lost forever. To get around this for now, I'd recommend using Camel to listen transactionally from the JMS queue and send the message to CXF for marshalling (as per Christian's article "Better JMS Transport for CXF"). That way, if the server goes down then message will be redelivered at a later stage. Of course, you should in your code check to see if the message is a redelivery, and take appropriate action to ensure that your application remains consistent.

    The impact of this "early acknowledgement" on request-response services over JMS is not so fatal, as failure of the sever will result in no reply message getting to the client - a timeout will alert the client that something has gone wrong and they can resend.