Improve Key-Value Backwards Compatibility
Currently, the entire Spring Service Connector implementation is backwards compatible to Spring Data 1 except for the Key Value (Redis) services. This is broken because the Spring Data 2 Redis API has been improved. It turns out that the Spring 2 Redis API doesn't remove the previous Spring Data 1 variant and therefore, the two can coexist. This change reinstates the previous Spring Data 1 Redis implementation and adds it to the list of ServiceConnectorCreator services. If the classpath contains the Spring Data 2 variant, then only the Spring Data 2 Creator will be used. If the classpath contains the Spring Data 1 variant, then only the Spring Data 1 Creator will be used.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
package org.springframework.cloud.service.keyval;
|
||||
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.cloud.service.MapServiceConnectionConfigurer;
|
||||
import org.springframework.cloud.service.MapServiceConnectorConfig;
|
||||
import org.springframework.cloud.service.PooledServiceConnectorConfig;
|
||||
import org.springframework.cloud.service.ServiceConnectorConfigurer;
|
||||
import org.springframework.cloud.service.Util;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Scott Frederick
|
||||
*
|
||||
*/
|
||||
public class SpringData1RedisConnectionFactoryConfigurer implements ServiceConnectorConfigurer<JedisConnectionFactory, RedisConnectionFactoryConfig> {
|
||||
private MapServiceConnectionConfigurer<JedisConnectionFactory, MapServiceConnectorConfig> mapServiceConnectionConfigurer =
|
||||
new MapServiceConnectionConfigurer<JedisConnectionFactory, MapServiceConnectorConfig>();
|
||||
|
||||
@Override
|
||||
public JedisConnectionFactory configure(JedisConnectionFactory connectionFactory, RedisConnectionFactoryConfig config) {
|
||||
if (config != null) {
|
||||
configurePool(connectionFactory, config);
|
||||
configureConnection(connectionFactory, config);
|
||||
}
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
public JedisConnectionFactory configure(JedisConnectionFactory connectionFactory, PooledServiceConnectorConfig config) {
|
||||
if (config != null) {
|
||||
configurePool(connectionFactory, config);
|
||||
}
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
private void configurePool(JedisConnectionFactory connectionFactory, PooledServiceConnectorConfig config) {
|
||||
if (config.getPoolConfig() != null) {
|
||||
JedisPoolConfig poolConfig = new JedisPoolConfig();
|
||||
BeanWrapper target = new BeanWrapperImpl(poolConfig);
|
||||
BeanWrapper source = new BeanWrapperImpl(config.getPoolConfig());
|
||||
Util.setCorrespondingProperties(target, source);
|
||||
connectionFactory.setPoolConfig(poolConfig);
|
||||
}
|
||||
}
|
||||
|
||||
private void configureConnection(JedisConnectionFactory connectionFactory, RedisConnectionFactoryConfig config) {
|
||||
if (config.getConnectionProperties() != null) {
|
||||
mapServiceConnectionConfigurer.configure(connectionFactory, config.getConnectionProperties());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.springframework.cloud.service.keyval;
|
||||
|
||||
import static org.springframework.cloud.service.Util.hasClass;
|
||||
|
||||
import org.springframework.cloud.service.AbstractServiceConnectorCreator;
|
||||
import org.springframework.cloud.service.PooledServiceConnectorConfig;
|
||||
import org.springframework.cloud.service.ServiceConnectorConfig;
|
||||
import org.springframework.cloud.service.ServiceConnectorCreationException;
|
||||
import org.springframework.cloud.service.common.RedisServiceInfo;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
|
||||
/**
|
||||
* Simplified access to creating Redis service objects.
|
||||
* Supports Jedis and lettuce Redis clients.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Jennifer Hickey
|
||||
* @author Thomas Risberg
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class SpringData1RedisConnectionFactoryCreator extends AbstractServiceConnectorCreator<RedisConnectionFactory, RedisServiceInfo> {
|
||||
|
||||
private static final String JEDIS_CLASS_NAME = "redis.clients.jedis.Jedis";
|
||||
private static final String LETTUCE_CLASS_NAME = "com.lambdaworks.redis.RedisClient";
|
||||
|
||||
@Override
|
||||
public RedisConnectionFactory create(RedisServiceInfo serviceInfo, ServiceConnectorConfig serviceConnectorConfig) {
|
||||
|
||||
if (hasClass(JEDIS_CLASS_NAME)) {
|
||||
|
||||
SpringData1RedisConnectionFactoryConfigurer configurer = new SpringData1RedisConnectionFactoryConfigurer();
|
||||
|
||||
JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
|
||||
connectionFactory.setHostName(serviceInfo.getHost());
|
||||
connectionFactory.setPort(serviceInfo.getPort());
|
||||
connectionFactory.setPassword(serviceInfo.getPassword());
|
||||
|
||||
if (serviceConnectorConfig instanceof RedisConnectionFactoryConfig) {
|
||||
configurer.configure(connectionFactory, (RedisConnectionFactoryConfig) serviceConnectorConfig);
|
||||
} else {
|
||||
configurer.configure(connectionFactory, (PooledServiceConnectorConfig) serviceConnectorConfig);
|
||||
}
|
||||
|
||||
connectionFactory.afterPropertiesSet();
|
||||
return connectionFactory;
|
||||
}
|
||||
else if (hasClass(LETTUCE_CLASS_NAME)) {
|
||||
|
||||
SpringData1RedisLettuceConnectionFactoryConfigurer configurer = new SpringData1RedisLettuceConnectionFactoryConfigurer();
|
||||
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory();
|
||||
connectionFactory.setHostName(serviceInfo.getHost());
|
||||
connectionFactory.setPort(serviceInfo.getPort());
|
||||
connectionFactory.setPassword(serviceInfo.getPassword());
|
||||
|
||||
configurer.configure(connectionFactory, (RedisConnectionFactoryConfig) serviceConnectorConfig);
|
||||
|
||||
connectionFactory.afterPropertiesSet();
|
||||
return connectionFactory;
|
||||
}
|
||||
else {
|
||||
throw new ServiceConnectorCreationException(String.format("Failed to create cloud Redis connection factory " +
|
||||
"for %s service. No client implementation classes "
|
||||
+ " of jedis or lettuce clients implementation (%s, %s) not found", serviceInfo.getId(),
|
||||
JEDIS_CLASS_NAME, LETTUCE_CLASS_NAME));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.springframework.cloud.service.keyval;
|
||||
|
||||
import org.springframework.cloud.service.*;
|
||||
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class SpringData1RedisLettuceConnectionFactoryConfigurer implements ServiceConnectorConfigurer<LettuceConnectionFactory, RedisConnectionFactoryConfig> {
|
||||
private MapServiceConnectionConfigurer<LettuceConnectionFactory, MapServiceConnectorConfig> mapServiceConnectionConfigurer =
|
||||
new MapServiceConnectionConfigurer<LettuceConnectionFactory, MapServiceConnectorConfig>();
|
||||
|
||||
@Override
|
||||
public LettuceConnectionFactory configure(LettuceConnectionFactory connectionFactory, RedisConnectionFactoryConfig config) {
|
||||
if (config != null) {
|
||||
configureConnection(connectionFactory, config);
|
||||
}
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
private void configureConnection(LettuceConnectionFactory connectionFactory, RedisConnectionFactoryConfig config) {
|
||||
if (config.getConnectionProperties() != null) {
|
||||
mapServiceConnectionConfigurer.configure(connectionFactory, config.getConnectionProperties());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ org.springframework.cloud.service.relational.PostgresqlDataSourceCreator
|
||||
org.springframework.cloud.service.relational.OracleDataSourceCreator
|
||||
org.springframework.cloud.service.relational.DB2DataSourceCreator
|
||||
org.springframework.cloud.service.keyval.RedisConnectionFactoryCreator
|
||||
org.springframework.cloud.service.keyval.SpringData1RedisConnectionFactoryCreator
|
||||
org.springframework.cloud.service.document.MongoDbFactoryCreator
|
||||
org.springframework.cloud.service.messaging.RabbitConnectionFactoryCreator
|
||||
org.springframework.cloud.service.smtp.MailSenderCreator
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.springframework.cloud.service.redis;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.springframework.cloud.service.AbstractCloudServiceConnectorFactoryTest;
|
||||
import org.springframework.cloud.service.ServiceConnectorConfig;
|
||||
import org.springframework.cloud.service.common.RedisServiceInfo;
|
||||
import org.springframework.cloud.service.keyval.RedisConnectionFactoryFactory;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public class SpringData1RedisConnectionFactoryFactoryTest extends AbstractCloudServiceConnectorFactoryTest<RedisConnectionFactoryFactory, RedisConnectionFactory, RedisServiceInfo> {
|
||||
@Mock RedisConnectionFactory mockConnector;
|
||||
|
||||
public RedisConnectionFactoryFactory createTestCloudServiceConnectorFactory(String id, ServiceConnectorConfig config) {
|
||||
return new RedisConnectionFactoryFactory(id, config);
|
||||
}
|
||||
|
||||
public Class<RedisConnectionFactory> getConnectorType() {
|
||||
return RedisConnectionFactory.class;
|
||||
}
|
||||
|
||||
public RedisConnectionFactory getMockConnector() {
|
||||
return mockConnector;
|
||||
}
|
||||
|
||||
public RedisServiceInfo getTestServiceInfo(String id) {
|
||||
return new RedisServiceInfo(id, "host", 0, "password");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.springframework.cloud.service.redis;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.cloud.service.common.RedisServiceInfo;
|
||||
import org.springframework.cloud.service.keyval.SpringData1RedisConnectionFactoryCreator;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public class SpringData1RedisServiceConnectorCreatorTest {
|
||||
private static final String TEST_HOST = "10.20.30.40";
|
||||
private static final int TEST_PORT = 1234;
|
||||
private static final String TEST_PASSWORD = "mypass";
|
||||
|
||||
|
||||
@Mock private RedisServiceInfo mockRedisServiceInfo;
|
||||
|
||||
private SpringData1RedisConnectionFactoryCreator testCreator = new SpringData1RedisConnectionFactoryCreator();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cloudRedisCreationNoConfig() throws Exception {
|
||||
RedisServiceInfo serviceInfo = createServiceInfo();
|
||||
|
||||
RedisConnectionFactory dataSource = testCreator.create(serviceInfo, null);
|
||||
|
||||
assertConnectorProperties(serviceInfo, dataSource);
|
||||
}
|
||||
|
||||
public RedisServiceInfo createServiceInfo() {
|
||||
when(mockRedisServiceInfo.getHost()).thenReturn(TEST_HOST);
|
||||
when(mockRedisServiceInfo.getPort()).thenReturn(TEST_PORT);
|
||||
when(mockRedisServiceInfo.getPassword()).thenReturn(TEST_PASSWORD);
|
||||
|
||||
return mockRedisServiceInfo;
|
||||
}
|
||||
|
||||
private void assertConnectorProperties(RedisServiceInfo serviceInfo, RedisConnectionFactory connector) {
|
||||
assertNotNull(connector);
|
||||
|
||||
assertEquals(serviceInfo.getHost(), ReflectionTestUtils.getField(connector, "hostName"));
|
||||
assertEquals(serviceInfo.getPort(), ReflectionTestUtils.getField(connector, "port"));
|
||||
assertEquals(serviceInfo.getPassword(), ReflectionTestUtils.getField(connector, "password"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user