Groovy example: ActiveMQ broker and Apache Camel

I’m still playing around with groovy scripting. It’s an excellent way to quickly prototype some ESB scenarios. Last week i blogged about using groovy to write files to a gtalk account using Apache Camel, the example below shows you how to start an ActiveMQ broker, which persists messages to a PostgreSQL database. An Apache Camel route is create to test the ActiveMQ queue.

#!/home/akoelewijn/programs/groovy-1.6.0/bin/groovy

import org.apache.camel.impl.DefaultCamelContext
import org.apache.camel.language.groovy.GroovyRouteBuilder
import org.apache.activemq.camel.component.ActiveMQComponent

@Grab(group='org.apache.camel', module='camel-groovy', version='1.6.0')
@Grab(group='org.apache.camel', module='camel-jms', version='1.6.0')
@Grab(group='org.apache.activemq',module='activemq-core',version='5.2.0')
@Grab(group='org.apache.activemq',module='activemq-camel',version='5.2.0')
@Grab(group='org.apache.camel', module='camel-core', version='1.6.0')
@Grab(group='postgresql', module='postgresql', version='8.3-603.jdbc4')
@Grab(group='commons-dbcp', module='commons-dbcp', version='1.2.2')
class SampleRoute extends GroovyRouteBuilder {
  protected void configure(){
  	from("file:///tmp/from").
  	  to("activemq:queue:q1")
  	from("activemq:queue:q1").
  	  to("file:///tmp/to")
  }
}

def ds = new org.apache.commons.dbcp.BasicDataSource()
ds.setDriverClassName("org.postgresql.Driver")
ds.setUrl("jdbc:postgresql://localhost/dev1")
ds.setUsername("rgw_owner")
ds.setPassword("rgw_owner")

def pa = new org.apache.activemq.store.jdbc.JDBCPersistenceAdapter()
pa.setDataSource(ds)
pa.setAdapter(new org.apache.activemq.store.jdbc.adapter.PostgresqlJDBCAdapter())

def brokerSvc = new org.apache.activemq.broker.BrokerService()
brokerSvc.setBrokerName("q1")
brokerSvc.addConnector("tcp://localhost:61616")
brokerSvc.setPersistenceAdapter(pa)
brokerSvc.start()

def camelCtx = new DefaultCamelContext()
camelCtx.addComponent("activemq", ActiveMQComponent.activeMQComponent("tcp://localhost:61616"));
camelCtx.addRoutes(new SampleRoute())
camelCtx.start()

OpenOffice Python API much nicer than Java API

I wrote a small Python program today, to see if a could create a workaround for a problem i have in Java. I’ve written a couple of Java applications that use OpenOffice’s API to create ODF and MS-Word documents. The OpenOffice API that i used in Java is pretty horrible: very verbose, not intuitive. You can’t use intellisense/autocomplete, instead you query interfaces, that you just have to know exist. I documented some examples here: Getting started using openoffice in java, Mailmerge MS-Word template using OpenOffice and Java.

To my surprise, the python api doesn’t require you to use the whole query interface nonsense. Makes you code a lot smaller and more readable.

Here’s an example that replaces database field in a document (similar to the example here: Mailmerge MS-Word template using OpenOffice and Java).

#!/usr/bin/python

import sys
import uno
from os import getcwd
from unohelper import Base, systemPathToFileUrl, absolutize
from com.sun.star.beans import PropertyValue, UnknownPropertyException
from com.sun.star.uno import Exception as UnoException, RuntimeException

localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext )
ctx = resolver.resolve( "uno:socket,host=localhost,port=8100;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx )

inProps = PropertyValue( "Hidden" , 0 , True, 0 ),
fileUrl = absolutize(systemPathToFileUrl( getcwd() ) ,"letter1.ott")
doc = desktop.loadComponentFromURL( fileUrl , "_blank", 0, inProps )

fields = doc.getTextFields().createEnumeration()
while fields.hasMoreElements():
        field = fields.nextElement()
        fieldname = field.getPresentation(0)

        try:
                isDatabaseField = field.getPropertyValue("DataBaseFormat")
        except UnknownPropertyException :
                isDatabaseField = False

        if isDatabaseField:
                try:
# this is incorrect usage of insertString
#                        doc.Text.insertString(field.getAnchor(),"New value for " + fieldname,1)
# this is the correct approach
                        fieldAnchor = field.getAnchor()
                        fieldAnchor.Text.insertString(fieldAnchor,"New value for " + fieldname,1)
                except RuntimeException, e:
                        print "RuntimeException while to replacing field: " + e.Message

# save document
outProps = PropertyValue( "Overwrite" , 0 , True, 0 ),
saveUrl = absolutize(systemPathToFileUrl( getcwd() ) ,"letter1.odt")
doc.storeToURL(saveUrl, outProps)

Beware of this code though, it throws a RuntimeException when trying to replace a database field in the header of a document. So, in that sense, Python is no better than Java.

Update: a reply on the openoffice forum put me on the right track. My usage of insertString was incorrect. I’ve fixed the code above.

How to find true cause of com.sun.star.uno.RuntimeException?

I’m stuck with OpenOffice. I’m hoping somebody can help me with this. I’ve also posted the question to the OpenOffice.org forums and to StackOverflow, but so far no luck.

I’m trying to replace a field in an openoffice document using the OpenOffice java api. I’m using the insertString method:

  xText.insertString(((XTextField) fieldMaster).getAnchor(), value.toString(), false);

The stacktrace is as follows:

com.sun.star.uno.RuntimeException:
	at com.sun.star.lib.uno.environments.remote.Job.remoteUnoRequestRaisedException(Job.java:182)
	at com.sun.star.lib.uno.environments.remote.Job.execute(Job.java:148)
	at com.sun.star.lib.uno.environments.remote.JobQueue.enter(JobQueue.java:344)
	at com.sun.star.lib.uno.environments.remote.JobQueue.enter(JobQueue.java:313)
	at com.sun.star.lib.uno.environments.remote.JavaThreadPool.enter(JavaThreadPool.java:101)
	at com.sun.star.lib.uno.bridges.java_remote.java_remote_bridge.sendRequest(java_remote_bridge.java:652)
	at com.sun.star.lib.uno.bridges.java_remote.ProxyFactory$Handler.request(ProxyFactory.java:154)
	at com.sun.star.lib.uno.bridges.java_remote.ProxyFactory$Handler.invoke(ProxyFactory.java:136)
	at $Proxy14.insertString(Unknown Source)
...

If i interpret this correctly, it’s telling me that it connected to a different process from java, something in the other process failed, but it’s not telling me what.

I found that there are some environment variables (PROT_REMOTE…) that would let me log messages from these remote (different process, same computer, btw) processes, but only if i run an OpenOffice version with debugging enabled? I’m using an openoffice version from an deb repository on ubuntu, and have to interest in compiling my own openoffice version.

Is there any way i can get some useful error messages from the remote process to help me understand why my code is failing?

NOiV promotes collaboration

One important aspect of open source is often overlooked: collaboration. Open source enables organizations to collaborate on building the software they need. Too often open source is just consumed: downloaded and installed because it’s free.

To my surprise, the report i mentioned earlier, Ranking OS and OSS: NOIV monitor does reward organizations that release their own software with an open source license. It’s on the list of criteria by which the organizations are ranked: NOiV toelichting.

I think this is a very important aspect in the adoption of open source: government agencies that collaborate on software, instead of every organization writing their own version of something. There’s a big opportunity for, for example. local government to collaborate on software. There are about 470 municipalities in the netherlands, that all do the same things, and all need more or less the same software. Why not collaborate on this?

Ranking OS and OSS: NOiV monitor

A study by a dutch government agency (ICTU) was just released which discusses the current results of implementing open standards and open source by dutch government agencies: Verbinding in het vizier (dutch, pdf).

What is interesting is that the results are not just discussed, but all agencies are ranked by their results to implement the goals of Actieplan Nederland Open in Verbinding (Open Connected Netherlands Plan). You can find the ranking here: NOiV Ranking. It will be updated twice per year. You can even find the details how the organizations are ranked:

Also interesting is a list that shows the perceived effects of using Open Standards and Open Source by these organizations: The effects of the NOiV plan. OS and OSS have the biggest impact on improved interoperability and improved collaboration. Only in 8 percent of the organisations costs havev been reduced by using OS and OSS.

update from sql statement

I’ve been using sql for a number of years now, and thought i knew most of the sql syntax. So i was quite surprised to find out about the existence of UPDATE … FROM. Turns out, this doesn’t exist in Oracle, but is supported by PostgreSQL.

Here’s a small example:


update response
set    house_id = ?
from   house as h
where  response_text = 'Offered'
and    house_id = h.id
and    h.address = ?

In this example the response table is joined with the house table to find the responses that need to be updated. You could probably achieve this in oracle with an inline view in the where clause, but this syntax is pretty readable.

I also wanted to try what this would look like in Grails with the hibernate criteria api. I think the following should achieve the same, but i got some weird exception, so there must be something wrong.


def results = Response.withCriteria{
  house {
    eq("address",myHouse.address)
  }
  eq("responseText","Offered")
}
results.each {
  it.house = myHouse
  it.save(flush:true)
}

I think the criteria api could be more readable than sql in some cases, but from a performance point of view it doesn’t make sense in this case. Why query all data, move the data to the app server, change the data, move it back to the database, and execute the update statements, when you can do it all in one statement?

Anyway, if anybody knows why my criteria is failing, please enlighten me. (it’s throwing an exception on the house { eq… } parts, something about House.call() not existing…

Using google talk from java example

Sending and receiving messages to and from google talk accounts is actually very easy. Google uses the xmpp (jabber) protocol. The Smack library enables you to use the xmpp protocol in java.

I was actually trying to use xmpp in apache camel, but couldn’t get it working with google accounts, just with other accounts, so i decided to do some basic smack testing. Smack doesn’t have any problems with google accounts. Here’s a basic example i wrote to test it


// connect to gtalk server
ConnectionConfiguration connConfig = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
XMPPConnection connection = new XMPPConnection(connConfig);
connection.connect();

// login with username and password
connection.login("camel.test.1", "secret");

// set presence status info
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);

// send a message to somebody
Message msg = new Message("camel.test.2@gmail.com", Message.Type.chat);
msg.setBody("hello");
connection.sendPacket(msg);

// receive msg
PacketListener pl = new PacketListener() {
@Override
public void processPacket(Packet p) {
System.out.println(p.getFrom() + ": " + p.toString());
if (p instanceof Message) {
Message msg = (Message) p;
System.out.println(msg.getFrom() + ": " + msg.getBody());
}
}
};
connection.addPacketListener(pl, null);

// wait for user to end program
System.in.read();

// set presence status to unavailable
presence = new Presence(Presence.Type.unavailable);
connection.sendPacket(presence);

This is a very basic example, you’d normally create a chat session, and listen for messages part of the chat. More info on the smack site.

“I’m Linux” video brought to you by Mac/Windows

Good chance that the winner of the “I’m Linux” video contest will create his entry on a Windows or Mac computer. I use Linux a lot, but i bought an iMac for editing HD video. The state of video editing on Linux is really, really sad. I tried a couple of programs, nothing really worked with my AVCHD videos recorded using a Canon HF100.

iMovie isn’t too great either, as far as i know, it can’t actually render HD video, but at least it allows me to easily create video’s. I’d be really happy with some simple video editing program, the simpler the better. The fact that I’m satisfied with iMovie 08 should be proof enough.

In fact, if it weren’t for movie editing, i’d probably not have bought the iMac. I’m happy with my ubuntu laptop, actually use it more than the iMac. If Adobe or better yet Sony would release their video editing software for Linux, i’d probably bought that instead of the iMac.

Devoxx day 4

Another good day at devoxx, more surprises: keynotes don’t have to be boring marketing talks. The day started with 2 good keynotes by sun. The first by Joshua Bloch, containing lots of code and good tips from his book: Effective Java. The next keynote presented the plans to modularize Java starting with Java 7. You can find more info here Java SE: Project Jigsaw: Modularizing JDK 7, and on Mark Reinhold’s blog

Paul Fremantle did a presentation on Event Driven Architecture and Complex Event Processing, showing examples using Apache Synapse and Esper. CEP seems very usefull in situations where you have to find informations in a large number of events. Currently Esper can be used in Synapse. Not sure how easy it integrates with other ESBs. Would be nice to have it available as an OSGi bundle, which can be used in Spring DM, ServiceMix 4, and Glassfish 3.

Next up: a talk about using Geospatial Software to create a website for kitesurfers. I do a lot of kitesurfing and windsurfing myself, so i had to see this presentation. After a short introduction, the presenter demoed how you can build geospatial websites using open source software. It was interesting to see, but not really about programming. You can achieve most of what you want using existing software, it’s mostly about configuring the software and loading the data.

Paul Sandoz did a talk on JAX-RS and the Jersey implementation. I haven’t used JAXRS yet, as i’ve been doing most of my REST stuff using Grails, which is dead easy. But Jax-RS seems like a pretty good way to do it in java. Also, i learned that they have support for JSON in JAXB, which i wasn’t aware off.