Monday, May 5, 2014

Spring Integration 4.0: A complete XML-free example

1   Introduction


Spring Integration 4.0 is finally here, and this release comes with very nice features. The one covered in this article is the possibility to configure an integration flow without using XML at all. Those people that don’t like XML will be able to develop an integration application with just using JavaConfig.

This article is divided in the following sections:
  1. Introduction.
  2. An overview of the flow.
  3. Spring configuration.
  4. Detail of the endpoints.
  5. Testing the entire flow.
  6. Conclusion.

The source code can be found at github.

The source code of the web service invoked in this example can be found at the spring-samples repository at github.


2   An overview of the flow


The example application shows how to configure several messaging and integration endpoints. The user asks for a course by specifying the course Id. The flow will invoke a web service and return the response to the user. Additionally, some type of courses will be stored to a database. 

The flow is as follows:
  • An integration gateway (course service) serves as the entry to the messaging system.
  • A transformer builds the request message from the user specified course Id.
  • A web service outbound gateway sends the request to a web service and waits for a response.
  • A service activator is subscribed to the response channel in order to return the course name to the user.
  • A filter is also subscribed to the response channel. This filter will send some types of courses to a mongodb channel adapter in order to store the response to a database.

The following diagram better shows how the flow is structured:




3   Spring configuration


As discussed in the introduction section, the entire configuration is defined with JavaConfig. This configuration is split into three files: infrastructure, web service and database configuration. Let’s check it out:

3.1   Infrastructure configuration


This configuration file only contains the definition of message channels. The messaging endpoints (transformer, filter, etc...) are configured with annotations.

InfrastructureConfiguration.java
The @ComponentScan annotation searches for @Component annotated classes, which are our defined messaging endpoints; the filter, the transformer and the service activator.

The @IntegrationComponentScan annotation searches for specific integration annotations. In our example, it will scan the entry gateway which is annotated with @MessagingGateway.

The @EnableIntegration annotation enables integration configuration. For example, method level annotations like @Transformer or @Filter.

3.2   Web service configuration


This configuration file configures the web service outbound gateway and its required marshaller.

WebServiceConfiguration.java
The gateway allows us to define its output channel but not the input channel. We need to annotate the adapter with @ServiceActivator in order to subscribe it to the invocation channel and avoid having to autowire it in the message channel bean definition.

3.3   Database configuration


This configuration file defines all necessary beans to set up mongoDB. It also defines the mongoDB outbound channel adapter.

MongoDBConfiguration.java
Like the web service gateway, we can’t set the input channel to the adapter. I also have done that by specifying the input channel in the @ServiceActivator annotation.


4   Detail of the endpoints


The first endpoint of the flow is the integration gateway, which will put the argument (courseId) into the payload of a message and send it to the request channel.

The message containing the course id will reach the transformer. This endpoint will build the request object that the web service is expecting:

Subscribed to the response channel, which is the channel where the web service reply will be sent, there’s a service activator that will receive the response message and deliver the course name to the client:

Also subscribed to the response channel, a filter will decide based on its type, if the course is required to be stored to a database:


5   Testing the entire flow


The following client will send two requests; a BC type course request that will be stored to the database and a DF type course that will be finally filtered:

This will result in the following console output:

CourseRequestBuilder|Building request for course [BC-45]
CourseResponseHandler|Course with ID [BC-45] received: Introduction to Java
StoredCoursesFilter|Course [BC-45] validated. Storing to database
CourseRequestBuilder|Building request for course [DF-21]
CourseResponseHandler|Course with ID [DF-21] received: Functional Programming Principles in Scala
StoredCoursesFilter|Course [DF-21] filtered. Not a BF course



6   Conclusion


We have learnt how to set up and test an application powered with Spring Integration using no XML configuration. Stay tuned, because Spring Integration Java DSL with Spring Integration extensions is on its way!

I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.

Monday, April 28, 2014

Spring Integration - Configure web service client timeout

1   Introduction


With the support of Spring Integration, your application can invoke a web service by using an outbound web service gateway. The invocation is handled by this gateway, thus you just need to worry about building the request message and handling the response. However, with this approach it is not obvious how to configure additional options like setting timeouts or caching of operations. This article will show how to set a client timeout and integrate it with the gateway.

This article is divided in the following sections:
  1. Introduction.
  2. Web service invocation overview.
  3. Configuring a message sender.
  4. The sample application.
  5. Conclusion.

The source code can be found at github.


2   Web service invocation overview


The web service outbound gateway delegates the web service invocation to the Spring Web Services WebServiceTemplate. When a message arrives to the outbound gateway, this template uses a message sender in order to create a new connection. The diagram below shows an overview of the flow:


By default, the web service template sets an HttpUrlConnectionMessageSender as its message sender, which is a basic implementation without support for configuration options. This behavior though, can be overridden by setting a more advanced message sender with the capability of setting both read and connection timeouts.

We are going to configure the message sender in the next section.


3   Configuring a message sender


We are going to configure a message sender to the outbound gateway. This way, the gateway will set the template’s message sender with the one provided.

The implementation we are providing in the example is the HttpComponentsMessageSender class, also from the Spring Web Services project. This message sender allows us to define the following timeouts:
  • connectionTimeout: Sets the timeout until the connection is established.
  • readTimeout: Sets the socket timeout for the underlying HttpClient. This is the time required for the service to reply.

Configuration:

The properties file contains the values, which are both set to two seconds:

timeout.connection=2000
timeout.read=2000

Once configured, we add it to the web service outbound gateway configuration:

To use this message sender, you will need to add the following dependency:

And that’s it; the next section will show the sample application to see how it works.


4   The sample application


The flow is simple; it consists in an application that sends a request to a web service and receives a response. The web service source code can be found at github.

The gateway contains the method through which we will enter the messaging system:

Finally, the test:


5   Conclusion


We have learnt how to set additional options to the web service outbound gateway in order to establish a timeout.

I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.


Monday, February 24, 2014

Thymeleaf integration with Spring (Part 2)

1   Introduction


This is the second part of the Thymeleaf integration with Spring tutorial. You can read the first part here, where you will learn how to configure this project.

As explained at the beginning of the first part of this tutorial, the web application will send two types of requests:
  • Insert a new guest: Sends a synchronous request to the server for adding a new guest. This will demonstrate how Thymeleaf is integrated with Spring’s form backing beans.
  • List guests: Sends an AJAX request that will update a region (fragment) of the page in order to show the guest list returned from the server.

Let's see how we will accomplish this.


2   Handling forms


In this section we are going to see how a form is submitted with Thymeleaf. We will basically need three attributes:

th:action
th:object
th:field

The first two are defined in the form element:

The th:action attribute rewrites the action url, prefixing the application context to it.

The th:object attribute in the form element is the object selection. It can then be referenced within the form. What we do here is bind the form backing bean to the model attribute, which we defined in the controller before rendering the view:

As we see, th:object refers to the Guest form backing bean, while th:field will refer to its properties.  Take a look at the form body:

What th:field will do is assign the value of its input element to the backing bean property. So, when the user submits the form, all these th:field will set the form backing bean properties.

At the controller, we will receive the Guest instance:

Now the guest can be inserted into the database.


3   Sending AJAX requests


When trying to find a simple example of sending an AJAX request with Thymeleaf, I have found examples with Spring Webflow (render fragments). I also read others saying that you need Tiles in order to accomplish that.

I didn't want to use those frameworks so in this section I'm using jQuery to send an AJAX request to the server, wait for the response and partially update the view (fragment rendering).

The form

This form contains an input text with a search string (searchSurname) that will be sent to the server. There's also a region (resultsBlock div) which will be updated with the response received from the server.



When the user clicks the button, the retrieveGuests() function will be invoked.

The jQuery load function makes a request to the server at the specified url and places the returned HTML into the specified element (resultsBlock div).

If the user enters a search string, it will search for all guests with the specified surname. Otherwise, it will return the complete guest list. These two requests will reach the following controller request mappings:

Since Spring is integrated with Thymeleaf, it will now be able to return fragments of HTML. In the above example, the return string "results :: resultsList" is referring to a fragment named resultsList which is located in the results page. Let's take a look at this results page:

The fragment, which is a table with registered guests, will be inserted in the results block:



4   Conclusion


After integrating both frameworks, we learnt how forms are linked to the Spring MVC model. We also learnt how to send AJAX requests and partially update the view.

I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.

Monday, February 17, 2014

Thymeleaf integration with Spring (Part 1)

1   Introduction


This article is focused on how Thymeleaf can be integrated with the Spring framework. This will let our MVC web application take advantage of Thymeleaf HTML5 template engine without losing any of the Spring features. The data layer uses Spring Data to interact with a mongoDB database.

The example consists in a Hotel's single page web application from where we can send two different requests:

  • Insert a new guest: A synchronous request that shows how Thymeleaf is integrated with Spring's form backing beans.
  • List guests: An asynchronous request that shows how to handle fragment rendering with AJAX.

This tutorial expects you to know the basics of Thymeleaf. If not, you should first read this article.

Here's an example of the application flow:


This example is based on Thymeleaf 2.1 and Spring 4 versions.

The source code can be found at github.


2   Configuration


This tutorial takes the JavaConfig approach to configure the required beans. This means xml configuration files are no longer necessary.

web.xml
Since we want to use JavaConfig, we need to specify AnnotationConfigWebApplicationContext as the class that will configure the Spring container. If we don't specify it, it will use XmlWebApplicationContext by default.

When defining where the configuration files are located, we can specify classes or packages. Here, I'm indicating my configuration class.

Spring Configuration
My configuration is split in two classes: thymeleaf-spring integration (WebAppConfiguration class) and mongoDB configuration (MongoDBConfiguration class).

WebAppConfiguration.java

Things to highlight from looking at the above code:
  • @EnableWebMvc: This enables Spring MVC annotations like @RequestMapping. This would be the same as the xml namespace <mvc:annotation-driven />
  • @ComponentScan(“xpadro.thymeleaf”): Activates component scanning in the xpadro.thymeleaf package and subpackages. Classes annotated with @Component and related annotations will be registered as beans.
  • We are registering three beans which are necessary to configure Thymeleaf and integrate it with the Spring framework.
    • template resolver: Resolves template names and delegates them to a servlet context resource resolver.
    • template engine: Integrates with Spring framework, establishing the Spring specific dialect as the default dialect.
    • view resolver: Thymeleaf implementation of the Spring MVC view resolver interface in order to resolve Thymeleaf views.

MongoDBConfiguration.java

This class extends AbstracMongoConfiguration, which defines mongoFactory and mongoTemplate beans.  
The @EnableMongoRepositories will scan the specified package in order to find interfaces extending MongoRepository. Then, it will create a bean for each one. We will see this later, at the data access layer section.


3   Thymeleaf – Spring MVC Integration


HotelController
The controller is responsible for accessing the service layer, construct the view model from the result and return a view. With the configuration that we set in the previous section, now MVC Controllers will be able to return a view Id that will be resolved as a Thymeleaf view.

Below we can see a fragment of the controller where it handles the initial request (http://localhost:8080/th-spring-integration/spring/home):

A typical MVC Controller that returns a "home" view id. Thymeleaf template resolver will look for a template named "home.html" which is located in /WEB-INF/html/ folder, as indicated in the configuration. Additionally, a view attribute named "hotelData" will be exposed to the Thymeleaf view, containing hotel information that needs to be displayed on the initial view.

This fragment of the home view shows how it accesses some of the properties of the view attribute by using Spring Expression Language (Spring EL):

Another nice feature is that Thymeleaf will be able to resolve Spring managed message properties, which have been configured through the MessageSource interface. 


Error handling
Trying to add a new user will raise an exception if a user with the same id already exists. The exception will be handled and the home view will be rendered with an error message.

Since we only have one controller, there's no need to use @ControllerAdvice. We will instead use a @ExceptionHandler annotated method. You can notice that we are returning an internationalized message as the error message:

Thymeleaf will resolve the view attribute with ${} and then it will resolve the message #{}:

The th:unless Thymeleaf attribute will only render the span element if an error message has been returned.


4   The Service layer


The service layer accesses the data access layer and adds some business logic. 


5   The Data Access layer


The HotelRepository extends the Spring Data class MongoRepository

This is just an interface, we won't implement it. If you remember the configuration class, we added the following annotation:

Since this is the package where the repository is located, Spring will create a bean and inject a mongoTemplate to it. Extending this interface provides us with generic CRUD operations. If you need additional operations, you can add them with the @Query annotation (see code above).


6   Conclusion


We have configured Thymeleaf to resolve views in a Spring managed web application. This allows the view to access to Spring Expression Language and message resolving. The next part of this tutorial is going to show how forms are linked to Spring form backing beans and how we can reload fragments by sending an AJAX request.

Read the next part of this tutorial: Thymeleaf integration with Spring (Part 2)

I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.

Monday, January 20, 2014

Migrating Spring MVC RESTful web services to Spring 4

1   Introduction


Spring 4 brings several improvements for MVC applications. In this post I will focus on restful web services and try these improvements by taking a project implemented with Spring 3.2 and upgrading it to Spring 4. The following points sum up the content of this post:

The source code of the following projects can be found at github:

Original project (spring 3.2)

Migration to Spring 4


2   The Spring 3.2 RESTful sample


The starting project is implemented with Spring 3.2 (pom.xml) . It consists in a Spring MVC application that access a database to retrieve data about TV series. Let's have a look at its REST API to see it clearer:



Spring configuration

root-context.xml

db-context.xml

Service implementation
This class is responsible of retrieving the data from a mongoDB database:


Controller implementation
This controller will handle requests and interact with the service in order to retrieve series data:


Integration testing
These integration tests will test our controller within a mock Spring MVC environment. In this way, we will be able to also test the mappings of our handler methods. For this purpose, the MockMvc class becomes very useful. If you want to learn how to write tests of Spring MVC controllers I highly recommend the Spring MVC Test Tutorial series by Petri Kainulainen.


I'm showing some of the tests implemented. Check SeriesIntegrationTesting for complete implementation.

Functional testing
The application contains some functional testing by using the RestTemplate class. You need the webapp deployed in order to test this.


That's all, the web application is tested and running. Now is time to migrate to Spring 4.


3   Migrating to Spring 4


Check this page to read information about migrating from earlier versions of the Spring framework

3.1   Changing maven dependencies


This section explains which dependencies should be modified. You can take a look at the complete pom.xml here.

The first step is to change Spring dependencies version from 3.2.3.RELEASE to 4.0.0.RELEASE:


The next step is to update to Servlet 3.0 specification. This step is important since some of the Spring features are based on Servlet 3.0 and won't be available. In fact, trying to execute SeriesIntegrationTesting will result in a ClassNotFoundException due to this reason, which is also explained here.


3.2   Updating of Spring namespace


Don't forget to change the namespace of your spring configuration files:

Review the information page linked in section 2 since there are some changes regarding mvc namespace.


3.3   Deprecation of jackson libraries


If you check SeriesFunctionalTesting (setup method) again you will notice that the Jackson converter is now deprecated. If you try to run the test it will throw a NoSuchMethodError due to method change in Jackson libraries:

java.lang.NoSuchMethodError: org.codehaus.jackson.map.ObjectMapper.getTypeFactory()Lorg/codehaus/jackson/map/type/TypeFactory

In Spring 4, support to Jackson 1.x has been deprecated in favor of Jackson v2. Let's change the old dependency:


For these:

Finally, if you are explicitly registering message converters you will need to change the deprecated class for the new version:


3.4   Migration complete


The migration is done. Now you can run the application and execute its tests. The next section will review some of the improvements I mentioned at the beginning of this post.


4 Spring 4 Web improvements


4.1 @ResponseBody and @RestController


If your REST API serves content in JSON or XML format, some of the API methods (annotated with @RequestMapping) will have its return type annotated with @ResponseBody. With this annotation present, the return type will be included into the response body. In Spring 4 we can simplify this in two ways:

Annotate the controller with @ResponseBody
This annotation can now be added on type level. In this way, the annotation is inherited and we are not forced to put this annotation in every method.


Annotate the controller with @RestController


This annotation simplifies the controller even more. If we check this annotation we will see that it is itself annotated with @Controller and @ResponseBody:

Including this annotation won't affect methods annotated with @ResponseEntity. The handler adapter looks up into a list of return value handlers in order to resolve who is capable of handling the response. The handler responsible of handling the ResponseEntity return type is asked before the ResponseBody type, so it will be used if ResponseEntity annotation is present at the method.


4.2 Asynchronous calls


Using the utility class RestTemplate for calling a RESTful service will block the thread until it receives a response. Spring 4 includes AsyncRestTemplate in order to execute asynchronous calls. Now you can make the call, continue doing other calculations and retrieve the response later.


Asynchronous calls with callback
Although the previous example makes an asynchronous call, the thread will block if we try to retrieve the response with futureEntity.get() if the response hasn't already been sent.
AsyncRestTemplate returns ListenableFuture, which extends Future and allows us to register a callback. The following example makes an asynchronous call and keeps going with its own tasks. When the service returns a response, it will be handled by the callback:



5 Conclusion


We took a Spring 3.2.x web application and migrated it to the new release of Spring 4.0.0. We also reviewed some of the improvements that can be applied to a Spring 4 web application.

I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.

Tuesday, December 31, 2013

Retry web service operations with RequestHandlerRetryAdvice

1   Introduction


Sometimes when invoking a web service, we may be interested in retrying the operation in case an error occurs. When using Spring Integration, we can achieve this functionality with RequestHandlerRetryAdvice class. This class will allow us to retry the operation for a specified number of times before giving up and throwing an exception. This post will show you how to accomplish this.

The test application will invoke a web service and if it fails to respond, it will wait for a specified time and try it again until it receives a response or it reaches a retry limit. If the limit is reached, the failed request will be stored into a database. Mainly, this post shows an example of the following:



The source code of the application can be found at github.
You can also get the source code of the web service project that is called by the application at github.


2   Web service invocation


Use case: The client invokes the web service and receives a response.


The request enters the messaging system through the "system entry" gateway. It then reaches the outbound gateway, invokes the web service and waits for the response. Once received, the response is sent to the response channel.

The above image is the result of this configuration:

Mapped to the response channel there's a service activator which just logs the result.


TestInvocation.java: Sends the request to the entry gateway

With this configuration, if the service invocation fails, a MessagingException will be raised and sent to the error channel. In the next section, we will add the retry configuration.


3   Adding the retry advice


Use case: The initial request failed because the service is not active. We will retry the operation until a response is received from the service.

In this case, we need to add the retry advice to the web service outbound gateway:


Now the web service outbound gateway will delegate the invocation to the retry advice, which will try the operation as many times as specified until it gets a response from the service.

Let's define the retry advice:


To accomplish its objective, the advice uses a RetryTemplate, which is provided by the Spring Retry project. We can customize its behavior by defining backoff and retry policies.

Backoff policy: Establishes a period of time between each retry. The more interesting types are:

  • FixedBackOffPolicy: Used in our example. It will wait for the same specified amount of time between each retry.
  • ExponentialBackOffPolicy: Starting with a determined amount of time, it will double the time on each retry. You can change the default behavior by establishing a multiplier.


Retry policy: Establishes how many times will retry the failed operation. Some of the types:

  • SimpleRetryPolicy: Used in our example. Specifies a retry attempts limit.
  • ExceptionClassifierRetryPolicy: Allows us to establish a different maxAttempts depending on the exception raised.
  • TimeoutRetryPolicy: Will keep retrying until a timeout is reached.


4   No luck, logging the failed request


Use case: The service won't recover, storing the request to the database.



The final part of the configuration is the following:

The service activator subscribed to the error channel will retrieve the failed message and send it to the outbound adapter, which will insert it to a mongoDB database.

The service activator:


If we not succeed in obtaining a response from the service, the request will be stored into the database:



6   Conclusion


We've learnt how Spring Integration gets support from the Spring Retry project in order to achieve retry of operations. We've used the int-ws:request-handler-advice-chain, but the 'int' namespace also supports this element to add this functionality to other types of endpoints.


I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.

Saturday, November 30, 2013

How error handling works in Spring Integration

1   Introduction


The target of this post is to show you how errors are handled when using the messaging system with Spring Integration. You will see that error handling is different between synchronous and asynchronous messaging. As usual, I'll skip the chat and proceed with some examples.

You can get the source code at github.


2   The sample application


I will use a basic example, since I want to focus on exception handling. The application consists in an order service, which receives an order, processes it and returns a confirmation.

Below we can see how the messaging system is configured:

int-config.xml
The gateway is the entry point of the messaging system. It will receive the order and send it to the direct channel "requestChannel" where a router will redirect it to the appropriate channel based on the order id:

  • syncChannel: A direct channel that will send the order to an order processor subscribed to this channel.
  • asyncChannel: A queue channel from which the order processor will actively retrieve the order.

Once the order is processed, an order confirmation will be sent back to the gateway. Here is a graphic representing this:

Ok, let's start with the simplest case, synchronous sending using a Direct Channel.


3   Synchronous sending with Direct channel


The order processor is subscribed to the "syncChannel" Direct Channel. The "processOrder" method will be invoked in the sender's thread.

Now, we will implement a test that will provoke an exception by sending an invalid order. This test will send an order to the gateway:


The test:

TestSyncErrorHandling.java

We run the test and see how an exception is raised in the order processor and reaches the test. That's fine; we wanted to validate that sending an invalid order raised an exception. This happened because the test sent the order and blocked waiting for the order to be processed in the same thread. But, what happens when we use an asynchronous channel? Let's continue to the next section.


4   Asynchronous sending with Queue Channel


This section's test sends an order that will be redirected by the router to the queue channel. The gateway is shown below:

Notice that this time the gateway is returning a Future. If we didn't return this, the gateway would block the test thread. By returning Future, the gateway becomes asynchronous and doesn't block the sender's thread.

The test:

TestKoAsyncErrorHandling.java
Ok, so now we are going to launch the test and see the exception raising...

java.lang.AssertionError: Expected exception: org.springframework.integration.MessageHandlingException

Oops the test failed because no exception reached the test! What happened? Well, the explanation is below:

Since we are using an asynchronous channel (a queue), the sender sends the order and moves on. Then, the receiver polls the order from a different thread. For this reason, it won't be possible to throw the Exception back to the sender. Let's act like nothing happened then? Well you better not, there are other options.


5   Asynchronous error handling


When using asynchronous messaging, Spring Integration handles exceptions by publishing them to message channels. The exception thrown will be wrapped into a MessagingException and become the payload of the message.

What channel is the error message sent to? First, it will check if the request message contains a header called "errorChannel". If found, the error message will be sent there. Otherwise, the message will be sent to a so-called global error channel.


5.1   Global error channel


By default, a global error channel called "errorChannel" is created by Spring Integration. This channel is a publish-subscribe channel. This means we can subscribe several endpoints to this channel. In fact, there's already an endpoint subscribed to it: a logging handler.This handler will log the payload of messages arriving to the channel, though it can be configured to behave differently.

We will now subscribe a new handler to this global channel and test that it receives the exception message by storing it into a database.

First of all, we will need to change a few things in our configuration. I've created a new file so it doesn't interfere with our previous tests:

int-async-config.xml
The gateway: I've added an error channel. If the invocation fails, the error message will be sent to this channel. If I hadn't defined an error channel, the gateway would have propagated the exception to the caller, but in this case it wouldn't have worked since this is an asynchronous gateway.

The error handler: I've defined a new endpoint that is subscribed to the global error channel. Now, any error message sent to the global error channel will be delivered to our handler.

I've also added a configuration file in order to configure the database. Our error handler will insert received errors to this database:

db-config.xml
The error handler is pretty simple; it receives the error message and inserts its information to the database:

Ok, now is all set. Let's implement a new test:

TestOkAsyncErrorHandlingTest.java
This time the test is successful, the error message has been stored to the database.


5.2   Other mechanisms


Custom error channel: You can define your error channel and define it as a queue channel instead of the default publish-subscribe channel:


ErrorMessageExceptionTypeRouter: This Spring Integration specialized router will resolve the channel where the error message will be sent. It bases its decision on the most specific cause of the error:



6   Conclusion


We have learnt what are the different mechanisms for error handling when using Spring Integration. With this base, you will be able to extend it and configure your error handling by implementing transformers to extract the information from the error message, using header enrichers for setting error channel or implementing your own router among other things.

I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.