Sunday, February 24, 2013

Use Cloudfoundry in Spring without the dedicated XML namespace

Spring allows you to configure a dead simple connection on a provisioned service, like mysql, redis, rabbitmq and many others. It's really simple, since you don't even need to configure explicit credentials and connection strings. Instead, you can retrieve a reference to this service from the cloud itself using the CloudFoundry “cloud” namespace.

Problem is, you have to create an XML file, and we have more and more projects without XML anymore. So, how to use the Cloudfoundry integration without XML?

Like the XML version, you need the Maven dep:

<dependency> 
<groupId>org.cloudfoundry</groupId> 
<artifactId>cloudfoundry-runtime</artifactId> 
<version>0.8.1</version> 
</dependency>

The package org.cloudfoundry.runtime.service offers 4 implementations of AbstractCloudServiceFactory:
- CloudDataSourceFactory
- CloudMongoDbFactoryBean
- CloudRabbitConnectionFactoryBean
- CloudRedisConnectionFactoryBean

So, depending of the type of your service, choose the right implementation and create a configuration class. Here is an example using Redis:


import javax.inject.Inject;

import org.cloudfoundry.runtime.service.CloudPoolConfiguration;
import org.cloudfoundry.runtime.service.keyvalue.CloudRedisConnectionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;


@Configuration
@ComponentScan(basePackages = { "..." })
@Order(1)
public class KeyValueConfig {

@Inject
private RedisConnectionFactory redisConnectionFactory;

@Bean
public StringRedisTemplate redisTemplate() {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(
redisConnectionFactory);
return stringRedisTemplate;
}

/**
* Properties to support the local and test mode of operation.
*/
@Configuration
@Profile({ Profiles.LOCAL, Profiles.TEST, Profiles.PROD })
static class Default {

@Inject
private Environment environment;

@Bean
public RedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory redis = new JedisConnectionFactory();
redis.setHostName(environment.getProperty("redis.hostname"));
redis.setPort(environment.getProperty("redis.port", Integer.class));
redis.setPassword(environment.getProperty("redis.password"));
redis.setUsePool(true);
return redis;
}
}

/**
* Properties to support the cloud mode of operation.
*/
@Configuration
@Profile(Profiles.CLOUDFOUNDRY)
static class Cloud {

@Bean
public RedisConnectionFactory redisConnectionFactory() throws Exception {
CloudPoolConfiguration cloudPoolConfiguration = new CloudPoolConfiguration();
cloudPoolConfiguration.setPoolSize("3-5");

CloudRedisConnectionFactoryBean factory = new CloudRedisConnectionFactoryBean();
factory.setCloudPoolConfiguration(cloudPoolConfiguration);

return factory.getObject();
}
}

}

And that's all!

No comments:

Post a Comment