<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Transentia &#187; SOA</title>
	<atom:link href="http://wordpress.transentia.com.au/wordpress/tag/soa/feed/" rel="self" type="application/rss+xml" />
	<link>http://wordpress.transentia.com.au/wordpress</link>
	<description>transentia pty. ltd.; development, consulting, training at the leading-edge of technology</description>
	<lastBuildDate>Thu, 17 Jun 2010 10:08:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Solving the Enterprise Integration Puzzle with Spring Integration</title>
		<link>http://wordpress.transentia.com.au/wordpress/2010/01/25/solving-the-enterprise-integration-puzzle-with-spring-integration/</link>
		<comments>http://wordpress.transentia.com.au/wordpress/2010/01/25/solving-the-enterprise-integration-puzzle-with-spring-integration/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 12:28:45 +0000</pubDate>
		<dc:creator>bob</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://wordpress.transentia.com.au/wordpress/?p=652</guid>
		<description><![CDATA[Back in May 2009, I mentioned that I had an article published in GroovyMag.
GroovyMag is very nice in that it allows the author to republish their work after a &#8216;decent&#8217; interval has passed (either 60 or 90 days, can&#8217;t quite remember at the moment). That period is well and truly passed for this article so [...]]]></description>
			<content:encoded><![CDATA[<p>Back in May 2009, I <a href="/wordpress/2009/05/05/groovymag-may-issuenow-with-added-bob-brown/">mentioned</a> that I had an article published in <a href="http://groovymag.com/">GroovyMag</a>.</p>
<p>GroovyMag is very nice in that it allows the author to republish their work after a &#8216;decent&#8217; interval has passed (either 60 or 90 days, can&#8217;t quite remember at the moment). That period is well and truly passed for this article so here it is in its full resplendency. Enjoy!</p>
<p><em>[edit]</em><br />
Forgot to <a href='http://wordpress.transentia.com.au/wordpress/wp-content/uploads/2010/01/exemplar-2009.apr.15.zip'>make the source available</a> when I first republished this article. Silly me. All fixed now!</p>
<hr />
<img src="/wordpress/wp-content/uploads/2009/05/gm7_400.jpg" alt="gm7_400" title="gm7_400" width="400" height="517" class="alignnone size-full wp-image-334" /></p>
<p><strong>Solving the Enterprise Integration Puzzle<br />
Getting Started with Spring Integration</strong></p>
<p>Groovy is frequently promoted as &#8220;the scripting language for the JVM.&#8221; Grails is often described as being &#8220;great for smaller, quick-to-build web applications.&#8221; Neither of these pieces of perceived wisdom really gives the Groovy/Grails combination its due: a powerful tool in the Systems Integrator&#8217;s armory. This article will show how Groovy and Grails&#8211;in conjunction with SpringSource&#8217;s up-and-coming &#8220;Spring Integration&#8221; project&#8211;can make complex systems integration tasks as easy as building a standalone web application.</p>
<h1>A Brief Overview of Spring Integration</h1>
<p>Systems integration is frequently likened to attempting to piece together a badly made jigsaw puzzle. The end goal is often quite fuzzy; there may be several potential solutions to consider; there may be many conflicting approaches to evaluate; and when all is said and done, sometimes all that can be done is to say &#8220;To heck with the Grand Plan!&#8221; and &#8216;adapt&#8217; the puzzle using a pair of nice sharp scissors.</p>
<p>Spring Integration (SI) is a recent project within the Spring stable that provides numerous tools to make the systems integration task less frustrating. SI builds on several existing Spring stablemates, but provides a unified way of configuring these components and linking them together. According to SI, all message endpoints (which act with and on behalf of application components) interact via messages sent over various flavors of messaging channels, perhaps undergoing various transformations along the way. In addition, external resources (files, JMS-based queueing systems, SOAP-based WebServices, etc.)  interact with these channels via simple-to-configure adapters.</p>
<p>SI imposes very little onto the developer; almost everything in the system can be implemented using simple POG/JOs (Plain Old Groovy/Java Objects) and configuration is typically via XML or Annotations.</p>
<p>SI provides out-of-the-box support for many of the patterns defined in Hohpe and Woolfe&#8217;s <em>Enterprise Integration Patterns</em> book and associated website and&#8211;as this article will show&#8211;is quite &#8220;Groovy friendly.&#8221;</p>
<h1>A Small Example Application</h1>
<p>In this article, I am going to take a very simple systems integration task and build a small example application. The application is a small Grails application that performs a simple function: given a customer number, it calculates the shipping cost for a single widget.</p>
<p>To show how Spring Integration can be used, I am assuming that a customer will enter their customer ID into a Grails-originated web page, which is then routed to one instance of a set of JMS servers. The associated address data is then retrieved, the city field extracted and then passed on to a SOAP-based WebService that calculates the cost of shipping widgets from Brisbane to the customer&#8217;s home city. To add a smidgen of realism, I have built the various services to be completely unrelated; in particular, they do not reference any form of standardized messaging schema. The integration pipeline needs to handle various simple message types, including strings, CSV-formatted data records, XML-formatted strings and floats.</p>
<p>Figure 1 provides a high-level view of the application.</p>
<p><img src="http://wordpress.transentia.com.au/wordpress/wp-content/uploads/2010/01/gm_si_image001.jpg" alt="gm_si_image001" title="gm_si_image001" width="665" height="289" class="alignnone size-full wp-image-667" /></p>
<p>Figure 1: The processing flow and major components comprising the example application</p>
<p>The various steps highlighted in this flow are:</p>
<ol>
<li>The customer ID (a simple string) is entered into the Grails web application and passed off to a generic SI gateway. The gateway places the customer ID on an internal channel that leads to a message router.</li>
<li>The router retrieves the message from its inbound channel and determines which available channel to use to ensure that the message is handled by the appropriate JMS server instance.</li>
<li>The message is then handled by a SI JMS &#8220;channel adapter,&#8221; which deals with the mechanics of working with the underlying external JMS server.</li>
<li>The nominated JMS server instance produces a record (a CSV-formatted string) that is placed onto a shared reply channel.</li>
<li>The CSV record is removed from the shared channel and transformed. The result of the transformation is an XML-formatted string which is again placed on a ‘downstream&#8217; queue.</li>
<li>The WebService channel adaptor removes the string from its request channel and invokes the external SOAP WebService for further processing.</li>
<li>The WebService response (a single float) is then passed back to the originating messaging gateway, which returns it to the Grails controller.</li>
</ol>
<p>This is a very simple system and it may seem that this is overkill. There is a payoff, however: SI makes it easy to plug in disparate (often legacy) systems and thus produces an expandable framework that is capable of being built out to cover future, more complex, situations.</p>
<h2>The Pieces of the Jigsaw Puzzle</h2>
<p>Before starting out on the integration exercise proper, it is worth taking a quick look at the various pieces of the jigsaw puzzle that are going to be joined together.</p>
<p>You will quickly see that all the pieces are exceptionally simplistic. I haven&#8217;t even tried to make them correspond to a multitude of real-life issues such as error handling, logging, configuration, etc., which have been almost completely ignored. This is by design: for the purposes of this article, I want to focus mostly on SI, not on the various services.</p>
<h2>The Grails Web Application</h2>
<p>Figure 2 shows the Grails web interface &#8220;in action.&#8221; It is very simple, with only a single form and a single results page.</p>
<p><img src="http://wordpress.transentia.com.au/wordpress/wp-content/uploads/2010/01/gm_si_image002.jpg" alt="gm_si_image002" title="gm_si_image002" width="665" height="246" class="alignnone size-full wp-image-670" /></p>
<p>Figure 2: The deployed Grails web application</p>
<p>The ‘meat&#8217; of the application (as far as this article is concerned) lies in the single Grails controller class shown in Listing 1.</p>
<pre>
public class SpringIntegrationController {

  def siGateway

  def index = { }

  def submit = {
    long start = System.currentTimeMillis()
    def msg = params.custid
    siGateway.send(msg)
    def got = siGateway.receive()
    flash.message =
      "Query took: ${System.currentTimeMillis() - start} millis."
    [shippingCost: got]
    }
  }
</pre>
<p>Listing 1: The Grails controller class</p>
<p>There are two points of interest in this simple class.</p>
<p>The siGateway instance injected from the Spring application context constitutes the sole point of contact between the Grails web application and the SI framework. (In theory, SI allows for an even less intrusive interface than this, based around dynamically constructed proxies, but a bug surfaced as I started writing the application…no matter, the hard way is not too onerous to use and I am sure that the SI guys will soon squash the bug.)</p>
<p>The submit closure is responsible for handling the POSTed form data and for driving the injected siGateway instance through its paces. It is pretty straightforward: all the action is happening over in &#8220;SI-land.&#8221;</p>
<h2>The JMS Application</h2>
<p>For the example application, I have written a very simple JMS service (using Apache ActiveMQ as the messaging provider), as shown in Listing 2.</p>
<pre>
import javax.jms.Session
import org.apache.activemq.ActiveMQConnectionFactory

public class AMQService
{
  private static factory =
	  new ActiveMQConnectionFactory("tcp://localhost:61616")

  public static void main(String[] args) throws Exception
  {
    def cKey = args[0]
    def cFile = args[1]

    println 'Starting...'
    println "Config key: $cKey"
    println "Config file: $cFile"

    def config =
      new ConfigSlurper(cKey).parse(new File(cFile).toURL())

    def database = config.database
    println "Database: $database"

    def inQ = config.inQ
    println "Incoming Queue: $inQ"

    def replyTopic = config.replyTopic
    println "Reply Topic: $replyTopic"

    def qConn = factory.createQueueConnection()
    def qSession =
      qConn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE)
    def consumer =
      qSession.createConsumer(qSession.createQueue(inQ))

    def tConn = factory.createTopicConnection()
    def tSession =
      qConn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE)
    def producer =
      tSession.createProducer(tSession.createTopic(replyTopic))

    qConn.start()
    tConn.start()

    for ( ; ; )
      process(database,
              tSession.createTextMessage(),
              consumer,
              producer)
  }

  private static process(database, replyMessage, consumer, producer)
  {
    try
    {
      def textMessage = consumer.receive()  // indefinite blocking
      replyMessage.with {
        setText(getResponse(database, textMessage.getText()))
        setJMSCorrelationID(textMessage.getJMSCorrelationID())
      }
      producer.send(replyMessage)
    }
    catch (Throwable t)
    {
      t.printStackTrace()
    }
  }

  private static getResponse(database, inMsg)
  {
    def resp = database[inMsg]
    println "Request: '$inMsg'; Response: '$resp'"
    resp
  }
}
</pre>
<p>Listing 2: The JMS server</p>
<p>This is a standard JMS service; no need to elaborate.</p>
<p>One point to note (that is not directly SI-related, but of interest nonetheless) is that the service is written to allow multiple instances to run at the same time, dealing with a partitioned data space. For the purposes of the example application, I have configured two instances. One instance is prepared to deal with customer IDs whose first character is in the range a-l and the second will deal with the rest of the alphabet.</p>
<p>The service accepts input via a uniquely-designated input queue, but sends its response to a shared topic. This structure simplifies things by ensuring that any downstream component merely has to handle a single publish/subscribe channel (which can carry data from multiple sources), rather than trying to deal with a multitude of point-to-point links.</p>
<p>Each server instance is driven by a pair of application parameters, defining:</p>
<ul>
<li>The location of the configuration file to use</li>
<li>The appropriate environment section in the designated configuration file</li>
</ul>
<p>The configuration file supplies:</p>
<ul>
<li>The name of the input queue to use</li>
<li>The name of the output topic to receive the responses</li>
<li>The actual static database to use (I did warn that these applications were extremely simple!)</li>
</ul>
<p>The service makes use of ConfigSlurper&#8217;s ability to deal with different environment sections and so I can define a single configuration file (see Listing 3) to configure the different instances uniquely.</p>
<pre>
replyTopic="SI.REPLY.TOPIC"

replyTopic="SI.REPLY.TOPIC"

environments {
  al {
    inQ="SI.AL.REQUEST"
    database=['b9876':'123 Nowhere St,Brisbane',
              'f0234':'42 Imaginary Place,Darwin']
    }
  mz {
    inQ="SI.MZ.REQUEST"
    database=['x5555':'123 Fake St,Hobart',
              'w8888':'000 Talkfest Lane,Canberra']
    }
  }
</pre>
<p>Listing 3: JMS server configuration file</p>
<p>This service accepts a string, but returns a CSV-formatted record.</p>
<h2>The WebService</h2>
<p>The final part in the jigsaw puzzle is a SOAP WebService built on top of the facilities provided by GroovyWS.</p>
<p>The service&#8217;s raison-d&#8217;être is to retrieve the cost of shipping <em>n</em> widgets between major cities in Australia; see Listing 4 and Listing 5.</p>
<pre>
public class ShippingCostWebService {

  static costs = [
    Brisbane: [ Brisbane:0.0F,
                Darwin:44.44F,
                Canberra:22.22F,
                Hobart:88.88F ],
    Darwin: [ Brisbane:44.44F,
              Darwin:0.0F,
              Canberra: 33.33F,
              Hobart: 99.99F ],
    Canberra: [ Brisbane:22.22F,
                Darwin:33.33F,
                Canberra: 0.0F,
                Hobart: 77.77F ],
    Hobart: [ Brisbane:88.88F,
              Darwin:99.99F,
              Canberra: 77.77F,
              Hobart: 0.0F ],
  ]

  Float calculateShippingCost(String fromLoc,
                              String toLoc,
                              Integer nItem) {
    def cost = costs[fromLoc][toLoc] * nItem
    println "calculateShippingCost($fromLoc,$toLoc,$nItem) => $cost"
    cost
    }
}
</pre>
<p>Listing 4: The shipping cost WebService</p>
<pre>
println 'Starting...'

def ws = new groovyx.net.ws.WSServer()

ws.setNode("ShippingCostWebService",
           "http://localhost:6980/ShippingCostWebService")

ws.start()

println '...Started.'
</pre>
<p>Listing 5: The GroovyWS WebService server harness</p>
<p>I can&#8217;t lie! This is just an old WebService that I had lying around that I created for a conference presentation, and which I have adopted for this application. It doesn&#8217;t have a customized API and isn&#8217;t necessarily a perfect fit to the task. In the systems integration world, improvisation is often required to squeeze data out of the numerous ‘sub-optimal&#8217; nooks and crannies that are found all over an enterprise.</p>
<h1>Joining the Pieces Together</h1>
<p>Now that you are familiar with the basic componentry, it is time to look at SI proper.</p>
<p>As with any Spring project, SI is configured separately to the actual code in an application. Since this application is based on Grails, I have chosen to use the nice resources.groovy Grails Spring Beans DSL configuration file, rather than the ‘traditional&#8217; XML-based configuration.</p>
<p>Listing 6 shows the complete configuration.</p>
<pre>
beans = {
  xmlns si:"http://www.springframework.org/schema/integration"
  xmlns jms:"http://www.springframework.org/schema/integration/jms"
  xmlns stream:"http://www.springframework.org/schema/integration/stream"
  xmlns ws:"http://www.springframework.org/schema/integration/ws"

  // SI componentry and plumbing
  si {
    poller(default: true) {
      "interval-trigger"(interval: 1, "time-unit": "SECONDS")
    }
    router("input-channel": "routerChannel",
           ref: "highLowRouter",
           method: "route")
    transformer("input-channel": "InboundTopic",
                "output-channel": "TransformedInbound",
                ref: "csvStringTransformer",
                method: "transform")
    channel(id: "routerChannel")
    channel(id: "ALOutboundChannel")
    channel(id: "MZOutboundChannel")
    channel(id: "RoutingRejectChannel") {
      queue(capacity: "256")
    }
    channel(id: "TransformedInbound") {
      queue(capacity: "16")
    }
    channel(id: "InboundTopic") {
      queue(capacity: "16")
    }
    channel(id: "ShippingCostChannel",
            dataType: "java.lang.Float") {
      queue(capacity: "16")
    }
  }

  stream {
    "stderr-channel-adapter"(channel:"errorChannel",
                             "append-newline": true)
  }

  // WebService stuff
  ws {
    "outbound-gateway"("request-channel": "TransformedInbound",
                       "reply-channel": "ShippingCostChannel",
                        uri: "http://localhost:6980/ShippingCostWebService")
  }

  // AMQ/JMS stuff
  connectionFactory(org.apache.activemq.pool.PooledConnectionFactory) { bean ->
    bean.destroyMethod = "stop"
    connectionFactory = { org.apache.activemq.ActiveMQConnectionFactory cf ->
      brokerURL = "tcp://localhost:61616"
    }
  }

  "AL.REQUEST"(org.apache.activemq.command.ActiveMQQueue, "SI.AL.REQUEST")
  "MZ.REQUEST"(org.apache.activemq.command.ActiveMQQueue, "SI.MZ.REQUEST")
  "REPLY"(org.apache.activemq.command.ActiveMQTopic, "SI.REPLY.TOPIC")

  jms {
    "outbound-channel-adapter"(channel: "ALOutboundChannel",
                               destination: "AL.REQUEST")

    "outbound-channel-adapter"(channel: "MZOutboundChannel",
                               destination: "MZ.REQUEST")

    "message-driven-channel-adapter"(channel: "InboundTopic",
                                     destination: "REPLY")
   }

  // general componentry
  siGateway(org.springframework.integration.gateway.SimpleMessagingGateway) {
    requestChannel = ref("routerChannel")
    replyChannel = ref("ShippingCostChannel")
    replyTimeout = "10000"
  }

  highLowRouter(au.com.transentia.si.LookupRouter)

  csvStringTransformer(au.com.transentia.si.CsvTransformer) {
    homeBase = 'Brisbane'
  }
}
</pre>
<p>Listing 6: The Spring Integration configuration</p>
<p>As you read the following discussion, you may find it useful to refer back to Figure 1.</p>
<p>The configuration is structured into various sections, according to the needs of SI and of the various resources that are being integrated.</p>
<p>The si section (more precisely, those elements of SI configured via the XML namespace allocated the si prefix in this document) configures the various aspects of SI itself. This includes establishing the various channels that interlink the components, defining a few application-specific components (such as the router and transformer), and putting in place a default polling schedule for those parts of SI that need to poll.</p>
<p>It is worth examining the router and transformer components here. I have mentioned that the JMS services deal with a partitioned data space and that traffic is directed to an individual service based on the actual data message being processed. SI allows for the definition of an application-specific router to perform this type of task, in this case the method route of the highLowRouter instance. Listing 7 shows the code for the router.</p>
<pre>
package au.com.transentia.si

public class LookupRouter {

  public String route(String msg) {
    switch(msg) {
      case ~/(?i:[a-l].*)/: return 'ALOutboundChannel'
      case ~/(?i:[m-z].*)/: return 'MZOutboundChannel'
      default: return 'reject'
    }
  }
}
</pre>
<p>Listing 7: The router class</p>
<p>The router examines the incoming message data and determines the appropriate outbound path for the message. Groovy&#8217;s wonderfully versatile switch statement, combined with the ability to do case-independent pattern matching, makes for beautifully minimalistic code.</p>
<p>The transformer is equally simple, as Listing 8 shows.</p>
<pre>
package au.com.transentia.si

public class CsvTransformer {
  def homeBase

  public String transform(String csv) {
    def dest = csv.tokenize(',')[1]

    """<def :calculateShippingCost xmlns:def="http://DefaultNamespace">
         </def><def :arg0>$homeBase</def>
         <def :arg1>$dest</def>
         <def :arg2>1</def>
      """
  }
}
</pre>
<p>Listing 8: The transformer class</p>
<p>This code is presented with an input CSV-formatted record, extracts the relevant field, and passes an XML-formatted string onwards.</p>
<p>Recall that the WebService&#8217;s API is not custom-built for the purpose of this application; for this use, arg2 (the nItems parameter) is always fixed at 1.</p>
<p>The stream section of the configuration merely allocates a generic channel listener so that the standard errorChannel is not silently ignored; this configuration will ensure that errors/exceptions, etc., are logged.</p>
<p>The ws section deals&#8211;unsurprisingly&#8211;with WebService integration. The section configures an SI outbound gateway that is capable of receiving a request on a specified channel, invoking the configured WebService and finally sending the result to the appropriate response channel. All this is specified declaratively: the actual mechanism of dealing with the WebService (retrieving WSDL documents, generating proxies and handling XML-based request/response messages) is completely hidden away.</p>
<p>The remaining configuration concerns SI&#8217;s JMS adapter and ActiveMQ integration.</p>
<p>The siGateway has been discussed previously.</p>
<p>By default, all SI&#8217;s JMS adapters reference a bean with the standard name of connectionFactory. It is the responsibility of this bean to ‘vend&#8217; connections to the external JMS system. In this case, a connection pool to a local Apache ActiveMQ server running at the URL &#8220;tcp://localhost:61616&#8243; is being created. Since the external connections are pooled for efficiency, by specifying destroyMethod=&#8217;stop&#8217; we ensure that they are simply inactivated after each (re)use and are never actually discarded.</p>
<p>Note: I found the actual syntax used to declare the connectionFactory a little tricky. I had to ask for help on the excellent user@grails.codehaus.org mailing list to get it right! Thanks to the generous souls who pointed me in the right direction.</p>
<p>Following the definition of the the connectionFactory, we create two instances of ActiveMQ queues and an instance of an ActiveMQ topic. It is these that carry the messages to/from the external JMS resources.</p>
<p>The jms section configures two JMS-specific outbound channel adapters and one inbound channel adapter. As the names suggest, these are concerned with driving (or being driven by) the ActiveMQ instances declared above. The configured message-driven-channel-adapter instance defines a component that will be asynchronously &#8220;actively invoked&#8221; to handle an incoming message. It is possible to configure a polling-oriented component, but this is generally less flexible, and may waste CPU, and increase the latency in the system.</p>
<p>As with the WebService gateway, everything is declarative.</p>
<h1>Admiring the Finished Puzzle</h1>
<p>SI has enabled a deceptively simple solution to a fairly complex problem. There are no messy tracts of confusing mechanistic code; the system is essentially defined all in a single configuration; the individual components are simple and (generally) reusable; and the groundwork for coping with change set with very little effort.</p>
<p>SI is a simple but powerful toolkit; the example application I have discussed here has really just touched the surface of what is possible. SI provides much more, including facilities for secure channels, inbound/outbound mail handling, event handling, RMI integration and much better XML handling than I have touched upon here.</p>
<p>Remember that these are still early days for SI: for example, there are no debuggers or GUI editors as found in the big &#8220;name brand&#8221; systems integration tools. In time these tools may come but for now remember that SI is orders of magnitude simpler, and the SI/Groovy/Grails triumvirate makes the developer many times more productive than some other tools I have used.</p>
<p>I hope that I have stimulated your interest in SI and shown that a Grails application need not be limited to serving up &#8220;little web apps&#8221; but can actually service the needs of larger-scale systems integration tasks.</p>
<p>I hope that I have also been able to show that when the time comes to get out the scissors, Groovy is more than equal to the task of &#8220;slicing and dicing&#8221; until the pieces of the systems integration jigsaw puzzle fit nicely together.</p>
<h1>Learn More</h1>
<ul>
<li>Gregor Hohpe and Bobby Woolf, <em>Enterprise</em><em> Integration Patterns : Designing, Building, and Deploying Messaging Solutions (ISBN 0321200683)</em>, also <a href="http://www.enterpriseintegrationpatterns.com/">http://www.enterpriseintegrationpatterns.com/</a></li>
<li>Spring Integration Home, <a href="http://www.springsource.org/spring-integration">http://www.springsource.org/spring-integration</a></li>
<li>Apche ActiveMQ, <a href="http://activemq.apache.org/">http://activemq.apache.org</a></li>
<li>GroovyWS, <a href="http://docs.codehaus.org/display/GROOVY/GroovyWS">http://docs.codehaus.org/display/GROOVY/GroovyWS</a>. The exemplar application uses the 0.5 snapshot jars from <a href="http://snapshots.dist.codehaus.org/groovy/distributions/groovyws/">http://snapshots.dist.codehaus.org/groovy/distributions/groovyws/</a></li>
</ul>
<p><em>Bob Brown is the director and owner of Transentia Pty. Ltd.. Based in beautiful Brisbane, Australia, Bob is a specialist in Enterprise Java and has found his niche identifying and applying leading-edge technologies and techniques to customers problems.</em></p>
<hr />
Watch out for my other Groovymag articles&#8230;coming soon to a browser near you.</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.transentia.com.au/wordpress/2010/01/25/solving-the-enterprise-integration-puzzle-with-spring-integration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SOAP/WebServices Courseware: Now DonationWare</title>
		<link>http://wordpress.transentia.com.au/wordpress/2009/07/05/soapwebservices-courseware-now-donationware/</link>
		<comments>http://wordpress.transentia.com.au/wordpress/2009/07/05/soapwebservices-courseware-now-donationware/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 08:14:47 +0000</pubDate>
		<dc:creator>bob</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[DonationWare]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://wordpress.transentia.com.au/2009/07/05/soapwebservices-courseware-now-donationware/</guid>
		<description><![CDATA[DonationWare!  
I am opening up old courseware to the world on a &#8220;pay if you like it&#8221; or have it free basis. 
My fourth offering is SOAP/WebServices Overview.
(You will find other offerings in this site&#8217;s DonationWare Category.)
This course was created in mid-2003.
It was a quick, one-day overview/review of the current &#8220;state of the art.&#8221;
How [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&#038;hosted_button_id=6565587">DonationWare!</a> <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&#038;hosted_button_id=6565587"><img src="https://www.paypal.com/en_AU/i/btn/btn_donate_SM.gif" align="middle" border="0"/></a> </p>
<p>I am opening up old courseware to the world on a &#8220;pay if you like it&#8221; or have it free basis. </p>
<p>My fourth offering is <em>SOAP/WebServices Overview</em>.<br />
(You will find other offerings in this site&#8217;s <a href="/wordpress/category/donationware/">DonationWare Category</a>.)</p>
<p>This course was created in mid-2003.</p>
<p>It was a quick, one-day overview/review of the current &#8220;state of the art.&#8221;</p>
<p>How things change!</p>
<p>I remember  going down to Sydney to give this course on behalf of &#8220;A Famous Database Company&#8221; for a group of South Korean V.I.P.s&#8230;who (it turned out) did not speak ANY English. The poor translator almost had a nervous breakdown. It was a very strange session, almost surreal!</p>
<p>Here&#8217;s the &#8216;blurb&#8217;:</p>
<div style="padding-left:10px;padding-right:10px;margin-left:20px;margin-right:20px;background:#FFFFCC;">
<br />
The new internet-focussed software architectures now on the drawing boards of the World-Wide Web Consortium (W3C) and the major vendors are being planned around a triumvirate of standards-oriented XML-based technologies: SOAP, the Simple Object Access Protocol; WebServices; and UDDI, the Universal Description Discovery and Integration system. These new technologies are fated to become ever more important as they slowly assume the role of underpinning major initiatives such as Microsoft’s .NET and grow to provide the foundation for much of what HP, IBM and the various members of the open source community are intending to provide for the next iteration of the Internet. </p>
<p>This session will provide an overview of the new business-to-business technologies that are being promulgated for what some cynics have called “basically a more object-oriented, somewhat buzzword-compliant upgrade to CGI” and others have more charitably called the “grown up internet.”</p>
<p>&nbsp;
</p>
</div>
<p>The course is now well and truly at End of Life.</p>
<p>I figure that it would be such a pity for it to end as a set of bits decaying away on my hard disk so I am opening it up to the world on as &#8220;as-is&#8221; basis:</p>
<p><a href="/wordpress/wp-content/uploads/2009/07/sws-courseware-donationware.04.july.2009.zip">sws-courseware-donationware.04.july.2009.zip</a><br />
(MD5: 150f88d70d5a86d1129af4e21059594c; size:  6,692,573 bytes)</p>
<p>Some (unfortunately necessary) legalese:</p>
<ul>
<li>This content is provided &#8220;as-is&#8221;, with no guarantees.
</li>
<li>Feel free to use it, but not to abuse it (to give a couple of examples: don&#8217;t make hundreds of copies for friends; don&#8217;t claim it as your own work).
</li>
<li>I retain copyright, so &#8220;<a href="http://en.wikipedia.org/wiki/All_rights_reserved">all rights reserved</a>.&#8221;
</li>
</ul>
<p>Enjoy!</p>
<p>If you like it, or have any questions/comments, send me an email (<em><script type="text/javascript">
// obfuscate this stuff...
var who = 'soapwebservicescoursewaredonationware'
var a = 'transentia'
var b = 'com'
var c = 'au'
var s = who + '@' + a + '.' + b + '.' + c;
document.write(s)
</script></em>).</p>
<p>If you find this material useful, <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&#038;hosted_button_id=6565587">please consider paying me a small amount</a>: <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&#038;hosted_button_id=6565587"><img src="https://www.paypal.com/en_AU/i/btn/btn_donate_SM.gif" align="middle" border="0"/></a> via PayPal.</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.transentia.com.au/wordpress/2009/07/05/soapwebservices-courseware-now-donationware/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Is SOA Dead?</title>
		<link>http://wordpress.transentia.com.au/wordpress/2009/05/28/is-soa-dead/</link>
		<comments>http://wordpress.transentia.com.au/wordpress/2009/05/28/is-soa-dead/#comments</comments>
		<pubDate>Thu, 28 May 2009 08:59:22 +0000</pubDate>
		<dc:creator>bob</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://wordpress.transentia.com.au/2009/05/28/is-soa-dead/</guid>
		<description><![CDATA[The title of a nice summary on infoq.
A few gems:
So having vendors claiming &#8220;we are still shifting products&#8221; while analysts who told people to go and buy those products are now complaining that they haven&#8217;t seen the value really is just a farce&#8230; SOA hasn&#8217;t failed, what has failed is the next generation lipstick on [...]]]></description>
			<content:encoded><![CDATA[<p>The title of a <a href="http://www.infoq.com/news/2009/05/SOADead">nice summary</a> on infoq.</p>
<p>A few gems:</p>
<blockquote><p>So having vendors claiming &#8220;we are still shifting products&#8221; while analysts who told people to go and buy those products are now complaining that they haven&#8217;t seen the value really is just a farce&#8230; SOA hasn&#8217;t failed, what has failed is the next generation lipstick on the pig, buy my technology it will save your problems, do a big project it will fix everything style of IT that has <strong>always failed</strong>.</p>
</blockquote>
<p>And:</p>
<blockquote><p>&#8230;those companies that have not yet started a SOA initiative did so because they could not articulate and demonstrate its business value.</p>
</blockquote>
<p>And even:</p>
<blockquote><p>&#8230;you should probably avoid using the word &#8220;SOA&#8221; and instead focus your efforts on building &#8220;services&#8221; that deliver measurable value to the business.</p>
</blockquote>
<p>What a horrifying idea: &#8220;deliver measurable value to the business&#8221;! What will they think of next ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.transentia.com.au/wordpress/2009/05/28/is-soa-dead/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SoapUI 3.0 Beta</title>
		<link>http://wordpress.transentia.com.au/wordpress/2009/05/27/soapui-30-beta/</link>
		<comments>http://wordpress.transentia.com.au/wordpress/2009/05/27/soapui-30-beta/#comments</comments>
		<pubDate>Wed, 27 May 2009 09:02:22 +0000</pubDate>
		<dc:creator>bob</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://wordpress.transentia.com.au/2009/05/27/soapui-30-beta/</guid>
		<description><![CDATA[Is available.
Improvements include reporting and upgraded Groovy support.
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.soapui.org/">Is available</a>.</p>
<p><a href="http://www.soapui.org/new_and_noteworthy_3_0.html">Improvements</a> include reporting and upgraded Groovy support.</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.transentia.com.au/wordpress/2009/05/27/soapui-30-beta/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SOA Source Book</title>
		<link>http://wordpress.transentia.com.au/wordpress/2009/05/14/soa-source-book/</link>
		<comments>http://wordpress.transentia.com.au/wordpress/2009/05/14/soa-source-book/#comments</comments>
		<pubDate>Thu, 14 May 2009 20:33:41 +0000</pubDate>
		<dc:creator>bob</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://wordpress.transentia.com.au/2009/05/14/soa-source-book/</guid>
		<description><![CDATA[The Open Group&#8217;s SOA Source Book is a collection of source material for use by enterprise architects working with Service-Oriented Architecture.
Useful grist for the mill&#8230;
]]></description>
			<content:encoded><![CDATA[<p>The Open Group&#8217;s <a href="http://www.opengroup.org/projects/soa-book/">SOA Source Book</a> is a collection of source material for use by enterprise architects working with Service-Oriented Architecture.</p>
<p>Useful <a href="http://en.wikipedia.org/wiki/Gristmill">grist</a> for the mill&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.transentia.com.au/wordpress/2009/05/14/soa-source-book/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Useful SOA Reference Site</title>
		<link>http://wordpress.transentia.com.au/wordpress/2009/03/19/a-useful-soa-reference-site/</link>
		<comments>http://wordpress.transentia.com.au/wordpress/2009/03/19/a-useful-soa-reference-site/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 23:16:43 +0000</pubDate>
		<dc:creator>bob</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://wordpress.transentia.com.au/2009/03/19/a-useful-soa-reference-site/</guid>
		<description><![CDATA[http://www.soapatterns.org/, a site dedicated to the on-going development and expansion of the SOA design pattern catalog.
I came across it when I was trying to remind myself what VETRO stood for (&#8221;Validate, Enrich, Transform, Route, Operate&#8221;&#8230;I simply could not remember what the &#8216;O&#8217; was for&#8230;) .
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.soapatterns.org/">http://www.soapatterns.org/</a>, a site dedicated to the on-going development and expansion of the SOA design pattern catalog.</p>
<p>I came across it when I was trying to remind myself what <a href="http://it.toolbox.com/blogs/the-soa-blog/soa-integration-architect-4023">VETRO</a> stood for (&#8221;Validate, Enrich, Transform, Route, Operate&#8221;&#8230;I simply <em>could not</em> remember what the &#8216;O&#8217; was for&#8230;) .</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.transentia.com.au/wordpress/2009/03/19/a-useful-soa-reference-site/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SOA &amp; The Tarpit of Irrelevancy</title>
		<link>http://wordpress.transentia.com.au/wordpress/2009/02/25/soa-the-tarpit-of-irrelevancy/</link>
		<comments>http://wordpress.transentia.com.au/wordpress/2009/02/25/soa-the-tarpit-of-irrelevancy/#comments</comments>
		<pubDate>Wed, 25 Feb 2009 21:12:33 +0000</pubDate>
		<dc:creator>bob</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://wordpress.transentia.com.au/2009/02/25/soa-the-tarpit-of-irrelevancy/</guid>
		<description><![CDATA[InfoQ précis a nicely down-to-earth examination of &#8220;the state of SOA/BPM software and its vendors.&#8221;
Here&#8217;s a taster:
While rank and file developers go to conferences to soak in deep technical content, their peripherally technical managers (the ones who wrote some rockin&#8217; good Cobol code back in the day, but now they make decisions about modern enterprise [...]]]></description>
			<content:encoded><![CDATA[<p>InfoQ <a href="http://www.infoq.com/news/2009/02/TarpitofIrrelevancy">précis a nicely down-to-earth examination</a> of &#8220;the state of SOA/BPM software and its vendors.&#8221;</p>
<p>Here&#8217;s a taster:</p>
<blockquote><p>While rank and file developers go to conferences to soak in deep technical content, their peripherally technical managers (the ones who wrote some rockin&#8217; good Cobol code back in the day, but now they make decisions about modern enterprise architecture) go to different conferences in Palm Springs. At those conferences, they have a 2-hour morning session, run by a big tool vendor, then play golf for the balance of the afternoon. And what the vendors show them is poison.</p>
</blockquote>
<p>I just <em>love</em> the term &#8220;doodleware&#8221; the author introduces!</p>
<p>It&#8217;s a curious thing: just yesterday I was pontificating on a similar theme to a colleague; it&#8217;s nice to know that my cynical world-view is not <em>completely</em> in my own head, after all&#8230;</p>
<p>Perhaps the author wanted something along the lines of <a href="http://www.grailsflow.org/">grailsflow</a>?</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.transentia.com.au/wordpress/2009/02/25/soa-the-tarpit-of-irrelevancy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What Features Characterise &quot;Enterprise Applications&quot;?</title>
		<link>http://wordpress.transentia.com.au/wordpress/2008/11/21/what-features-characterise-enterprise-applications/</link>
		<comments>http://wordpress.transentia.com.au/wordpress/2008/11/21/what-features-characterise-enterprise-applications/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 06:03:07 +0000</pubDate>
		<dc:creator>bob</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://wordpress.transentia.com.au/2008/11/21/what-features-characterise-enterprise-applications/</guid>
		<description><![CDATA[This topic came up at lunch today&#8230;it is a contentious issue, but I&#8217;ll wade in fearlessly!
It seems to me that although there are many applications used in an enterprise, very few of them are actually deserving of the title &#8220;Enterprise.&#8221;
I am sure that this is one of those &#8220;how long is a piece of string&#8221;-type [...]]]></description>
			<content:encoded><![CDATA[<p>This topic came up at lunch today&#8230;it is a contentious issue, but I&#8217;ll wade in fearlessly!</p>
<p>It seems to me that although there are <em>many</em> applications used in an enterprise, very few of them are actually deserving of the title &#8220;Enterprise.&#8221;</p>
<p>I am sure that this is one of those &#8220;how long is a piece of string&#8221;-type arguments that can&#8217;t ever be &#8216;won&#8217; but one of the best &#8220;feature-lists&#8221; that seems to cover all the requisite bases is given in the Gartner report <a href="http://mediaproducts.gartner.com/reprints/microsoft/vol3/article2/article2.html">Magic Quadrant for Enterprise Application Servers, 2Q08</a>, which I excerpt here:</p>
<p>&#8220;&#8230;a system software product of the following minimal characteristics:</p>
<ul>
<li> Offers a &#8220;container&#8221; implementation for the execution of application software modules (SM):
<ul>
<li> The container provides a &#8220;programming model&#8221; (a set of APIs for use by the SMs).
</li>
<li> The container deploys as a long-running server operating system (OS) task (OS &#8220;daemon&#8221;).
</li>
<li> SMs are programmatically addressable on request remotely through services that are associated with the container.
</li>
<li> The container allocates and uses OS resources (memory, threads, tasks) on behalf of the individual SMs, freeing SM code from the necessity of direct interaction with the OS.
</li>
<li> The container provides resource pooling (database connections and network connections), and the pools are shared by the SMs.
</li>
</ul>
</li>
<li> Supports distributed computing (load balancing and failover clustering between container instances).
</li>
<li> Provides an API or other means for authentication and authorization by the container.
</li>
<li> Provides an API or other means for monitoring the status and minimal management (such as start and stop) of the container instance(s).
</li>
<li> Provides an API or other means to access a file system by an SM.
</li>
<li> Provides an API or other means of access to a relational DBMS (RDBMS) by an SM.
</li>
<li> Provides an API or other means of invoking SMs by an SM:
<ul>
<li> Within the same container instance
</li>
<li> Across like container instances
</li>
<li> In other unlike container types
</li>
</ul>
</li>
<li> Provides an API or other means to demarcate an atomicity, consistency, isolation, durability (ACID)-style transaction by an SM.
</li>
</ul>
<p>&#8230;&#8221;</p>
<p>In addition to all this, <a href="http://martinfowler.com/">Martin Fowler</a>, in the introduction to his book <a href="http://www.amazon.com/Enterprise-Application-Architecture-Addison-Wesley-Signature/dp/0321127420">Patterns of Enterprise Architecture</a> gives other properties:</p>
<ul>
<li> A lot of persistent data
</li>
<li> Concurrent data access
</li>
<li> A lot of user interface screens
</li>
<li> Integrate with other enterprise applications, often transactionally or in a time-sensitive fashion
</li>
<li> Lots of translation between data formats (usually for integration or reporting)
</li>
<li> Complex business &#8216;illogic&#8217;
</li>
<li> A requirement for &#8217;scalability&#8217; (meaning the application has to deal with those intangible and ill-defined issues of response time, responsiveness, latency, throughput, load sensitivity and degradation, to name but a few)
</li>
</ul>
<p>But wait, there&#8217;s more!</p>
<p>An Enterprise Application also lives in a <em>context</em>: what is the application&#8217;s <a href="http://en.wikipedia.org/wiki/Service_level_agreement">Service Level Agreement</a> and <em>how is that monitored</em>; how is that application deployed and how is it maintained; how does server/network infrastructure maintenance impact on the application; what logging facilities should be made available and <em>how are those logs to be used</em> (reporting); how is &#8216;uptime&#8217; defined and managed; etc., etc., etc.</p>
<p>Don&#8217;t forget the people! A typical Enterprise Application is not simply &#8220;install and forget&#8221;, indeed, it may resemble an overgrown baby with very particular care and feeding needs; &#8216;nanny&#8217; must have a <em>very</em> different skillset to that needed by a person skilled at managing a desktop SOE.</p>
<p>Just because an application is used in an &#8220;enterprise&#8221;, just because it is client-server, just because it is written in Java, C#, C, Python, or <a href="http://compsoc.dur.ac.uk/whitespace/">Whitespace</a>, just because it is running on JBoss Application Server, Oracle WebLogic Server, IBM WebSphere, or whatever, just because you have a load balancer in front of a load of disparate server instances, etc. doesn&#8217;t necessarily make the software worthy of the term &#8220;Enterprise.&#8221;</p>
<p>Not many applications will touch all the bases outlined here, but it should be quite clear that real Enterprise applications are hard to build and that in reality the tag &#8216;Enterprise&#8217; is a hard one for an application to earn.</p>
<p>It should also be quite clear that the tag &#8216;Enterprise&#8217; is a hard one for a <em>developer</em> to earn! </p>
<p>Truthfully, it is hard for a <em>development team</em> to earn. The days when an Enterprise application can be developed by a guy and his (C/Java/C#/&#8230;) compiler are (or should be&#8230;) long gone. Of course, that one guy can produce good, useful software having significant value to its owning enterprise but it is doubtful whether that code will qualify as true &#8220;Enterprise&#8221; grade stuff.</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.transentia.com.au/wordpress/2008/11/21/what-features-characterise-enterprise-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Another Outstanding Tool: SoapUI</title>
		<link>http://wordpress.transentia.com.au/wordpress/2008/11/21/another-outstanding-tool-soapui/</link>
		<comments>http://wordpress.transentia.com.au/wordpress/2008/11/21/another-outstanding-tool-soapui/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 10:34:02 +0000</pubDate>
		<dc:creator>bob</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://wordpress.transentia.com.au/2008/11/21/another-outstanding-tool-soapui/</guid>
		<description><![CDATA[I have used this tool &#8216;in anger&#8217; more than once, to develop and test webservices. 
I often talk to people who have heard the term &#8216;WebService&#8217; but don&#8217;t really understand what they are about and SoapUI is really excellent at showing &#8220;what&#8217;s what.&#8221; It&#8217;s also great for helping people understand that &#8220;Interfaces Matter; Implementation Tool/Language/Organisation [...]]]></description>
			<content:encoded><![CDATA[<p>I have used this tool &#8216;in anger&#8217; more than once, to develop and test webservices. </p>
<p>I often talk to people who have heard the term &#8216;WebService&#8217; but don&#8217;t really understand what they are about and SoapUI is really excellent at showing &#8220;what&#8217;s what.&#8221; It&#8217;s also great for helping people understand that &#8220;Interfaces Matter; Implementation Tool/Language/Organisation Doesn&#8217;t&#8230;&#8221; </p>
<p>Version 2.5 looks even better than what has gone before. Get it: <a href="http://soapui.org">http://soapui.org</a></p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.transentia.com.au/wordpress/2008/11/21/another-outstanding-tool-soapui/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
