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.

Monday, October 21, 2013

Spring Integration – Using RMI Channel Adapters

1   Introduction


This article explains how to send and receive messages over RMI using Spring Integration RMI channel adapters. It is composed of the following sections:

  • Implementing the service: The first section focuses on creating and exposing a service.
  • Implementing the client: Shows how to invoke the service using the MessagingTemplate class.
  • Abstracting SI logic: Finally, I’ve added another section explaining how to implement the same client abstracting all Spring Integration code, leaving the client focused on its business logic.

You can get the source code at github.


2   Implementing the service


This first part is pretty simple. The service is defined through annotations, so it will be autodetected by component scanning. It has a repository injected, which gets the data from an embedded database, as it will be shown in this same section:

The repository is as follows:


The following configuration exposes the service over RMI:

server-config.xml
Let’s focus on the lines with the ‘int’ namespace:

The gateway’s function is to separate the plumbing of the messaging system from the rest of the application. In this way, it gets hidden from the business logic. A gateway is bidirectional, so you have:

  • Inbound gateway: Brings a message into the application and waits for a response.
  • Outbound gateway: Invokes an external system and sends the response back to the application.


In this example, we are using a RMI inbound gateway. It will receive a message over RMI and send it to the requestEmployee channel, which is also defined here.

Finally, the service activator allows you to connect a spring bean to a message channel. Here, it is connected to the requestEmployee channel. The message will arrive to the channel and the service activator will invoke the retrieveEmployee method. Take into account that the ‘method’ attribute is not necessary if the bean has only one public method or has a method annotated with @ServiceActivator.

The response will then be sent to the reply channel. Since we didn’t define this channel, it will create a temporary reply channel.




3   Implementing the client


The client we are going to implement will invoke the service in order to retrieve an employee. To do this, it will use the MessagingTemplate class:

The client uses the messagingTemplate to convert the Integer object to a Message and send it to the local channel. As shown below, there’s an outbound gateway connected to the local channel. This outbound gateway will send the request message over RMI.



4   Abstracting SI logic


In the previous section, you may have noticed that the client class which accesses the service has Spring Integration specific logic mixed with its business code:
  • It uses the MessagingTemplate, which is a SI class.
  • It knows about the local channel, which is specific to the messaging system

In this section, I will implement this same example abstracting the messaging logic, so the client will only care about its business logic.

First, let’s take a look at the new client:

We can see now that the client just implement its business logic, without using neither message channels nor messaging template. It will just call the service interface. All the messaging definitions are in the configuration file.

client-gateway-config.xml
What we did here is add a gateway that will intercept calls to the service interface EmployeeService. Spring Integration will use the GatewayProxyFactoryBean class to create a proxy around the service interface. This proxy will use a messaging template to send the invocation to the request channel and wait for the response.



5   Conclusion


We have seen how to use Spring Integration to access a service over RMI.  We have also seen that we can not only explicitly send messages using the MessagingTemplate but also do it transparently with GatewayProxyFactoryBean.

Monday, September 30, 2013

Creating contract-first web services with Spring WS

1   Introduction


This article explains how to implement and test a SOAP web service using the Spring Web Services project. This example uses JAXB2 for (un)marshalling. To develop the service, I’ll use the contract-first approach, which consists in definning the service contract first, and based on this contract implement the service.

The article is divided into the following sections:

2   Explaining the application
3   Implementing the service
3.1   Creating the contract
3.2   Generating Java classes
3.3   Implementing the SOAP endpoint
3.4   Configuring the application
4   Testing the service
5   Additional information
5.1   Implementing the client
5.2   How it works internally


2   Explaining the application


The example application processes orders. We’ve got a front controller (messageDispatcher servlet) that will handle order requests, invoke the service to process the order and return a result.


You can get the source code at github.


3   Implementing the service
3.1   Creating the contract


Since we will use the contract-first approach, the simplest way to create the contract is by first definning sample xml documents and from that, we will generate the contract using a tool. Below are the sample xml documents:

client-request.xml

client-response.xml

In order to create the schema, we can use Trang, which is an open source tool that will allow us to generate the xsd schema from the xml documents. I’ve included this library into the project build path (you can get this jar from Trang web site) and I’ve created an Ant task for executing the conversion:

generate-schema.xml

Once the Ant task is executed, it will generate the schemas. Since schemas have been automatically generated, it is possible that we need to make some modifications to adapt it to our needs. Let’s take a look:

client-request.xsd
client-response.xsd

We can add different validations to these schemas, but in this example I’ll just modify several types like clientId, productId and confirmationId (xs:string) and orderDate (xs:date). The mapping of XML data types to Java types is done by JAXB. You can check which are the mappings provided here.

To finish with the schema, we will copy the response element into the request schema. I’ve created a third schema with both response and request:

client-service.xsd

The last step would consist in writting the contract, generally expressed as a WSDL file. If you don’t want to create it by hand, the Spring-ws project provides us with a way to generate this file from an XSD schema. We will use this second approach as you will see in the configuring the application section.


3.2   Generating Java classes


We will use JAXB2 to generate request and response objects. The XJC compiler from JAXB will be responsible of converting these objects from the XSD schema that we generated before. It will be executed as an Ant task:
This task will create Java classes in the xpadro.spring.ws.types package (you may need to refresh the project).



3.3   Implementing the SOAP endpoint


The endpoint receives the unmarshalled message payload and uses this data to invoke the order service. It will then return the service response, which will be marshalled by the endpoint adapter:
Here's a brief description of the annotations used by the endpoint:

@Endpoint: Registers the class as a component. In this way, the class will be detected by component scan.

@PayloadRoot: Registers the endpoint method as a handler for a request. This annotation will define what type of request message can be handled by the method. In our example, it will receive messages where its payload root element has the same namespace as defined in the XSD schema we created, and its local name is the one defined for the request (clientDataRequest).

@RequestPayload: Indicates the payload of the request message to be passed as a parameter to the method.

@ResponsePayload, indicates that the return value is used as the payload of the response message.


3.4   Configuring the application


web.xml
Application configuration (like datasource, transactionManager...)

Loads the application context
This is the servlet that will act as a Front Controller to handle all SOAP calls. Its function is to derive incoming XML messages to endpoints, much like the DispatcherServlet of Spring MVC.
servlet-config.xml

This configuration contains web service infrastructure beans.
In the dynamic wsdl, it doesn’t matter what value you put in the locationUri attribute because it will be handled by the MessageDispatcherServlet. Hence, the wsdl will be available at:

http://localhost:8081/spring-ws/orders/whatever/orderDefinition.wsdl


4   Testing the service


The following example creates a mock client which will access the web service:

The configuration file used on this test is pretty simple, just contains scanning of the service components:

5   Additional information

5.1   Implementing a client


To facilitate the client to access the web service, Spring provides us with the WebServiceTemplate class. This class contains methods for sending and receiving messages and it also uses converters to (un)marshal objects.

I’ve created a test that acts as a client of the service:

The configuration test file contains WebServiceTemplate configuration:
Just remember to start the server with the deployed web service application before executing this test.


5.2   How it works internally


If you just want to implement a web service, the article finished in the previous section. For those curious about how this really works, I will try to explain how a request is mapped to the endpoint, just a little more low-level than explained until this point.

When a request arrives to the MessageDispatcher, it relies on two components:

  1. It asks the EndpointMapping which is the appropriate endpoint.
  2. With the information received from the mapping it uses an endpoint adapter to invoke the endpoint. The adapter also support argument resolvers and return type handlers.


Endpoint mapping

MessageDispatcher contains a list of endpoint mappings, each of them, containing a map of previously registered method endpoints. In our case, the JAXB mapping PayloadRootAnnotationMethodEndpointMapping has registered all methods annotated with @PayloadRoot. If the qualified name of the payload of the message resolves as a registered method, it will be returned to the MessageDispatcher. If we didn’t annotate our method it would fail to process the request.



Endpoint adapter

MessageDispatcher will then ask each of its endpoint adapters if it supports the current request. In our case, the adapter checks if the following conditions are both true:

  • At least one of the arguments passed to the method is annotated with @RequestPayload
  • If the endpoint method returns a response, it must be annotated with @ResponsePayload

If an adapter is returned, it will then invoke the endpoint, unmarshalling the parameter before passing it to the method. When the method returns a response, the adapter will marshal it.

The following diagram is a much reduced version of this step in order to keep it simple:



Conclusion


We've seen an introduction on how to implement a simple web service and then test it. If you are interested, you can also take a look at how to test the client-side with MockWebServiceServer.

Tuesday, August 27, 2013

Spring JMS: Processing messages within transactions

1 Introduction

This post will show you how an error in the execution of the consumer during the asynchronous reception of messages with JMS, can lead to the loss of messages. I then will explain how you can solve this problem using local transactions.

You will also see that this solution can cause in some cases, message duplication (for example, when it saves the message to the database and then the listener execution fails). The reason why this happens is because the JMS transaction is independent to other transactional resources like the DB. If your processing is not idempotent or if your application does not support duplicate message detection, then you will have to use distributed transactions.

Distributed transactions are beyond the scope of this post. If you are interested in handling distributed transactions, you can read this interesting article.

I've implemented a test application that reproduces the following cases:

  1. Sending and reception of a message: The consumer will process the received message, storing it to a database.
  2. The producer sends the message to a queue:

    The consumer retrieves the message from the queue and processes it:

  3. Error occurred before message processing: The consumer retrieves the message but the execution fails before storing it to the DB.
  4. Error occurred after processing the message: The consumer retrieves the message, stores it to the DB, and then the execution fails.

The source code for this application can be found at github.


2   The test application

The test application executes two test classes, TestNotTransactedMessaging and TestTransactedMessaging. These classes will both execute the three cases above described.

Let's see the configuration of the application when it is executed without transactions.

app-config.xml
Application configuration. Basically it checks within the indicated packages to autodetect the application beans: producer and consumer. It also configures the in-memory database where processed notifications will be stored.
notx-jms-config.xml
Configures the JMS infrastructure, which is:
  • Broker connection
  • The JmsTemplate
  • Queue where notifications will be sent
  • The listener container that will send notifications to the listener to process them

The producer simply uses the jmsTemplate to send notifications
The listener is responsible for retrieval of notifications from the queue and stores them to the database.
The checkPreprocessException method will throw a runtime exception when a notification with id=1 arrive. In this way, we will cause an error before storing the message to the DB.

The checkPostprocessException method will throw an exception if a notification with id=2 arrive, thereby causing an error just after storing it to the DB.

The getDeliveryNumber method returns the number of times the message has been sent. This only applies within transactions, since the broker will try to resend the message after listener processing failure led to a rollback.

Finally, the saveToDB method is pretty obvious. It stores a notification to the DB.

You can always check the source code of this application by clicking the link at the beginning of this article.


3   Testing message reception without transactions

I will launch two test classes, one without transactions and the other within a local transaction. Both classes extend a base class that loads the common application context and contains some utility methods:
The utility methods are explained below:

  • getSavedNotifications: Returns the number of notifications stored to the DB. I've used the queryForObject method because it is the recommended since version 3.2.2. The queryForInt method has been deprecated.
  • getMessagesInQueue: Allows you to check which messages are still pending in the specified queue. For this test we are interested in knowing how many notifications are still waiting to be processed.

Now, let me show you the code for the first test (TestNotTransactedMessaging). This test launches the 3 cases indicated at the beginning of the article.

4   Executing the test

Ok, let's execute the test and see what the results are:

testCorrectMessage output:
Producer|Sending notification | Id: 0
NotificationProcessor|Received notification | Id: 0 | Redelivery: 1
TestNotTransactedMessaging|Total items in "incoming" queue: 0
TestNotTransactedMessaging|Total items in DB: 1

No problem here, the queue is empty since the message has been correctly received and stored to the database.

testFailedAfterReceiveMessage output:
Producer|Sending notification | Id: 1
NotificationProcessor|Received notification | Id: 1 | Redelivery: 1
AbstractMessageListenerContainer|Execution of JMS message listener failed, and no ErrorHandler has been set.
java.lang.RuntimeException: error after receiving message
TestNotTransactedMessaging|Total items in "incoming" queue: 0
TestNotTransactedMessaging|Total items in DB: 0

Since it is executing outside a transaction, the acknowledge mode (auto by default) is used. This implies that the message is considered successfully delivered once the onMessage method is invoked and therefore deleted from the queue. Because the listener failed before storing the message to the DB, we have lost the message!!

testFailedAfterProcessingMessage output:
2013-08-22 18:39:09,906|Producer|Sending notification | Id: 2
2013-08-22 18:39:09,906|NotificationProcessor|Received notification | Id: 2 | Redelivery: 1
2013-08-22 18:39:09,906|AbstractMessageListenerContainer|Execution of JMS message listener failed, and no ErrorHandler has been set.
java.lang.RuntimeException: error after processing message
2013-08-22 18:39:15,921|TestNotTransactedMessaging|Total items in "incoming" queue: 0
2013-08-22 18:39:15,921|TestNotTransactedMessaging|Total items in DB: 1

In this case, the message has been deleted from the queue (AUTO_ACKNOWLEDGE) and stored to the DB before the execution failed.


5   Adding local transactions

Usually we can't allow losing messages like the second case of the test, so what we will do is to invoke the listener within a local transaction. The change is pretty simple and it does not imply modifying a single line of code from our application. We will only need to change the configuration file.

To test the 3 cases with transactions, I will replace the configuration file notx-jms-config.xml for the following:

tx-jms-config.xml
First, I've added the number of re-deliveries made in case of a rollback (caused by an error in the listener execution):
Next, I indicate that the listener will be executed within a transaction. This can be done by modifying the listener container definition:
This will cause every invocation of the listener to be executed within a local JMS transaction. The transaction will start when the message is received. If the listener execution fails, message reception will be rolled back.

And that's all we have to change. Let's launch the tests with this configuration.


6   Testing message reception within transactions

The code from the TestTransactedMessaging class is practically the same as the previous test. The only difference is that it adds a query to the DLQ (dead letter queue). When executed within transactions, if the message reception is rolled back, the broker will send the message to this queue (after all re-deliveries failed).

I'm skipping the output of the successful receiving as it does not bring anything new.

testFailedAfterReceiveMessage output:
Producer|Sending notification | Id: 1
NotificationProcessor|Received notification | Id: 1 | Redelivery: 1
AbstractMessageListenerContainer|Execution of JMS message listener failed, and no ErrorHandler has been set.
java.lang.RuntimeException: error after receiving message
NotificationProcessor|Received notification | Id: 1 | Redelivery: 2
AbstractMessageListenerContainer|Execution of JMS message listener failed, and no ErrorHandler has been set.
...
java.lang.RuntimeException: error after receiving message
NotificationProcessor|Received notification | Id: 1 | Redelivery: 5
AbstractMessageListenerContainer|Execution of JMS message listener failed, and no ErrorHandler has been set.
java.lang.RuntimeException: error after receiving message
TestTransactedMessaging|Total items in "incoming" queue: 0
TestTransactedMessaging|Total items in "dead letter" queue: 1
TestTransactedMessaging|Total items in DB: 0

As you can see, the first receiving has failed, and the broker has tried to resend it four more times (as indicated in the maximumRedeliveries property). Since the situation persisted, the message has been sent to the special DLQ queue. In this way, we do not lose the message.

testFailedAfterProcessingMessage output:
Producer|Sending notification | Id: 2
NotificationProcessor|Received notification | Id: 2 | Redelivery: 1
AbstractMessageListenerContainer|Execution of JMS message listener failed, and no ErrorHandler has been set.
java.lang.RuntimeException: error after processing message
NotificationProcessor|Received notification | Id: 2 | Redelivery: 2
TestTransactedMessaging|Total items in "incoming" queue: 0
TestTransactedMessaging|Total items in "dead letter" queue: 0
TestTransactedMessaging|Total items in DB: 2

In this case, this is what happened:
  1. The listener retrieved the message
  2. It stored the message to the DB
  3. Listener execution failed
  4. The broker resends the message. Since the situation has been solved, the listener stores the message to the DB (again). The message has been duplicated.

7   Conclusion

 Adding local transactions to the message reception avoids losing messages. What we have to take into account is that duplicate messages can occur, so our listener will have to detect it, or our processing will have to be idempotent to process it again without any problem. If this is not possible, we will have to go for distributed transactions, since they support transactions that involve different resources.

Tuesday, July 23, 2013

Introduction to messaging with Spring JMS

1   Introduction

In this post I will show you how to configure a standalone application in order to see different ways of sending and receiving messages using Spring JMS. Basically, I will divide the examples into the following sections:
  • Point-to-point messaging (queue)
    • Synchronous reception
    • Asynchronous reception
  • Publish-subscribe messaging (topic)

The source code with all the examples shown in this article is available at github.


2   Configuring the provider

The first thing we need to do is to configure the ConnectionFactory. The connection factory is part of the JMS specification and allows the application to create connections with the JMS provider.

The factory is used to create a connection which is then used to create a session. In the following examples, we won't need to care about this since the JmsTemplate class will do this for us.

Spring provides its own ConnectionFactory implementations, which are specified below:
  • SingleConnectionFactory: All createConnection() calls will return the same connection. This is useful for testing.
  • CachingConnectionFactory: It provides caching of sessions.

The JmsTemplate aggressively opens and closes resources like sessions since it assumes that are cached by the connectionFactory. Using the CachingConnectionFactory will improve its performance. In our example, we will define a cachingConnectionFactory passing our previously defined AMQ connectionFactory to its targetConnectionFactory property:


3   Point-to-point messaging (queue)

This Destination implementation consists in sending a message to a single consumer. The producer will send a message to the queue where it will be retrieved by the consumer.



The consumer will actively retrieve the message from the queue (synchronous reception) or it will retrieve the message passively (asynchronous reception). Now we will see an example of each.


3.1   Synchronous reception


3.1.1   Configuration


Spring JMS uses JmsTemplate class for message production and synchronous message reception. This template is a central class of Spring JMS, and helps us by:
  • Reducing boilerplate code: It handles the creation and release of resources transparently (connection, session...).
  • Handling exceptions and converting them to runtime exceptions.
  • Providing utility methods and callbacks.

Let's configure the jmsTemplate:

This template will handle our point-to-point messaging. To use topics it will need further configuration, which will be shown in the following sections.

The Queue destination is defined below:

In our example, a producer will send a message to this queue and a consumer will retrieve it.

3.1.2   The producer


This producer will use a jmsTemplate to send a message. Note the @Component annotation, this class will be auto detected and registered as a bean.

It is also important to see that we are passing a Notification object to the jmsTemplate method. If we do not define a message converter, the template will register a SimpleMessageConverter by default (check JmsTemplate constructor). This converter will be able to convert the following types:
  • String to TextMessage
  • Serializable to ObjectMessage
  • Map to MapMessage
  • byte[] to BytesMessage

If the object being sent is not an instance of any of the previous list, it will throw a MessageConversionException. The common cause of this exception is that your object is not implementing Serializable interface.

In this case, it will convert our Notification object to an ObjectMessage and send it to its default destination, which we previously defined as "test.sync.queue".

3.1.3   The consumer


You should use this method carefully as it blocks the current thread until it receives the message. You should better define a timeout in case there's a problem receiving the message. The jmsTemplate has no timeout setter method defined. You will need to define it when configuring the AMQ connection factory:

<property name="sendTimeout" value="5000"/>

3.1.4   The test



3.2   Asynchronous reception


Spring lets you receive messages asynchronously in two different ways:
  • Implementing MessageListener interface
  • Using a simple POJO

The following example will show the second approach.

3.2.1   Configuration


We can use the same jmsTemplate we configured in the previous example. In this case we will configure another queue where the producer will send its message and a consumer that will act as a listener:

We are configuring a consumer which will be the asyncReceiver bean, and the listener container will invoke its receiveMessage method when a message arrives to the test.async.queue.

3.2.2   The producer


The producer will be the same defined in the previous section, but it will send the message to a different queue:


3.2.3   The consumer


As you can see, it's a simple Java class. It does not need to implement any interface. The consumer saves received notifications to a registry. This registry will be used by the test class to assert that notifications arrived correctly.

3.2.4   The test



4   Publish-subscribe messaging (topic)

The message is sent to a topic, where it will be distributed to all consumers that are subscribed to this topic.



4.1   Configuration


We will need another jmsTemplate since the template we configured before is set to work with queues.

We just need to configure its destination accessor by defining its pubSubDomain property and set its value to true. The default value is false (point-to-point).

Next, we configure a new destination, which will be the topic for this example:

Finally, we define the listeners. We define two listeners to make sure both consumers receive the message sent to the topic by the producer.

You may notice a difference in the listener configuration. We need to change the destination type of the listener container, which is set to queue by default. Just set its value to topic and we are done.

4.2   The producer



4.3   The consumer


The asyncTopicFooReceiver has the same method.

4.4   The test


Monday, June 17, 2013

Applying aspect oriented programming

1 Introduction

The main target of the aspect oriented programming is the separation of cross-cutting concerns. When we talk about cross-cutting concerns we are referring to generic functionality that is used in several places in our system or application. These concepts are, among others:

  • Logging
  • Transaction management
  • Error handling
  • Monitoring
  • Security

The way to achieve this separation is by modularizing these concepts. This will allow us to keep our business logic classes clean, containing only the code for which the class was designed. If we don't modularize these concerns, it will lead to code tangling (the class contains different concerns) and code scattering (the same concern will be spread across the system).

In this example, we have a Spring MVC application that access the requested data (clients and orders) and shows a page with its information. We can take a look at the different layers:



In the above graphic, we can appreciate that there are functionalities spread across different classes (monitoring is implemented in every service), and some classes contain different concerns (for example, the class ClientController contains logging and exception handling). In order to fix that, we will write aspects to implement our cross-cutting concerns. The goal is to implement the following model:



Each class contains only the business logic related code, while the aspects will be responsible of intercepting the code in order to inject the cross-cutting concerns.

Let's see this with an example.

Source code can be found at github.


2   Checking controller code

ClientController:

The objective of this controller consists in retrieving a client and returning a view showing its information but, as you can see, this code contains additional logic. In one hand, it handles exceptions that may be thrown by the service and it redirects to an error page. On the other hand, it generates logging information and notification sending in case of error. All this code is generic to all controllers in this application (and probably to other classes).

It's true that we could have used the @ControllerAdvice annotation to centralize exception handling, but the target of this post is to see how to accomplish it with Spring AOP.

The same happens with the order controller. I won't include it here because I don't want to make the post unnecessary long. If you want to check it out, you can get the source code included in the previous link.


3   Checking services code

ClientService:

In addition to the service invocation, it also contains logging generation and monitoring of the execution time in each invocation.

We could also use aspects to modularize transaction management if we needed to use programmatic transaction management, but it's not the case in this example.


4   Data access layer

ClientRepositoryImpl:

This code does not contain any cross-cutting concern but I've included it to show all the sample application layers.


5   Activating AOP

To configure AOP, it is necessary to import the following dependencies:

In the Spring configuration file, we need to add the following tags:

The component-scan tag will search within the base package in order to find our aspects. To use auto scan, you not only need to define the aspect class with @Aspect annotation, but also you will need to include @Component annotation. If you don't include @Component you will need to define the aspect in the xml configuration file.


6   Centralizing error handling

We'll write an aspect with an @Around advice. This advice will intercept every method annotated with @RequestMapping annotation and will be responsible of invoking it, catching exceptions thrown by the service.

The @Target annotation allows us to reference the intercepted class. Now we have the exception handling handled by the aspect so we can get rid of this logic in our controllers.

Just a note, you could have intercepted exceptions thrown by the controller with the following advice:

But be aware that this advice will not prevent the exception from propagating.


7   Centralizing logging

The logging aspect will have two advices, one for controller logging and another one for service logging:


8   Finally, the monitoring concern

We will write another aspect for monitoring concern. The advice is as follows:


9   Checking the final code

After we have modularized all the cross-cutting concerns, our controllers and services contain only the business logic:


10   Conclusion

We have seen how to apply aspect oriented programming to keep our code clean and focused to the logic for which it was designed. Before using AOP, just take into account its known limitations.

Monday, May 20, 2013

Handling different subresources with JAX-RS subresource locator

1   Introduction


 In this article I won't explain what a resource or subresource is, since there are several pages that explain perfectly well its meaning. For example, you can check Oracle tutorial or Jersey documentation. I will focus on implementing a RESTful service with a subresource locator which will decide at runtime what type of subresource will be returned.

You can check the source code on github.


2   Configuration


You need to include the JAX-RS reference implementation libraries:
The first two dependencies are necessary if you want to develop services, while the third contains the implementation to convert your classes to JSON.

Next step is to define the Jersey servlet that will handle requests to our services. Include the content below on your web.xml file:
I have included two init parameters:

  • com.sun.jersey.config.property.packages: Required. It must define one or more packages separated by ";". These are the packages where your resource classes must be located.

  • com.sun.jersey.api.json.POJOMappingFeature: Activates POJO support, which means that it will use the Jackson library to convert your Java Objects to JSON and the other way back.

We are done with the configuration, let's implement the resources.


3   The root resource


To declare a root resource you must annotate your class with @Path.
The @GET annotated getWarehouseInfo() method will handle requests to the root resource, so when the user enters the following URI:

http://localhost:8080/rest-subresources/rest/warehouse


It will return the warehouse information.

Take into account that if I had included the @Path annotation in conjunction with @GET, I would be declaring a subresource method.

The getItem method is annotated with @Path but not with any request method designator (get, post...). This is because I'm declaring a subresource locator. This subresource locator will return an object  that will be capable of handling the HTTP request, but which one? It will depend on the id parameter. Both the TypeAResource and TypeBResource implement the same interface ItemResource, so we can return any of them.


4   Subresources


These subresources have a method with a request method designator, but no @Path annotation has been included.
The following requests will return a different subresource:

http://localhost:8080/rest-subresources/rest/warehouse/items/1: Will return a Type B resource:

{"id":1,"price":33.5,"type":"B"}

http://localhost:8080/rest-subresources/rest/warehouse/items/12: Will return a Type A resource:

{"id":12,"price":35.5,"type":"A","code":"12SS34"}


5   Possible mistakes


I'm including some errors that may occur if you fail to configure the application properly:

Fail on deploy. com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes

You did not define the packages init-param, so it will fail to find nor load your resource classes.
Fail on runtime. com.sun.jersey.api.MessageException: A message body writer for Java class [yourModelClass], and Java type class [yourModelClass], and MIME media type application/json was not found.

You did not define the JSON feature on web.xml. It won't be able to convert your object to JSON.
Fail on runtime. com.sun.jersey.api.MessageException: A message body writer for Java class [yourModelClass], and Java type class [yourModelClass], and MIME media type application/json was not found.

This error might also be produced because the JSON maven dependency was not included.
Fail on deploy. java.lang.ClassNotFoundException: com.sun.jersey.spi.container.servlet.ServletContainer.

The jersey-servlet maven dependency was not included. Older versions of Jersey included this class in jersey-core library, but in newer versions they have put it in a separate jar.

Monday, May 13, 2013

Retrieving method annotations with Spring Annotation Utils

1   Introduction

The JDK provides us with several lookup methods that allow us to retrieve annotations from a class, method, field or added to method parameters. The Spring framework included a general utility class for annotations, org.springframework.core.annotation.AnnotationUtils, which extends the basic functionalities. In this post I will explain the main features of this class, focusing on retrieving annotations from a method.


2   getAnnotation method

Signature:
This method looks up if method contains the specified annotation type and returns it if found. So, what's the difference between the JDK getAnnotation method? The Spring version handles bridge methods. You can check effects of Type Erasure and Bridge Methods tutorial to get a good explanation.

Let's see it with an example. Imagine we got a generic class Foo, and a Bar class that extends it:
Now we try to retrieve @MyAnnotation with both utility methods:
The result is as follows:



3   findAnnotation method

Signature:
This method also retrieves the specified annotation type from method. The difference between getAnnotation is that in this case, it will look up the entire inheritance hierarchy of the specified method.

Let's see another example. We got the classes below:
Trying to retrieve @MyAnnotation from anotherMethod in Bar class using the different utility methods
will get the following results:



Monday, April 29, 2013

Unit testing with PowerMock

In this article I will implement several unit tests using PowerMock framework. This framework is more powerful than other libraries and allows you to mock static methods, private methods and change field properties among other things. I will use the Mockito extension but it also supports EasyMock.


1   Installation


If you use Maven, you can add the following dependencies to your pom.xml:
Otherwise, you can get the libraries here.


2   Preparing the tests


You must add the @RunWith annotation. This annotation will tell JUnit to use the class PowerMockRunner to run the tests.
I'm going to test Foo.class. Using the spy method, all real methods of the class will be invoked except those I mock.


3   Mocking private methods


I want to test methodWithPrivateDependency, but this method internally calls a private method which, let's say, calls an external resource.
The test:
The @PrepareForTest annotation tells PowerMock to prepare the class so it can manipulate it. This is necessary if the class is final, or it contains final, private, static or native methods that should be mocked. In this case, I will need to mock the private method.

If you put this annotation at class level, it will affect all test methods within the class. It would be as follows:

4   Mocking static access


The next method that needs to be tested gets some information by accessing a static method of an inner static class. You need to mock the static access.

The method to test:
The static class:
The test:
I use the @PrepareForTest annotation because I need to mock the static method getData of this class.


5   Mocking chained dependencies


In this example, I want to mock the chainMocks method. There's a singleton Helper class which returns a manager from which the method to test invokes it.
The test:
I only need to prepare Helper class for test because I need to mock its static method getInstance (that's not the case for ConfigurationManager where initializeRegistry is a public instance method).

Wednesday, April 3, 2013

Communication in Spring Webflow 2

1   Introduction

This article tries to complement the reference documentation with examples on how to communicate within a flow in Spring Web flow 2, showing different ways to share data between controllers and views that form a flow. The article is divided into the following sections:
  • Setting flow variables
  • Setting attribute values
  • Using additional scopes
  • Communication with sub flows
  • Communication with other flows
  • Launching events with attributes
  • Accessing RequestContext
  • Accessing Spring beans
  • Using implicit variables

The example explained here uses Spring Web flow 2.3.1 and Spring 3.0.5 versions. You can get the source code here, with all the examples shown in this article.


2   Setting flow variables

There are different ways of setting variables and storing them into the flow scope, where they will then be accessible to controllers and views.

2.1   var element (variable)

The var element instantiates a class and stores it in the flow scope. Since the instance will be stored between flow requests, the class should implement java.io.Serializable. It does not allow you to assign a value, making this element useless for classes without a default constructor (it will crash at runtime with a nice NoSuchMethodException). In that case, you can use the set element (see section 3).

Defining a variable:

You can use this variable in the flow definition, for example, passing it as a parameter to a controller:

The method will receive the car parameter:
Since it is automatically stored in the flow scope, you can also retrieve the value from the request context:
Or use it in the view using for example ${car.color}

2.2   At flow starting point

If your class has no default constructor or you want to retrieve the instance from a service, the element var won't be enough. You can use a controller instead:
In this sample, the information could be retrieved from a service. The result attribute will get the object returned by the controller and store it in the flow scope.

You can also use this approach when entering a state (on-entry) or before rendering a view (on-render).

2.3   Anywhere in the flow

Since you have access to the Web flow RequestContext when invoking a controller, you can set a flow scoped variable as shown below:


3   Setting attribute values

The set element allows you to define an attribute and specify a scope. This element takes the following attributes:
  • name: Scope and name for the attribute, delimited by a dot (scope.name).
  • value: Value set to the attribute.
  • type: Class type.

For example, you can use it at the beginning of a flow (on-start) or when entering into a state (on-entry). The following sample show how to assign it a specified value when the flow starts:
Or you could set it when launching a transition:

The set element not only allows you to define objects, but also String values. For example, if you have a bean named 'myBean', the first set element in the following sample, will retrieve the Car instance from the bean and store it in the request scope with the name 'carObject'. On the other hand, the second set element will store in the request scope an attribute named 'carString' that will contain the String 'myBean.car'.

You can also use implicit variables when setting the value of the set element (see section 10 for a list of these variables):


4 Using additional scopes

The RequestContext interface contains access to all the other scopes defined in Spring Web flow: request, flash, view, flow and conversation.

You can also access these scopes at flow definition level by using implicit EL variables, which are: requestScope, flashScope, viewScope, flowScope and conversationScope.

For other scopes, you can use the external context:

At flow definition using implicit variables:

Or at controller level through RequestContext interface:


5   Communication with sub flows

When invoking a sub flow from the main flow, you can pass it input attributes. Once the sub flow has finished, it may return output attributes.

Input:
The input element allows you to send parameters to the sub flow. When the sub flow starts, these input attributes are stored in the flow scope of the sub flow. You will need to define the input element in the sub flow, using the same name attribute as used in the main flow.

Output:
Once the sub flow ends, the main flow can receive output parameters. These output parameters are defined within sub flow's end-states. When the execution returns to the main flow. output parameters will be available as attributes inside the launched event.

Main flow: invoking a sub flow

When returning to the main flow, you will need to define an attribute with the value returned by the sub flow in order to make it accessible to following states.

You could also invoke a controller that would set the value and store it in the needed scope:

Sub flow definition

There are other options to pass information to a subflow which consists in the following:
  • Storing the information at conversation scope (this scope is available from within a flow and its sub flows).
  • Pass the information in the transition which access the sub flow:


6   Communication with other flows

You have two options of passing data to another flow which is not related to the current flow:
  1. Session scoped attributes
  2. URL Request parameters
If you choose the second option, you can do it the following way:

In the view:

When starting the other flow, you can use the requestParameters implicit variable to retrieve the value and store it in the needed scope.

You could also do it in the controller:

Or use the requestParameterMap directly through the getRequestParameters shortcut method:


7   Launching events with attributes

When exiting a controller, it is possible to add attributes to the current event. To do that you need to generate an attribute map.

The controller which launches the event adds the attribute as follows:


8   Accessing the request context

If you want to invoke methods from classes other than controllers, like beans, it is possible to retrieve the web flow request context. There are two ways:

Passing the request context as a parameter to the bean method:

Or you can use the RequestContextHolder class:


9   Accessing Spring beans

If you need to retrieve beans from the Spring context, you can implement a utility class. The following method accesses the Spring context through the web flow request context.


10   Using implicit variables

There's a full list of all available implicit variables at the web flow reference documentation

springsource web flow reference (el-variables)


Tuesday, March 5, 2013

Centralize validation and exception handling with @ControllerAdvice



1 Introduction

The @ControllerAdvice annotation introduced by Spring 3.2 allows us to handle several functionalities in a way that can be shared by all controllers (through its handler methods, annotated with @RequestMapping). This annotation is mainly used to define the following methods:
  • @ExceptionHandler: Handles exceptions thrown by handler methods.
  • @InitBinder: Initializes the WebDataBinder, which will be used to populate objects passed as arguments to the handler methods. Usually, it is used to register property editors or validators.
  • @ModelAttribute: Binds a parameter or return value to an attribute, which will then be exposed to a web view.

Source code can be found at github.


2 Adding validation and exception handling

The following is a description of  the controller's handler methods before implementing the @ControllerAdvice.

Add person controller:

@RequestMapping(value="/persons", method=RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public void addPerson(@Valid @RequestBody Person person, HttpServletRequest request, HttpServletResponse response) {
personRepository.addPerson(person);
logger.info("Person added: "+person.getId());
response.setHeader("Location", request.getRequestURL().append("/").append(person.getId()).toString());
}

@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setValidator(new PersonValidator());
}
      
@ExceptionHandler({MethodArgumentNotValidException.class})
public ResponseEntity<String> handleValidationException(MethodArgumentNotValidException pe) {
return new ResponseEntity<String>(pe.getMessage(), HttpStatus.BAD_REQUEST);
}


Besides the handler method, this controller has the following methods:
  • initBinder: Registers a validator to prevent that a person with invalid data is introduced. To make the validator validate the person object passed as a parameter, it is necessary to add the @Valid annotation to the argument. Spring 3 fully supports JSR-303 bean validation API, but it does not implement it. The reference implementation which is used in this example is Hibernate Validator 4.x.
  • handleValidationException: Handles the MethodArgumentNotValidException that can be thrown by the handler method. This exception is thrown by Spring MVC when an argument annotated with @Valid, fails its validation.


Get person controller:

@RequestMapping(value="/persons/{personId}", method=RequestMethod.GET)
public @ResponseBody Person getPerson(@PathVariable("personId") long id) {
return personRepository.getPerson(id);
}
     
@ExceptionHandler({PersonNotFoundException.class})
public ResponseEntity<String> handlePersonNotFound(PersonNotFoundException pe) {
return new ResponseEntity<String>(pe.getMessage(), HttpStatus.NOT_FOUND);
}
      

This controller adds an exception handler for handling when a request asks to retrieve a person that does not exist.





Update person controller:

@RequestMapping(value="/persons", method=RequestMethod.PUT)
@ResponseStatus(HttpStatus.CREATED)
public void updatePerson(@Valid @RequestBody Person person, HttpServletRequest request, HttpServletResponse response) {
personRepository.updatePerson(person);
logger.info("Person updated: "+person.getId());
response.setHeader("Location", request.getRequestURL().append("/").append(person.getId()).toString());
}
      
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setValidator(new PersonValidator());
}
      
@ExceptionHandler({PersonNotFoundException.class})
public ResponseEntity<String> handlePersonNotFound(PersonNotFoundException pe) {
return new ResponseEntity<String>(pe.getMessage(), HttpStatus.NOT_FOUND);
}
      
@ExceptionHandler({Exception.class})
public ResponseEntity<String> handleValidationException(MethodArgumentNotValidException pe) {
return new ResponseEntity<String>(pe.getMessage(), HttpStatus.BAD_REQUEST);
}
 
We are repeating code, since @ExceptionHandler is not global.


3 Centralizing code

@ControllerAdvice annotation is itself annotated with @Component, so the class that we are implementing will be autodetected through classpath scanning.

@ControllerAdvice
public class CentralControllerHandler {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setValidator(new PersonValidator());
}
      
@ExceptionHandler({PersonNotFoundException.class})
public ResponseEntity<String> handlePersonNotFound(PersonNotFoundException pe) {
return new ResponseEntity<String>(pe.getMessage(), HttpStatus.NOT_FOUND);
}
      
@ExceptionHandler({MethodArgumentNotValidException.class})
public ResponseEntity<String> handleValidationException(MethodArgumentNotValidException pe) {
return new ResponseEntity<String>(pe.getMessage(), HttpStatus.BAD_REQUEST);
}
}

Now we can delete these methods from the controllers, taking rid of code duplication, since this class will handle exception handling and validation for all handler methods annotated with @RequestMapping.

 

4 Testing

The methods described below, test the retrieval of persons:

@Test
public void getExistingPerson() {
String uri = "http://localhost:8081/rest-controlleradvice/spring/persons/{personId}";
Person person = restTemplate.getForObject(uri, Person.class, 1l);
assertNotNull(person);
assertEquals("Xavi", person.getName());
}
      
@Test
public void getNonExistingPerson() {
String uri = "http://localhost:8081/rest-controlleradvice/spring/persons/{personId}";
try {
restTemplate.getForObject(uri, Person.class, 5l);
throw new AssertionError("Should have returned an 404 error code");
} catch (HttpClientErrorException e) {
assertEquals(HttpStatus.NOT_FOUND, e.getStatusCode());
}
}


The rest of tests can be found with the source code linked above.