Saturday, December 12, 2009

New features in grails-jaxrs 0.3

In this blog post I present some new features of the recently released grails-jaxrs 0.3 plugin. A complete list of new features is available in the release notes. A feature overview and links to the complete documentation is on the plugin home page.

grails-jaxrs is a Grails plugin that supports the development of RESTful web services based on the Java API for RESTful Web Services (JSR 311: JAX-RS). It is targeted at developers who want to structure the web service layer of an application in a JSR 311 compatible way but still want to continue to use Grails' powerful features such as GORM, automated XML and JSON marshalling, Grails services, Grails filters and so on. This plugin is an alternative to Grails' built-in mechanism for implementing RESTful web services.

The following example shows how to do content negotiation for Grails domain objects. Grails domain classes like

class Person {
String firstName
String lastName
}

can now be used in JAX-RS resource methods directly (e.g. Person parameter in the create method):

import static javax.ws.rs.core.UriBuilder.fromPath

import javax.ws.rs.Consumes
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.POST
import javax.ws.rs.core.Response

@Path('/api/person')
@Consumes(['application/xml','application/json'])
@Produces(['application/xml','application/json'])
class PersonCollectionResource {

@POST
Response create(Person person) {
person.save() // use GORM
URI uri = fromPath(person.id as String).build()
Response.created(uri).entity(person).build()
}

// ...

}

Content negotiation and conversion between domain objects and their XML or JSON representations is done by domain object providers. There's no need any more for application code to deal with representation formats directly.

The PersonCollectionResource.create method handles POST requests for creating new Person objects in the database. The method uses GORM to persist the domain object. Clients can send either XML or JSON representations for POSTing person data (see Content-Type header):

POST /hello/api/person HTTP/1.1
Content-Type: application/xml
Accept: application/xml
Host: localhost:8080
Content-Length: 78

<person>
<firstname>Sam</firstname>
<lastname>Hill</lastname>
</person>

or

POST /hello/api/person HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: localhost:8080
Content-Length: 58

{"class":"Person","firstName":"Fabien","lastName":"Barel"}

In either case, the plugin will convert it to a Person object, as required by the person parameter. For creating a response the method uses the JAX-RS API. It first creates a URI for the response Location header and uses the Response builder to set the status code to 201 (created) and the response entity. Note that the method itself doesn't create an XML or JSON representation of the response domain object. This is again done by a domain object provider which uses the Accept request header to determine the response representation format. The responses to the above POST requests are:

HTTP/1.1 201 Created
Content-Type: application/xml
Location: http://localhost:8080/hello/api/person/1
Transfer-Encoding: chunked
Server: Jetty(6.1.14)

<?xml version="1.0" encoding="UTF-8"?>
<person id="1">
<firstname>Sam</firstname>
<lastname>Hill</lastname>
</person>

and

HTTP/1.1 201 Created
Content-Type: application/json
Location: http://localhost:8080/hello/api/person/2
Transfer-Encoding: chunked
Server: Jetty(6.1.14)

{"class":"Person","id":"2","firstName":"Fabien","lastName":"Barel"}

The PersonCollectionResource.create method is even more verbose than necessary. It could equally be written as

import static org.grails.jaxrs.response.Responses.*

@Path('/api/person')
@Consumes(['application/xml','application/json'])
@Produces(['application/xml','application/json'])
class PersonCollectionResource {

@POST
Response create(Person person) {
created person.save()
}

// ...

}

using helper methods (a mini-DSL) from org.grails.jaxrs.response.Responses. That's exactly the code that is generated when using scaffolding for the Person domain class i.e.

grails generate-resources person

With the grails-jaxrs scaffolding feature, one can generate RESTful service interface for domain objects supporting the HTTP methods POST, GET, PUT and DELETE. A scaffolding example is given in the Scaffolding section of the grails-jaxrs documentation, a walk through the generated code is in the Using GORM section.

By default, grails-jaxrs uses Grail's XML and JSON converters for converting between domain objects and their XML or JSON representations. Applications can easily customize this conversion logic as explained in the Custom entity providers section.

Besides usage of GORM, grails-jaxrs also supports auto-injection of Grails services into JAX-RS resource and provider classes or usage of Grails filters, to mention a few. With version 0.3 the included JAX-RS implementations have been upgraded to their latest versions: Jersey 1.1.4.1 and Restlet 2.0-M6.

Tuesday, November 17, 2009

Camel components for Google App Engine

The upcoming Apache Camel version 2.1 will include components for connecting to the cloud computing services of Google App Engine. At the moment the following three components are available.

  • ghttp: Provides connectivity to the GAE URL fetch service but can also be used to receive messages from servlets
  • gtask: Supports asynchronous message processing on GAE by using the task queueing service as message queue.
  • gmail: Supports sending of emails via the GAE mail service. Receiving mails is not supported yet but will be added later.

Camel components for the other Google App Engine cloud computing services such as Memcache service, XMPP service, Images service, Datastore Service and the Authentication service are planned.

There's also a tutorial that explains how to develop a non-trivial Camel GAE application using the Camel components for GAE.

From a conceptual point of view, connecting to cloud computing services via Camel components introduces an abstraction-layer that decouples Camel applications from provider-specific cloud service interfaces. Supporting several cloud computing environments in Camel can significantly reduce the burden of migrating Camel applications from one provider to another. The Camel components for Google App Engine are a first step into this direction.

Sunday, October 18, 2009

First steps with Apache Camel on Google App Engine

This post describes how to get a simple Camel 2 application running on Google App Engine (GAE). I'll focus on the workarounds and fixes that were necessary to succeed. Please note that the following descriptions are by no means best-practices or recommendations. They only describe my first steps for which better solutions will likely exist in the future. I plan to work on improvements to
  • make Camel deployments on GAE easier and to
  • allow Camel applications access GAE services via Camel components
For my experiments, I was using a Camel 2.1 development snapshot, the App Engine SDK 1.2.6 and the Google Plugin for Eclipse which makes local testing and remote deployment very easy. The Camel components I used are:
  • camel-core
  • camel-spring
  • camel-servlet
  • camel-http
The following snippet shows the route definition of the sample application. It uses the camel-servlet component to receive input via HTTP, converts the HTTP request body to a String, prepends a "Hello " to the body and returns the result.

package example;

import org.apache.camel.builder.RouteBuilder;

public class ExampleRoute extends RouteBuilder {

@Override
public void configure() throws Exception {
from("servlet:/test")
.convertBodyTo(String.class)
.transform(constant("Hello ").append(body()));
}
}

The route doesn't make use of any GAE services (URL fetch, tasks queues, storage, mail ...) Also, message processing is synchronous because GAE doesn't allow applications to create their own threads. For example, using SEDA or JMS queues will not work.

For processing HTTP requests, I created my own servlet class and extended the CamelHttpTransportServlet from the camel-servlet component.

package example;

import org.apache.camel.component.servlet.CamelHttpTransportServlet;
import org.apache.camel.management.JmxSystemPropertyKeys;

public class ExampleServlet extends CamelHttpTransportServlet {

static {
System.setProperty(JmxSystemPropertyKeys.DISABLED, "true");
}

}

The only thing this servlet does is to disable all JMX-related functionality because the GAE JRE doesn't support JMX. All request processing and dispatching is done by the CamelHttpTransportServlet. Configuring the servlet in the web.xml was done as follows.

<servlet>
<servlet-name>CamelServlet</servlet-name>
<servlet-class>example.ExampleServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>context.xml</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>CamelServlet</servlet-name>
<url-pattern>/camel/*</url-pattern>
</servlet-mapping>

The servlet init-param points to the Spring application context that configures the route builder and the Camel context:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="camelContext"
class="org.apache.camel.spring.CamelContextFactoryBean">
<property name="builderRefs">
<list>
<ref bean="routeBuilderRef"/>
</list>
</property>
</bean>

<bean id="routeBuilderRef"
class="org.apache.camel.model.RouteBuilderDefinition">
<constructor-arg value="routeBuilder" />
</bean>

<bean id="routeBuilder"
class="example.ExampleRoute">
</bean>

</beans>

A severe limitation is that one cannot use the Camel-specific configuration XML schema from the http://camel.apache.org/schema/spring namespace for configuring the Camel context. The problem is that the CamelNamespaceHandler uses JAXB to parse bean definitions which isn't supported by GAE either. One has to fallback to plain old <bean> definitions (POBD?) to configure the Camel context in Spring. Using Spring JavaConfig or something similar would make more sense here but I didn't try it.

Another JAXB-releated problem arises with Camel's Spring DSL. It is also processed with JAXB and therefore cannot be used on GAE.

Going completely without Spring leads to another problem. In this case the CamelContext uses a JndiRegistry by default that depends on javax.naming.InitialContext. This class isn't on the JRE whitelist either. Writing a simple Map-based implementation of org.apache.camel.impl.Registry and configuring the CamelContext with it does the trick.

The last obstacle to get the sample application running was to replace the Camel's UuidGenerator with another one that uses java.util.UUID from the JRE. Camel's original UuidGenerator also uses a class that is not on the JRE whitelist. Since replacement by configuration was not possible, changes to the Camel code base were necessary (patch already submitted).

After deploying the application to GAE and POSTing a request containing "Martin" to http://<appname>.appspot.com/camel/test I was able to send myself greetings. In the URL, <appname> must of course be replaced with the name of an existing application.

Wednesday, October 14, 2009

IPF 2.0 milestone 2 and IPF Tools milestones released

I'm pleased to announce the following milestone releases from the IPF core project and the IPF Tools project.

IPF 2.0 milestone 2 (release notes)
IPF Tools
- IPF Runtime 2.0 milestone 2 (release notes)
- IPF Manager 2.0 milestone 2 (release notes)
- IPF IDE 1.0 milestone 2 (release notes)

IPF 2.0 milestone 2

This release is feature-equivalent to IPF 1.7.0 but runs on Camel 2.0. Users who plan to upgrade to IPF 2.0 or Camel 2.0 in the near future are highly recommended to use this milestone release. Please note that IPF 2.0 is not backwards-compatible to IPF 1.x. This is mainly due to non-backwards compatible API changes in Camel 2.0. It is therefore important to carefully read the Camel 2.0.0 release notes as well as the IPF 2.0-m2 upgrade notes.

With the release of IPF 2.0-m2 and IPF 1.7.0, IPF 1.x development will go into maintainance mode and new features will be developed on the IPF 2.0 development branch. We leave it open whether to backport selected IPF 2.x features to IPF 1.x. Please add any backport requests to the IPF issue tracker.

Other changes compared to IPF 1.7.0 are:

  • The platform manager has been moved to the IPF Tools project.
  • The IPF OSGi distributable (IPF runtime) and the IPF OSGi documentation have been moved to the IPF Tools project.
  • The HL7-independent parts of the mapping service have been factored out into a new commons-map component.
  • The IPF 2.0 documentation has been forked from the IPF 1.7 documentation and revised.

IPF Runtime 2.0 milestone 2


The IPF Runtime is an IPF distribution that is running on the Equinox OSGi platform. It is available as Eclipse plugin or as standalone package. The runtime is used to develop OSGi-based IPF applications.

IPF Manager 2.0 milestone 2


IPF Manager is an Eclipse application for managing IPF services and applications. It is available as Eclipse plugin or as standalone package. In its current state it provides a flow management user interface and a general-purpose JMX client. The IPF Manager is compatible with IPF Runtime 2.0-m2.

IPF IDE 1.0 milestone 2


The IPF IDE supports developers in creating, testing and packaging IPF applications within the Eclipse plugin development environment (PDE) on top of the IPF runtime. The IPF IDE is compatible with IPF Runtime 2.0-m2.

Wednesday, October 7, 2009

IPF 1.7.0 released

I'm pleased to announce the release of IPF 1.7.0. The main focus of this release was support for clinical standards, in particular the IHE profiles XDS.a, XDS.b, PIX, PDQ and support for the clinical document architecture (CDA) and the Continuity of Care Document (CCD) content profile. The release notes are here.

With IPF's IHE support, IHE actor interfaces can be implemented in IPF routes via URIs. This is as simple as using other Camel or IPF components such as the HTTP or JMS components. The URIs denote individual transactions (ITI) in IHE profiles. For example

from('xds-iti18:myIti18Service')
...

implements the 'XDS Registry Stored Query' service interface of an XDS document registry and can be used from any XDS ITI18-compliant consumer. Such a consumer can also be implemented using the same IPF xds-iti18 component on client side e.g.

...
.to('xds-iti18://somehost:8080/myWebApp/services/myIti18Service')


All the low-level details like communicating with ebXML messages over SOAP etc. is handled by that component. IPF routes deal with easy-to-use object representations of messages exchanged within IHE transactions. The full list of supported transactions is given in the IHE quick reference.

With IPF's CDA and CCD support clinical documents can be created, parsed, rendered and queried/analyzed using a domain-specific language (DSL). This DSL hides away most of the technical details you usually encounter when dealing with the complex XML-representation of clinical documents. In addition to these content-DSL extensions, IPF also provides some route DSL extension for parsing, validating and marshalling CDA documents in IPF routes.

Here's an excerpt of new IPF 1.7.0 features added since 1.6.0

* IHE support
** IHE XDS.a+b transactions (ITI 14-18, 41-43)
** IHE PIX transactions (ITI 8-10)
** IHE PDQ transactions (ITI 21-22)
** IHE ATNA for all the above transactions
* CDA support
** Generic CDA support
** CCD profile support
* Advanced XML processing
** Caching XSLT transmogrifier
** Schematron validator
* Detailed XDS tutorial
* Performance measurement support
* Scheduled flow management database cleanup
* ...

IPF 1.7.0 is based on Camel 1.6. In parallel, a Camel 2.0-based version is developed on the IPF 2.0 branch. The current development snapshot is feature-equivalent with IPF 1.7.0 but runs on Camel 2.0. The next IPF 2.0 milestone 2 release will follow within the next one or two weeks. I recommend you to use the 2.0 milestone releases unless you upgrade from an older IPF 1.x release. After releasing IPF 2.0.0, work on IPF 1.x will go into maintainance mode (but we leave it open whether to backport selected IPF 2.x features).

Exciting new features in IPF 2.0 which didn't make it into IPF 1.7 are Eclipse-based IPF development tools and improvements to IPF's OSGi support. These features are developed and documented in a separate IPF Tools project. The Eclipse-based IPF management client has been moved to this project as well. I'll give a more detailed IPF 2.0 overview in a separate post.

Many thanks to the whole development team and contributors for their excellent and high-quality work!

Wednesday, September 23, 2009

New release of JSR 311 plugin for Grails

It's about two weeks ago that the latest version (0.2) of the JSR 311 plugin for Grails (grails-jaxrs) has been released. In contrast to the first release (0.1) , which was mainly a proof-of-concept, this new release focused, among other things, on a closer Grails integration. In particular
  • JAX-RS classes like resource classes and entity providers are now auto-detected by the plugin. There's no need any more to add them to the Spring application context manually.
  • JAX-RS classes managed by the plugin can be changed at runtime in development mode. Code changes are detected by the plugin and reloaded in the same way as Grails controllers or services are.
Antoher enhancement in this version is support for deployments on the Google App Engine (GAE). This required to support Restlet as JAX-RS implementation in addition to Jersey. In contrast to Jersey, Restlet can be deployed to GAE and since version 2.0-m4 its JAX-RS extension as well. For a running example go to http://grails-jaxrs.appspot.com/test?name=World. Please note that initializing Grails applications on GAE can take very long (up tp 30 seconds) at the moment. Subsequent requests are served much faster, of course.

Also the documentation has been and extended and completely revised. The easiest way to get started with the plugin is the Getting Started guide.

Wednesday, July 8, 2009

JSR 311 plugin for Grails

Project homepage: grails-jaxrs

Recently, I wanted to make a full two-weeks mountain bike tour through the Alps but bad weather on a few days caused me to make detours on the less rocky roads of JSR 311 (JAX-RS: The Java API for RESTful Web Services). I took the chance reading the spec, did some hacking with Jersey and I must really say I like to work with it. I liked it so much that I started to use it inside Grails to combine it with features such as GORM and XML and JSON marshalling.

From my experiments I factored out what I think is reusable into a Grails plugin named grails-jaxrs and made it open source. The plugin takes care of initializing Jersey inside a Grails application, implements a controller that does the dispatch to Jersey and provides some Grails-specific entity provider implementations.

Here's a very simple example of a resource class that represents a collection of notes and that makes use of Grails object relational mapping (GORM) and XML marshaling:

import grails.converters.*

import javax.ws.rs.Consumes
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.PathParam
import javax.ws.rs.POST
import javax.ws.rs.Produces
import javax.ws.rs.core.Response
import javax.ws.rs.core.UriBuilder

@Path('/notes')
class NotesResource {

@POST
@Consumes('text/plain')
@Produces('text/xml')
Response addNote(String text) {

// Create new Note object and store save it to DB
def note = new Note(text:text).save()

// Construct the URI for the newly created note
URI uri = UriBuilder.fromPath(note.id as String).build()

// Return an XML representation of the note object
// along with a Location response header with the URI
Response.created(uri).entity(note as XML).build()
}

@GET
@Produces('text/xml')
Response getNotes() {

// Find all notes in the database and return
// an XML representation of the note list
Response.ok(Note.findAll() as XML).build()
}

}

A note is an object that contains some text. Notes are instances of the Note Grails domain class. A collection of notes are made available through a RESTful service interface using the above NotesResource class and the grails-jaxrs plugin. A POST to http://host:port/notes/ creates a new note. A GET to http://host:port/notes returns an XML repsresentation of all existing notes in the database. For more details refer to the getting started tutorial.

Sunday, May 24, 2009

Moving towards IPF 1.7

Work on the next IPF release is in progress and focuses on

  • Components for implementing IHE actor interfaces (XDS.a, XDS.b, PIX, PDQ). Implementing IHE actor interfaces will be as simple as using other Camel components for communication (e.g. the HTTP component). IPF IHE components represent transactions in IHE profiles. For example, to create a web service for the server-side of the ITI-41 transaction (provide and register document set) from the XDS.b profile just write from('xdsb-iti41:service1') in your route definition. xdsb-iti41 is the name of the component, service1 the endpoint name. The rest of the route has to deal with connecting to (proprietary) backend systems that implement the corresponding actor functionality (document registry/repository). For more detailed information refer to this article (section Outlook).
  • DSL (Groovy builder) for creating CDA documents. This DSL supports the creation of structurally correct CDA documents by enforcing CDA-relevant schema definitions but without dealing with low-level XML details. See also outlook on IPF's CDA support.
  • Extension of OSGi support. Not all features of IPF have been fully OSGi-enabled with release 1.6, like the large binary support or the event infrastructure. This will be fixed with IPF 1.7. You'll also be able to use the new IHE components on OSGi platforms. We also plan to extend existing Camel components to make use of standard OSGi services such as the HTTP service.
  • Better IDE (Eclipse) integration, especially for developing IPF OSGi applications. This includes application development and packaging with Eclipse PDE tools and providing an Eclipse update site for downloading the IPF runtime. Code completion for DSL extensions is currently under discussion.
  • Performance testing framework. DSL extensions to performance-measure IPF applications including calculation and reporting of message processing statistics during load tests.

In parallel we will also create a SVN branch for experimenting with Camel 2.0 milestone releases. I'll let you know about our upgrade/migration experiences in a separate blog post.

Monday, April 13, 2009

Open eHealth Integration Platform 1.6.0 released

Last week we've released the Open eHealth Integration Platform (IPF) version 1.6.0. IPF is an extension of the Apache Camel routing and mediation engine. It has an application programming layer based on the Groovy programming language and comes with comprehensive support for message processing and connecting systems in the eHealth domain. Please see the release notes for further details.

Give it a try! We welcome your feedback!