Thursday, May 21, 2015

Akka samples with scala and Spring

I was looking around recently for Akka samples with Spring and found a starter project which appeared to fit the bill well. The project however utilizes Spring-Scala which is an excellent project, but is no longer maintained. So I wanted to update the sample to use core Spring java libraries instead. So here is an attempt on a fork of this starter project with core Spring instead of Spring-scala. The code is available here.

The project utilizes Akka extensions to hook in Spring based dependency injection into Akka.

Here is what the extension looks like:

package sample

import akka.actor.{ActorSystem, Props, Extension}
import org.springframework.context.ApplicationContext
/**
 * The Extension implementation.
 */
class SpringExtension extends Extension {
  var applicationContext: ApplicationContext = _

  /**
   * Used to initialize the Spring application context for the extension.
   * @param applicationContext
   */
  def initialize(applicationContext: ApplicationContext) = {
    this.applicationContext = applicationContext
    this
  }

  /**
   * Create a Props for the specified actorBeanName using the
   * SpringActorProducer class.
   *
   * @param actorBeanName  The name of the actor bean to create Props for
   * @return a Props that will create the named actor bean using Spring
   */
  def props(actorBeanName: String): Props =
    Props(classOf[SpringActorProducer], applicationContext, actorBeanName)

}

object SpringExtension {
  def apply(system : ActorSystem )(implicit ctx: ApplicationContext) :  SpringExtension =  SpringExt(system).initialize(ctx)
}

So the extension wraps around a Spring application context. The extensions provides a props method which returns an Akka Props configuration object which uses the application context and the name which the actor is registered with Spring to return an instance of the Actor. The following is the SpringActorProducer:

package sample

import akka.actor.{Actor, IndirectActorProducer}
import org.springframework.context.ApplicationContext


class SpringActorProducer(ctx: ApplicationContext, actorBeanName: String) extends IndirectActorProducer {

  override def produce: Actor = ctx.getBean(actorBeanName, classOf[Actor])

  override def actorClass: Class[_ <: Actor] =
    ctx.getType(actorBeanName).asInstanceOf[Class[Actor]]

}

Given this base code, how does Spring find the actors, I have used scanning annotations to annotate the actors this way:

package sample.actor

import akka.actor.Actor
import sample.service.CountingService
import sample.SpringExtension._
import org.springframework.stereotype.Component
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Scope
import akka.actor.ActorRef
import sample.SpringExtension
import org.springframework.context.ApplicationContext

@Component("countingCoordinatingActor")
@Scope("prototype")
class CountingCoordinating @Autowired() (implicit ctx: ApplicationContext) extends Actor {

  import sample.messages._

  var counter: Option[ActorRef] = None

  
  def receive = {
    case COUNT => countingActor() ! COUNT
    case g:GET => countingActor() ! g
  }
  
  private def countingActor(): ActorRef = {
     if (counter.isEmpty) {
        val countingActorProp = SpringExtension(context.system).props("countingActor")
        counter = Some(context.actorOf(countingActorProp, "counter"))
     }  
     
     counter.get
  }
  
}


@Component("countingActor")
@Scope("prototype")
class CountingActor @Autowired()(countingService: CountingService) extends Actor {

  import sample.messages._

  private var count = 0

  def receive = {
    case COUNT => count = countingService.increment(count)
    case GET(requester: ActorRef) => requester ! RESULT(count)
  }
  
}

The CountingService is a simple service that gets injected in by Spring. The following is the main Spring Application configuration where all the wiring takes place:

import akka.actor.ActorSystem
import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Bean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.ComponentScan

@Configuration
@ComponentScan(Array("sample.service", "sample.actor"))
class AppConfiguration {

  @Autowired
  implicit var ctx: ApplicationContext = _;
  
  /**
   * Actor system singleton for this application.
   */
  @Bean
  def actorSystem() = {
    val system = ActorSystem("AkkaScalaSpring")
    // initialize the application context in the Akka Spring Extension
    SpringExt(system)
    system    
  }
}

To make use of this entire set-up in a sample program:

import akka.actor.{ActorRef, ActorSystem}
import sample.SpringExtension._
import scala.concurrent.duration._
import scala.concurrent._
import scala.util._
import sample.messages._
import org.springframework.context.annotation.AnnotationConfigApplicationContext
import akka.actor.Inbox


object Main extends App {
  // create a spring context
  implicit val ctx = new AnnotationConfigApplicationContext(classOf[AppConfiguration])

  import Config._

  // get hold of the actor system
  val system = ctx.getBean(classOf[ActorSystem])

  val inbox = Inbox.create(system)
  
  val prop = SpringExtension(system).props("countingCoordinatingActor")

  // use the Spring Extension to create props for a named actor bean
  val countingCoordinator = system.actorOf(prop, "counter")

  // tell it to count three times
  inbox.send(countingCoordinator, COUNT)
  inbox.send(countingCoordinator, COUNT)
  inbox.send(countingCoordinator, COUNT)
  
  inbox.send(countingCoordinator, GET(inbox.getRef()))
  
  val RESULT(count) = inbox.receive(5.seconds)

  println(s"Got $count")
  system.shutdown
  system.awaitTermination
}

References:

Monday, May 11, 2015

Docker on Mac OSX with docker-machine and VMWare fusion

If you use Cisco Anyconnect VPN on your Mac OSX machine you would have found your experience with docker using boot2docker not working at times. The basic issue is that the Cisco Anyconnect VPN rewrites the routing rules which map the boot2docker Virtual box network interfaces.

The fix that has worked better for me in the last few days has been to not use boot2docker, but instead to use docker-machine to create a VMWare fusion based docker VM.

So to try out this approach first ensure that you have VMWare Fusion installed. Then install docker and docker-machine. Docker and docker-machine command line can be installed using homebrew:

brew install docker
brew install docker-machine

Once the VMWare fusion, docker and docker-machine are in place, then use docker-machine to create a docker host using VMWare fusion this way:

docker-machine create -d vmwarefusion --vmwarefusion-boot2docker-url https://github.com/cloudnativeapps/boot2docker/releases/download/v1.6.0-vmw/boot2docker-1.6.0-vmw.iso fusion                       

Here I have explicitly specified the url of the VM image that has fixes for a couple of issues identified in the image that is normally installed by default.

Once the Host is properly created, verify that it is in a running state using docker-machine:

docker-machine ls

That is essentially it, to use this shiny new docker host ensure that the appropriate environment variables are set in the shell:

eval "$(docker-machine env fusion)"

and your docker commands should work with or without VPN connectivity:

docker ps -a

Tuesday, May 5, 2015

Netflix Archaius for property management - Basics

Netflix Archaius provides a neat set of features to load dynamic properties into an application.

This blog post is just a documentation of the extent of Archaius that I have understood, there is much more to it than I have documented here, but this should provide a good start:

Default Behavior

Consider a simple properties file:
stringprop=propvalue
listprop=value1, value2, value3
mapprop=key1=value1, key2=value2
longprop=100

If these entries are placed in a config.properties file in the classpath, then the following test demonstrates how each of these properties can be resolved by Archaius in code:

@Test
public void testBasicStringProps() {
    DynamicStringProperty sampleProp = DynamicPropertyFactory.getInstance().getStringProperty("stringprop", "");
    assertThat(sampleProp.get(), equalTo("propvalue"));
}

@Test
public void testBasicListProps() {
    DynamicStringListProperty listProperty = new DynamicStringListProperty("listprop", Collections.emptyList());
    assertThat(listProperty.get(), contains("value1", "value2", "value3"));
}

@Test
public void testBasicMapProps() {
    DynamicStringMapProperty mapProperty = new DynamicStringMapProperty("mapprop", Collections.emptyMap());
    assertThat(mapProperty.getMap(), allOf(hasEntry("key1", "value1"), hasEntry("key2", "value2")));
}

@Test
public void testBasicLongProperty() {
    DynamicLongProperty longProp = DynamicPropertyFactory.getInstance().getLongProperty("longprop", 1000);
    assertThat(longProp.get(), equalTo(100L));
}

Loading Properties from a non-default file in classpath

So now, how do we handle a case where the content is to be loaded from a file with a different name, say newconfig.properties but still available in the classpath. The following is one way to do that:

@Before
public void setUp() throws Exception{
    ConfigurationManager.loadCascadedPropertiesFromResources("newconfig");
}

With this change the previous test will just work.

Another option is to provide a system property to indicate the name of the properties file to load from the classpath:

System.setProperty("archaius.configurationSource.defaultFileName", "newconfig.properties");

Overriding for environments


Now, how do we override the properties for different application environments - Archaius provides a neat feature where a base property file can be loaded up but then overridden based on the context. More details are here. To demonstrate this consider two files, one containing the defaults and one containing overrides for a "test" environment:

sample.properties
sampleprop=propvalue
@next=sample-${@environment}.properties

sample-test.properties
sampleprop=propvalue-test

See the notation at the end of the default file @next=sample-${@environment}.properties, it is a way to indicate to Archaius that more properties need to be loaded up based on the resolved @environment parameter. This parameter can be injected in a couple of ways and the following test demonstrates this:

@Before
public void setUp() throws Exception{
    ConfigurationManager.getConfigInstance().setProperty("@environment", "test");
    ConfigurationManager.loadCascadedPropertiesFromResources("sample");
}

@Test
public void testBasicStringPropsInTestEnvironment() throws Exception {
    DynamicStringProperty sampleProp = DynamicPropertyFactory.getInstance().getStringProperty("sampleprop", "");
    assertThat(sampleProp.get(), equalTo("propvalue-test"));
}

The base property file itself now has to be loaded in through a call to ConfigurationManager.loadCascadedPropertiesFromResources..

Conclusion

These are essentially the basics of Netflix Archaius, there is much more to it of course which can be gleaned from the wiki on the Archaius github site. If you are interested in exploring the samples shown here a little more, they are available in this github project

Thursday, April 23, 2015

Spring-session demonstration using docker-compose

I have earlier written about an exciting new project called Spring-session which provides a clean way to externalize user sessions for java based web applications.

I managed to get a good demonstration set-up for spring-session using docker-compose which shows off the strengths of this project and I wanted to write about this here. In short, this is the set-up that running docker-compose will bring up:


Two instances of the application which makes use of Spring-session are started up, these instances use the same redis container for storing the session state and are in turn fronted by an nginx server.

All that needs to be done to bring up this topology is to:

  • clone my repo available here
  • install docker-compose 
  • build the app - "mvn package -DskipTests" - skipping tests as the tests depend on a local redis-server, which may or may not be available
  • run "docker-compose up" in the cloned folder
That is it, if everything has been set-up cleanly nginx should be available at http://docker-ip  url - in my mac, it is typically http://192.168.59.103

Details and Demonstration:
Docker-compose is a tool providing a means to put together a set of docker containers into a coherent stack. The stack can be defined declaratively, and the following is a sample stack used here:

nginx:
  image: nginx
  volumes:
    - nginx:/etc/nginx:ro
  links:
    - shop1
    - shop2
  ports:
   - "80:80"

shop1:
  build: .
  hostname: shop1
  links:
    - redis
  ports:
    - "8081:8080"

shop2:
  build: .
  hostname: shop2
  links:
    - redis
  ports:
    - "8082:8080"

redis:
  image: redis
  hostname: redis
  ports:
    - "6379:6379"


This application itself makes use of the user session to maintain the state of a "shopping cart", since this application is configured to use spring-session the session will be maintained in redis database. There are two instances of the application behind nginx, either one of the servers would end up getting the request, but the externalized session state would continue to work seamlessly irrespective of the application instance handling the request.

The following is the view of the shopping cart:


The session id and the details of the instance handling the request are printed at the bottom of the page.

As can be seen in the following screenshot, even if a different instance handles the request, the session state continues to be cleanly maintained.


Wednesday, April 8, 2015

Spring Enable* annotation - writing a custom Enable annotation

Spring provides a range of annotations with names starting with Enable*, these annotations in essence enable certain Spring managed features to be activated. One good example of such an annotation is EnableWebMvc which brings in all the beans needed to support a MVC flow in Spring based applications. Another good example is the EnableAsync annotation to activate beans to support async functionality in Spring based applications.

I was curious about how such annotations work and wanted to document my understanding. The way these annotations are supported can be considered part of the SPI and so may break if the internal implementation changes in future.

Simple Enable* Annotations

One way to think about these custom annotations is that they add a set of new beans into the Spring's application context. Let us start by defining one such custom annotation:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface EnableSomeBeans {}



and apply this annotation on a Spring @Configuration class:

@Configuration
@EnableSomeBeans
public static class SpringConfig {}

So now to bring in a set of beans when this annotation is applied is as simple as adding the set of beans to bring in using @Import annotation this way:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(SomeBeanConfiguration.class)
@interface EnableSomeBeans {}

That is essentially it, if this imported @Configuration class defines any beans, they would now be part of the Application context:

@Configuration
class SomeBeanConfiguration {

    @Bean
    public String aBean1() {
        return "aBean1";
    }

    @Bean
    public String aBean2() {
        return "aBean2";
    }
}

Here is a gist with a working sample.

Enable* Annotations with Selectors


Enable annotations can be far more complex though, they can activate a different family of beans based on the context around them. An example of such an annotation is EnableCaching which activates configuration based on different caching implementations available in the classpath.

Writing such Enable* annotations is a little more involved than the simpler example earlier. As before start with a custom annotation:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(SomeBeanConfigurationSelector.class)
public @interface EnableSomeBeansSelector {
    String criteria() default "default";
}

Note that in this case the custom annotation has a sample field called criteria, what I want to do is to activate two different set of beans based on this criteria. This can be achieved using a @Configuration selector which can return different @Configuration file based on the context(in this instance the value of the criteria field). This selector has a simple signature and this is a sample implementation:

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

public class SomeBeanConfigurationSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        AnnotationAttributes attributes =
                AnnotationAttributes.fromMap(
                        importingClassMetadata.getAnnotationAttributes(EnableSomeBeansSelector.class.getName(), false));
        String criteria = attributes.getString("criteria");
        if (criteria.equals("default")) {
            return new String[]{"enableannot.selector.SomeBeanConfigurationDefault"};
        }else {
            return new String[]{"enableannot.selector.SomeBeanConfigurationType1"};
        }
    }
}

@Configuration
class SomeBeanConfigurationType1 {

    @Bean
    public String aBean() {
        return "Type1";
    }

}

@Configuration
class SomeBeanConfigurationDefault {

    @Bean
    public String aBean() {
        return "Default";
    }

}

So if the criteria field is "default", the beans in "SomeBeanConfigurationDefault" gets added in, else the one in "SomeBeanConfigurationType1"

Here is a gist with a working sample.

Conclusion

I hope this gives an appreciation for how Spring internally implements the @Enable* annotations, as an application developer you may not need to create such annotations yourself, a simpler mechanism will be to use @Configuration classes and Spring bean profiles to compose applications.

Friday, March 27, 2015

Hot and cold rx-java Observable

My own understanding of Hot and Cold Observable is quite shaky, but here is what I have understood till now!

Cold Observable

Consider an API which returns an rx-java Observable:

import obs.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rx.Observable;
import rx.schedulers.Schedulers;

public class Service1 {
    private static final Logger logger = LoggerFactory.getLogger(Service1.class);
    public Observable<String> operation() {
        return Observable.<String>create(s -> {
            logger.info("Start: Executing slow task in Service 1");
            Util.delay(1000);
            s.onNext("data 1");
            logger.info("End: Executing slow task in Service 1");
            s.onCompleted();
        }).subscribeOn(Schedulers.computation());
    }
}

Now, the first thing to note is that the typical Observable does not do anything until it is subscribed to:

So essentially if I were to do this:

Observable<String> op1 = service1.operation();

Nothing would be printed or returned, unless there is a subscription on the Observable this way:

Observable<String> op1 = service1.operation();

CountDownLatch latch = new CountDownLatch(1);

op1.subscribe(s -> logger.info("From Subscriber 1: {}", s),
        e -> logger.error(e.getMessage(), e),
        () -> latch.countDown());

latch.await();

So now, what happens if there are multiple subscriptions on this Observable:

Observable<String> op1 = service1.operation();

CountDownLatch latch = new CountDownLatch(3);

op1.subscribe(s -> logger.info("From Subscriber 1: {}", s),
        e -> logger.error(e.getMessage(), e),
        () -> latch.countDown());

op1.subscribe(s -> logger.info("From Subscriber 2: {}", s),
        e -> logger.error(e.getMessage(), e),
        () -> latch.countDown());

op1.subscribe(s -> logger.info("From Subscriber 3: {}", s),
        e -> logger.error(e.getMessage(), e),
        () -> latch.countDown());

latch.await();

With a cold observable the code would get called once more and the items emitted again, I get this on my machine:

06:04:07.206 [RxComputationThreadPool-2] INFO  o.b.Service1 - Start: Executing slow task in Service 1
06:04:07.208 [RxComputationThreadPool-3] INFO  o.b.Service1 - Start: Executing slow task in Service 1
06:04:08.211 [RxComputationThreadPool-2] INFO  o.b.BasicObservablesTest - From Subscriber 2: data 1
06:04:08.211 [RxComputationThreadPool-1] INFO  o.b.BasicObservablesTest - From Subscriber 1: data 1
06:04:08.211 [RxComputationThreadPool-3] INFO  o.b.BasicObservablesTest - From Subscriber 3: data 1
06:04:08.213 [RxComputationThreadPool-2] INFO  o.b.Service1 - End: Executing slow task in Service 1
06:04:08.214 [RxComputationThreadPool-1] INFO  o.b.Service1 - End: Executing slow task in Service 1
06:04:08.214 [RxComputationThreadPool-3] INFO  o.b.Service1 - End: Executing slow task in Service 1

Hot Observable - using ConnectableObservable


Hot Observable on the other hand does not really need a subscription to start emitting items. A way to implement a Hot Observable is using a ConnectableObservable, which is a Observable which does not emit items until its connect method is called, however once it starts emitting items, any subscriber to it gets items only from the point of subscription. So again revisiting the previous example, but with a ConnectableObservable instead:

Observable<String> op1 = service1.operation();

ConnectableObservable<String> connectableObservable =  op1.publish();

CountDownLatch latch = new CountDownLatch(3);

connectableObservable.subscribe(s -> logger.info("From Subscriber 1: {}", s),
        e -> logger.error(e.getMessage(), e),
        () -> latch.countDown());

connectableObservable.subscribe(s -> logger.info("From Subscriber 2: {}", s),
        e -> logger.error(e.getMessage(), e),
        () -> latch.countDown());

connectableObservable.subscribe(s -> logger.info("From Subscriber 3: {}", s),
        e -> logger.error(e.getMessage(), e),
        () -> latch.countDown());

connectableObservable.connect();

latch.await();

and the following gets printed:
06:07:23.852 [RxComputationThreadPool-3] INFO  o.b.Service1 - Start: Executing slow task in Service 1
06:07:24.860 [RxComputationThreadPool-3] INFO  o.b.ConnectableObservablesTest - From Subscriber 1: data 1
06:07:24.862 [RxComputationThreadPool-3] INFO  o.b.ConnectableObservablesTest - From Subscriber 2: data 1
06:07:24.862 [RxComputationThreadPool-3] INFO  o.b.ConnectableObservablesTest - From Subscriber 3: data 1
06:07:24.862 [RxComputationThreadPool-3] INFO  o.b.Service1 - End: Executing slow task in Service 1

Hot Observable - using Subject

Another way to convert a cold Observable to a hot one is to use a Subject. Subjects behave both as an Observable and an Observer, there are different types of Subjects available with different behavior. Here I am using a Subject called a PublishSubject which has a Pub/Sub behavior - the items get emitted to all the subscribers listening on it. So with a PublishSubject introduced the code looks like this:

Observable<String> op1 = service1.operation();

PublishSubject<String> publishSubject = PublishSubject.create();

op1.subscribe(publishSubject);

CountDownLatch latch = new CountDownLatch(3);

publishSubject.subscribe(s -> logger.info("From Subscriber 1: {}", s),
        e -> logger.error(e.getMessage(), e),
        () -> latch.countDown());

publishSubject.subscribe(s -> logger.info("From Subscriber 2: {}", s),
        e -> logger.error(e.getMessage(), e),
        () -> latch.countDown());

publishSubject.subscribe(s -> logger.info("From Subscriber 3: {}", s),
        e -> logger.error(e.getMessage(), e),
        () -> latch.countDown());


latch.await();

See how the PublishSubject is introduced as a subscriber to the Observable and the other subscribers subscribe to the PublishSubject instead. The output will be similar to the one from ConnectableObservable.

This is essentially it, the extent of my understanding of Hot Observable. So to conclude, the difference between a Cold and a Hot Observable is about when the subscribers get the emitted items and when the items are emitted - with a Cold Observable they are emitted when they are subscribed to and typically get all the emitted items, with a Hot Observable the items are emitted without a Subscriber and subscribers get items emitted after the point of subscription typically.


Reference

1. http://www.introtorx.com/content/v1.0.10621.0/14_HotAndColdObservables.html
2. Excellent javadoc on rx-java - http://reactivex.io/RxJava/javadoc/index.html

Saturday, March 14, 2015

Using rx-java Observable in a Spring MVC flow

Spring MVC has supported asynchronous request processing flow for sometime now and this support internally utilizes the Servlet 3 async support of containers like Tomcat/Jetty.

Spring Web Async support

Consider a service call that takes a little while to process, simulated with a delay:

public CompletableFuture<Message> getAMessageFuture() {
    return CompletableFuture.supplyAsync(() -> {
        logger.info("Start: Executing slow task in Service 1");
        Util.delay(1000);
        logger.info("End: Executing slow task in Service 1");
        return new Message("data 1");
    }, futureExecutor);
}

If I were to call this service in a user request flow, the traditional blocking controller flow would look like this:

@RequestMapping("/getAMessageFutureBlocking")
public Message getAMessageFutureBlocking() throws Exception {
    return service1.getAMessageFuture().get();
}

A better approach is to use the Spring Asynchronous support to return the result back to the user when available from the CompletableFuture, this way not holding up the containers thread:

@RequestMapping("/getAMessageFutureAsync")
public DeferredResult<Message> getAMessageFutureAsync() {
    DeferredResult<Message> deffered = new DeferredResult<>(90000);
    CompletableFuture<Message> f = this.service1.getAMessageFuture();
    f.whenComplete((res, ex) -> {
        if (ex != null) {
            deffered.setErrorResult(ex);
        } else {
            deffered.setResult(res);
        }
    });
    return deffered;
}

Using Observable in a Async Flow


Now to the topic of this article, I have been using Rx-java's excellent Observable type as my service return types lately and wanted to ensure that the web layer also remains asynchronous in processing the Observable type returned from a service call.

Consider the service that was described above now modified to return an Observable:

public Observable<Message> getAMessageObs() {
    return Observable.<Message>create(s -> {
        logger.info("Start: Executing slow task in Service 1");
        Util.delay(1000);
        s.onNext(new Message("data 1"));
        logger.info("End: Executing slow task in Service 1");
        s.onCompleted();
    }).subscribeOn(Schedulers.from(customObservableExecutor));
}

I can nullify all the benefits of returning an Observable by ending up with a blocking call at the web layer, a naive call will be the following:

@RequestMapping("/getAMessageObsBlocking")
public Message getAMessageObsBlocking() {
    return service1.getAMessageObs().toBlocking().first();
}

To make this flow async through the web layer, a better way to handle this call is the following, essentially by transforming Observable to Spring's DeferredResult type:

@RequestMapping("/getAMessageObsAsync")
public DeferredResult<Message> getAMessageAsync() {
    Observable<Message> o = this.service1.getAMessageObs();
    DeferredResult<Message> deffered = new DeferredResult<>(90000);
    o.subscribe(m -> deffered.setResult(m), e -> deffered.setErrorResult(e));
    return deffered;
}

This would ensure that the thread handling the user flow would return as soon as the service call is complete and the user response will be processed reactively once the observable starts emitting values.


If you are interested in exploring this further, here is a github repo with working samples: https://github.com/bijukunjummen/spring-web-observable.

References:

Spring's reference guide on async flows in the web tier: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-async

More details on Spring DeferredResult by the inimitable Tomasz Nurkiewicz at the NoBlogDefFound blog - http://www.nurkiewicz.com/2013/03/deferredresult-asynchronous-processing.html