Support AMQP service on Heroku

This commit is contained in:
Ramnivas Laddad
2014-05-07 16:53:59 -07:00
parent 8f0ebb6f0e
commit b4c3580e7d
15 changed files with 124 additions and 43 deletions

View File

@@ -2,20 +2,20 @@ package org.springframework.cloud.cloudfoundry;
import java.util.Map;
import org.springframework.cloud.service.common.RabbitServiceInfo;
import org.springframework.cloud.service.common.AmqpServiceInfo;
/**
*
* @author Ramnivas Laddad
*
*/
public class RabbitServiceInfoCreator extends CloudFoundryServiceInfoCreator<RabbitServiceInfo> {
public class AmqpServiceInfoCreator extends CloudFoundryServiceInfoCreator<AmqpServiceInfo> {
public RabbitServiceInfoCreator() {
public AmqpServiceInfoCreator() {
super("rabbitmq");
}
public RabbitServiceInfo createServiceInfo(Map<String,Object> serviceData) {
public AmqpServiceInfo createServiceInfo(Map<String,Object> serviceData) {
@SuppressWarnings("unchecked")
Map<String,Object> credentials = (Map<String, Object>) serviceData.get("credentials");
@@ -26,7 +26,7 @@ public class RabbitServiceInfoCreator extends CloudFoundryServiceInfoCreator<Rab
uri = (String) credentials.get("url");
}
return new RabbitServiceInfo(id, uri);
return new AmqpServiceInfo(id, uri);
}
}

View File

@@ -2,6 +2,6 @@ org.springframework.cloud.cloudfoundry.MysqlServiceInfoCreator
org.springframework.cloud.cloudfoundry.PostgresqlServiceInfoCreator
org.springframework.cloud.cloudfoundry.RedisServiceInfoCreator
org.springframework.cloud.cloudfoundry.MongoServiceInfoCreator
org.springframework.cloud.cloudfoundry.RabbitServiceInfoCreator
org.springframework.cloud.cloudfoundry.AmqpServiceInfoCreator
org.springframework.cloud.cloudfoundry.MonitoringServiceInfoCreator
org.springframework.cloud.cloudfoundry.SmtpServiceInfoCreator

View File

@@ -13,7 +13,7 @@ import org.springframework.cloud.service.ServiceInfo;
* @author Ramnivas Laddad
*
*/
public class CloudFoundryConnectorRabbitServiceTest extends AbstractCloudFoundryConnectorTest {
public class CloudFoundryConnectorAmqpServiceTest extends AbstractCloudFoundryConnectorTest {
@Test
public void rabbitServiceCreationWithTags() {
String[] versions = {"2.0", "2.2"};

View File

@@ -1,16 +1,16 @@
package org.springframework.cloud.cloudfoundry;
import org.springframework.cloud.service.common.RabbitServiceInfo;
import org.springframework.cloud.service.common.AmqpServiceInfo;
import java.util.Map;
public class UserProvidedRabbitServiceInfoCreator extends UserProvidedServiceInfoCreator<RabbitServiceInfo> {
public class UserProvidedRabbitServiceInfoCreator extends UserProvidedServiceInfoCreator<AmqpServiceInfo> {
public UserProvidedRabbitServiceInfoCreator() {
super("amqp:");
}
public RabbitServiceInfo createServiceInfo(Map<String,Object> serviceData) {
public AmqpServiceInfo createServiceInfo(Map<String,Object> serviceData) {
@SuppressWarnings("unchecked")
Map<String,Object> credentials = (Map<String, Object>) serviceData.get("credentials");
@@ -18,7 +18,7 @@ public class UserProvidedRabbitServiceInfoCreator extends UserProvidedServiceInf
String uri = (String) credentials.get("uri");
return new RabbitServiceInfo(id, uri);
return new AmqpServiceInfo(id, uri);
}
}

View File

@@ -12,12 +12,12 @@ import org.springframework.cloud.util.UriInfo;
*
*/
@ServiceLabel("rabbitmq")
public class RabbitServiceInfo extends UriBasedServiceInfo {
public RabbitServiceInfo(String id, String host, int port, String username, String password, String virtualHost) {
public class AmqpServiceInfo extends UriBasedServiceInfo {
public AmqpServiceInfo(String id, String host, int port, String username, String password, String virtualHost) {
super(id, "amqp", host, port, username, password, virtualHost);
}
public RabbitServiceInfo(String id, String uri) throws CloudException {
public AmqpServiceInfo(String id, String uri) throws CloudException {
super(id, uri);
}

View File

@@ -0,0 +1,25 @@
package org.springframework.cloud.heroku;
import org.springframework.cloud.service.common.AmqpServiceInfo;
/**
*
* @author Ramnivas Laddad
*
*/
public class AmqpServiceInfoCreator extends HerokuServiceInfoCreator<AmqpServiceInfo> {
public AmqpServiceInfoCreator() {
super("amqp");
}
@Override
public AmqpServiceInfo createServiceInfo(String id, String uri) {
return new AmqpServiceInfo(HerokuUtil.computeServiceName(id), uri);
}
@Override
public String[] getEnvPrefixes() {
return new String[]{ "CLOUDAMQP_URL" };
}
}

View File

@@ -2,7 +2,6 @@ package org.springframework.cloud.heroku;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

View File

@@ -1,3 +1,4 @@
org.springframework.cloud.heroku.PostgresqlServiceInfoCreator
org.springframework.cloud.heroku.MysqlServiceInfoCreator
org.springframework.cloud.heroku.MongoServiceInfoCreator
org.springframework.cloud.heroku.MongoServiceInfoCreator
org.springframework.cloud.heroku.AmqpServiceInfoCreator

View File

@@ -0,0 +1,56 @@
package org.springframework.cloud.heroku;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.service.common.AmqpServiceInfo;
/**
*
* @author Ramnivas Laddad
*
*/
public class HerokuConnectorAmqpServiceTest extends AbstractHerokuConnectorTest {
@Test
public void amqpServiceCreation() {
Map<String, String> env = new HashMap<String, String>();
String amqpUrl = getAmqpServiceUrl("db");
env.put("CLOUDAMQP_URL", amqpUrl);
when(mockEnvironment.getEnv()).thenReturn(env);
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
ServiceInfo serviceInfo = getServiceInfo(serviceInfos, "CLOUDAMQP");
assertNotNull(serviceInfo);
assertTrue(serviceInfo instanceof AmqpServiceInfo);
assertAmqpServiceInfo((AmqpServiceInfo)serviceInfo, "db");
}
private String getAmqpServiceUrl(String name) {
String template = "amqp://$username:$password@$hostname:$port/$virtualHost";
return template.replace("$username", username).
replace("$password", password).
replace("$hostname", hostname).
replace("$port", Integer.toString(port)).
replace("$virtualHost", name);
}
protected void assertAmqpServiceInfo(AmqpServiceInfo serviceInfo, String virtualHost) {
assertEquals(hostname, serviceInfo.getHost());
assertEquals(port, serviceInfo.getPort());
assertEquals(username, serviceInfo.getUserName());
assertEquals(password, serviceInfo.getPassword());
assertEquals(virtualHost, serviceInfo.getPath());
}
}

View File

@@ -4,7 +4,7 @@ import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.cloud.service.AbstractServiceConnectorCreator;
import org.springframework.cloud.service.ServiceConnectorConfig;
import org.springframework.cloud.service.common.RabbitServiceInfo;
import org.springframework.cloud.service.common.AmqpServiceInfo;
/**
* Simplified access to creating RabbitMQ service objects.
@@ -15,9 +15,9 @@ import org.springframework.cloud.service.common.RabbitServiceInfo;
*
*/
public class RabbitConnectionFactoryCreator extends AbstractServiceConnectorCreator<ConnectionFactory, RabbitServiceInfo> {
public class RabbitConnectionFactoryCreator extends AbstractServiceConnectorCreator<ConnectionFactory, AmqpServiceInfo> {
@Override
public ConnectionFactory create(RabbitServiceInfo serviceInfo, ServiceConnectorConfig serviceConnectorConfiguration) {
public ConnectionFactory create(AmqpServiceInfo serviceInfo, ServiceConnectorConfig serviceConnectorConfiguration) {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(serviceInfo.getHost());
connectionFactory.setVirtualHost(serviceInfo.getVirtualHost());
connectionFactory.setUsername(serviceInfo.getUserName());

View File

@@ -19,7 +19,7 @@ import org.springframework.cloud.service.ServiceConnectorCreator;
import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.service.common.MongoServiceInfo;
import org.springframework.cloud.service.common.MysqlServiceInfo;
import org.springframework.cloud.service.common.RabbitServiceInfo;
import org.springframework.cloud.service.common.AmqpServiceInfo;
import org.springframework.cloud.service.common.RedisServiceInfo;
import org.springframework.cloud.service.common.RelationalServiceInfo;
import org.springframework.cloud.service.relational.MysqlDataSourceCreator;
@@ -105,7 +105,7 @@ public class CloudTest extends StubCloudConnectorTest {
@Test
public void servicePropsRabbit() {
String serviceId = "my-rabbit";
RabbitServiceInfo rabbitServiceInfo = createRabbitService(serviceId);
AmqpServiceInfo rabbitServiceInfo = createRabbitService(serviceId);
CloudConnector stubCloudConnector = getTestCloudConnector(rabbitServiceInfo);
Cloud testCloud = new Cloud(stubCloudConnector, serviceCreators);
@@ -134,7 +134,7 @@ public class CloudTest extends StubCloudConnectorTest {
assertBasicProps(leadKey, serviceInfo, cloudProperties);
}
private void assertRabbitProps(String leadKey, RabbitServiceInfo serviceInfo, Properties cloudProperties) {
private void assertRabbitProps(String leadKey, AmqpServiceInfo serviceInfo, Properties cloudProperties) {
assertBasicProps(leadKey, serviceInfo, cloudProperties);
}
}

View File

@@ -5,7 +5,7 @@ import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.service.common.MongoServiceInfo;
import org.springframework.cloud.service.common.MysqlServiceInfo;
import org.springframework.cloud.service.common.PostgresqlServiceInfo;
import org.springframework.cloud.service.common.RabbitServiceInfo;
import org.springframework.cloud.service.common.AmqpServiceInfo;
import org.springframework.cloud.service.common.RedisServiceInfo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -64,8 +64,8 @@ abstract public class StubCloudConnectorTest {
return new MongoServiceInfo(id, "10.20.30.40", 1234, "username", "password", "db");
}
protected RabbitServiceInfo createRabbitService(String id) {
return new RabbitServiceInfo(id, "10.20.30.40", 1234, "username", "password", "vh");
protected AmqpServiceInfo createRabbitService(String id) {
return new AmqpServiceInfo(id, "10.20.30.40", 1234, "username", "password", "vh");
}
protected RedisServiceInfo createRedisService(String id) {

View File

@@ -5,7 +5,7 @@ import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.cloud.service.common.RabbitServiceInfo;
import org.springframework.cloud.service.common.AmqpServiceInfo;
import org.springframework.cloud.service.messaging.RabbitConnectionFactoryCreator;
import org.springframework.test.util.ReflectionTestUtils;
@@ -26,18 +26,18 @@ public class RabbitConnectionFactoryCreatorTest {
@Test
public void cloudRabbitCreationNoConfig() throws Exception {
RabbitServiceInfo serviceInfo = createServiceInfo();
AmqpServiceInfo serviceInfo = createServiceInfo();
ConnectionFactory connector = testCreator.create(serviceInfo, null);
assertConnectorProperties(serviceInfo, connector);
}
public RabbitServiceInfo createServiceInfo() {
return new RabbitServiceInfo("id", TEST_HOST, TEST_PORT, TEST_USERNAME, TEST_PASSWORD, TEST_VH);
public AmqpServiceInfo createServiceInfo() {
return new AmqpServiceInfo("id", TEST_HOST, TEST_PORT, TEST_USERNAME, TEST_PASSWORD, TEST_VH);
}
private void assertConnectorProperties(RabbitServiceInfo serviceInfo, ConnectionFactory connector) {
private void assertConnectorProperties(AmqpServiceInfo serviceInfo, ConnectionFactory connector) {
assertNotNull(connector);
assertEquals(serviceInfo.getHost(), connector.getHost());

View File

@@ -4,7 +4,7 @@ import org.mockito.Mock;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.cloud.service.AbstractCloudServiceConnectorFactoryTest;
import org.springframework.cloud.service.ServiceConnectorConfig;
import org.springframework.cloud.service.common.RabbitServiceInfo;
import org.springframework.cloud.service.common.AmqpServiceInfo;
import org.springframework.cloud.service.messaging.RabbitConnectionFactoryFactory;
/**
@@ -12,7 +12,7 @@ import org.springframework.cloud.service.messaging.RabbitConnectionFactoryFactor
* @author Ramnivas Laddad
*
*/
public class RabbitConnectionFactoryFactoryTest extends AbstractCloudServiceConnectorFactoryTest<RabbitConnectionFactoryFactory, ConnectionFactory, RabbitServiceInfo> {
public class RabbitConnectionFactoryFactoryTest extends AbstractCloudServiceConnectorFactoryTest<RabbitConnectionFactoryFactory, ConnectionFactory, AmqpServiceInfo> {
@Mock ConnectionFactory mockConnector;
public RabbitConnectionFactoryFactory createTestCloudServiceConnectorFactory(String id, ServiceConnectorConfig config) {
@@ -27,7 +27,7 @@ public class RabbitConnectionFactoryFactoryTest extends AbstractCloudServiceConn
return mockConnector;
}
public RabbitServiceInfo getTestServiceInfo(String id) {
return new RabbitServiceInfo(id, "host", 0, "username", "password", "vh");
public AmqpServiceInfo getTestServiceInfo(String id) {
return new AmqpServiceInfo(id, "host", 0, "username", "password", "vh");
}
}

View File

@@ -3,7 +3,7 @@ package org.springframework.cloud.service.rabbit;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.cloud.service.common.RabbitServiceInfo;
import org.springframework.cloud.service.common.AmqpServiceInfo;
/**
*
@@ -13,7 +13,7 @@ import org.springframework.cloud.service.common.RabbitServiceInfo;
public class RabbitServiceInfoTest {
@Test
public void uriBasedParsing() {
RabbitServiceInfo serviceInfo = new RabbitServiceInfo("id", "amqp://myuser:mypass@myhost:12345/myvhost");
AmqpServiceInfo serviceInfo = new AmqpServiceInfo("id", "amqp://myuser:mypass@myhost:12345/myvhost");
assertEquals("myhost", serviceInfo.getHost());
assertEquals(12345, serviceInfo.getPort());
@@ -24,38 +24,38 @@ public class RabbitServiceInfoTest {
@Test(expected=IllegalArgumentException.class)
public void badProtocol() {
new RabbitServiceInfo("id", "XX://myuser:mypass@myhost:12345/myvhost");
new AmqpServiceInfo("id", "XX://myuser:mypass@myhost:12345/myvhost");
}
@Test(expected=IllegalArgumentException.class)
public void missingHost() {
new RabbitServiceInfo("id", "amqp://myuser:mypass@:12345/myvhost");
new AmqpServiceInfo("id", "amqp://myuser:mypass@:12345/myvhost");
}
@Test
public void missingPort() {
RabbitServiceInfo serviceInfo = new RabbitServiceInfo("id", "amqp://myuser:mypass@myhost/myvhost");
AmqpServiceInfo serviceInfo = new AmqpServiceInfo("id", "amqp://myuser:mypass@myhost/myvhost");
assertEquals(5672, serviceInfo.getPort()); // the default port is 5672
}
@Test(expected=IllegalArgumentException.class)
public void badUserInfo() {
new RabbitServiceInfo("id", "amqp://myuser@myhost/myvhost");
new AmqpServiceInfo("id", "amqp://myuser@myhost/myvhost");
}
@Test(expected=IllegalArgumentException.class)
public void missingUserInfo() {
new RabbitServiceInfo("id", "amqp://myhost:12345/myvhost");
new AmqpServiceInfo("id", "amqp://myhost:12345/myvhost");
}
@Test
public void missingVirtualHost() {
RabbitServiceInfo serviceInfo = new RabbitServiceInfo("id", "amqp://myuser:mypass@myhost:12345");
AmqpServiceInfo serviceInfo = new AmqpServiceInfo("id", "amqp://myuser:mypass@myhost:12345");
assertEquals("/", serviceInfo.getVirtualHost());
}
@Test(expected=IllegalArgumentException.class)
public void badVirtualHost() {
new RabbitServiceInfo("id", "amqp://myuser:mypass@myhost:12345/a/b");
new AmqpServiceInfo("id", "amqp://myuser:mypass@myhost:12345/a/b");
}
}