Friday, February 5, 2016

Does Spring's RestTemplate re-use connections?

This question has come up recently in several conversations with my colleagues: does Spring's RestTemplate re-use connections when making REST requests to the same host?

The answer was not that obvious. Even though we are using RestTemplate for executing REST calls, the actual connections are opened by underlying ClientHttpRequestFactory. By default, RestTemplate is created with SimpleClientHttpRequestFactory, which uses standard Java Library's UrlHttpConnection.

Starting from Java ?, UrlHttpConnection supports HTTP 1.1 and keep-alive, if destination server supports it, if certain conditions are satisfied. You can turn it off or specify the maximum number of open connections via system properties, but those are all the options you have.  For several reasons, there is no option to specify how long  the connection can stay open.

However, we have an option to instantiate RestTemplate with HttpComponentsClientHttpRequestFactory, which uses Apache's HttpComponents library to manage connections. This allows greater control over connection pool settings. 

So, the answer to the question in the title: YES, RestTemplate re-uses connections if certain conditions are met.




Thursday, January 7, 2016

Tutorial: connecting to Cassandra using Spring Boot and spring-data-cassandra.

Starting version 1.3, Spring Boot supports Cassandra auto configuration. That made using spring-cassandra-data even easier.

Prerequisites:
  •    Configured Spring Boot project version 1.3 or higher.
  •    Cassandra instance. On this instance, create a keyspace movies and in it table movie
       Create table movie:

CREATE TABLE movie (
  movieid text,
  name text,
  PRIMARY KEY ((movieid))
)
     and insert a couple of rows:

   insert into movie(movieid, name) values('id1', 'Star Wars');
   insert into movie(movieid, name) values('id2', 'Casablanca');

1. Add spring-data-cassandra dependency for Spring Boot:

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-cassandra</artifactId>
    </dependency>

2. Create a Java Bean with mapping to cassandra table:


@Table
public class Movie {
    @PrimaryKey
    private String movieid;

    @Column
    private String name;
        // add getters, setters, equals, hashCode

}

3.  Create Repository Interface for your bean:

 public interface MovieRepository extends TypedIdCassandraRepository<Movie,String> {
}


4.  Add basic  RestController which can be expanded on later:

@RestController
public class MovieController {
    @Autowired
    MovieRepository movieRepository;

    @RequestMapping(value="/movies")
    public Iterable<Movie> getTable1(){
        return movieRepository.findAll();
    }

}
5.  Update resources/application.properties with Cassandra connection details:

spring.data.cassandra.keyspace-name=...
spring.data.cassandra.contact-points=...
spring.data.cassandra.port=...
6.  Add mappingContext bean to your configuration with the package with mapped beans:


    @Bean
    public CassandraMappingContext mappingContext() throws Exception {
        BasicCassandraMappingContext bean = new BasicCassandraMappingContext();
        bean.setInitialEntitySet(CassandraEntityClassScanner.scan(("yourpackage")));

        return bean;
    }

7. Run your app. You should see the following at localhost:8080/movies:

[
  {
    "movieid": "id1",
    "name": "Star Wars"
  },
  {
    "movieid": "id2",
    "name": "Casablanca"
  }
]