Search This Blog

Friday, April 25, 2008

REST Web Service Example with Restlet, Spring and Maven...

Time for me to blog something of technical interest again. Ever since I have
joined Overstock.com, I have found myself working with two new technologies, REST and
MAVEN. By no means do I consider myself an expert on the same but feel that
sharing some of my experience might prove beneficial to someone else.

A Restlet 2.0 Example is available in a later POST I would however recommend a read of this one before proceeding to the 2.0 example.

Clearly, I cannot share any OSTK proprietary work...

First some words about Maven. I have always wanted to use Maven even during
my career at PRFT. Sadly, I didn't get to it. Maven is not another ANT, it
so much more. Ever since I have started using Maven, I cannot find myself
not using it when possible.

Noting a few maven terms (some coined by me others maybe not ;-)):

1. Maven Repository:

A Maven repository is a public/private site that hosts different libraries
or jars.

2. Artifact Coordinates:

Every jar in a Maven repository can be identified by coordinates. For example,
if one is trying to find spring-2.5.1.jar, the artifact is represented as:

<groupid>org.springframework</groupid>
<artifactid>spring</artifactid>
<version>2.5.1</version>


Think of group Id as being a top level folder that aggregates multiple artifact
types. An artifact Id describes a particular artifact in the group and the
version helps identify the version of the artifact.

3. Local Repository:

Maven downloads artifacts and places them in your $HOME/.m2 folder. Thus, you
always maintain a copy of the jar, i.e., a nicely shelved away via version. Thus the jar will not
be downloaded all the time but only once.

4. POM:

The foundation of maven lies in what is known as a POM or
Project Object Module. When using Maven, you will often find files titled
pom.xml. These pom files describe your project for you. A Maven project
can serve as an 'Aggregator' project that serves to group children project
under one umbrella. These project are typically called "Multi-Module" projects.

5. Maven Eclipse Plugin:

I use the Q4E Maven Eclipse plugin. Its pretty nice but not yet perfect. With the plugin, I am able to import the different maven projects into eclipse. The visual dependency management feature of this plugin is awesome.

6. Maven Archetype:

An Archetype is a template for creating projects in its likeness. There are different archetype available, for example an archetype to create a J2EE EAR project, a Web Project, a simple java project and App fuse projects as well.

Enough about Maven, a bit about REST!

I am not planning on entering into a REST versus SOAP or what is REST
discussion here but merely wanting to demonstrate a Web Service that uses
REST and Maven.

The stir created by Roy Fieldings dissertation has opened multiple discussions
and thoughts regarding how the Web should be viewed.

An implementation of REST concepts in Java was facilitated by the RESTLET project pioneered by Jérome Louvel.

One of the core classes of the RESTLET framework is the Resource class. Resources tend to represent exactly what their name means, a resource! For example, an Order Resource that
represents Order related data, a Product Resource that represents Product
information etc. I would like to talk more about REST and the RESTLET project
but the posting would be too verbose...maybe a later post.. One can get a good understanding of the RESTLET project via their documentation and starter examples.

Onto the example:

The example demonstrates a simple Restful Web service developed
using Restlet + Spring Framework + JaxB + JSON + Maven + Dozer + JUnit + EasyMock.

The project is organized as follows:


SpringTest
.
-- client

-- common

-- integration-test

-- service

`-- webapp


1. Spring Test:
The Web Service project is a multi module Maven Project. The SpringTest project
is the root level aggregator project that aggregates the modules such
as common, client, service, integration-test and webapp.

2. common:

The common project contains the code that is shared by other modules
of the web service project. It contains the DTO (data transfer objects), common
exceptions, utilities etc.

3. client:

The client project represents the Webservice client code. This project is
pretty much a wrapper around the Restlet API so that consumers of the service
have an easy way to communicate with the web service without having to
concern themselves with specifics of the web service.

4. service:

The service project represents the heart of the web service. The
service is not mixed in with the webapp project as the business logic is
not necessarily tied to RESTLET or REST. If required in the future, a
SOAP or EJB version of the web service could be exposed by re-using the code
from the service project.

The domain model is included in the service project itself. The reason for
the same is; in many cases the model and the service go hand in hand. Now, it
could be argued that the model could be placed in a separate maven module for
re-use. That IMO should be the direction should the model appear to be
re-usable. Also note that the model need not necessarily translate to what
is transferred via the web service. I am therefore making a separation of the
model and the DTO. There is clearly no one size fits all here and depending
on the scope of the project, making the model and the DTO one and the same
might be an option.

5. integration-test:

The project contains a test which will perform end to end integration test.
When an integration test is run, a Jetty Server instance is started using
Cargo and the webapp is deployed onto the server. Then the integration test
is performed which will communicate with the server to assert that the
web service contract is valid and the server will ensure that it performs
as expected. My reason for using Cargo is that one could easily switch to a
different container for testing if required.

Note that one could have additional integration test projects defined when the service
undergoes an upgrade and there is a need to maintain backward compatibility with the Web Service clients.

What does the example do?
The example is a simple mock of an order system. One can get a list of
Products supported by using the Product Service. The Product Service
uses JSON for its transport (just to demonstrate). The Order Service
can place an order, update an order, query an order and delete and order.
The Order Service uses JAXB for marshaling its data.

Standard REST concepts like POST, PUT, GET and DELETE are explored by the
example. I don't believe that I have 100% conformity with REST concepts in the example :-)

The example is a 'simple' one in all senses of the word. Thread safety,
exceptions etc are not even considered. One could easily incorporate the
same if developing a real world web service.

The Project uses Spring as a DI container. Rest Resources are injected with
dependencies using Spring auto-wiring.

Running the example:

1. JDK 1.5.X or Greater:
Ensure you have jdk1.5.X+ installed. The code uses annotations extensively.
From your command line, when issuing a "java -version" make sure that
it is greater than or equals to 1.5.X.

2. Maven Install:

Download Maven and install it. If on a *Nix environment, install maven at
/opt/. Ensure that maven is available in your PATH. What this means is if
you execute a "mvn -version" you should see details of your installation. Additionally, ensure you obtain a 2.0.x version of maven.

3. Eclipse Install:

Download and install an eclipse distribution. Eclipse is not required to run the examples but helps in viewing editing the code.

4. Q4E Maven Plugin:

Open eclipse and install the Q4E Maven plugin. Note that you might need to point the plugin to your maven installation.

5. Download Example:

Download and extract the SpringTest.zip project using your favorite archiving tool. The example has been tested with Restlet 1.1-M4 and Java Version 1.5.X and 1.6.X. If you would like to use a version that uses the API's from Restlet 1.1-M2, then the same can be obtained from HERE.

6. Import into Eclipse:
Import the modules into eclipse as Maven projects. Again this step is optional. It is required if you would like to view the project.

7. Installing Modules:
From the command line, issue a "mvn install" from within the
SpringTest project. What this command does is installs the maven modules in your local repository. As part of the process it will execute JUnit tests and integration tests.

8. An Integration Test:

Run a "mvn integration-test" from the SpringTest folder to see the
integration test in action.

8. Debugging the Web App:
Alternatively, you can watch the project in action by starting jetty
from the webapp project and debugging via remote server attach.

You will need to start jetty from the webapp project using "mvn jetty:run" and then do a remote server attach from eclipse. Ken Steven's blog has a pretty nice description as to how to do the same.

If you have difficulties executing the project, ping me...;-).. Once again the code for the example is available HERE.

The very same example that uses JAXRS (JSR 311) is described HERE.

Wednesday, February 27, 2008

Spring 2.5 Auto Wiring and Annotations

Introduction:

Software developers in general look for the following in a framework or tool:

  • An easy and rapid way to get their development tasks done
  • An easy way to change existing software (Refactor) for the better.

In the current J2EE development environment, the preferred method of configuration is XML. XML and Java seem to walk hand in hand. The structure provided by XML serves well as the place where configuration meta information is defined.

The Spring framework also uses the services of this heavenly match up to provide bean definitions and Dependency Injection. One of the complaints/concerns that I have heard from potential adopters and current users is that Spring is very configuration heavy and one has to deal with a lot of XML. The concern is valid and these concerns are abated to an extent via different strategies such as segregating beans across multiple configuration files, auto-wiring of beans, being selective about what are the dependencies that really need to be injected etc. However, the "Silver Bullet" answer seems elusive.

For the sake of discussion, consider a Simple Airline Application using Spring:

Without going into the anaemic data model debate, the following is a typical structure of layered MVC application:

  • Spring Controllers
  • Business or Service Delegates
  • Data Access Objects

Spring Controllers service a request from the browser by delegating their business processing to service delegates which in turn utilize Data access objects to perform CRUD operations.

When developing a layered architecture, not all components of the different layers are available at the same time. Developing to interfaces and providing Mock implementations (Dummy objects or using JMock, Easy Mock etc) helps decouple the layers and facilitate the development of each layer independently. Once the components in different layers become available they can be "glued" for integration testing. This pattern has helped me on many projects and has led to rapid development in stringent time lines.

As an example, consider the following Flight Application:


/**
* Controller
*/

public class FlightController extends MultiActionController {
private FlightService flightService;
......

public ModelAndView searchFlight(HttpServletRequest request,
HttpServletResponse response) throws Exception {
....
}

public ModelAndView bookFlight(HttpServletRequest request,
HttpServletResponse response) throws Exception {
....
}
}

/**
* Flight Service Definition.
*/

public interface FlightService {
public FlightSearchResult searchFlights(FlightSearchRequest request);

public Ticket bookFlight(BookingRequest request)
throws NoSuchFlightException, NoSeatAvailableException;
....
// Other definitions
}

/**
* Implementation of a Flight Service. Books flights, gets flight
* matching a criteria etc...
*/

public class FlightServiceImpl implements FlightService {
private FlightDAO flightDAO;
.....
//Setters/Getters, business logic etc.
...
}

/**
* Flight DAO definition.
*/

public interface FlightDAO {
public void savePassenger(...);
...
public Flight findFlight(Long id);
}

/**
* Hibernate implementation of the flight DAO
*/

public FlightDAOHibernate extends HibernateDAOSupport implements FlightDAO {
......
// Actual Hibernate implementation of the Interface.
}

/**
* Mock or Dummy Implementation of the Flight DAO
*/

public class FlightDAOMock implements FlightDAO {
...
// Mock implementation
}

The spring configuration without auto-wiring:



<beans>

<!- A URL Mapper to map a 'url' to controller -->
<bean id="urlMapper"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

<property name="mappings">
<props>
<prop key="/flight/search.html">flightController</prop>
<prop key="/flight/book.html">flightController</prop>
......
</props>
</property>
</bean>

<!-- One step below to map a key to a particular method -->
<bean id="propsResolver"
class="org....mvc.multiaction.PropertiesMethodNameResolver">
<prop key="/flight/search.html">searchFlights</prop>
<prop key="/flight/book.html">bookFlight</prop>
.....
</bean>

<!-- Controller class that uses the property resolver.
Note injection of Flight Service -->
<bean id="flightController"
class="com.welflex.flight.web.controller.FlightController">

<property name="methodNameResolver" ref="propsResolver"/>
<!-- Injection of flight service -->
<property name="flightService" ref="flightService"/>
</bean>

<!-- Transaction Template -->
<bean id="txProxyTemplate" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<!-- Flight DAO -->
<bean id="flightDAO"
class="com.welflex.flight.dao.impl.FlightDAOHibernate">
...
</bean>

<!-- Actual Implementation of the Flight Service. Note injection of Flight DAO -->
<bean id="flightServiceTarget"
class="com.welflex.flight.service.impl.FlightServiceImpl">
<!-- Injection of Flight DAO -->
<property name="flightDAO" ref="flightDAO"/>
</bean>

<!-- Wraps the actual service with transaction support -->
<bean id="flightService" parent="txProxyTemplate">
<!-- Injection of Target service -->
<property name="target" ref="flightServiceTarget"/>
</bean>
....
</beans>






The XML Bean Bloat and auto-wiring problem:


As seen above there is a lot of bean definitions present in the configuration file that need to be wired (dependencies setup) together, i.e:

  • Define and Inject Service level beans into controllers
  • Define and Inject Data Access Objects into the Services
  • Define resources and other ancillary artifacts like Data sources, transaction helpers etc.

As seen above, we are not only defining the beans but also defining what gets injected into them. The avoid the latter, we can use Spring's auto-wiring ability.

Auto wiring of the beans can be accomplished by name, by type, etc. Clearly auto wiring by type suffers when one has more than one bean of a type, the auto wiring will fail. For example, if I had two beans defined, a flightDAOHibernate and a flightDAOMock with both implementing the same interface of FlightDAO, the container will not be able to choose between the two implementations for injection.

Auto wiring by name looks like a good idea but results in having to explicitly give names to the various beans.

Further, there is a lack of fine grained control where one cannot auto wire some properties and not others, auto wire some by name and others by type etc.With the above stated, the general best practice has been, its OK to use auto-wiring if your app is small, i.e., few bean definitions, however, if you application is larger, it is better to use explicit wiring. There are ways to keep the XML files manageable by splitting the definitions across multiple files segregated by layer for example.

But regardless, there seems to be no escape from having to define the beans. The direction of having to have to go to XML to define the beans and the wiring has detracted some people from adopting Spring. Are we heading toward a meta-data hell here?

As an additional note, the Java code does not contain information as to what is injected and what is not, one has to fall back to the XML configuration to figure out the injections.Of course, we can mark via documentation as to what is injected etc but then we need to ensure that the documentation is updated when injected properties are added or removed. Additionally, there is no way of validating the documentation or enforcing its practice.

There has to be an easier way where we can get away from the bloated bean definitions when dealing with a decoupled layered architecture :-)!

Annotation Based Auto wiring:

To read more about annotations, the tutorial from Sun is the place to start (http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html)

Spring 2.0 introduced a powerful concept of recognizing stereotypes with the introduction of the @Repository annotation, an annotation that served as a marker for DAO level code. Spring 2.5 went further by adding additional stereotypes like @Controller, and @Service to serve as markers for Controller and Service level objects respectively. Spring 2.5 also introduced a generic marker annotation, @Component which the other stereotypes extend and denotes a Spring managed object.

With Spring 2.5, the ability to auto-wire using annotations was introduced.
The @Autowire annotation allows for more fine grained control than was possible with prior versions, i.e., control over what properties are auto wired and how they are wired, i.e., fields, constructors and methods. For an excellent article about the @Autowired annotation, refer to the article by Mark Fisher at (http://www.infoq.com/articles/spring-2.5-part-1)

The original Java code has been altered to use stereotype annotations and the @Autowire annotation as shown below:



/**
* Flight DAO marked with @Transactional annotation.
* Most of the methods here are readonly.
*/

@Transactional(readOnly = true)
public interface AirlineService {

public FlightSearchResult searchFlights(FlightSearchRequest request);

/**
* Transaction marked for rollback in case of exception when booking a flight.
*/

@Transactional(rollbackFor = {NoSuchFlightException.class, NoSeatAvailableException.class})
public Ticket bookFlight(BookingRequest request)
throws NoSuchFlightException, NoSeatAvailableException;
}

/**
* True hibernate implementation of the Flight DAO marked
* with the @Repository annotation
*/

@Repository
public class FlightDAOHibernate implements FlightDAO {
...
}

/**
* @Repository tag not required. Done to demononstrate
* multiple implementations of an interface.
*/

@Repository
public class FlightDAOMock implements FlightDAO {
}

/**
* Flight Service Implementation. Marked with the @Service implementation.
*/

@Service
public class FlightServiceImpl implements FlightService {
@Autowired
private FlightDAO flightDAO;
...
}

/**
* Controller class changes with not having to explictly extend
* MultiActionController.
*/

@Controller
public class FlightController {
// Flight service will be auto-wired in
@Autowired
private FlightService flightService;
......
@RequestMapping("/search.html")
public ModelAndView searchFlight(HttpServletRequest request,
HttpServletResponse response) throws Exception {
....
}

@RequestMapping("/book.html")
public ModelAndView bookFlight(HttpServletRequest request,
HttpServletResponse response) throws Exception {
....
}

}

The following are the changes that have been effected:

  • Removed the transaction XML declarations in favor of the @Transactional annotation.
  • The XML definitions of the Service, DAO and Controller have been replaced by stereotypes such as @Service, @Controller and @Resource which are defined in the java source. Further the use of the @Autowire annotation has helped in autowiring the components together.
  • By using the @RequestMapping annotation, the mapping between web request to Controller method have been defined right in the Java class. Additionally, the FlightController is no longer extending the MultiActionController class.

The Bloated XML configuration has now reduced to:


<beans>

<!-- required for autowiring -->
<context:annotation-config/>

<!-- Scan the package and below for stereo types-->
<context:component-scan base-package="com.welflex.flight">
</context:component-scan>

...data sources etc...
</beans>

Rather small compared to the earlier configuration wouldn't you say?

The tags shown above will ensure that the Spring container scans the classpath defined to look for Spring stereotypes such as @Controller, @Service and @Resource and will auto-wire the beans.


It is to be noted that when beans are auto wired by type using annotations, the problem that existed with Spring pre-2.5 auto-wiring, i.e., where the container fails to auto wire when there is more than one implementation of the expected type is still an issue.

In the above example, there are two implementations of the FlightDAO, i.e., the FlightDAOMock and FlightDAOHibernate. Spring cannot determine which of the two mentioned beans should be injected into the FlightServiceImpl and will fail to auto-wire.

So what does one do in such a case ?:

1. Explicitly define Beans in Spring config files when there are multiple implementations of an injected type:

Note that in practice one might not have a single file for "true" and "mock" objects but have them separated in different files. I guess that depends on the way you choose your strategy. For the sake of this example, consider that both the beans are defined and available for the spring container to detect as shown below:

<beans>
....
<!-- Hibernate impl -->
<bean id="flightDAOHibernate" class="com....FlightDAOHibernate"/>

<!-- Mock Impl -->
<bean id="flightDAOMock" class="com...FlightDAOMock"/>
...
</beans>





The FlightServiceImpl class can decide which implementation to pick up using the @Qualifier tag which explicitly states the implementation the service expects to be injected as shown below:



public class FlightServiceImpl implements FlightService {

// Explicitly asking for the flightDAOHibernate
@Autowired
@Qualifier("flightDAOHibernate")
private FlightDAO flightDAO;
...
}


Spring will inject in the flightDAOHibernate. But we are back to defining our beans in XML :-(. Also we are forcing the implementation right in the code.


2. Use Annotations/Stereotypes and/or filtered component scanning:

Let us define a marker annotation called 'Mock' that will be applied to the objects that are mock or dummy implementations. The objective is to ensure that the true implementations are auto wired by Spring when running in an integration environment, i.e., objects such as flightDAOHibernate are injected and not their mock counterparts. The following is an annotation that will serve to 'mark' mock objects in the system.


@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface Mock {
}
Mock objects like the FlightDAOMock are tagged with the Mock annotations as shown below:
@Mock
public class FlightDAOMock implements FlightDAO {
...
}
Now when using unit tests or when the real Hibernate DAO is not ready, the mock implementation are what should be used. But as mentioned when testing integration of the layers, one would need to use the true implementation of the FlightDAO.

This selection can be accomplished using selective classpath scanning of components to ignore the Mock implementations. The following shows the filtering of Mock objects when running in an integrated environment:



<context:component-scan base-package="com.welflex.flight">
<context:exclude-filter type="annotation"
expression="com.welflex.flight.util.annotation.Mock"/>
</context:component-scan>



The above component scanning will exclude objects marked with the Mock annotation.

As an alternative to using the @Mock annotation, if the test structure was under a test package, eg: package of com.weflex.flight.test, the class path scanning rule could be changed to exclude the classes under the test package.

So which beans are a case for annotated auto-wiring and which beans are a case for XML definition ? :

I don't think there is a clear definition of what is the best practice regarding whichobjects are best suited for annotated auto-wiring and which need explict XML definition.I guess it depends on a case by case basis and what direction is chosen.

From a personal perspective, I would choose to use the annotations for the defined stereotypes such as @Controller, @Service, @Repository objects. In cases where there is ambiguity regarding the types that are available, I would explicitly define the beans in XML and use the @Qualifier tag to select implementations.

To separate by environment, I would definitely use custom annotations where possible.

Database resources, LDAP Resources, JMS Resources are some of the definitions that I beleive are best defined in XML configuration. Having more than one data source for example could lead to auto-wiring failure. In such a case the use of @Qualifier annotation would help select the right data source.

For other beans, the annotation driven approach seems to provide a promising solution.

Code Example:

I have linked herewith an example that I used for understanding Spring 2.5. In the example, I have explored the various 2.5 tags. The code itself has been largely based on the spring-ws example code by Arjen Poutsma. I have used MyEclipse 6.0 with Tomcat, My SQL and Hibernate. The code can be accessed from Code Samples. There are two files of interest, namely FlightReservation.zip and AirlineSQLBackup.sql. You will need to import the database into MySQL and then create a user with login airline and password airline. Deploy the application on Tomcat and see it in action.

Conclusion:

Sun had a great concept with annotations way back with the @deprecated and @author annotations. The introduction of 'Common Annotations for the Java Platform' with Java EE 5 makes the java language so much richer and easier to use. Spring's foray in the annotation based development model makes Spring so much a viable option IMO to the wary adopter. Some additional annotations are demonstrated in the FlightReservation example, i.e., annotations such as @Aspect, @PostConstruct and @PreDestroy.

As most people who have been deterred by the "XML Bean Bloat", I would suggest they re-think the option of using Spring 2.5 and onward. For my fellow developer:

1. The use of annotations, sterotypes etc can really make the process of developing with Spring straight forward, i.e., without having to contend with the XML Bean bloat problem.

2. Refactoring and researching existing code becomes rather easy as one needs to only look at the java source to determine:

  • Which beans are being injected and which are not.
  • Where and how transactions are applied.
  • Which web requests map to which methods in a Controller.

Neat Links:


RAMBLING END....:-)