Archive for June, 2008

Axis2/C has AMQP support via Apache Qpid

June 16th, 2008  |  Published in AMQP, Axis2, Qpid  | Add to del.icio.us

Danushka Menikkumbura has got AMQP support going for Axis2/C via the Apache Qpid project.
This will only work on Linux as the Qpid c++ client so far has only a Linux implementation. Currently there is ongoing work from two contributors trying to port the code base to support Windows and Solaris. This is scoped for the M3 release.

Watch the WSO2 blog space or the Axis2/C website for a tutorial/blog post from Danushka.

Restructuring Code

June 9th, 2008  |  Published in Architecture, programming  | Add to del.icio.us

Most programmers need to deal with restructuring the code they work on due to a variety of reasons. While most of the time it is driven by demand, sometimes it is also done for personal reasons. Here are some of the reasons I have had or seen within the teams that I have worked over the years.

  1. The current code would have reached a stage where it is impossible to do any more modifications without breaking something else
  2. The requirements have changed so much that the current architecture/design cannot handle it without a redesign
  3. The current application doesn’t/will not scale, perform well enough as it wasn’t designed to handle the current load/anticipated growth
  4. The folks who worked on the code are no longer there and nobody knows what the code really does (or what it was supposed to do)
  5. You don’t really like the current way it is implemented and think that there is a better way to do it using framework X or library Y

While sometimes restructuring could be done easily, but 90% of the time it is not a trivial task. When the frustration gets to you, you may have even entertained the idea of rewriting an application/module/section from scratch. Is this really a good idea? Sometimes this maybe the only option, but most of the time this may end up being a bad idea due to a variety of reasons.

  • One of the biggest mistakes is to throw away the old code without any due consideration simply based on the assumption that the old code is bad and we are going to write much better code.

    Throwing away the old code (especially if it was in production) means, you are throwing away months (or years) of tested, battle hardned code that may have had fixes for bugs that you aren’t even aware of. If you don’t take this into account, the new code you write may end up showing the same bugs that are already fixed in the old code. This will waste a lot of time ,effort, knowledge gained over the years

  • This method or class is ugly, lets throw it away and write again.

    That odd looking method or that badly written class may have some fix for a race condition or an optimization that one of your customers is depending upon. Discarding that code as crap without really understanding whats going on may end up with dire consequences for your team.

  • Not paying enough attention to the existing unit tests/ test frameworks when building the new system.

    These tests were added for a reason, possibly in response to a bug or some sort of intermittent failure that was reported on a production system. These failures/errors may have been reported way before you joined the company. Sometimes none of the current team members are aware of all the issues. So discarding the test code means you are throwing away years of hard work and knowledge

  • The current code is way behind all the cool technology we have today. The new framework X can do things a lot more elegantly, so lets re write.

    This is by far the worst mistake. If something is not broken then why try to fix it?. The code is ugly, or technology used is not cool are not good reasons. Simply bcos the style or structure of the code is not according to your personal preference is not a reason at all for unwanted restructuring .

I have been guilty of doing most the of the above mentioned points and through hard lessons I have realized that,

  • The best approach for restructuring starts with taking stock of the existing code base and tests written against that code. This will help you understand the strengths and weaknesses in the existing code, so you could ensure that you preserve the strong points while avoiding the mistakes.
  • It is best to reuse as much code as possible, bcos no matter how ugly the code is, it has been tested/reviewed etc.
  • Incremental changes are better than one massive code change. Incremental changes allows you to gauge the impact on the system more easily through feedback from tests etc. It is not fun to see 80 test failures after you make a change and can lead to frustration/preasure that will in turn result in more bad decesions . A couple of test failures is easy to deal with and provides a more managable approach.
  • After each iteration it is important to ensure that the existing tests pass. Analyze why the tests are failing, and make modifications/add new tests if nessacery if the existing tests are not sufficient enough to cover the changes you made. Failure to do so can result in a lot of pain down the road.
  • Avoid the temptation to rewrite everything. Personal preferences and ego shouldn’t get in the way. If something works then don’t change it.
  • Remember that humans make mistakes and restructing will always not garuntee that it will be atleast as good as the previous attempt. I have seen and have been part of several failed restructuring attempts

Having said all of that, sometimes you have no option but to rewrite from scratch. But IMHO that should be your last resort.

Axis2/Synapse - AMQP support via JMS Transport using Apache Qpid

June 8th, 2008  |  Published in AMQP, Axis2, Qpid, Synapse  | Add to del.icio.us

I have tested the following with Axis2 1.4 release and the up comming Synapse 1.2 release.

Documentation is broken into two sections.
It is important to read and understand the pros and cons for each option.

If you have any questions/suggestions please post on qpid-users@incubator.apache.org
And/Or open a JIRA at http://issues.apache.org/jira/browse/qpid
Your feedback is most welcomed.

  1. Configuring the JMS transport using Apache Qpid M2.1 release.
    • This version is the latest stable release and supports the 0-9 version of the AMQP protocol.
    • You can download it from here
    • It is recomended that you use the Java broker.
    • This is the recomended production version.
  2. Configuring the JMS transport using Apache Qpid trunk. (with the usual caveat that it is a less stable and a moving target).
    • The trunk supports the 0-10 version of the AMQP protocol and the next release is M3.
    • You can build it from source. https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid
    • Has the following enchancements in the JMS client over M2.1
      1. You can specify multiple binding keys per destination. i.e you could bind a queue to a particular exchange using several binding keys there by allowing you to listen from multiple sources.
      2. You can bind your queue to any exchange type using the binding URL.
      3. You can set the following options per JMS connection.
        • maxprefetch - The maximum number of pre-fetched messages per destination
        • sync_persistence - When true, a sync command is sent after every persistent message to guarantee that it has been received by the broker.
      4. A new blocking transport (as an alternative to MINA) that gives much better latency, memory and increased throughput in many cases.
      5. Currently only the c++ broker supports the 0-10 version and only works on linux.
      6. In the pipeline
        • Java Broker - expected to be in M3 release. Currently being refactored
        • C++ broker - solaris and windows port are in progress (likely to be in M3 release)

1.0 Configuring the JMS transport using Apache Qpid M2.1 release

  • 1.1 Qpid provides a convinient properties file based JNDI mechanism.
    • For provider URL please specify the location of the jndi.properties file.
    • The following link provides documentation for the jndi.properties file. JNDI How To
    • The connection URL format is given here. Connection URL format


    <parameter name="myTopicConnectionFactory">
    <parameter name="java.naming.factory.initial">org.apache.qpid.jndi.PropertiesFileInitialContextFactory</parameter>
    <parameter name="java.naming.provider.url">file:///opt/workspace/sandbox/axis2-1.4</parameter>
    <parameter name="transport.jms.ConnectionFactoryJNDIName">TopicConnectionFactory</parameter>
    </parameter>

  • 1.2 If you didn’t specify a custom destination for your service via the “transport.jms.Destination” parameter then the JMS transport will create a queue with the service name as its name. In AMQP world the above translates as follows. A queue will be created with service name as its name and will be bound to the amq.direct exchange with service name as the routing key
  • 1.3 If you specify a custom destination name via transport.jms.Destination in your services.xml then Qpid will look that up in the jndi.properties file and create queue based on the definition given in the file.
    The binding URL format is given here. Binding URL format

2.0 Configuring the JMS transport using Apache Qpid trunk
In addition to whats described above you can do the following.

  • 2.1 Specifing multiple binding keys per destination

    destination.wetherServiceQueue=topic://amq.topic/WeatherQueue?bindingkey='weather.us.*'&bindingkey='weather.ca.*'

    The above will create a queue named WeatherQueue and will bind it to amq.topic with ‘weather.us.*’ and ‘weather.ca.*’ as the binding keys. The broker will then route any messages that matches the above patterns into WeatherQueue.
  • 2.2 Binding your queue to any exchange type the broker supports by using the binding URL.

    For example if you want to bind your queue to a fanout exchange
    destination.top10StockQueue=fanout://amq.fanout/WeatherQueue

  • 2.3 Setting prefetch limit and sync_persistence per JMS connection

    amqp://username:password@clientid/test?brokerlist='tcp://localhost:5672'&maxprefetch=2000&sync_persistence=true

  • 2.4 Using the new transport

    Set -Dtransport=io when starting Axis2 or Synapse.

Read the rest of this entry »