tag:blogger.com,1999:blog-72925371685429785372024-02-18T18:31:04.958-08:00IntegrationSphereConfessions of a JVM tech geekAnonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.comBlogger27125tag:blogger.com,1999:blog-7292537168542978537.post-56076051798117030442015-11-06T01:59:00.002-08:002015-11-06T01:59:57.821-08:00JetBrains shot themselves in the foot with their new pricing modelI've been an avid Intellij user since ~5 years back when I finally took the dive and walked away from Eclipse. Suffice to say I've been very impressed with the tooling and consider myself as a better developer when I'm armed with it.<br />
<br />
The IDE has also been instrumental in showing me the "right way" to develop with it's hints, auto completion etc. I can therefore probably say that it has helped me shape the type of developer I am today and how I like to get stuff done.<br />
Jetbrains domination over the JVM IDE tooling market has been all but complete as nowadays you hardly see any other IDE's being used, especially not if you look at what conference speakers and other types of influencers use.<br />
<br />
This type of monopoly is always dangerous as it is really easy to get locked up with one vendor which is seldom a very good thing. Recently Jetbrains announced their new pricing model (latest <a href="http://blog.jetbrains.com/blog/2015/09/18/final-update-on-the-jetbrains-toolbox-announcement/" target="_blank">update</a>) which will mean that it becomes quite a lot more expensive for the typical Intellij Ultimate user. The <a href="https://www.reddit.com/r/programming/comments/3lfh31/final_update_on_the_jetbrains_toolbox_announcement/" target="_blank">backlash </a>was not late to be seen in their forums and on blogs as users were anxious about how a "rent-your-IDE" model would hurt them in the end.<br />
<br />
I can only speak for myself, but the first thing I did after I read the announcment was to give Netbeans a second (or perhaps tenth?) chance at winning me over. What I saw was a fairly complete IDE that except for some styling warts nowadays seems to work pretty well. We're all still waiting for the <a href="https://netbeans.org/bugzilla/show_bug.cgi?id=242387" target="_blank">ES6 support</a>, but once that is in place I think that I definitely could use it during my day to day work.<br />
<br />
<h4>
Just this day another thought crossed my mind though:</h4>
Intellij IDEA comes in two flavors, a community edition as well as the Ultimate edition.<br />
If you look at the <a href="https://www.jetbrains.com/idea/features/editions_comparison_matrix.html" target="_blank">comparison matrix</a> you'll see that the biggest missing features of the free community edition are:<br />
<br />
<ul>
<li>HTML / Javascript support</li>
<li>Server support (Run Tomcat / JBoss / Websphere et al.)</li>
<li>Framework support (Spring beans / xml context, Java EE etc..)</li>
</ul>
<br />
Now I don't know about you, but these features are stuff that I'm more than willing to give up as the typical software stack of a JVM developer has changed quite radically lately.<br />
<br />
<ul>
<li>As we're all building runnable JAR types of applications you really do not have the need to manage the typical Tomcat / Java EE servers anymore.</li>
<li>Frameworks are loosing their significance as well as more of the open source world is moving towards a library mindset rather than heavy frameworks to adapt to. Take Spark, Ratpack, RxNetty, Spring boot etc as examples.</li>
<li>HTML / Javascript is a bummer to loose, but personally I've been using Sublime coupled with some favourite plugins for that kind of environment. Sublime is mature, fast and has a lot of momentum going for it. It's a perfect solution to HTML/JS development with its abundance of linters, language and framework plugins etc.</li>
</ul>
<br />
It just strikes me that a feature complete IDE's is not as relevant in the modern JVM developer toolbox and it will be interesting to see how adoption of the new pricing model will turn out.<br />
<br />
I'm predicting that the outcome of the pricing change is that modern JVM developers will probably do one of the following:<br />
<br />
<ul>
<li>Switch to Netbeans one it's Javascript support is up to par</li>
<li>Use Intellij Community coupled with Sublime text for the front end development</li>
<li>Toss the JVM, drink the cool-aid and join the Node team</li>
</ul>
<br />
And no Eclipse, we will not let you fool us to coming back again. Don't even consider yourself as an alternative.<br />
<br />
What's your take?Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-23382461763085997902015-04-14T08:12:00.000-07:002015-04-14T08:19:13.472-07:00Ok, ok I get it... So this Node thingy IS actually quite cool...<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?skin=default"></script>
I consider myself a polyglot developer who typically uses the best tools for the particular task at hand. Nevertheless when it comes to actually building production ready applications my main language has historically been within the JVM, more times than not relying on the always trusty Java ecosystem with it's abundance of libraries and frameworks.<br />
<br />
Today I really got one of those OMGOD moments when you realize just how easy alternative technologies makes your life comparing to what you usually have to keep up with.<br />
<br />
At my current customer project we unfortunately have to deal with a remote external SOAP service, which in my and most developers opinion is a protocol born out of hell and is the perfect example of an over engineered solution to something that should be pretty simple.<br />
<br />
After dealing with a botched release due to threading problems and bugs within the SOAP framework we used I intended to switch to CXF, which is probably the most popular JAX-WS implementation in Java land.<br />
<br />
Many hours later I had a working client after tearing my hair out fighting questions such as:<br />
<br />
<ul>
<li>How do we authenticate using WS-Security</li>
<li>Which JAR's to include in the Maven build? (CXF has a lot of modules)</li>
<li>How to make the JAXB code generation behave well and produce the types of classes we need</li>
<li>How to intercept and log relevant request / responses over the wire</li>
<li>How to cope with threading, JAX-WS is not thread safe while CXF as an implementation claims to be</li>
<li>How to configure CXF to use our logging framework of choice</li>
<li>etc...</li>
</ul>
<br />
You get the idea, a lot of ceremony just to create something that could send structured data over the wire and parse responses into something that we can work with.<br />
<br />
Just out of curiosity I went ahead and started investigating how you would create a soap client in Node.js land as I have previously built a couple of lightweight internal Node apps for testing, service bridging etc. My first thought was that the cool JS kids would probably never even poke a stick at something like SOAP, so I did not expect to find any good NPM modules for it.<br />
<br />
Turns out that even JS developers aren't immune to the protocol madness of SOAP and someone actually went ahead and wrote a very clean and simple client and service module. After reading the example (<a href="https://github.com/vpulim/node-soap">https://github.com/vpulim/node-soap</a>) and about 5 minutes of experimenting I was up and running. This was what it took to create the same thing I fought for hours with CXF.<br />
<pre class="prettyprint">
npm install soap<br />
</pre>
<br />
<pre class="prettyprint">
var soap = require('soap');
var url = 'gateway.wsdl'; //local file, could also be a remote http url
var args = {};
soap.createClient(url, function(err, client) {
//WS-Security UserNameToken out of the box
client.setSecurity(new soap.WSSecurity('myUser', 'myPassword'));
//GetProducts is an operation in the wsdl
client.GetProducts(args, function(err, result) {
if (!err) {
//Do something valuable with the response, for now just log.
//Each XML element in the response would become a corresponding field on the result object
console.log(JSON.stringify(result, null, 2));
}
else {
console.log(err);
}
});
});
</pre>
<br />
So, I guess Java and CXF lost this one. And for Node... well it's something you probably should consider learning ASAP. Even if you're a grumpy old-school JVM developer like yours truly.<br />
<br />Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-71597617959417074622013-11-12T03:37:00.002-08:002013-11-12T08:00:11.940-08:00Love is in the details. Or when I really fell in love with DropwizardSo <a href="http://dropwizard.codahale.com/">Dropwizard</a> seems to be the rage around Java / Scala developers today as an extremely clean and minimalistic framework for DTRS ("Doing The Right Stuff") when it comes to serving up thick clients with REST-ful data. If you haven't checked it out yet, I urge you to.<br />
It is really one of those few frameworks that looks so shiny and sexy that you immediately start thinking about in which of your projects you could introduce it. The last time I was this enthustiastic about a new library was when I first laid my eyes on Camel, which shares the same minimalistic mindset.<br />
<br />
Now, a lot has been said about it's excellent choice of best-of-breeds libraries, the YAML configuration, server-less environment and the ability to quickly assemble healtchecks. But the tiny one thing that made me realize that the folks at Yammer really put in a lot of thought into the package was not as profound as the above points. It was a really small feature that simply tells you that these guys has been in the trenches and know what they're doing. Now, which of all features could that be?<br />
<br />
Error logging...<br />
<br />
As I started to play around with a small hello world hobby project and got my first 500 error back at me it said something like:<br />
<br />
"There was an error processing your request. It has been logged (ID 2e7c06aac7bcf2aa)."<br />
<br />
Looking into the server logs I see a stacktrace with the same ID appended:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp96sWPfkUPkNsL4NRu-uN9zaXrskKqg1z6I8wYXESC6VWi_d8gc6M_ZMm-FtfI5ITt-iqSmzCqG7Q8AMY_AlD7DvS1-wp4Mjk3YBTaVsj9sZ18ykSp52XNgZv7-5aaZw_GBj7K7KpzD1C/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> ERROR [2013-11-12 11:18:23,651] com.yammer.dropwizard.jersey.LoggingExceptionMapper: Error handling a request: 2e7c06aac7bcf2aa
! java.lang.RuntimeException: My extremely PITA error
! at se.com.eyc.employeecatalog.EmployeeCatalogue.allEmployees(EmployeeCatalogue.java:38) ~[dropwizard.jar:na]
! at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_45]
! at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_45]
! at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_45]
! at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_45]
! at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60) ~[jersey-server-1.17.1.jar:1.17.1]
! at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185) ~[jersey-server-1.17.1.jar:1.17.1] ! at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) ~[jersey-server-1.17.1.jar:1.17.1]
! at com.yammer.dropwizard.jersey.OptionalResourceMethodDispatchAdapter$OptionalRequestDispatcher.dispatch(OptionalResourceMethodDispatchAdapter.java:37) ~[dropwizard-core-0.6.2.jar:na]
! at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302) ~[jersey-server-1.17.1.jar:1.17.1]
! at com.sun.jersey.server.impl.uri.rules.ResourceObjectRule.accept(ResourceObjectRule.java:100) ~[jersey-server-1.17.1.jar:1.17.1]
! at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) ~[jersey-server-1.17.1.jar:1.17.1]
!etc....
</code></pre>
<br />
Now this is great handing out of the box for three reasons:
<br />
<ul>
<li>Your customer / client system has an ID they can refer to which you can find with a simple grep in the logs</li>
<li>The default behaviour in DW is to NOT hand your stacktrace to your clients (unlike say a plain Tomcat among others). I can not believe that you still today sometimes see customer facing sites with no configured error page. That actually happened to me just a couple of days ago when a pretty big web shop happily informed me that they had not tweaked their connection pool for the MySQL database in the backend. This is just sloppy and DW simply does the right thing for you out of the box.</li>
<li>The stacktrace actually contains the artifact id and version of the dependencies that was involved in the stack. This is pure genious as it helps tremendesly i.e. when you submit bugs since everyone can easily see which versions of what you were using.</li>
</ul>
So, just a small example why I think DW rocks and proves that the guys who built it knows what they're doing. It seems to be a stable foundation to build your next web app or service on. I sincerely hope that it can stay out of the typical OS feature creep and stay simple and lean.<br />
<br />
Til next time!Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-82316874846712006192012-12-06T02:31:00.002-08:002012-12-06T05:08:27.912-08:00Using Groovy and Camel for your scripting purposesThis topic has been displayed at other blogs, but it's such a great concept and served me very well quite recently so I think it warrants a revisit.<br />
<br />
As a JVM developer (isn't that what we ought to call us nowaday when Scala/Groovy/Clojure is all the hype?) you're often sidelined by your scripting wiz fellows when it comes to writing quick "one-off" scripts for testing purposes and what-not.<br />
<br />
I've personally gone as far as learning a bit of Python for this purpose, but I tend to miss my favorite java libraries and the ecosystem, although I must give the deepest respect to Python which is a really nice and powerful language. I must also confess that I've yet to find the time needed to become really proficient with it.<br />
<br />
On our current project we had a requirement for a one-way http multicast solution in one of our test environments, as the backend system we were mediating requests to had more test environments than the rest of the chain. In EIP patterns you'd call this a fanout, multicast proxy or something similar.<br />
<br />
Well... I thought this would be a really good fit for Camel, so I started setting up a standard Maven project. After a while it became quite obvious that while the Camel route itself was extremely small and simple, the project consisted of more Maven ceremony than actual code.<br />
<br />
As this was an application for a test environment I was really not that interested in having a full build process for it. I'd rather just have something up and running in as few lines as possible.<br />
<br />
<h3>
Well, groovy scripts + grape to the rescue...</h3>
As any of you who've dealt with Groovy programming know, it is a great language for creating standalone scripts which are compiled and executed at runtime. Although Scala is my personal #1 choice when it comes to the JVM languages and offers scripting support as well, Groovy has one up in the Grape ecosystem which I've not yet seen in the Scala world.<br />
<br />
So after moving the essential part of my application (the route) to it's own groovy script and adding a few Grape annotations to download the external Camel dependencies the solution was basically finished and executable by running "<i>groovy Multicaster.groovy</i>". Mind you, this is an extremely simple route and the dependencies will be downloaded at runtime which would be totally forbidden in a production environment. But for this purpose it fit the bill perfectly.<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp96sWPfkUPkNsL4NRu-uN9zaXrskKqg1z6I8wYXESC6VWi_d8gc6M_ZMm-FtfI5ITt-iqSmzCqG7Q8AMY_AlD7DvS1-wp4Mjk3YBTaVsj9sZ18ykSp52XNgZv7-5aaZw_GBj7K7KpzD1C/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> @Grab('org.apache.camel:camel-core:2.10.0')
@Grab('org.slf4j:slf4j-api:1.6.6')
@Grab('org.slf4j:slf4j-log4j12:1.6.6')
@Grab('log4j:log4j:1.2.16')
@Grab('org.apache.camel:camel-jetty:2.10.0')
import org.apache.camel.*
import org.apache.camel.impl.*
import org.apache.camel.builder.*
def camelContext = new DefaultCamelContext()
camelContext.addRoutes(new RouteBuilder() {
def void configure() {
from('jetty:http://0.0.0.0:6080/?chunked=false')
.convertBodyTo(byte[].class) //To read multiple times, default is InputStream which is only readable once
.removeHeader(Exchange.HTTP_PATH) //So as not to forward URI to next call...
.wireTap("seda:multicaster")
.setBody().constant(STATIC_RESPONSE);
//Using SEDA here as it implies async handoff
from("seda:multicaster")
.multicast().parallelProcessing().to(
//bridgeEndpoint is used to indicate that http headers (SOAPAction etc) should be copied
'http://testserver1:6060/myService?bridgeEndpoint=true&throwExceptionOnFailure=false', //consumer1
'http://testserver2:6060/myService?bridgeEndpoint=true&throwExceptionOnFailure=false', //consumer2
'http://testserver3:6060/myService?bridgeEndpoint=true&throwExceptionOnFailure=false', //etc...
'http://testserver4:6060/myService?bridgeEndpoint=true&throwExceptionOnFailure=false',
'http://testserver5:6060/myService?bridgeEndpoint=true&throwExceptionOnFailure=false'
);
}
final String STATIC_RESPONSE = '''\
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ipl="http://www.acme.se/ipl">
<soapenv:Body>
<ipl:ipl>OK</ipl:ipl>
</soapenv:Body>
</soapenv:Envelope>'''.stripIndent()
})
camelContext.start()
addShutdownHook{ camelContext.stop() }
synchronized(this){ this.wait() }
</code></pre>
<br />
The combination of Camel in a scripting environment is extremely powerful. Just imagine the possibilities for statistic gathering utilities etc.. Now off to some more Groovying..<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com1tag:blogger.com,1999:blog-7292537168542978537.post-14868311373973833042012-06-01T00:43:00.001-07:002012-12-06T02:43:47.438-08:00Free integration breakfast seminar in Stockholm, Oslo and CopenhagenI'd just like to inform you that we at Redpill Linpro will be hosting a series of breakfast seminars about the FuseSource line of products, meaning Camel, CXF, ActiveMQ and ServiceMix.<br />
<br />
The seminars will give you a technical quickstart to using Camel and ServiceMix in your projects and is intended for developers and architects. So there will be no fluffy slides or sales pitches but rather a more "down to the core" type of seminar with lots of coding and examples of why Camel is such an awesome integration framework to work with.<br />
<br />
If you are interested and either in the Stockholm, Oslo or Copenhagen areas, just register at the specific event. The seminar is of course free. Hope to see you there!<br />
<br />
<a href="http://www.redpill-linpro.com/breakfast-seminar-technical-introduction-fusesource-integration-products-stockholm">Stockholm (12/6)</a>
<br />
<a href="http://www.redpill-linpro.com/breakfast-seminar-welcome-technical-introduction-fusesource-integration-products">Oslo (13/6)</a>
<br />
<a href="http://www.redpill-linpro.com/fusesoure-introduktionsseminar">Copenhagen (14/6)</a>
<br />
<br />
Until next time!<br />
<br />
<br />
UPDATE<br />
<br />
I'd like to update you with the links to the presentations as well as the source code. Many thanks to all of you who attended. Especially to <a href="http://www.davsclaus.com/">Claus Ibsen</a> (the Camel project lead) who took the time to show up in the audience at the Copenhagen session.<br />
<br />
Slides at slideshare:<br />
<a href="http://www.slideshare.net/RedpillLinpro">http://www.slideshare.net/RedpillLinpro</a><br />
<br />
Code at github:<br />
<a href="https://github.com/billybong/stockGwDemo">https://github.com/billybong/stockGwDemo</a><br />
<br />Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-35818571003881888082012-03-08T05:48:00.003-08:002012-03-08T06:01:13.300-08:00Bridging between JMS and RabbitMQ (AMQP) using Spring IntegrationAn old customer recently asked me if I had a solution for how to integrate between their existing JMS infrastructure on Websphere MQ with RabbitMQ.<br /><br />Although I know that RabbitMQ has the shovel plugin which can bridge between Rabbit instances I've yet not found a good plugin for JMS <-> AMQP forwarding.<br />The first thing that came to my mind was to utilize a Spring Integration mediation as SI has excellent support for both JMS and Rabbit.<br /><br />Curious as I am I started a PoC and this is the result. It takes messages of a JMS queue and forwards to an AMQP exchange that is bound to a queue the consumer application is supposed to listen to. I used an external HornetQ instance in JBoss 6.1 as the JMS Provider, but I am 100% secure that the same setup would work for Websphere MQ as they both implement JMS.<br /><br />Be aware that I've done no performance tweaking or QoS setup yet as this is just a proof-of-concept. For a real setup you'd probably have to think about delivery guarantees versus performance and etc...<br /><br />The code will be available at a GitHub repository near you soon..<br /><br />SpringContext in XML:<br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><?xml version="1.0" encoding="UTF-8"?><br /><beans:beans xmlns="http://www.springframework.org/schema/integration"<br /> xmlns:beans="http://www.springframework.org/schema/beans"<br /> xmlns:aop="http://www.springframework.org/schema/aop"<br /> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br /> xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp"<br /> xmlns:rabbit="http://www.springframework.org/schema/rabbit"<br /> xmlns:int-jms="http://www.springframework.org/schema/integration/jms"<br /> xmlns:int="http://www.springframework.org/schema/integration"<br /> xsi:schemaLocation="http://www.springframework.org/schema/integration/amqp http://www.springframework.org/schema/integration/amqp/spring-integration-amqp-2.1.xsd<br /> http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd<br /> http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd<br /> http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms-2.1.xsd<br /> http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd<br /> http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><br /> <br /> <beans:bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"><br /> <beans:property name="environment"><br /> <beans:props><br /> <beans:prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</beans:prop><br /> <beans:prop key="java.naming.provider.url">jnp://localhost:1099</beans:prop><br /> <beans:prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</beans:prop><br /> </beans:props><br /> </beans:property><br /> </beans:bean><br /><br /> <beans:bean id="jmsQueueConnectionFactory"<br /> class="org.springframework.jndi.JndiObjectFactoryBean"><br /> <beans:property name="jndiTemplate"><br /> <beans:ref bean="jndiTemplate"/><br /> </beans:property><br /> <beans:property name="jndiName"><br /> <beans:value>ConnectionFactory</beans:value><br /> </beans:property><br /> </beans:bean><br /><br /> <!-- Channels and adapters for SI --><br /> <int-jms:message-driven-channel-adapter connection-factory="jmsQueueConnectionFactory" destination-name="myJmsQueue" channel="rabbitChannel"/><br /> <channel id="rabbitChannel"/><br /> <int-amqp:outbound-channel-adapter channel="rabbitChannel" exchange-name="fromJmsExchange" amqp-template="rabbitTemplate"/><br /> <br /> <!-- Connectivity to Rabbit --><br /> <rabbit:template id="rabbitTemplate" connection-factory="cf"/><br /> <rabbit:connection-factory id="cf" host="localhost"/><br /> <br /> <!-- Rabbit entities, to be created at context startup --><br /> <rabbit:admin connection-factory="cf"/><br /> <rabbit:queue name="fromJMS"/><br /> <rabbit:direct-exchange name="fromJmsExchange"><br /> <rabbit:bindings><br /> <rabbit:binding queue="fromJMS"/><br /> </rabbit:bindings><br /> </rabbit:direct-exchange><br /></beans:beans><br /></code></pre><br /><br />Maven POM:<br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><br /><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br /> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><br /> <modelVersion>4.0.0</modelVersion><br /><br /> <groupId>org.rl</groupId><br /> <artifactId>si.jmstorabbit</artifactId><br /> <version>0.0.1-SNAPSHOT</version><br /> <packaging>jar</packaging><br /><br /> <name>si.jmstorabbit</name><br /> <url>http://maven.apache.org</url><br /><br /> <properties><br /> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><br /> <hornet.version>2.2.5.Final</hornet.version><br /> <spring.integration.version>2.1.0.RELEASE</spring.integration.version><br /> </properties><br /><br /> <repositories><br /> <repository><br /> <id>springsource-release</id><br /> <url>http://repository.springsource.com/maven/bundles/release</url><br /> <snapshots><br /> <enabled>false</enabled><br /> </snapshots><br /> </repository><br /> <repository><br /> <id>springsource-external</id><br /> <url>http://repository.springsource.com/maven/bundles/external</url><br /> <snapshots><br /> <enabled>false</enabled><br /> </snapshots><br /> </repository><br /> </repositories><br /><br /> <dependencies><br /> <dependency><br /> <groupId>org.springframework.integration</groupId><br /> <artifactId>spring-integration-core</artifactId><br /> <version>${spring.integration.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>org.springframework.integration</groupId><br /> <artifactId>spring-integration-file</artifactId><br /> <version>${spring.integration.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>org.springframework.integration</groupId><br /> <artifactId>spring-integration-amqp</artifactId><br /> <version>${spring.integration.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>org.springframework.integration</groupId><br /> <artifactId>spring-integration-jms</artifactId><br /> <version>${spring.integration.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>junit</groupId><br /> <artifactId>junit</artifactId><br /> <version>3.8.1</version><br /> <scope>test</scope><br /> </dependency><br /> <dependency><br /> <groupId>org.springframework</groupId><br /> <artifactId>spring-context</artifactId><br /> <version>3.0.7.RELEASE</version><br /> </dependency><br /> <br /> <dependency><br /> <groupId>jboss</groupId><br /> <artifactId>jnp-client</artifactId><br /> <version>4.2.2.GA</version><br /> </dependency><br /> <br /> <br /> <dependency><br /> <groupId>org.hornetq</groupId><br /> <artifactId>hornetq-core-client</artifactId><br /> <version>${hornet.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>org.hornetq</groupId><br /> <artifactId>hornetq-jms-client</artifactId><br /> <version>${hornet.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>org.hornetq</groupId><br /> <artifactId>hornetq-jms</artifactId><br /> <version>${hornet.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>jboss</groupId><br /> <artifactId>jboss-common-client</artifactId><br /> <version>3.2.3</version><br /> </dependency><br /> <dependency><br /> <groupId>org.jboss.netty</groupId><br /> <artifactId>netty</artifactId><br /> <version>3.2.7.Final</version><br /> </dependency><br /> <dependency><br /> <groupId>javax.jms</groupId><br /> <artifactId>jms</artifactId><br /> <version>1.1</version><br /> </dependency><br /> </dependencies><br /> <br /></project><br /></code></pre>Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com5tag:blogger.com,1999:blog-7292537168542978537.post-85354733200823247352011-12-01T05:59:00.001-08:002011-12-01T06:22:53.146-08:00Gotcha when using camel-servletIn my current project I'm using Apache Camel for the integration, and I bumped into a significant "oups"-moment while using the camel-servlet component.<br /><br />I found that while I had multiple applications (WAR's) deployed I often started the wrong routes, even though I was hitting the correct endpoint url.<br /><br />Say i.e. that you have two application, A and B. Both of these has the same endpoint addresses, i.e. servlet:/myservice<br /><br />The logical thing would be that you could reach application A through:<br />http://localhost/A/myservice<br /><br />and B through:<br />http://localhost/B/myservice<br /><br />Now imagine my surprise when requests for the A application would up in the route for B. It took me a while to figure this out, but here's the reason for this...<br /><br />When you expose your routes through servlet's you are using the CamelHttpTransportServlet class. An example web.xml could be something like this:<br /><br /> <!-- Camel servlet --><br /> <servlet><br /> <servlet-name>CamelServlet</servlet-name><br /> <servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class><br /> <load-on-startup>1</load-on-startup><br /> </servlet><br /><br /> <!-- Camel servlet mapping --><br /> <servlet-mapping><br /> <servlet-name>CamelServlet</servlet-name><br /> <url-pattern>/*</url-pattern><br /> </servlet-mapping><br /><br /><br />Now, if you name your servlet the same for both applications you're actually only publishing one common servlet class. The camel servlet component does not take your context-root into account, which means that you hit the same endpoint irregardless whether you go to /A/myservice or /B/myservice. The one that gets hit is the one that was last deployed (or started).<br /><br />Ok, easily fixed I thought... Just rename the servlet-name to something more unique for each application...<br />After that my routes where no longer reachable and I was just left with 404's each time I tried to hit the endpoints.<br />After some trial and error as well as googling I found out that if you rename your servlet from the default "CamelServlet" you *have* to specify the servlet name in your endpoint uri as well.<br />That is, the endpoint in application A would be i.e.:<br /><br />servlet:/myService?servletName=AServlet<br /><br />and B:<br /><br />servlet:/myservice?servletName=BServlet<br /><br />So, the lesson is:<br /><br />- Always rename the camel servlet name, you never know which other applications will be deployed together on the same server. Your endpoints might clash with these and you'll have a mess figuring out why.<br /><br />- Always include the servletName in your endpoint uri.<br /><br />These tips should definitely be added to the documentation page to help others avoid making the same mistake.<br /><br />'til next time!Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-34294350779391335692011-09-01T06:38:00.000-07:002012-04-20T06:02:47.454-07:00Implementing your own "SOA" registry, the maven waySaw a very interesting article on InfoQ by Ben Wilcock where he described a dead simple SOA R&R using a very pragmatic approach with Maven combined with a simple HTML app.
<br /><a href="http://www.infoq.com/articles/SimpleServiceRepository">http://www.infoq.com/articles/SimpleServiceRepository</a>
<br />
<br />As an integration consultant I've worked with registries ranging from overly complex offerings (IBM Websphere Registry and Repository) to time-consuming simple wikis, but I have to say that his solution is arguably the most elegant yet.
<br />
<br />The best part is that you both get the visibility as your schemas and contracts are available to all your stakeholders, while keeping your co-developers happy by just pointing them to a Maven project to include in their dependencies.
<br />
<br />I'm definately hijacking this concept to my current project, and I find it very interesting that this solution has been under my nose all this time without reflecting on it.Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-21438201794885615652011-07-26T02:37:00.000-07:002011-07-26T02:45:17.940-07:00Camel and HornetQ as JMS providerIn my current project we're utilizing JBoss HornetQ as the messaging bus, and I wanted to try out how Camel could connect to it. My intention was to have the HornetQ instance running externally from the Camel application and connect to it. There are a bunch of examples on how to embedd HornetQ 2.2.5 (the release I'm dealing with) inside Spring, but I could'nt find a single one for how to connect to an external instance.<br /><br />For my own reference I post the working solution here which uses HornetQ's JNDI to lookup the ConnectionFactory as well as a Spring JNDI template.<br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><beans xmlns="http://www.springframework.org/schema/beans"<br /> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br /> xmlns:camel="http://camel.apache.org/schema/spring"<br /> xsi:schemaLocation="<br /> http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd<br /> http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"><br /><br /> <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"><br /> <property name="environment"><br /> <props><br /> <prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop><br /> <prop key="java.naming.provider.url">jnp://localhost:1099</prop><br /> <prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</prop><br /> </props><br /> </property><br /> </bean><br /><br /> <bean id="jmsQueueConnectionFactory"<br /> class="org.springframework.jndi.JndiObjectFactoryBean"><br /> <property name="jndiTemplate"><br /> <ref bean="jndiTemplate"/><br /> </property><br /> <property name="jndiName"><br /> <value>ConnectionFactory</value><br /> </property><br /> </bean><br /> <br /> <bean name="jms" class="org.apache.camel.component.jms.JmsComponent"><br /> <property name="connectionFactory" ref="jmsQueueConnectionFactory"/><br /> </bean><br /><br /> <camel:camelContext id="context1"><br /> <camel:route id="FirstRoute"><br /> <camel:from uri="jms:queue:inputqueue"/><br /> <camel:log logName="jmsLog" message="Got message from JMS queue:"/><br /> <camel:to uri="jms:topic:helloworld"/><br /> </camel:route><br /> </camel:camelContext><br /></beans><br /></code></pre><br /><br />And the Maven POM:<br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><?xml version="1.0" encoding="UTF-8"?><br /><project xmlns="http://maven.apache.org/POM/4.0.0"<br /> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br /> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><br /> <modelVersion>4.0.0</modelVersion><br /><br /> <groupId>camelHornet</groupId><br /> <artifactId>camelHornet</artifactId><br /> <version>1.0-SNAPSHOT</version><br /><br /> <properties><br /> <camel.version>2.8.0</camel.version><br /> <hornet.version>2.2.5.Final</hornet.version><br /> </properties><br /> <dependencies><br /> <dependency><br /> <groupId>org.apache.camel</groupId><br /> <artifactId>camel-core</artifactId><br /> <version>${camel.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>org.apache.camel</groupId><br /> <artifactId>camel-spring</artifactId><br /> <version>${camel.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>org.apache.camel</groupId><br /> <artifactId>camel-jms</artifactId><br /> <version>${camel.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>org.hornetq</groupId><br /> <artifactId>hornetq-core-client</artifactId><br /> <version>${hornet.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>org.hornetq</groupId><br /> <artifactId>hornetq-jms-client</artifactId><br /> <version>${hornet.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>org.hornetq</groupId><br /> <artifactId>hornetq-jms</artifactId><br /> <version>${hornet.version}</version><br /> </dependency><br /><br /> <dependency><br /> <groupId>javax.jms</groupId><br /> <artifactId>jms</artifactId><br /> <version>1.1</version><br /> <type>jar</type><br /> <scope>runtime</scope><br /> </dependency><br /> <dependency><br /> <groupId>org.hornetq</groupId><br /> <artifactId>hornetq-logging</artifactId><br /> <version>${hornet.version}</version><br /> </dependency><br /> <dependency><br /> <groupId>org.jboss.netty</groupId><br /> <artifactId>netty</artifactId><br /> <version>3.2.3.Final</version><br /> </dependency><br /> <dependency><br /> <groupId>jboss</groupId><br /> <artifactId>jnp-client</artifactId><br /> <version>4.0.2</version><br /> </dependency><br /> <dependency><br /> <groupId>org.jboss.logging</groupId><br /> <artifactId>jboss-logging</artifactId><br /> <version>3.0.0.CR1</version><br /> </dependency><br /> </dependencies><br /> <build><br /> <plugins><br /> <plugin><br /> <groupId>org.apache.camel</groupId><br /> <artifactId>camel-maven-plugin</artifactId><br /> <version>${camel.version}</version><br /> <configuration><br /> <applicationContextUri>META-INF/context.xml</applicationContextUri><br /> </configuration><br /> </plugin><br /> </plugins><br /> </build><br /></project><br /></code></pre>Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com5tag:blogger.com,1999:blog-7292537168542978537.post-71775711766732475422011-04-19T12:43:00.000-07:002011-04-19T13:23:44.826-07:00Three mindblowing days of filling my brain with new stuffThis week we at Redpill-Linpro had the great fortune to be instructed by Charles Moulliard (FuseSource) on advanced topics covering ServiceMix and Camel.<br /><br />Talking from my own experience I already had quite a good grasp of Camel, but ServiceMix was probably the eye-opener for me. Until now I've previously rolled my eyes each time SM was mentioned, thinking "why do we need yet another application platform when we have web servers, Spring, JEE servers etc already?".<br />What I did not understand until now is the flexibility you gain when deploying your integrations to a pure OSGI stack such as Karaf (which is the layer on top of your OSGI runtime) instead of using classic hierarchical class-loading servers.<br /><br />One thing that also was clear is that ServiceMix, although labeled as an ESB, is actually sort of an application server in the sense that it is not only used for integration applications. Sure, you have a lot of Camel/CXF/ActiveMQ bundles already prebuilt and ready to be utilized, but looking at the architecture it is plain to see that any type of OSGI applications could benefit by being deployed into Karaf.<br /><br />I can safely say that I've bought the hype of OSGI now after finally understanding what it actually gives you. I just hope for some better tooling when it comes to declaring your package exports and imports as that seems to be an area where you'll need to perform a lot of trial and error to get correct.<br /><br />We also had some good discussions concerning the fact that a lot of supplementary (Activiti, JAMES etc..) and even competing frameworks already bundle Camel to expose transport options that are not already implemented by the framework itself. JBoss ESB i.e. comes with a Camel Gateway which could be used to handle messages originating from all types of transports available in Camel that the native ESB does not have adapters for.<br />It will be very interesting to see how long it takes for the big players (IBM and Oracle, I'm looking at you) to bundle Camel as part of their connector strategy. I can easily fantasize about i.e. a future Camel node in the Websphere Message Broker product as a way to extend the possible transport that it could provide.<br /><br />'til next time!Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-12244074225245281582011-04-05T11:20:00.000-07:002011-04-05T11:34:55.196-07:00New career, new opportunitiesToday marked my first day as an employer at the open source consultant firm <a href="http://www.redpill-linpro.se/">Redpill-Linpro</a>. As you readers might have noticed, my interest in OS offerings in the integration space has recently risen up to the level where I'd like to make it into a career. Therefore I chose to switch my focus and work fulltime with the projects that has so far mostly been an interesting hobby at my spare time.<br /><br />Personally I think that change is a good thing and you should always try to give yourself new insights, challenges and other perspectives on your knowledge. Therefore I am leaving the trusty IBM stacks I've known to love for the last 6 years or so and head out into the unknown, starting with JBoss SOA products and the FuseSource projects (Camel, ServiceMix etc..).<br /><br />With that said, I am absolutely sure that I will miss all of my colleagues at Connecta since we've had some great moments and fond memories of assignments and projects (as well as some less strict endeavours in between).<br /><br />Best of luck to you all, and hope we will see each other again soon!Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-81534084548327381272011-03-22T12:31:00.000-07:002011-03-22T14:17:38.536-07:00Templating webservices with Velocity using CamelWhen creating webservices a lot of people has objections against using JAXB for binding XML to objects. This may be because of performance reasons, allergy to generated code or simply a philosophical belief that you should not mix document centric services with an object oriented model. Whatever the reasons for not using JAXB you have I'll try to describe a possible other solution using Camel.<br /><br />I created this laboration after viewing Adrian Trenamans excellent talk about CXF usage in camel, so I can and will not take credit for anything you'll see. In that talk he showed a little trick were you could use Velocity as the templating engine for generating your soap responses, without ever doing any marshalling or parsing of the XML documents.<br /><br />His complete session could be found <a href="http://download.progress.com/5331/open/adobe/fusesource/030311_FUSE_Camel_CXF_ServiceMix/index.htm">here</a>, but do note that you need a registration at fusesource.com to see it. It is free, so if you're interested I urge you to check it out.<br /><br /><br /><h2>Defining our contract</h2><br />As mostly all SOA architects would tell you should always try to start by defining a wsdl, creating the service top-down. Our intended service in this sample is going to be a very simple credit check service that accepts a customer and provides a credit score and a detailed description about the reasoning behind the score.<br /><br />Our service only has one operation for now, called PerformCreditCheck:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKP1r6NG7qEqWegXcjX4R9sqkDl6MGyBLLrdnsow8pPeOPsAoaC5_y1mMMnpDOjOFSDqvr6_p9HkANXDjJ0bLxAqf-SyzHZ7FzfclnK5hItRt2vin-uisCy2e0XTMrSmUUddR_zKv69uaw/s1600/wsdl.bmp"><img style="center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 244px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKP1r6NG7qEqWegXcjX4R9sqkDl6MGyBLLrdnsow8pPeOPsAoaC5_y1mMMnpDOjOFSDqvr6_p9HkANXDjJ0bLxAqf-SyzHZ7FzfclnK5hItRt2vin-uisCy2e0XTMrSmUUddR_zKv69uaw/s400/wsdl.bmp" border="0" alt=""id="BLOGGER_PHOTO_ID_5586992345708343762" /></a><br /><br />The response is a simple message containing the Score as well as a Details field:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGEyZrDYyhyOmaS-R8zqKxYtetRVyI2pRogNSpRThEaCdAxtt6Jcs4xOsVJRw0AIfTeKR1HT8XS4V6YRmYYO94QKREhAIZS_KTlhIP4yMd8f8geha9ryqy3XqrVRJHbAx3Gw5CM9fwZNmr/s1600/response.bmp"><img style="center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 212px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGEyZrDYyhyOmaS-R8zqKxYtetRVyI2pRogNSpRThEaCdAxtt6Jcs4xOsVJRw0AIfTeKR1HT8XS4V6YRmYYO94QKREhAIZS_KTlhIP4yMd8f8geha9ryqy3XqrVRJHbAx3Gw5CM9fwZNmr/s400/response.bmp" border="0" alt=""id="BLOGGER_PHOTO_ID_5586992734049841442" /></a><br /><br /><h2>The Camel context</h2><br />I've chosen to implement the route using the Java DSL, so after setting up the CXF endpoint in the camel context I point the package scan to the java package where my route is. The complete camel-context.xml is as follows:<br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><?xml version="1.0" encoding="UTF-8"?><br /><br /><beans xmlns="http://www.springframework.org/schema/beans"<br /> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br /> xmlns:cxf="http://camel.apache.org/schema/cxf"<br /> xsi:schemaLocation="<br /> http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd<br /> http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd<br /> http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd"><br /><br /> <import resource="classpath:META-INF/cxf/cxf.xml"/><br /> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/><br /> <import resource="classpath:META-INF/cxf/cxf-extension-http-jetty.xml"/><br /> <br /> <cxf:cxfEndpoint xmlns:c="http://billy.laborations/CreditCheckService/" id="creditCheckEndpoint"<br /> address="http://localhost:9000/creditcheck"<br /> wsdlURL="META-INF/wsdl/CreditCheckService.wsdl" <br /> serviceName="c:CreditCheckService"<br /> endpointName="c:CreditCheckServiceSOAP"<br /> serviceClass="billy.laborations.creditcheck.DummyService"><br /> <cxf:properties><br /> <entry key="schema-validation-enabled" value="true" /><br /> </cxf:properties><br /> </cxf:cxfEndpoint><br /><br /> <camelContext xmlns="http://camel.apache.org/schema/spring"><br /> <package>billy.laborations.creditcheck</package><br /> </camelContext><br /><br /></beans><br /><br /></code></pre><br /><br />As you can see I'm providing the wsdl for the service, its endpoint address as well as an implementation class.<br /><br /><h2>The JAX-WS Endpoint</h2><br />Looking at this class is where things are starting to get interesting. Since I don't want to deal with JAXB I chose the JAX-WS Provider type of service which accepts arbitrary messages. Any type of message that hits this service will kick of the invoke() method, leaving XML parsing etc up to the developer. If you look at the method however, you'll notice that it is set up to always throw an exception, how could it possibly work? Well, it seems that Camel hijacks this method and kicks of the route instead, but this class still needs to be existing in order for the CXF runtime to initialize.<br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><br />package billy.laborations.creditcheck;<br /><br />import javax.xml.transform.stream.StreamSource;<br />import javax.xml.ws.Provider;<br />import javax.xml.ws.Service.Mode;<br />import javax.xml.ws.ServiceMode;<br />import javax.xml.ws.WebServiceProvider;<br /><br />@WebServiceProvider(portName="CreditCheckPort", serviceName="CreditCheckService", targetNamespace="http://billy.laborations/CreditCheckService/")<br />@ServiceMode(Mode.PAYLOAD)<br />public class DummyService implements Provider<StreamSource> {<br /><br /> public StreamSource invoke(StreamSource request) {<br /> throw new UnsupportedOperationException("Not implemented yet.");<br /> }<br />}<br /><br /></code></pre><br /><br /><h2>Routing</h2><br />The route is implemented as:<br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><br />package billy.laborations.creditcheck;<br /><br />import javax.xml.transform.stream.StreamSource;<br /><br />import org.apache.camel.Exchange;<br />import org.apache.camel.Processor;<br />import org.apache.camel.builder.RouteBuilder;<br />import org.apache.camel.builder.xml.Namespaces;<br />import org.apache.cxf.message.MessageContentsList;<br /><br /><br />public class CreditCheckRoute extends RouteBuilder {<br /><br /> public void configure() {<br /> // lets define the namespaces we'll need in our filters<br /> Namespaces ns = new Namespaces("c", "http://billy.laborations/CreditCheckService/");<br /><br /> from("cxf:bean:creditCheckEndpoint").routeId("CreditCheckRoute")<br /> .process(new Processor(){<br /> public void process(Exchange exchange) throws Exception {<br /> <br /> //Cxf stores requests in a MessageContentList. The actual message is the first entry<br /> MessageContentsList messageList = (MessageContentsList)exchange.getIn().getBody();<br /> exchange.getIn().setBody(messageList.get(0), String.class); <br /> }<br /> })<br /> .wireTap("seda:audit")<br /> .setHeader("FirstName", xpath("/c:Customer/FirstName").resultType(String.class).namespaces(ns))<br /> .setHeader("LastName", xpath("/c:Customer/LastName").resultType(String.class).namespaces(ns))<br /> .setHeader("SocialNr", xpath("/c:Customer/SocialNr").resultType(Integer.class).namespaces(ns))<br /> .process(new CreditCheckCalculator())<br /> .to("velocity:META-INF/velocity/creditCheckResponse.vm")<br /> .convertBodyTo(StreamSource.class)<br /> ;<br /> <br /> <br /> from("seda:audit")<br /> .inOnly()<br /> .to("log:audit")<br /> .to("file:target/audit/?fileName=${date:now:yyyyMMdd}.txt&fileExist=Append");<br /> }<br />}<br /><br /></code></pre><br /><br />As you can see the route uses XPath to set some headers based on the incoming values. This is done so that our service (CreditCheckCalculator) has easy access to them.<br /><br /><h2>The business service</h2><br />I've kept the service simple in this case, but the interesting part is that it's using the camel headers for getting and setting the data. You don't have to implement the service as a camel Processor, there are a lot of ways to call i.e. an existing POJO using bean referencing, but I'll leave that for now.<br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><br />package billy.laborations.creditcheck;<br /><br />import org.apache.camel.Exchange;<br /><br />public class CreditCheckCalculator implements org.apache.camel.Processor{<br /><br /> public void process(Exchange exchange) throws Exception {<br /> String firstName = (String)exchange.getIn().getHeader("FirstName");<br /> String lastName = (String)exchange.getIn().getHeader("LastName");<br /> int socialNr = (Integer)exchange.getIn().getHeader("SocialNr");<br /> <br /> int creditScore;<br /> String details;<br /> <br /> if(firstName.equalsIgnoreCase("Billy")){<br /> creditScore = 99;<br /> details = firstName + " is a really good customer!";<br /> }else{<br /> creditScore = 1;<br /> details = firstName + " should not be trusted!";<br /> }<br /> <br /> exchange.getIn().setHeader("CreditScore", creditScore);<br /> exchange.getIn().setHeader("Details", details); <br /> }<br />}<br /><br /></code></pre><br /><br /><h2>Generating the response</h2><br />Why are the headers a good place to store the result then? Well, in our case it's because we have easy access to them from the velocity template:<br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><br /><CreditScore xmlns="http://billy.laborations/CreditCheckService/"><br /> <Score>$headers.CreditScore</Score><br /> <Details>$headers.Details</Details><br /></CreditScore><br /></code></pre><br /><br />The trick here is that we're templating our response without touching any XML API's. The velocity template will simply return a String object which we can then transform to a StreamSource before handing it back to the JAX-WS endpoint.<br /><br /><h2>Final thoughts</h2><br />Well, that sums up my experiment. It might look like a complex setup for a very simple service, but the benefits of using templating are:<br /><br />* Performance - No need to parse the request or response messages<br />* WS stack - Exposing the route as an CXF endpoints gives us all the power of soap handlers and CXF injectors for i.e. adding security etc.<br />* Adding functionality to the route - The route can easily be extended to support other EIP patterns, such as custom auditing implemented by the wiretap in our example.<br /><br />If you are interested in the code, I'll make sure to upload it. Otherwise thank you for this time!Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com1tag:blogger.com,1999:blog-7292537168542978537.post-73691009035074155012011-03-11T01:12:00.000-08:002011-03-11T01:57:41.507-08:00Mule joins the GUI groupAs open-source integration stacks are becoming more and more mature the final push to convince the market about their usability seems to be to provide some sort of GUI for developing your solutions.<br /><br />I recently blogged about FuseSource's release of the Camel IDE, and now it seems that Mule is joining the fray by recently releasing the beta of the Mule Studio Eclipse plugin.<br /><br />Read more at: <a href="http://blogs.mulesoft.org/mule-studio-beta/">http://blogs.mulesoft.org/mule-studio-beta/</a><br /><br />So now the major OS integraiton players (Camel, Mule, JBoss ESB, Spring Integration) all have visual support for developers. I guess only time will tell how these tools will be able to keep up with the quick feature changes in the frameworks.Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-26772943874238045762011-02-07T03:31:00.000-08:002011-02-07T05:41:15.578-08:00First Scala book in Swedish is out! Congrats guys!On a personal note I'd like to congratulate my professional acquaintance Örjan Lundberg and his fellows Olle Kullberg and Viktor Klang for finalizing the Scala <span>introductory book </span><span style="font-style: italic;">"Ett första steg i Scala"</span>. It's to my knowledge the first Swedish book to explain the concept of the Scala language.<span style="font-style: italic;"><br /><br /></span>You can find it at:<span style="font-style: italic;"> <a href="http://www.studentlitteratur.se/o.o.i.s?id=2474&artnr=33847-01&csid=66&mp=4918">http://www.studentlitteratur.se/o.o.i.s?id=2474&artnr=33847-01&csid=66&mp=4918</a><br /><br /></span>Congratulations guys! Hope I get the chance to read it soon!<span style="font-style: italic;"><br /></span>Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-16755261966571926702011-01-30T14:03:00.001-08:002011-01-30T14:22:06.994-08:00Camel goes visualSo it seems that the Camel guys over at FuseSource has finally released the preview of the Camel development IDE. Basically an eclipse plugin that helps you author the spring xml files for your routes visually. I haven't tried it yet, but its an interesting tool which hopefully can help attract integrators into this nice framework.<br /><br />There's already a short introduction up on their site, so head on to <a href="http://fusesource.com/">http://fusesource.com/</a> and have a look.<br /><br />According to FuseSource they're also working on a runtime web version which you could use to inspect and author your flows directly against an executing ServiceMix/Karaf JVM.<br /><br />So with Spring Integration having visual IDE support in their latest release of the STS tooling and Camel joining now it will be interesting to see what the Mule guys will bring to the table when it comes to IDE's. A sneak peak last year showed something similar (<a href="http://blogs.mulesoft.org/new-mule-ide-coming/">http://blogs.mulesoft.org/new-mule-ide-coming/</a>) and you can also have a look at Saddle IDE which seems to target Mule developers as well (<a href="http://www.saddle-integration.org/">http://www.saddle-integration.org/</a>).<br /><br />Seems like all of them are going the XML-authoring way where your IDE generates XML configs in the background.<br /><br />2011 already looks like a promising year for integration developers!Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-88651490142760031452010-12-09T05:42:00.000-08:002010-12-09T05:44:45.609-08:00Eclipse XML autocompletion patch for Mule usersEarlier I wrote about my problems finding a good XML editor which works with Mule configuration files, as the one included in Eclipse WTP does not support XSD schema substitution groups.<br /><br />That time I simply gave up and registered for a trial of the Oxygen XML eclipse plugin editor since that was the only one that I found that could give me autocompletion while modeling flows.<br />Well, it seems that the MuleSoft guys has <a href="http://blogs.mulesoft.org/overcoming-the-eclipse-xml-autocomplete-bug/">figured out a way to patch this issue with Eclipse</a>, which is very good news for the myriad of Mule users out there. This patch may also be worth downloading even if you're not intending to use Mule and regularly deal with schema substitutions in eclipse.<br /><br />I have not yet tested the patch since I've been quite busy lately on my free time, but I'm sure it will be a welcome fix for many integrators.<br /><br />Bye bye Oxygen, been nice to know you!Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-25442278770609017112010-12-01T07:47:00.000-08:002010-12-02T00:11:43.188-08:00Soap through JMS support for WCFOne of the classic problems you face when dealing with webservices is how to assure a guaranteed delivery of your messages. Since http by its definition cannot guarantee that your messages are never lost a lot of initiatives has tried to solve this problem.<br /><br />Currently this is typically handled in one of the following ways:<br /><br /><span style="font-weight: bold;">WS-Transaction</span><br />Not primary used as a means of guaranteed delivery, WS-Transaction still in some sense tries to solve the same problem with a consistency angle. I'll not dwell into the architectural reasons for WS-Transaction but simply note that it introduces a tight coupling between the service consumer and provider and is not preferable in i.e. a B2B solution. It is my firm belief that http/xml should not be used as a transaction medium since it was just not defined with that in mind in the first place. It also has performance implications as well as introduces complex call-chains and possible deadlocks.<br /><br /><span style="font-weight: bold;">WS-Reliable Messaging</span><br />Typically your provider and consumer would store outbound messages in some kind of message store and delete these first when they've been acknowledged by the other part through a conversation mechanism. Messaging platforms are often used as the persistent store, but regular databases could also be included, either as part of the messaging provider or by the WS stack.<br /><br /><span style="font-weight: bold;">Retry mechanisms and idempotent provider services</span><br />Clients simply retry the calls until a successful invocation is acheived. This puts a requirement on the provider to be idempotent either through the nature of the service, or by utilizing some framework for blocking resent requests based on a uniqueness in the message.<br /><br /><span style="font-weight: bold;">Soap through JMS</span><br />Most, if not all Java WS runtimes now support sending soap messages through a JMS provider. Soap/JMS is not yet a standard, but several providers have in fact agreed on a set of JMS properties that maps to a soap world, so it is actually quite interoperable.<br /><br />This works fine for most Java implementations, but the .NET world has (to my knowledge) been left out on this option for a while.<br />Well, today I noticed an interesting thing in the Websphere MQ 7 documentation which apparently has support for hooking in WCF services/consumers to the Soap/JMS space. IBM has implemented transport interceptors that could be configured on WCF components. These are bundled with the MQ7 client and as far as I can see does not change either the MQ setup or your .NET code.<br /><br /><a href="http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/topic/com.ibm.mq.csqzav.doc/un12000_.htm">http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/topic/com.ibm.mq.csqzav.doc/un12000_.htm</a><br /><br />To me this is very good news as that makes Soap through JMS a valid alternative to the quite complicated stacks above even when you're looking for Java-WCF interoperability and guaranteed deliveries, given that IBM WMQ is already a part of your infrastructure.<br /><br />Once again messaging comes to the rescue! Either as the actual transport layer or as a building block for enabling WS-Reliable Messaging.<br /><br />Now I just have to bribe some .NET programmer to hook up with for a lab since my .NET skills are, lets say.. nonexistent at the momentAnonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-51203023496370086372010-11-23T07:24:00.000-08:002010-11-23T07:24:52.272-08:00Software Development Thoughts: Logging Do's and Dont'sWhat every java programmer must know...<br /><a href="http://blog.lidalia.org.uk/2010/11/logging-dos-and-donts.html">Software Development Thoughts: Logging Do's and Dont's</a>Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-15885415893497489072010-11-19T11:31:00.000-08:002011-02-27T12:15:11.160-08:00Comparing OSS offerings, like comparing apples to orangesRounding up the OSS integration frameworks described earlier is not easy and by no means a task of selecting an overall "winner". I've only scratched the surface on them, and most of the experience comes from testing simple samples, reading forums and blogs and in some cases implementing small solutions. There are also a bunch of frameworks that I haven't had time to test yet, so I'll focus on Mule, WSO2 and Apache Camel. Note that these are my personal reflections and experiences, so if you disagree completely, feel free to post so and call me a moron (maybe you're right :-)<div><br /></div><div><span class="Apple-style-span" style="font-size:large;">Mule ESB</span></div><div>Marketed as the "most popular" open source ESB this was a good alternative to start with.</div><div>Mule is quoted as a stand-alone ESB and offers a wealth of connectivity options. The Mulesoft company behind it are very commited to the product and posts regular updates to the documentation as well as blogs.</div><div>However, the configurations are all designed by editing a quite cumbersome XML files which might offput some users wishing for less "bracket coding". Editing these files is only more constrained by the amount of schemas that needs to be included, i.e. each transport has its own schema and restrictions.</div><div>It supports a stand-alone runtime, hot deployments and extra functions such as registries and management consoles if you opt for the Enterprise license.</div><div>Mule was not created with EIP in mind from the startup, but updates in the most recent version made it easier to design flows through the "flow" construct even though I've already found some bugs while using it.</div><div><br /></div><div><span class="Apple-style-span" style="font-size:large;">WSO2 ESB</span></div><div>Out of the three, wso2 is the only one that requires sort of an application server to run in the form of the Carbon server.</div><div>However, the management console is outstanding with its included support for statistics and registry. You also have the option to graphically design your integrations which is always good for beginners.</div><div>There are three things that bother me with WSO2 at the moment though:</div><div><br /></div><div>- Big focus on the WS-stack, which is not surprising given the WSO2 team background. If you're after a webservice framework, this product is perhaps the most promising of the three, but as far as I see it might not be perfectly suited for other integration scenarios.</div><div><br /></div><div>- Synapse. WSO2 is built upon Apache Synapse, a project that doesn't have as much community activity as the other two alternatives. Only the future will tell if it will grow in the same pace as the other ones, but I'm at least a bit concerned about its future.</div><div><br /></div><div>- The need for an application server</div><div>This might be a political issue, but I'd think it will be more difficult to sell in a new application server to your management than a simple API runtime. Other might see this as a strength, but when you're already sitting on a stack of servers you'll undoubtley will get the question why you'll need another one.</div><div><br /></div><div><span class="Apple-style-span" style="font-size:large;">Apache Camel</span></div><div>The most lightweight alternative of the three I've tested and probably the most flexible as well.</div><div>Since Camel is built as an implementation of the EIP patterns it fits right in to creating integration flows, which is the logical way of implementing integration.</div><div>With Camel you get alternatives wherever you go. Do you wish to develop your flows through XML? Or maybe java? Or perhaps Scala or Groovy? Would you like to execute it in a spring environemnt? Or as a routing component inside the ServiceMix OSGi runtime? Or inside a web application? Options everywhere... Which is acutally a good thing! Hopefully your team and organisation can settle with one and develop best practices using the one you prefer. Otherwise you could end up with a mess of implementations, but this holds true for all types of development environments, so its not a problem per se.</div><div><br /></div><div>The only downside I could possibly think of when using camel is that since it's so easy to use you might start putting integration logic all over your projects instead of at a central ICC team of integrators and designers. Integration is a very complex area and should be handled by dedicated staff with end-to-end focus in mind. Camel with it flexibility and pragmatic approach might lead you to solving integration tasks as part of application projects, but as you can see I'm only nitpicking for a possible future problem here.</div><div><br /></div><div>I especially like the fact that they've started to experiment with Scala as a a first-class citizen as I personally see a great future in Scala. Having this support from the start gives me hope that this component will have a long future even after Java has been declared as "dead" or legacy.</div><div><br /></div><div>As noted these are just my first impressions of the frameworks and I might be proven wrong or have missunderstood some parts of them, so take these words with a grain of salt.</div><div>There are also a lot of alternatives that I haven't been able to try out extensively yet, for example JBoss ESB, ServiceMix and Spring Integration 2.0 which looks promising. So many toys, so little time...</div><div><br /></div><div>See you soon!</div>Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com2tag:blogger.com,1999:blog-7292537168542978537.post-59624162477199700272010-11-17T07:48:00.000-08:002011-02-27T12:17:21.843-08:00Climbing the Camel<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sassywire.files.wordpress.com/2010/02/camel.jpg"><img style="float: left; margin: 0pt 10px 10px 0pt; cursor: pointer; width: 200px; height: 188px;" src="http://sassywire.files.wordpress.com/2010/02/camel.jpg" alt="" border="0" /></a><br />I remember my first ride with a live camel during one of our family vacations half a lifetime ago. It was a quite challenging task just to get up on the beast, and even hairier when this huge animal started to move. Rocketing back and forth it eventually managed to instill some sense of trust as it started to swaggle on with me sitting high atop on its back. After the first terror waned, the experience was actually simply a blast!<div><br /></div><div><br /></div><div><br /></div><div>Well, recently I had the chance to climb up to the camel's back again, but now in another context. This camel was maybe even more scarier as I had never seen something quite like it and I was first startled by its complexity. But again, once it started moving I understood the pure beauty of the beast and felt safe and secure again.</div><div><br /></div><div>I'm of course talking about Apache Camel, the lightweight OSS framework for designing and executing integration flows. It takes a pragmatic aproach to integration and has a very clean and efficient way of defining your integration logic between separate endpoints.</div><div>Camel is all about lightweight integration, and even though it does not qualify as a complete ESB since it misses some important parts such as manageability and hot deployments of your solutions, it certainly has some features which puts it right into the Enterprise integration space.</div><div><br /></div><div>First of all one has to understand that camel is not an integration product per se, but rather an API for defining integration patterns. It does not execute by itself but should preferably be bundled together with some existing hosting environment i.e. JBI, Spring applications, your messaging engine, an application server or what not.</div><div><br /></div><div>Setting up a Camel project is easy, since you could start out from Maven archetypes found on the Camel website. These will help you download all dependencies and create your Spring context. Camel does not force you to use either Maven or Spring, but much of the samples and tutorials on the net (and the documentation) assumes that you're already an experienced Maven/Spring user. After passing these first hurdles (which really had mostly to do with setting Maven up correctly) I was able to try out my first flows.</div><div><br /></div><div>You have several options for choosing how to define your integration logic. The two major ones are through either Spring xml files similar to i.e. Mule ESB or a fluid Java API. There are also options for Scala and Groovy if that's your fashion. No matter which, the flow executes the same way as the design languages are only a means to model your integrations.</div><div><br /></div><div>This separation is quite brilliant as it allows you to select the technology you are most proficient with, and the runtime will adapt. It also means that cross-functions such as automatic documentation is supported no matter which language you choose.</div><div><br /></div><div><span class="Apple-style-span" style="font-size:medium;"><h2><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-size:medium;"></span></span></h2><h2>Our first flow</h2></span><span class="Apple-style-span" style="font-size:medium;"></span></div><div><br /></div><div>So, enough babbling. Lets have a look at an example:<span class="Apple-style-span" style=";font-family:-webkit-monospace;font-size:13px;"></span></div><div><span class="Apple-style-span" style=";font-family:-webkit-monospace;font-size:13px;"><br /></span></div><div><blockquote><span class="Apple-style-span" style=";font-family:-webkit-monospace;font-size:13px;"><br /></span></blockquote></div><div><span class="Apple-style-span" style=";font-family:-webkit-monospace;font-size:13px;"><div>public class ExampleRouteBuilder extends RouteBuilder {</div><div><br /></div><div> /**</div><div> * A main() so we can easily run these routing rules in our IDE</div><div> */</div><div> public static void main(String... args) throws Exception {</div><div> Main.main(args);</div><div> }</div><div><br /></div><div> /**</div><div> * Lets configure the Camel routing rules using Java code...</div><div> */</div><div> public void configure() {</div><div> </div><div> from("jms:queue:purchaseOrder?concurrentConsumers=5")</div><div> .to("log:fromJms")</div><div> .split().xpath("//lineItem")</div><div> .choice()</div><div> <span class="Apple-tab-span" style="white-space: pre;"> </span>.when(body().contains("Pen"))</div><div> <span class="Apple-tab-span" style="white-space: pre;"> </span>.to("jms:queue:Pencils")</div><div> <span class="Apple-tab-span" style="white-space: pre;"> </span>.when(body().contains("Paper"))</div><div> <span class="Apple-tab-span" style="white-space: pre;"> </span>.to("jms:queue:Papers")</div><div> <span class="Apple-tab-span" style="white-space: pre;"> </span>.otherwise()</div><div><span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>.to("file:target/messages/invalid");</div><div> }</div><div>}</div></span></div><div><code></code><div></div><div></div><div><br /></div><div>So, what is going on here?<br /></div><div>Well, the first thing you'll notice is that we're extending the RouteBuilder abstract class and overide its configure() method. RouteBuilders are classes that configure your integration flows, or "routes" in camel language. The route itself starts with the from() method call and is described by chaining methods together.</div><div><br /></div><div><div>Regular code completion assist then shows you which types of "Processors" you can apply to the route. A processor is basically some part that does something with a message exchange in a pipe and filter architecture. Apache comes bundled with processors for most of the EIP patterns such as the split defined in the example above, but you can of course add extra processors by just implementing the org.apache.camel.Processor interface or by sending the message to a spring bean method.</div><div><br /></div><div>As you can see we've managed to include at least 4 EIP patterns in just a couple of lines (tecnically just one line of java, but you get the idea...) of code, namely the competing consumers, wiretap (the log endpoint), splitter and content-based router patterns. Now that's impressive!</div><div><br /></div><div>The same flow could as stated above be modeled using XML in a Spring-like fashion by just including the Camel namespace and using content-assist in your favourite XML editor with the exact same outcome, so it's up to you to decide which method that suits you best.</div><div><br /></div></div><div><span class="Apple-style-span" style="font-size:medium;"><h2><span class="Apple-style-span" style="font-weight: normal;font-size:medium;"></span></h2><h2>Transports</h2></span></div><div>Camel has the concept of adressing endpoints as URI's with the endpoint type first followed by the address and optional parameters on a query format. In our example we're instructing the route to use 5 concurrent threads to get the messages from the purchaseOrder jms queue.<br /></div><div><br /></div><div>The API relies on third party providers to implement the endpoint factories called components, so for our jms provider we could bind the jms transport to a component realised by i.e. Websphere MQ. This could either be performed by declaring the component through code, or as below as a spring bean in your context configuration.</div><div><br /></div><div><div><span class="Apple-style-span" style="white-space: pre-wrap;font-family:'Lucida Grande';"><span class="Apple-style-span" style="font-size:small;"><bean id="jms" class="org.apache.camel.component.jms.JmsComponent"></span></span></div><span class="Apple-style-span" style="white-space: pre-wrap;font-family:'Lucida Grande';"><span class="Apple-style-span" style="font-size:small;"> <property name="connectionFactory"></span></span></div><div><span class="Apple-style-span" style="white-space: pre-wrap;font-family:'Lucida Grande';"><span class="Apple-style-span" style="font-size:small;"> <bean class="com.ibm.mq.jms.MQXAQueueConnectionFactory"></span></span></div><div><span class="Apple-style-span" style="white-space: pre-wrap;font-family:'Lucida Grande';"><span class="Apple-style-span" style="font-size:small;"> <property name="hostName" value="localhost"/></span></span></div><div><span class="Apple-style-span" style="white-space: pre-wrap;font-family:'Lucida Grande';"><span class="Apple-style-span" style="font-size:small;"> <property name="queueManager" value="QM_ESB"/> </span></span></div><div><span class="Apple-style-span" style="white-space: pre-wrap;font-family:'Lucida Grande';"><span class="Apple-style-span" style="font-size:small;"> </bean></span></span><span class="Apple-style-span" style="font-size:small;"><br /></span></div><div><span class="Apple-style-span" style="white-space: pre-wrap;font-family:'Lucida Grande';"><span class="Apple-style-span" style="font-size:small;"> </property></span></span></div><div><span class="Apple-style-span" style="white-space: pre-wrap;font-family:'Lucida Grande';"><span class="Apple-style-span" style="font-size:small;"> </bean></span></span></div><div><br /></div><div>This snippet declares that the MQXAQueueConnectionFactory should be the queueconnectionfactory for our jms endpoints. Just make sure that the application user has access rights to the queue manager by including the user either in the mqm group or some other group with connect/read access.<br /></div><div><br /></div><div>You could also define your endpoints as beans in the Spring XML file and just reference them by name, making the actual endpoints changeable depending on i.e. your different test environments setup.</div><div><br /></div><div>So you could define your endpoints in a Camel context xml as:</div><div><br /></div><div><span class="Apple-style-span" style="white-space: pre-wrap;font-family:'Lucida Grande';"><span class="Apple-style-span" style="font-size:small;"><camel:endpoint id="PurchaseOrders.IN" uri="jms:queue:purchaseOrder?concurrentusers=5"/></span></span><br /></div><div><br /></div><div>.. and then just reference this endpoint in your route as:</div><div><br /></div><div><code>from("PurchaseOrders.IN")</code></div><div><br /></div><div>This gives you a very good flexibility for choosing the actual endpoint location and even transport outside the actual flow.</div><div><br /></div><div>Other cool features that Camel brings are for example</div><div><br /></div><div>- Automatic type conversion:</div><div>Note how we could just use an Xpath expression even though we did not know the exact inbound object format? Camel automatically type converts between a bunch of different standard formats so you dont need to know whether the data is delivered as i.e. a bytearray, string, jaxb objects, xml stream etc.<br />If you don't find support for your particular format you can always write your own converters and easily plug these in to the runtime.</div><div><br /></div><div>- A bunch of transport components out of the box:</div><div>We only saw two very common components in the example, but have a look at the <a href="http://camel.apache.org/components.html">http://camel.apache.org/components.html</a> and you'll find that even the most obscure transport options are available.</div><div><br /></div><div>- Bean support for i.e. defining a Spring bean as a service.</div><div><br /></div><div>So, this was just a quick intro on the capabilities of Camel. I advise you to take a look at the number of articles written about it and get a feeling for this awesome framework at <a href="http://camel.apache.org/articles.html">http://camel.apache.org/articles.html</a></div><div><br /></div><div>'til next time,</div><div><br /></div><div>Over and out!</div><div><br /></div></div>Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-85781776019504359332010-11-02T12:38:00.000-07:002010-11-17T23:58:09.807-08:00First look at WSO2 ESBEarlier this year I promised myself to educate me on the open source offerings for ESB's and BPM products out in the field.<div><br /></div><div>As you may have noticed I took a first step into Mule ESB recently, a product that clearly suprises me, even though it is quite cumbersome to work with since it requires some fiddling around with XML files and a quite comprehensive stack of XML schemas. I guess it'll all become second nature to you once you get the hang of it.</div><div><br /></div><div>Well, today I downloaded WSO2 ESB for the first time and my initial impression was just "WOW!". I knew that the guys at WSO2 are experts in their field, but for being an open source offering this product just instantly blew me away.</div><div><br /></div><div>Right out of the box you have a solution with features such as Web management, tracing and statistics, pattern catalogs, registry, EIP support for advanced features such as splitting and aggregation, transformation options (XSLT, XQuery, Smooks, Custom java/ruby just to name a few) as well as the option to add in extra transport adapters as you see fit. And so the list goes on...</div><div><br /></div><div>I've not yet scoured the full transport offerings, but to me it seems that Mule certainly has an upper hand when it comes to out-of-the box transports. But WSO2 wins my heart any day when it comes to manageability and ease of use.</div><div><br /></div><div>I also noticed that WSO2 has it's own IDE plugins to Eclipse which is always handy. I'm currently downloading it and hope to see if it eases the integration configuration even more.</div><div><br /></div><div>I'll also take a quick look into the BPEL editor and their runtime to see what's in store in that area as well.</div><div><br /></div><div>So, have you used WSO2 ESB or any other Carbon products? If so, how do you compare it to other OS offerings such as Mule, JBoss, ServiceMix, Camel etc? I'd be interested to hear your thoughts on the stack since it does not matter how many bells and whistles it brings if it has not been proved in production.</div>Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com1tag:blogger.com,1999:blog-7292537168542978537.post-88847764841816608312010-10-24T01:13:00.000-07:002010-10-24T01:42:31.978-07:00First bump in the SCA investigationDuring evalutations and investigations you sometimes come to a point where you hit the wall and finds an issue that leaves a big question mark in your head. Suffice to say I just hit one of those moments...<div><br /></div><div>If you've followed my previous posts you know that I've recently started to look into how the SCA Tuscany runtime and composition model could be utilized for building transport/implementation neutral services at my client.</div><div><br /></div><div>The existing strategy is based on building webservices with JAX-WS, Java's standard WebService framework. One great feature of any WS framework is the ability to define message interceptors/handlers that will be injected before the message receives the actual service. These handlers have access to the entire soap message, including the soap headers. So you could i.e. define a company-wide custom soapheader with meta-data which should be acted upon by each and every service before (or even after) invocation.</div><div><br /></div><div>This takes care of non-functional requirements such as traceability, security, end-to-end header propagation etc, since those aspects of the call can be separated from the actual business service.</div><div><br /></div><div>Looking at the SCA spec and what the tooling provides I have yet to find the similar function in the SCA world. Even if you i.e. expose a component as a webservice binding I cant find any way to specify my chain of handlers that should get invoked for incoming requests.</div><div><br /></div><div>Looking into the SCA 1.1 specification it states that jax-ws handlers are not included in the standard, but should/could be implemented by vendor implementations. From what I can see IBM has not chosen to do so in the current version of the SCA feature pack runtime nor tooling.</div><div>This seems a bit strange to me since I know that the BPM (0.9 SCA) products has had the support for adding handlers to a webservice export for a long time.</div><div><br /></div><div>I'll definately be going to dig into the subject more, since it could prove to be a big no-go for us as we otherwise would have to revise our entire call-chain strategy for i.e. composite services.</div><div><br /></div><div>To you readers out there, have you had experiences with interceptors/handlers in the SCA context? I might be missing some obvious features that you know about? If so, I'd be very delightful for all advices you could provide.</div><div><br /></div><div>Over and out...</div>Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-38884450569898195792010-10-20T00:34:00.000-07:002010-11-18T23:13:02.379-08:00Combining OpenSCA (WAS FP) and Classic SCA (WESB), continuedIn my previous post I mentioned that I'm currently assigned to test the interopability between an SCA component developed in RSA with the IBM BPM products version of SCA.<br /><br />I should perhaps start with a little background on the subject of SCA in the IBM products to give a little insight of the need for the test.<br /><span style="font-size:130%;"><br /><span style="font-weight: bold;">The history of SCA (from an IBM perspective)</span></span><br />IBM was a major influencer during the standardization of SCA and started to incorporate the framework as an early adopter before the standard was finalized. This version was called 0.9 and is the framework that the Process Server and ESB is built upon.<br /><br />Unfortunately (for IBM at least) the standardization body did not agree on some of the naming conventions and functionalities that IBM had specified in their draft version. Therefore there are some subtle differences between the 1.0 version and the IBM 0.9 version. The architecture as whole is fairly similar, but some implementation specifics differ.<br /><br />IBM has since then released a feature pack for its Application Server (which both WPS and WESB is deployed to) that implements the SCA 1.0 standard.<br />It is (at least to my knowledge) based on the Apache Tuscany SCA runtime and has a nice tooling support in Rational Application Developer.<br /><br />The idea behind SCA is to compose your applications from separate building blocks, each with a defined interface. This makes it possible to separate the bindings and the underlying implementation as well as the data representation for each component. As long as you adhere to the interface you can connect to the component through its exposed physical bindings.<br />This makes it possible to i.e. expose a java service over JMS, WS, java etc by configuration rather than implementation. It also separates non-functional requirements such as Quality of Service and security to name a few from the actual implementation. Think of SCA as WebServices on steroids and you get the picture..<br /><br />SCA is also a binding mechanism, which allows intra-JVM calls to a service through pass-by-reference rather than the ordinary serialization/deziralization normally required for i.e. a WS-call.<br />This has the benefit that if you'd like to call an SCA-composed service that is in the same JVM, you could call it directly without passing a physical transport. At the same time, if your service should be reachable from the outside all you have to do is to define a transport binding as well, i.e. SOAP/Http or SOAP/JMS.<br /><br />So, back to the task...<br /><br />I'm currently investigating whether it is possible (and beneficiary) to call a 1.0 SCA component from the 0.9 version provided in the WPS stack of products through an internal SCA binding. This could influence my client to bundle their services into SCA components to ease future integration with these types of products when they will be required by business projects.<br /><br /><span style="font-weight: bold;font-size:130%;" >Building the service component</span><br />I started by defining a simple HelloWorld echo service in the SCA tooling in RAD. The service is the simplest possible that accepts a string i.e. a name and responds with an appended "Hello" plus the input string.<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgexJwLL-t5P18CaeQWYmk24N7YbNAqqYU3SIEN144pWowGnPGDUB6gmfVzl61eiPYyYaAgExR0XP2MN8wDV1kWv_ie3bD6eFYhkLp_HWTt5oFBLgbj7awo7UT_3S_vBeC4Bj1T1o4hYQio/s1600/helloworld_wsdl.bmp"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 72px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgexJwLL-t5P18CaeQWYmk24N7YbNAqqYU3SIEN144pWowGnPGDUB6gmfVzl61eiPYyYaAgExR0XP2MN8wDV1kWv_ie3bD6eFYhkLp_HWTt5oFBLgbj7awo7UT_3S_vBeC4Bj1T1o4hYQio/s400/helloworld_wsdl.bmp" alt="" id="BLOGGER_PHOTO_ID_5530041549478076738" border="0" /></a><br /><br />Working top to bottom I set up an SCA project, composite and component implementing the service. The service specifies the WSDL as it's interface.<br />After implementing the service I chose to add two bindings to the service. One for Webservices calls to simulate an external client, and one SCA binding for intra-calls. Note the names on the bindings in the below picture.<br /><br /><div style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaigMHzbaFoPAopnzJuG1P4YivY9l5XAglrdM3hltoECBRDGUnGOdQP77p1WeYYCe-IEn1nmo-9OJSG5BxicPop0NNndGjCQQ5MdNNnmjUe5wBDQlxru6NwJ4G4hO3yL4u2tMKYIY1lcCp/s1600/RSAcomponent.bmp"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 164px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaigMHzbaFoPAopnzJuG1P4YivY9l5XAglrdM3hltoECBRDGUnGOdQP77p1WeYYCe-IEn1nmo-9OJSG5BxicPop0NNndGjCQQ5MdNNnmjUe5wBDQlxru6NwJ4G4hO3yL4u2tMKYIY1lcCp/s400/RSAcomponent.bmp" alt="" id="BLOGGER_PHOTO_ID_5530041695714591218" border="0" /></a></div><pic><br />After deploying this contribution to the Process Server the service is reachable as a Webservice on the endpoint http://localhost:9080/hellocomponent/WS ,where "hellocomponent" in the URI is the component and "WS" is the binding name.<br /><br /><br /><span style="font-weight: bold;font-size:130%;" >Building the client in WID</span><br />I then created a simple mediation in WID with an SCA import pointing to the SCA binding. The interface for the import is the original WSDL, and the binding names are shown below. Note that "Module name" specifies which component to call while "Export name" is the name of the binding.<br />I also created a proxy interface for this service and a mediation to simulate a typical transformation scenario in WID.<br /><br /></pic><div style="text-align: center;"><pic><pic></pic></pic><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirydPBW7AE6dWQMKIkgRq3jiAGrC7CDwyvZJfyDf3X2wyj_FnGt_EymVwd4E9zAIxFtCce5DoH4x0fOz32PeTSQ2Wkvq7-sbUHOLmoPM5t39fnvjTKmdQqg9l3tEziOd_Xda4N_V7jCv5n/s1600/WIDflow.bmp"><img style="cursor: pointer; width: 400px; height: 123px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirydPBW7AE6dWQMKIkgRq3jiAGrC7CDwyvZJfyDf3X2wyj_FnGt_EymVwd4E9zAIxFtCce5DoH4x0fOz32PeTSQ2Wkvq7-sbUHOLmoPM5t39fnvjTKmdQqg9l3tEziOd_Xda4N_V7jCv5n/s400/WIDflow.bmp" alt="" id="BLOGGER_PHOTO_ID_5530041039066330034" border="0" /></a><br /></div><pic><pic><br />The result is that the hellocomponent can be reached both through an SCA binding from Websphere ESB/Process server as well as through a webservice call.<br /><br />I'll continue to dig deeper into the interopability and will try to see i.e if the internal binding is indeed faster than if the Process server would call the component as a webservice (which is ofcourse also doable). I'll also try to fiddle around with specifying qualifiers (security, transaction scopes etc) and set up a reverse scenario where OSCA calls CSCA.<br /><br />'til next time.<br /><br />Over and out...<br /></pic></pic>Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-31969488200390110492010-10-18T05:34:00.000-07:002010-10-20T02:04:43.039-07:00Combining OpenSCA with IBM Classic SCA (WPS/WESB)My current client needs to perform a Proof-of-Concept on the interopability between the old style of SCA used by the Websphere BPM products (Process Server and Websphere ESB) with the standard SCA 1.0 that the WAS Feature pack for SCA implements.<br /><br />So far my task is to package one of their existing services as part of an SCA contribution and verify that it is accessible from a long-running process inside the process server.<br /><br />The first thing that hit me is that WID doesn't seem to include the SCA tooling plugin that RAD offers, so for the moment it seems to me that I'll have to develop the integration with 2 IDE's, RAD for the Java/SCA part and WID for the WPS parts. Hmm, I'm just wondering how my relatively weak workstation will respond to that.. :-D<br /><br />Anyway, for guidance I'll be looking at the excellent series of articles at IBM Developerworks:<br /><a href="http://www.ibm.com/developerworks/websphere/library/techarticles/1005_fong/1005_fong.html?ca=drs">http://www.ibm.com/developerworks/websphere/library/techarticles/1005_fong/1005_fong.html?ca=drs</a><br /><br />I'll keep you updated on my findings as I get along, but it is indeed an interesting subject.<br /><br />Over and out...Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com0tag:blogger.com,1999:blog-7292537168542978537.post-24843060430430815132010-10-16T08:01:00.000-07:002010-10-16T08:38:39.532-07:00Hunting for the best XML editor for Mule ESBRecently I've been hunting for a good XML editor to use for authoring Mule ESB configuration files.<div>Mule is an open source lightweight ESB that is quite simple to work with, but since configuring the flows is all xml-based it can be challenging to learn the ropes in the beginning.</div><div><br /></div><div>After starting out with the default eclipse xml editor I noticed that it doesn't cope very well with the complex namespace structures that the configuration files require.</div><div><br /></div><div>The solution?</div><div><br /></div><div>After trying out a couple editors I finally found the perfect match in the oXygen XML editor (<a href="http://www.oxygenxml.com/">http://www.oxygenxml.com/</a>), whose autocompletion handles Mule ESB's namespaces perfectly. It also exists as an eclipse plugin, making it a good fit together with the Mule IDE (which is eclipse-based).</div><div>The downside? It's not free... So I'll be trying it out a little more to see whether the product warrants a purchase.</div><div><br /></div><div>So, do you have an alternative xml editor that you can tip me about, and preferably a free/open source one? Give me your thoughts, especially if you've been using it in conjuction with Mule.</div><div><br /></div><div>Over and out...</div>Anonymoushttp://www.blogger.com/profile/16665575968269641445noreply@blogger.com1