From f48084a15a849bd642064ac6af1afdfcb859abca Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 17:33:29 -0500
Subject: [PATCH 01/52] add ignore for "bin/" for Gradle-Eclipse
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index ae08494..1eb96eb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ build
Servers
.gradle
_site
+/bin
From 0abf58f4918f75129539ae9185f67483bf838c9a Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 17:33:53 -0500
Subject: [PATCH 02/52] remove unused import
---
.../java/org/springframework/cloud/config/ServiceScanHelper.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/ServiceScanHelper.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/ServiceScanHelper.java
index bf162c9..deefb6f 100644
--- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/ServiceScanHelper.java
+++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/ServiceScanHelper.java
@@ -9,7 +9,6 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.cloud.Cloud;
-import org.springframework.cloud.CloudException;
import org.springframework.cloud.CloudFactory;
import org.springframework.cloud.config.java.ServiceScan;
import org.springframework.cloud.service.GenericCloudServiceConnectorFactory;
From 502eeeddddd23af4157d6697d6310280cb5f30cf Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 17:35:25 -0500
Subject: [PATCH 03/52] remove unused logger field from public class (used only
in secondary top-level)
---
.../src/main/java/org/springframework/cloud/Cloud.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/Cloud.java b/spring-cloud-core/src/main/java/org/springframework/cloud/Cloud.java
index 808b903..41fd035 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/Cloud.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/Cloud.java
@@ -38,8 +38,6 @@ import org.springframework.cloud.service.ServiceInfo.ServiceProperty;
*
*/
public class Cloud {
- private static Logger logger = Logger.getLogger(Cloud.class.getName());
-
private CloudConnector cloudConnector;
private ServiceConnectorCreatorRegistry serviceConnectorCreatorRegistry = new ServiceConnectorCreatorRegistry();
From 839a72569c81e82c696b97d65977db18b9dd1899 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:06:07 -0500
Subject: [PATCH 04/52] pull up KeyValuePair class from HerokuConnector to
AbstractCloudConnector
---
.../cloud/AbstractCloudConnector.java | 34 ++++++++++---
.../cloud/heroku/HerokuConnector.java | 50 ++++++-------------
.../heroku/HerokuServiceInfoCreator.java | 20 ++++----
3 files changed, 52 insertions(+), 52 deletions(-)
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/AbstractCloudConnector.java b/spring-cloud-core/src/main/java/org/springframework/cloud/AbstractCloudConnector.java
index 6a73afa..a515766 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/AbstractCloudConnector.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/AbstractCloudConnector.java
@@ -10,25 +10,25 @@ import org.springframework.cloud.service.ServiceInfo;
/**
* Helper abstract class to simplify {@link CloudConnector} implementations.
- *
+ *
* User the {@link ServiceLoader} approach to looks for file name matching the class passed in constructor
* and registers {@link ServiceInfoCreator} found there.
- *
+ *
* Implementation of {@link CloudConnector}s that wish to support the recommended service scanning approach
* should extends this approach to gain that functionality automatically.
- *
+ *
* @author Ramnivas Laddad
*
*/
public abstract class AbstractCloudConnector implements CloudConnector {
private static Logger logger = Logger.getLogger(AbstractCloudConnector.class.getName());
-
+
protected List> serviceInfoCreators = new ArrayList>();
protected abstract List getServicesData();
protected abstract FallbackServiceInfoCreator,SD> getFallbackServiceInfoCreator();
-
+
public AbstractCloudConnector(Class extends ServiceInfoCreator extends ServiceInfo, ?>> serviceInfoCreatorClass) {
scanServiceInfoCreators(serviceInfoCreatorClass);
}
@@ -39,7 +39,7 @@ public abstract class AbstractCloudConnector implements CloudConnector {
for (SD serviceData : getServicesData()) {
serviceInfos.add(getServiceInfo(serviceData));
}
-
+
return serviceInfos;
}
@@ -54,18 +54,36 @@ public abstract class AbstractCloudConnector implements CloudConnector {
registerServiceInfoCreator(serviceInfoCreator);
}
}
-
+
private ServiceInfo getServiceInfo(SD serviceData) {
for (ServiceInfoCreator extends ServiceInfo,SD> serviceInfoCreator : serviceInfoCreators) {
if (serviceInfoCreator.accept(serviceData)) {
return serviceInfoCreator.createServiceInfo(serviceData);
}
}
-
+
// Fallback with a warning
ServiceInfo fallackServiceInfo = getFallbackServiceInfoCreator().createServiceInfo(serviceData);
logger.warning("No suitable service info creator found for service " + fallackServiceInfo.getId()
+ " Did you forget to add a ServiceInfoCreator?");
return fallackServiceInfo;
}
+
+ public static class KeyValuePair {
+ private final String key;
+ private final String value;
+
+ public KeyValuePair(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+ }
}
\ No newline at end of file
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java
index 374b7f8..ac39931 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java
@@ -6,30 +6,30 @@ import java.util.List;
import java.util.Map;
import org.springframework.cloud.AbstractCloudConnector;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
import org.springframework.cloud.CloudException;
import org.springframework.cloud.FallbackServiceInfoCreator;
import org.springframework.cloud.ServiceInfoCreator;
import org.springframework.cloud.app.ApplicationInstanceInfo;
-import org.springframework.cloud.heroku.HerokuConnector.KeyValuePair;
import org.springframework.cloud.service.BaseServiceInfo;
import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.util.EnvironmentAccessor;
/**
* Implementation of CloudConnector for Heroku
- *
+ *
* Currently support Postgres (default provided), Mysql (Cleardb), MongoDb (MongoLab, MongoHQ, MongoSoup),
* Redis (RedisToGo, RedisCloud, OpenRedis, RedisGreen), and AMQP (CloudAmqp).
- *
+ *
* @author Ramnivas Laddad
*
*/
-public class HerokuConnector extends AbstractCloudConnector {
+public class HerokuConnector extends AbstractCloudConnector {
private EnvironmentAccessor environment = new EnvironmentAccessor();
- private ApplicationInstanceInfoCreator applicationInstanceInfoCreator
+ private ApplicationInstanceInfoCreator applicationInstanceInfoCreator
= new ApplicationInstanceInfoCreator(environment);
-
+
private List serviceEnvPrefixes;
@SuppressWarnings({ "unchecked", "rawtypes" })
@@ -41,28 +41,28 @@ public class HerokuConnector extends AbstractCloudConnector serviceInfoCreator) {
+ protected void registerServiceInfoCreator(ServiceInfoCreator extends ServiceInfo, KeyValuePair> serviceInfoCreator) {
super.registerServiceInfoCreator(serviceInfoCreator);
HerokuServiceInfoCreator> herokuServiceInfoCreator = (HerokuServiceInfoCreator>)serviceInfoCreator;
String[] envPrefixes = herokuServiceInfoCreator.getEnvPrefixes();
-
+
// need to do this since this method gets called during construction and we cannot initialize serviceEnvPrefixes before this
if (serviceEnvPrefixes == null) {
serviceEnvPrefixes = new ArrayList();
@@ -75,17 +75,17 @@ public class HerokuConnector extends AbstractCloudConnector
* Returns map whose key is the env key and value is the associated url
*
- * @return information about services bound to the app
+ * @return information about services bound to the app
*/
protected List getServicesData() {
List serviceData = new ArrayList();
-
+
Map env = environment.getEnv();
-
+
for (Map.Entry envEntry : env.entrySet()) {
for (String envPrefix : serviceEnvPrefixes) {
if (envEntry.getKey().startsWith(envPrefix)) {
- serviceData.add(new KeyValuePair(envEntry.getKey(), envEntry.getValue()));
+ serviceData.add(new KeyValuePair(envEntry.getKey(), envEntry.getValue()));
}
}
}
@@ -97,24 +97,6 @@ public class HerokuConnector extends AbstractCloudConnector getFallbackServiceInfoCreator() {
return new HerokuFallbackServiceInfoCreator();
}
-
- public static class KeyValuePair {
- private String key;
- private String value;
-
- public KeyValuePair(String key, String value) {
- this.key = key;
- this.value = value;
- }
-
- public String getKey() {
- return key;
- }
-
- public String getValue() {
- return value;
- }
- }
}
class HerokuFallbackServiceInfoCreator extends FallbackServiceInfoCreator {
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java
index 15ed4aa..00b6c6b 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java
@@ -1,11 +1,11 @@
package org.springframework.cloud.heroku;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
import org.springframework.cloud.ServiceInfoCreator;
-import org.springframework.cloud.heroku.HerokuConnector.KeyValuePair;
import org.springframework.cloud.service.ServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@@ -16,25 +16,25 @@ public abstract class HerokuServiceInfoCreator implement
public HerokuServiceInfoCreator(String urlProtocol) {
this.urlProtocol = urlProtocol;
}
-
+
public boolean accept(KeyValuePair serviceData) {
return serviceData.getValue().toString().startsWith(urlProtocol + "://");
}
-
+
public abstract SI createServiceInfo(String id, String uri);
-
+
public SI createServiceInfo(KeyValuePair serviceData) {
return createServiceInfo(serviceData.getKey(), serviceData.getValue());
}
-
+
/**
* Get prefixes for env variable with which the associated {@link ServiceInfo} may be created.
- *
+ *
* Unlike CloudFoundry which exposes VCAP_SERVICES as a single environment to encompass all services bound
* to the app, Heroku expose one environment variable per app. This method allows each info creator to declare
- * appropriate env variables.
- *
- * @return prefixes for the relevant environment variables
+ * appropriate env variables.
+ *
+ * @return prefixes for the relevant environment variables
*/
public abstract String[] getEnvPrefixes();
}
From 6e12152ebfccf15378afb911a253092e2939cf59 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:13:49 -0500
Subject: [PATCH 05/52] pull up URI-based common functionality into core
abstract base class
---
.../service/UriBasedServiceInfoCreator.java | 26 +++++++++++++++++++
.../heroku/HerokuServiceInfoCreator.java | 21 +++------------
2 files changed, 30 insertions(+), 17 deletions(-)
create mode 100644 spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfoCreator.java
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfoCreator.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfoCreator.java
new file mode 100644
index 0000000..b856bc0
--- /dev/null
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfoCreator.java
@@ -0,0 +1,26 @@
+package org.springframework.cloud.service;
+
+import org.springframework.cloud.ServiceInfoCreator;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
+
+public abstract class UriBasedServiceInfoCreator implements
+ ServiceInfoCreator {
+
+ private final String uriScheme;
+
+ public UriBasedServiceInfoCreator(String uriScheme) {
+ this.uriScheme = uriScheme;
+ }
+
+ @Override
+ public boolean accept(KeyValuePair serviceData) {
+ return serviceData.getValue().toString().startsWith(uriScheme + "://");
+ }
+
+ public abstract SI createServiceInfo(String id, String uri);
+
+ @Override
+ public SI createServiceInfo(KeyValuePair serviceData) {
+ return createServiceInfo(serviceData.getKey(), serviceData.getValue());
+ }
+}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java
index 00b6c6b..81094eb 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java
@@ -1,30 +1,17 @@
package org.springframework.cloud.heroku;
-import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
-import org.springframework.cloud.ServiceInfoCreator;
import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.UriBasedServiceInfoCreator;
/**
*
* @author Ramnivas Laddad
*
*/
-public abstract class HerokuServiceInfoCreator implements ServiceInfoCreator {
+public abstract class HerokuServiceInfoCreator extends UriBasedServiceInfoCreator {
- private String urlProtocol;
-
- public HerokuServiceInfoCreator(String urlProtocol) {
- this.urlProtocol = urlProtocol;
- }
-
- public boolean accept(KeyValuePair serviceData) {
- return serviceData.getValue().toString().startsWith(urlProtocol + "://");
- }
-
- public abstract SI createServiceInfo(String id, String uri);
-
- public SI createServiceInfo(KeyValuePair serviceData) {
- return createServiceInfo(serviceData.getKey(), serviceData.getValue());
+ public HerokuServiceInfoCreator(String uriScheme) {
+ super(uriScheme);
}
/**
From 82c0dfaaf2a35c86bd36cac0cdf29cdd252580f8 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:23:36 -0500
Subject: [PATCH 06/52] constant for MongoDB URI scheme
---
.../cloud/cloudfoundry/MongoServiceInfoCreator.java | 4 ++--
.../cloud/service/common/MongoServiceInfo.java | 11 +++++++----
.../cloud/heroku/MongoServiceInfoCreator.java | 4 ++--
3 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MongoServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MongoServiceInfoCreator.java
index 5aeace5..ac963c5 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MongoServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MongoServiceInfoCreator.java
@@ -12,8 +12,8 @@ import org.springframework.cloud.service.common.MongoServiceInfo;
public class MongoServiceInfoCreator extends CloudFoundryServiceInfoCreator {
public MongoServiceInfoCreator() {
- super(new Tags("mongodb"), "mongodb");
-
+ // the literal in the tag is CloudFoundry-specific
+ super(new Tags("mongodb"), MongoServiceInfo.URI_SCHEME);
}
public MongoServiceInfo createServiceInfo(Map serviceData) {
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MongoServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MongoServiceInfo.java
index b45800f..a332b65 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MongoServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MongoServiceInfo.java
@@ -4,23 +4,26 @@ import org.springframework.cloud.service.UriBasedServiceInfo;
import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@ServiceLabel("mongo")
public class MongoServiceInfo extends UriBasedServiceInfo {
+
+ public static final String URI_SCHEME = "mongodb";
+
public MongoServiceInfo(String id, String host, int port, String username, String password, String db) {
- super(id, "mongodb", host, port, username, password, db);
+ super(id, URI_SCHEME, host, port, username, password, db);
}
public MongoServiceInfo(String id, String uri) {
super(id, uri);
}
-
+
@ServiceProperty(category="connection")
public String getDatabase() {
return getUriInfo().getPath();
}
-
+
}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MongoServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MongoServiceInfoCreator.java
index bb1e11e..d75299e 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MongoServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MongoServiceInfoCreator.java
@@ -3,14 +3,14 @@ package org.springframework.cloud.heroku;
import org.springframework.cloud.service.common.MongoServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class MongoServiceInfoCreator extends HerokuServiceInfoCreator {
public MongoServiceInfoCreator() {
- super("mongodb");
+ super(MongoServiceInfo.URI_SCHEME);
}
@Override
From 5434952ca60ce56f8f88fad9495e2f40058bb4b1 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:25:57 -0500
Subject: [PATCH 07/52] pull up URI scheme for RabbitMQ
---
.../cloudfoundry/AmqpServiceInfoCreator.java | 6 +++---
.../cloud/service/common/AmqpServiceInfo.java | 19 +++++++++++--------
.../cloud/heroku/AmqpServiceInfoCreator.java | 4 ++--
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/AmqpServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/AmqpServiceInfoCreator.java
index 1753c11..af68eee 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/AmqpServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/AmqpServiceInfoCreator.java
@@ -5,20 +5,20 @@ import java.util.Map;
import org.springframework.cloud.service.common.AmqpServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class AmqpServiceInfoCreator extends CloudFoundryServiceInfoCreator {
public AmqpServiceInfoCreator() {
- super(new Tags("rabbitmq"), "amqp");
+ super(new Tags("rabbitmq"), AmqpServiceInfo.URI_SCHEME);
}
public AmqpServiceInfo createServiceInfo(Map serviceData) {
@SuppressWarnings("unchecked")
Map credentials = (Map) serviceData.get("credentials");
-
+
String id = (String) serviceData.get("name");
String uri = getStringFromCredentials(credentials, "uri", "url");
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/AmqpServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/AmqpServiceInfo.java
index 5ae72bb..aa7bb98 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/AmqpServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/AmqpServiceInfo.java
@@ -1,8 +1,8 @@
package org.springframework.cloud.service.common;
import org.springframework.cloud.CloudException;
-import org.springframework.cloud.service.UriBasedServiceInfo;
import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
+import org.springframework.cloud.service.UriBasedServiceInfo;
import org.springframework.cloud.util.UriInfo;
/**
@@ -13,29 +13,32 @@ import org.springframework.cloud.util.UriInfo;
*/
@ServiceLabel("rabbitmq")
public class AmqpServiceInfo extends UriBasedServiceInfo {
+
+ public static final String URI_SCHEME = "amqp";
+
public AmqpServiceInfo(String id, String host, int port, String username, String password, String virtualHost) {
- super(id, "amqp", host, port, username, password, virtualHost);
+ super(id, URI_SCHEME, host, port, username, password, virtualHost);
}
-
+
public AmqpServiceInfo(String id, String uri) throws CloudException {
super(id, uri);
}
-
+
@ServiceProperty(category="connection")
public String getVirtualHost() {
return getUriInfo().getPath();
}
-
+
@Override
protected UriInfo validateAndCleanUriInfo(UriInfo uriInfo) {
- if (!"amqp".equals(uriInfo.getScheme())) {
+ if (!URI_SCHEME.equals(uriInfo.getScheme())) {
throw new IllegalArgumentException("wrong scheme in amqp URI: " + uriInfo);
}
if (uriInfo.getHost() == null) {
throw new IllegalArgumentException("missing authority in amqp URI: " + uriInfo);
}
-
+
int port = uriInfo.getPort();
if (port == -1) {
port = 5672;
@@ -43,7 +46,7 @@ public class AmqpServiceInfo extends UriBasedServiceInfo {
String userName = uriInfo.getUserName();
String password = uriInfo.getPassword();
-
+
if (userName == null || password == null) {
throw new IllegalArgumentException("missing userinfo in amqp URI: " + uriInfo);
}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/AmqpServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/AmqpServiceInfoCreator.java
index a139bd6..86621f8 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/AmqpServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/AmqpServiceInfoCreator.java
@@ -3,14 +3,14 @@ package org.springframework.cloud.heroku;
import org.springframework.cloud.service.common.AmqpServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class AmqpServiceInfoCreator extends HerokuServiceInfoCreator {
public AmqpServiceInfoCreator() {
- super("amqp");
+ super(AmqpServiceInfo.URI_SCHEME);
}
@Override
From 84ba55aae86fb8b6e01042bfc7fee1f3d2a54fcb Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:26:45 -0500
Subject: [PATCH 08/52] make jdbcUrlDatabaseType final
---
.../cloud/service/common/RelationalServiceInfo.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RelationalServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RelationalServiceInfo.java
index 49fe00d..bac6236 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RelationalServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RelationalServiceInfo.java
@@ -7,7 +7,7 @@ import org.springframework.cloud.service.UriBasedServiceInfo;
*/
public abstract class RelationalServiceInfo extends UriBasedServiceInfo {
- protected String jdbcUrlDatabaseType;
+ protected final String jdbcUrlDatabaseType;
public RelationalServiceInfo(String id, String uriString, String jdbcUrlDatabaseType) {
super(id, uriString);
From 0629e84768c73e007bd5d5349fc306ffff0a2d5f Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:29:07 -0500
Subject: [PATCH 09/52] pull up MySQL URI scheme
---
.../cloud/cloudfoundry/MysqlServiceInfoCreator.java | 5 +++--
.../cloud/service/common/MysqlServiceInfo.java | 6 ++++--
.../cloud/heroku/MysqlServiceInfoCreator.java | 4 ++--
.../cloud/heroku/HerokuConnectorMysqlServiceTest.java | 6 +++---
4 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MysqlServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MysqlServiceInfoCreator.java
index aca803e..b5c6e15 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MysqlServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MysqlServiceInfoCreator.java
@@ -3,14 +3,15 @@ package org.springframework.cloud.cloudfoundry;
import org.springframework.cloud.service.common.MysqlServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class MysqlServiceInfoCreator extends RelationalServiceInfoCreator {
public MysqlServiceInfoCreator() {
- super(new Tags("mysql"), "mysql");
+ // the literal in the tag is CloudFoundry-specific
+ super(new Tags("mysql"), MysqlServiceInfo.URI_SCHEME);
}
@Override
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java
index 467a59c..2eccab0 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java
@@ -3,14 +3,16 @@ package org.springframework.cloud.service.common;
import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@ServiceLabel("mysql")
public class MysqlServiceInfo extends RelationalServiceInfo {
+ public static final String URI_SCHEME = "mysql";
+
public MysqlServiceInfo(String id, String url) {
- super(id, url, "mysql");
+ super(id, url, URI_SCHEME);
}
}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MysqlServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MysqlServiceInfoCreator.java
index 4318cb0..73bb8eb 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MysqlServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MysqlServiceInfoCreator.java
@@ -3,14 +3,14 @@ package org.springframework.cloud.heroku;
import org.springframework.cloud.service.common.MysqlServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class MysqlServiceInfoCreator extends RelationalServiceInfoCreator {
public MysqlServiceInfoCreator() {
- super("mysql");
+ super(MysqlServiceInfo.URI_SCHEME);
}
@Override
diff --git a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorMysqlServiceTest.java b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorMysqlServiceTest.java
index 349c738..439a854 100644
--- a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorMysqlServiceTest.java
+++ b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorMysqlServiceTest.java
@@ -13,15 +13,15 @@ import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.service.common.MysqlServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class HerokuConnectorMysqlServiceTest extends AbstractHerokuConnectorRelationalServiceTest {
public HerokuConnectorMysqlServiceTest() {
- super("mysql");
+ super(MysqlServiceInfo.URI_SCHEME);
}
-
+
@Test
public void mysqlServiceCreation() {
Map env = new HashMap();
From 098a856523ab85261402c22c440657f6a3777fec Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:30:06 -0500
Subject: [PATCH 10/52] pull up Oracle URI scheme
---
.../cloud/cloudfoundry/OracleServiceInfoCreator.java | 2 +-
.../cloud/service/common/OracleServiceInfo.java | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/OracleServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/OracleServiceInfoCreator.java
index 1b8159f..1d82ab3 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/OracleServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/OracleServiceInfoCreator.java
@@ -4,7 +4,7 @@ import org.springframework.cloud.service.common.OracleServiceInfo;
public class OracleServiceInfoCreator extends RelationalServiceInfoCreator {
public OracleServiceInfoCreator() {
- super(new Tags(), "oracle");
+ super(new Tags(), OracleServiceInfo.URI_SCHEME);
}
@Override
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java
index 13e0f49..8aef0c4 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java
@@ -5,8 +5,10 @@ import org.springframework.cloud.service.ServiceInfo;
@ServiceInfo.ServiceLabel("oracle")
public class OracleServiceInfo extends RelationalServiceInfo {
+ public static final String URI_SCHEME = "oracle";
+
public OracleServiceInfo(String id, String url) {
- super(id, url, "oracle");
+ super(id, url, URI_SCHEME);
}
@Override
From a720ab12dc688735861ad2a824628610aaeb4a6b Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:37:23 -0500
Subject: [PATCH 11/52] pull up Postgres URI schema, split out JDBC URL
types--this should probably be done in the interface instead of ad-hocky
---
.../cloudfoundry/PostgresqlServiceInfoCreator.java | 4 ++--
...ractCloudFoundryConnectorRelationalServiceTest.java | 5 +++--
.../cloud/service/common/MysqlServiceInfo.java | 10 ++++++----
.../cloud/service/common/OracleServiceInfo.java | 6 ++++--
.../cloud/service/common/PostgresqlServiceInfo.java | 9 +++++++--
.../cloud/heroku/PostgresqlServiceInfoCreator.java | 4 ++--
.../heroku/HerokuConnectorPostgresqlServiceTest.java | 6 +++---
7 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java
index da8be3e..4b38fbf 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java
@@ -3,14 +3,14 @@ package org.springframework.cloud.cloudfoundry;
import org.springframework.cloud.service.common.PostgresqlServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class PostgresqlServiceInfoCreator extends RelationalServiceInfoCreator {
public PostgresqlServiceInfoCreator() {
- super(new Tags("postgresql"), "postgres");
+ super(new Tags("postgresql"), PostgresqlServiceInfo.URI_SCHEMA);
}
@Override
diff --git a/spring-cloud-cloudfoundry-connector/src/test/java/org/springframework/cloud/cloudfoundry/AbstractCloudFoundryConnectorRelationalServiceTest.java b/spring-cloud-cloudfoundry-connector/src/test/java/org/springframework/cloud/cloudfoundry/AbstractCloudFoundryConnectorRelationalServiceTest.java
index 35a790a..9588e50 100644
--- a/spring-cloud-cloudfoundry-connector/src/test/java/org/springframework/cloud/cloudfoundry/AbstractCloudFoundryConnectorRelationalServiceTest.java
+++ b/spring-cloud-cloudfoundry-connector/src/test/java/org/springframework/cloud/cloudfoundry/AbstractCloudFoundryConnectorRelationalServiceTest.java
@@ -1,7 +1,7 @@
package org.springframework.cloud.cloudfoundry;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@@ -20,12 +20,13 @@ public abstract class AbstractCloudFoundryConnectorRelationalServiceTest extends
}
protected static String getJdbcUrl(String databaseType, String name) {
+ // this should be cleaned up more broadly; pull into RelationalServiceInfo interface?
String jdbcUrlDatabaseType = databaseType;
if (databaseType.equals("postgres")) {
jdbcUrlDatabaseType = "postgresql";
}
- return "jdbc:" + jdbcUrlDatabaseType + "://" + hostname + ":" + port + "/" + name +
+ return "jdbc:" + jdbcUrlDatabaseType + "://" + hostname + ":" + port + "/" + name +
"?user=" + username + "&password=" + password;
}
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java
index 2eccab0..f4609eb 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java
@@ -10,9 +10,11 @@ import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
@ServiceLabel("mysql")
public class MysqlServiceInfo extends RelationalServiceInfo {
- public static final String URI_SCHEME = "mysql";
+ public static final String JDBC_URL_TYPE = "mysql";
- public MysqlServiceInfo(String id, String url) {
- super(id, url, URI_SCHEME);
- }
+ public static final String URI_SCHEME = JDBC_URL_TYPE;
+
+ public MysqlServiceInfo(String id, String url) {
+ super(id, url, URI_SCHEME);
+ }
}
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java
index 8aef0c4..6d2289d 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java
@@ -5,10 +5,12 @@ import org.springframework.cloud.service.ServiceInfo;
@ServiceInfo.ServiceLabel("oracle")
public class OracleServiceInfo extends RelationalServiceInfo {
- public static final String URI_SCHEME = "oracle";
+ public static final String JDBC_URL_TYPE = "oracle";
+
+ public static final String URI_SCHEME = JDBC_URL_TYPE;
public OracleServiceInfo(String id, String url) {
- super(id, url, URI_SCHEME);
+ super(id, url, JDBC_URL_TYPE);
}
@Override
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java
index 98e478c..2927782 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java
@@ -4,13 +4,18 @@ import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@ServiceLabel("postgresql")
public class PostgresqlServiceInfo extends RelationalServiceInfo {
+
+ public static final String JDBC_URL_TYPE = "postgresql";
+
+ public static final String URI_SCHEMA = "postgres";
+
public PostgresqlServiceInfo(String id, String url) {
- super(id, url, "postgresql");
+ super(id, url, JDBC_URL_TYPE);
}
}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java
index 57a4e67..7a44ea0 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java
@@ -3,14 +3,14 @@ package org.springframework.cloud.heroku;
import org.springframework.cloud.service.common.PostgresqlServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class PostgresqlServiceInfoCreator extends RelationalServiceInfoCreator {
public PostgresqlServiceInfoCreator() {
- super("postgres");
+ super(PostgresqlServiceInfo.URI_SCHEMA);
}
@Override
diff --git a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java
index 35bf83b..9915ffa 100644
--- a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java
+++ b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java
@@ -13,15 +13,15 @@ import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.service.common.PostgresqlServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class HerokuConnectorPostgresqlServiceTest extends AbstractHerokuConnectorRelationalServiceTest {
public HerokuConnectorPostgresqlServiceTest() {
- super("postgres");
+ super(PostgresqlServiceInfo.URI_SCHEMA);
}
-
+
@Test
public void postgresqlServiceCreation() {
Map env = new HashMap();
From b46aa7addfa2bfdfdcc03e9476aab6a17a8325bc Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:38:52 -0500
Subject: [PATCH 12/52] pull up Redis URI scheme
---
.../cloud/cloudfoundry/RedisServiceInfoCreator.java | 3 ++-
.../cloud/service/common/RedisServiceInfo.java | 9 ++++++---
.../cloud/heroku/RedisServiceInfoCreator.java | 4 ++--
3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/RedisServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/RedisServiceInfoCreator.java
index 75e6df1..f8fcfa3 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/RedisServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/RedisServiceInfoCreator.java
@@ -12,7 +12,8 @@ import org.springframework.cloud.service.common.RedisServiceInfo;
public class RedisServiceInfoCreator extends CloudFoundryServiceInfoCreator {
public RedisServiceInfoCreator() {
- super(new Tags("redis"), "redis");
+ // the literal in the tag is CloudFoundry-specific
+ super(new Tags("redis"), RedisServiceInfo.URI_SCHEME);
}
public RedisServiceInfo createServiceInfo(Map serviceData) {
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RedisServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RedisServiceInfo.java
index d31be25..ab35a8e 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RedisServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RedisServiceInfo.java
@@ -4,16 +4,19 @@ import org.springframework.cloud.service.UriBasedServiceInfo;
import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@ServiceLabel("redis")
public class RedisServiceInfo extends UriBasedServiceInfo {
+
+ public static final String URI_SCHEME = "redis";
+
public RedisServiceInfo(String id, String host, int port, String password) {
- super(id, "redis", host, port, null, password, null);
+ super(id, URI_SCHEME, host, port, null, password, null);
}
-
+
public RedisServiceInfo(String id, String uri) {
super(id, uri);
}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/RedisServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/RedisServiceInfoCreator.java
index cfa88ad..1757bd7 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/RedisServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/RedisServiceInfoCreator.java
@@ -3,14 +3,14 @@ package org.springframework.cloud.heroku;
import org.springframework.cloud.service.common.RedisServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class RedisServiceInfoCreator extends HerokuServiceInfoCreator {
public RedisServiceInfoCreator() {
- super("redis");
+ super(RedisServiceInfo.URI_SCHEME);
}
@Override
From 1748257f64f7db1fa8fde5382edaf7b0253a3c23 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:40:42 -0500
Subject: [PATCH 13/52] pull up SMTP URI scheme
---
.../cloud/cloudfoundry/SmtpServiceInfoCreator.java | 13 +++++++------
.../cloud/service/common/SmtpServiceInfo.java | 6 ++++--
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/SmtpServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/SmtpServiceInfoCreator.java
index ccf7560..10bd6e5 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/SmtpServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/SmtpServiceInfoCreator.java
@@ -6,7 +6,7 @@ import org.springframework.cloud.service.common.SmtpServiceInfo;
import org.springframework.cloud.util.UriInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@@ -15,16 +15,17 @@ public class SmtpServiceInfoCreator extends CloudFoundryServiceInfoCreator serviceData) {
String id = (String) serviceData.get("name");
-
+
@SuppressWarnings("unchecked")
Map credentials = (Map) serviceData.get("credentials");
String host = (String) credentials.get("hostname");
-
+
int port = DEFAULT_SMTP_PORT;
if (credentials.containsKey("port")) {
port = Integer.parseInt(credentials.get("port").toString());
@@ -33,8 +34,8 @@ public class SmtpServiceInfoCreator extends CloudFoundryServiceInfoCreator
Date: Thu, 10 Jul 2014 12:34:45 -0500
Subject: [PATCH 14/52] blank new module
---
settings.gradle | 3 +-
spring-cloud-localconfig-connector/.gitignore | 1 +
spring-cloud-localconfig-connector/README.md | 59 +++++++++++++++++++
.../build.gradle | 5 ++
4 files changed, 67 insertions(+), 1 deletion(-)
create mode 100644 spring-cloud-localconfig-connector/.gitignore
create mode 100644 spring-cloud-localconfig-connector/README.md
create mode 100644 spring-cloud-localconfig-connector/build.gradle
diff --git a/settings.gradle b/settings.gradle
index c22faa4..bc6b88f 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -3,4 +3,5 @@ rootProject.name = "spring-cloud"
include "${rootProject.name}-core"
include "${rootProject.name}-cloudfoundry-connector"
include "${rootProject.name}-spring-service-connector"
-include "${rootProject.name}-heroku-connector"
\ No newline at end of file
+include "${rootProject.name}-heroku-connector"
+include "${rootProject.name}-localconfig-connector"
diff --git a/spring-cloud-localconfig-connector/.gitignore b/spring-cloud-localconfig-connector/.gitignore
new file mode 100644
index 0000000..5e56e04
--- /dev/null
+++ b/spring-cloud-localconfig-connector/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/spring-cloud-localconfig-connector/README.md b/spring-cloud-localconfig-connector/README.md
new file mode 100644
index 0000000..f9788aa
--- /dev/null
+++ b/spring-cloud-localconfig-connector/README.md
@@ -0,0 +1,59 @@
+Local-configuration connector for Spring Cloud
+=======================================
+
+Provides the ability to configure Spring Cloud services locally for development or testing.
+The current implementation reads from Java properties only; in order to prevent dependencies
+on the Spring Framework, the placeholder functionality is unavailable in the connector.
+Pull requests for also inspecting environment variables are welcome.
+
+Property sources
+----------------
+This connector first attempts to read the system properties generally and a property named
+`spring.cloud.propertiesFile` specifically. If the system properties are not readable
+(the security manager denies `checkPropertiesAccess`), then they will be treated as empty.
+If a system property named `spring.cloud.propertiesFile` is found, that file will be loaded
+as a property list.
+
+###Programmatically supplying properties
+You can programmatically supply a property source by calling the static method
+`LocalConfigConnector.supplyProperties(InputStream)` before invoking `getCloud()`.
+Calling this method will cause the connector to read the stream as a property list
+and then close the stream. Calling this method after invoking `getCloud()` will
+still read the stream, but the properties will have no effect on the connector
+service configuration. Calling this method multiple times will load the supplied
+streams onto the same `Properties` object, overwriting duplicates.
+
+###Property order
+To provide the maximum configuration flexibility, the connector will scan the available
+property sources in this order:
+
+- programmatically-supplied properties
+- properties read from `spring.cloud.propertiesFile`
+- system properties
+
+The last definition of a specific service ID wins. The connector will log a message at
+`INFO` to notify of service overrides for the same type of service and at `WARN` if you
+override a service ID with a URI to a different type of service.
+
+Activating the connector
+------------------------
+The Spring Cloud core expects exactly one cloud connector to return `true` for
+`isInMatchingCloud()`. This connector identifies the "local cloud" by the presence of
+a property named `spring.cloud.appId`, which will be used in the `ApplicationInstanceInfo`.
+
+Service definitions
+-------------------
+If the connector is activated, it will iterate through all the available properties
+for keys matching the pattern `spring.cloud.{serviceId}`. Each value is interpreted as a URI
+to the services, and the type of service is determined from the scheme. All of the standard
+`UriBasedServiceInfo`s are supported.
+
+Supporting additional services
+------------------------------
+Please see the documentation for [cloudfoundry-connector](../spring-cloud-cloudfoundry-connector), since the same
+mechanism applies to any cloud connector.
+
+Instance ID
+-----------
+This connector will create a UUID for use as the instance ID, as Java does not provide
+any portable mechanism for reliably determining hostnames or PIDs.
\ No newline at end of file
diff --git a/spring-cloud-localconfig-connector/build.gradle b/spring-cloud-localconfig-connector/build.gradle
new file mode 100644
index 0000000..eb5f5b6
--- /dev/null
+++ b/spring-cloud-localconfig-connector/build.gradle
@@ -0,0 +1,5 @@
+description = 'Spring Cloud local-configuration connector'
+
+dependencies {
+ compile project(':spring-cloud-core')
+}
From b8bd6989440bc2e34164f2a5dc061ab9ef785d1b Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Thu, 10 Jul 2014 13:17:43 -0500
Subject: [PATCH 15/52] pull up fallback BaseServiceInfo creator (just a
generic KVP creator)
---
.../service/FallbackBaseServiceInfoCreator.java | 11 +++++++++++
.../cloud/heroku/HerokuConnector.java | 12 +++---------
2 files changed, 14 insertions(+), 9 deletions(-)
create mode 100644 spring-cloud-core/src/main/java/org/springframework/cloud/service/FallbackBaseServiceInfoCreator.java
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/FallbackBaseServiceInfoCreator.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/FallbackBaseServiceInfoCreator.java
new file mode 100644
index 0000000..23a815a
--- /dev/null
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/FallbackBaseServiceInfoCreator.java
@@ -0,0 +1,11 @@
+package org.springframework.cloud.service;
+
+import org.springframework.cloud.FallbackServiceInfoCreator;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
+
+public class FallbackBaseServiceInfoCreator extends FallbackServiceInfoCreator {
+ @Override
+ public BaseServiceInfo createServiceInfo(KeyValuePair serviceData) {
+ return new BaseServiceInfo(serviceData.getKey());
+ }
+}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java
index ac39931..ab91ba0 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java
@@ -12,6 +12,7 @@ import org.springframework.cloud.FallbackServiceInfoCreator;
import org.springframework.cloud.ServiceInfoCreator;
import org.springframework.cloud.app.ApplicationInstanceInfo;
import org.springframework.cloud.service.BaseServiceInfo;
+import org.springframework.cloud.service.FallbackBaseServiceInfoCreator;
import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.util.EnvironmentAccessor;
@@ -95,13 +96,6 @@ public class HerokuConnector extends AbstractCloudConnector {
@Override
protected FallbackServiceInfoCreator getFallbackServiceInfoCreator() {
- return new HerokuFallbackServiceInfoCreator();
+ return new FallbackBaseServiceInfoCreator();
}
-}
-
-class HerokuFallbackServiceInfoCreator extends FallbackServiceInfoCreator {
- @Override
- public BaseServiceInfo createServiceInfo(KeyValuePair serviceData) {
- return new BaseServiceInfo(serviceData.getKey());
- }
-}
+}
\ No newline at end of file
From c9fbf933316a6e90bebbc302a0d2e4fe72a3b5fb Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Thu, 10 Jul 2014 16:18:31 -0500
Subject: [PATCH 16/52] initial local-config connector implementation; provides
ServiceData, still needs converters to ServiceInfo
---
spring-cloud-localconfig-connector/README.md | 5 +-
.../build.gradle | 1 +
.../localconfig/LocalConfigConnector.java | 187 ++++++++++++++++++
.../LocalConfigServiceInfoCreator.java | 11 ++
.../cloud/localconfig/LocalConfigUtil.java | 81 ++++++++
.../localconfig/LocalConfigConnectorTest.java | 145 ++++++++++++++
.../localconfig/LocalConfigUtilTest.java | 74 +++++++
.../src/test/resources/localconfig.properties | 3 +
8 files changed, 504 insertions(+), 3 deletions(-)
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigServiceInfoCreator.java
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigUtilTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
diff --git a/spring-cloud-localconfig-connector/README.md b/spring-cloud-localconfig-connector/README.md
index f9788aa..1f04dc9 100644
--- a/spring-cloud-localconfig-connector/README.md
+++ b/spring-cloud-localconfig-connector/README.md
@@ -8,7 +8,7 @@ Pull requests for also inspecting environment variables are welcome.
Property sources
----------------
-This connector first attempts to read the system properties generally and a property named
+This connector first attempts to read the system properties generally and a system property named
`spring.cloud.propertiesFile` specifically. If the system properties are not readable
(the security manager denies `checkPropertiesAccess`), then they will be treated as empty.
If a system property named `spring.cloud.propertiesFile` is found, that file will be loaded
@@ -32,8 +32,7 @@ property sources in this order:
- system properties
The last definition of a specific service ID wins. The connector will log a message at
-`INFO` to notify of service overrides for the same type of service and at `WARN` if you
-override a service ID with a URI to a different type of service.
+`WARN` if you override a service ID.
Activating the connector
------------------------
diff --git a/spring-cloud-localconfig-connector/build.gradle b/spring-cloud-localconfig-connector/build.gradle
index eb5f5b6..d020bde 100644
--- a/spring-cloud-localconfig-connector/build.gradle
+++ b/spring-cloud-localconfig-connector/build.gradle
@@ -2,4 +2,5 @@ description = 'Spring Cloud local-configuration connector'
dependencies {
compile project(':spring-cloud-core')
+ testCompile 'com.github.stefanbirkner:system-rules:1.5.0'
}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
new file mode 100644
index 0000000..93bb25f
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
@@ -0,0 +1,187 @@
+package org.springframework.cloud.localconfig;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+import org.springframework.cloud.AbstractCloudConnector;
+import org.springframework.cloud.FallbackServiceInfoCreator;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
+import org.springframework.cloud.app.ApplicationInstanceInfo;
+import org.springframework.cloud.app.BasicApplicationInstanceInfo;
+import org.springframework.cloud.service.BaseServiceInfo;
+import org.springframework.cloud.service.FallbackBaseServiceInfoCreator;
+
+/**
+ *
+ * @author Christopher Smith
+ *
+ */
+public class LocalConfigConnector extends AbstractCloudConnector {
+
+ private static final Logger logger = Logger.getLogger(LocalConfigConnector.class.getName());
+
+ /*--------------- String constants for property keys ---------------*/
+
+ public static final String PROPERTY_PREFIX = "spring.cloud.";
+
+ public static final Pattern SERVICE_PROPERTY_PATTERN = Pattern.compile("\\A" + Pattern.quote(PROPERTY_PREFIX) + "(.+)" + "\\Z");
+
+ public static final String APP_ID_PROPERTY = PROPERTY_PREFIX + "appId";
+
+ public static final String PROPERTIES_FILE_PROPERTY = PROPERTY_PREFIX + "propertiesFile";
+
+ /**
+ * These properties configure the connector itself and aren't service definitions.
+ */
+ public static final List META_PROPERTIES = Collections.unmodifiableList(
+ Arrays.asList(new String[] { APP_ID_PROPERTY, PROPERTIES_FILE_PROPERTY }));
+
+ /*--------------- sources for service-definition properties ---------------*/
+
+ static Properties programmaticProperties = new Properties();
+
+ private Properties fileProperties = null;
+
+ /*--------------- API implementation ---------------*/
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public LocalConfigConnector() {
+ super((Class) LocalConfigServiceInfoCreator.class);
+ }
+
+ /**
+ * Returns {@code true} if a property named {@code spring.cloud.appId} is present in any of the property sources.
+ * On the first call, attempts to load properties from a file specified in {@code spring.cloud.propertiesFile}.
+ */
+ @Override
+ public boolean isInMatchingCloud() {
+ if (fileProperties == null)
+ readFileProperties();
+
+ return findProperty(APP_ID_PROPERTY) != null;
+ }
+
+ @Override
+ public ApplicationInstanceInfo getApplicationInstanceInfo() {
+ return new BasicApplicationInstanceInfo(UUID.randomUUID().toString(), findProperty(APP_ID_PROPERTY),
+ Collections. emptyMap());
+ }
+
+ @Override
+ protected List getServicesData() {
+ LinkedHashMap propertySources = new LinkedHashMap();
+
+ propertySources.put("programmatic properties", programmaticProperties);
+ propertySources.put("properties from file", fileProperties);
+ try {
+ propertySources.put("system properties", System.getProperties());
+ } catch (SecurityException e) {
+ logger.log(Level.WARNING,
+ "couldn't read system properties; no service definitions from system properties will be applied", e);
+ }
+
+ return LocalConfigUtil.readServicesData(propertySources);
+ }
+
+ @Override
+ protected FallbackServiceInfoCreator getFallbackServiceInfoCreator() {
+ return new FallbackBaseServiceInfoCreator();
+ }
+
+ /*--------------- methods for manipulating properties and sources ---------------*/
+
+ /**
+ * Adds properties to be scanned from the supplied {@link InputStream}, overwriting
+ * existing properties with the same name. Closes the stream after loading.
+ *
+ * @param propertiesInputStream
+ * a property list
+ * @throws IOException
+ * if the underlying load operation throws an exception
+ */
+ public static void supplyProperties(final InputStream propertiesInputStream) throws IOException {
+ programmaticProperties.load(propertiesInputStream);
+ propertiesInputStream.close();
+ }
+
+ /**
+ * Checks for the presence of a supplied or system property named {@code spring.cloud.propertiesFile}. If the property
+ * is present, load its contents into {@link #fileProperties}. If there's a problem, log but continue.
+ */
+ private void readFileProperties() {
+ fileProperties = new Properties();
+ logger.fine("looking for a properties file");
+
+ String filename = null;
+
+ filename = programmaticProperties.getProperty(PROPERTIES_FILE_PROPERTY);
+
+ try {
+ filename = System.getProperty(PROPERTIES_FILE_PROPERTY, filename);
+ } catch (SecurityException e) {
+ logSystemReadException(PROPERTIES_FILE_PROPERTY, e);
+ return;
+ }
+
+ if (filename == null) {
+ logger.info("did not find a system property " + PROPERTIES_FILE_PROPERTY);
+ return;
+ }
+
+ logger.info("loading properties from file " + filename);
+
+ try {
+ InputStream fis = openFile(filename);
+ fileProperties.load(fis);
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "exception while loading properties from file " + filename, e);
+ return;
+ }
+
+ logger.info("properties loaded successfully");
+ }
+
+ /**
+ * Broken out into a separate method for mocking the filesystem.
+ * @param filename the file to open
+ * @return a {@code FileInputStream} to the file
+ * @throws IOException if opening the file throws
+ */
+ InputStream openFile(String filename) throws IOException {
+ return new FileInputStream(filename);
+ }
+
+ /**
+ * Look for a specific property in programmatically-supplied properties, properties from a file,
+ * or the system properties. Last source wins.
+ *
+ * @param key
+ * the property to look for
+ * @return the highest-priority value for the key, or {@code null} if the key is not found
+ */
+ private String findProperty(String key) {
+ String value = programmaticProperties.getProperty(key);
+ value = fileProperties.getProperty(key, value);
+ try {
+ value = System.getProperty(key, value);
+ } catch (SecurityException e) {
+ logSystemReadException(key, e);
+ }
+
+ return value;
+ }
+
+ private static void logSystemReadException(String key, SecurityException e) {
+ logger.log(Level.WARNING, "couldn't read system property " + key, e);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigServiceInfoCreator.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigServiceInfoCreator.java
new file mode 100644
index 0000000..98a8669
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigServiceInfoCreator.java
@@ -0,0 +1,11 @@
+package org.springframework.cloud.localconfig;
+
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.UriBasedServiceInfoCreator;
+
+public abstract class LocalConfigServiceInfoCreator extends UriBasedServiceInfoCreator {
+
+ protected LocalConfigServiceInfoCreator(String uriScheme) {
+ super(uriScheme);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
new file mode 100644
index 0000000..bd4d9f3
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
@@ -0,0 +1,81 @@
+package org.springframework.cloud.localconfig;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
+
+public final class LocalConfigUtil {
+ private static final Logger logger = Logger.getLogger(LocalConfigConnector.class.getName());
+
+ private LocalConfigUtil() {
+ }
+
+ static List readServicesData(LinkedHashMap propertySources) {
+ // we'll turn this into KVPs to return but need to eliminate duplicates first
+ Map collectedServices = new HashMap();
+
+ // iterate over the property sources in order, extracting matching properties
+ for (Map.Entry propertySource : propertySources.entrySet()) {
+ logger.info("reading services from " + propertySource.getValue());
+ Map services = readServices(propertySource.getValue());
+
+ // add each of the found services to the list, warning about duplicates
+ for (Map.Entry service : services.entrySet()) {
+ String oldUri = collectedServices.put(service.getKey(), service.getValue());
+ if (oldUri == null)
+ logger.info("added service '" + service.getKey() + "' from " + propertySource.getKey());
+ else
+ logger.warning("replaced service '" + service.getKey() + "' with new URI from " + propertySource.getKey());
+ }
+ }
+
+ // now we have a collated set of service IDs and URIs
+ List serviceData = new ArrayList(collectedServices.size());
+ for (Map.Entry serviceInfo : collectedServices.entrySet()) {
+ serviceData.add(new KeyValuePair(serviceInfo.getKey(), serviceInfo.getValue()));
+ }
+
+ return serviceData;
+ }
+
+ /**
+ * Goes through a {@code Properties} object, finding all service definitions (properties
+ * prefixed with {@code spring.cloud.} but not in {@code META_PROPERTIES}) and collects {@code (id,URI)} pairs.
+ *
+ * @param properties
+ * the {@code Properties} object to read
+ * @return all of the service definitions found
+ */
+ static Map readServices(Properties properties) {
+ Map services = new HashMap();
+
+ for (String propertyName : properties.stringPropertyNames()) {
+ if (LocalConfigConnector.META_PROPERTIES.contains(propertyName)) {
+ logger.finer("skipping meta property " + propertyName);
+ continue;
+ }
+
+ Matcher m = LocalConfigConnector.SERVICE_PROPERTY_PATTERN.matcher(propertyName);
+ if (!m.matches()) {
+ logger.finest("skipping non-Spring-Cloud property " + propertyName);
+ continue;
+ }
+
+ String serviceId = m.group(1);
+ String serviceUri = properties.getProperty(propertyName);
+
+ // no URI here because they will contain passwords
+ logger.fine("found service URI for service " + serviceId);
+ services.put(serviceId, serviceUri);
+ }
+
+ return services;
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
new file mode 100644
index 0000000..394e851
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
@@ -0,0 +1,145 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Properties;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.ClearSystemProperties;
+import org.junit.contrib.java.lang.system.ProvideSystemProperty;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
+
+public class LocalConfigConnectorTest {
+
+ static final Charset UTF_8 = Charset.forName("UTF-8");
+
+ public static final String APP_ID_1 = "appId1";
+ public static final String APP_ID_1_PROPERTY = LocalConfigConnector.APP_ID_PROPERTY + ": " + APP_ID_1;
+
+ public static final String APP_ID_2 = "appId2";
+ public static final String APP_ID_2_PROPERTY = LocalConfigConnector.APP_ID_PROPERTY + ": " + APP_ID_2;
+
+ public static final String PROPERTY_FILE_NAME = "propFile";
+ public static final String PROPERTY_FILE_PROPERTY = LocalConfigConnector.PROPERTIES_FILE_PROPERTY + ": " + PROPERTY_FILE_NAME;
+
+ public static class AppIdTest {
+
+ private LocalConfigConnector connector;
+
+ @Before
+ public void setup() {
+ connector = new LocalConfigConnector();
+ }
+
+ @After
+ public void clearProperties() {
+ LocalConfigConnector.programmaticProperties = new Properties();
+ }
+
+ @Rule
+ public final ClearSystemProperties NO_APP_ID_PROPERTY = new ClearSystemProperties(LocalConfigConnector.APP_ID_PROPERTY);
+
+ @Test
+ public void testNoAppIdAnywhere() {
+ assertFalse(connector.isInMatchingCloud());
+ }
+
+ @Test
+ public void testProgrammaticAppId() throws IOException {
+ LocalConfigConnector.supplyProperties(new ByteArrayInputStream(APP_ID_1_PROPERTY.getBytes(UTF_8)));
+ assertTrue(connector.isInMatchingCloud());
+ assertEquals(APP_ID_1, connector.getApplicationInstanceInfo().getAppId());
+ }
+
+ @Test
+ public void testProgrammaticAndFileAppIds() throws IOException {
+ LocalConfigConnector.supplyProperties(new ByteArrayInputStream(APP_ID_1_PROPERTY.getBytes(UTF_8)));
+ LocalConfigConnector.supplyProperties(new ByteArrayInputStream(PROPERTY_FILE_PROPERTY.getBytes(UTF_8)));
+
+ LocalConfigConnector stubConnector = new LocalConfigConnector() {
+ @Override
+ InputStream openFile(String filename) throws IOException {
+ assertEquals(PROPERTY_FILE_NAME, filename);
+ return new ByteArrayInputStream(APP_ID_2_PROPERTY.getBytes(UTF_8));
+ };
+ };
+
+ assertTrue(stubConnector.isInMatchingCloud());
+ assertEquals(APP_ID_2, stubConnector.getApplicationInstanceInfo().getAppId());
+ }
+
+ @Test
+ public void testProgrammaticFilenamePlusSystemAppId() throws IOException {
+ LocalConfigConnector.supplyProperties(new ByteArrayInputStream(PROPERTY_FILE_PROPERTY.getBytes(UTF_8)));
+
+ LocalConfigConnector stubConnector = new LocalConfigConnector() {
+ @Override
+ InputStream openFile(String filename) throws IOException {
+ assertEquals(PROPERTY_FILE_NAME, filename);
+ return new ByteArrayInputStream(APP_ID_2_PROPERTY.getBytes(UTF_8));
+ };
+ };
+
+ System.setProperty(LocalConfigConnector.APP_ID_PROPERTY, "helloApp");
+ assertTrue(stubConnector.isInMatchingCloud());
+ assertEquals("helloApp", stubConnector.getApplicationInstanceInfo().getAppId());
+ }
+ }
+
+ private LocalConfigConnector connector;
+
+ InputStream propertiesFile;
+
+ @Before
+ public void setup() {
+ connector = new LocalConfigConnector();
+ propertiesFile = LocalConfigConnectorTest.class.getClassLoader().getResourceAsStream("localconfig.properties");
+ }
+
+ @After
+ public void cleanup() throws IOException {
+ LocalConfigConnector.programmaticProperties = new Properties();
+ propertiesFile.close();
+ }
+
+ @Test
+ public void testLoadFromFile() throws IOException {
+ LocalConfigConnector.supplyProperties(propertiesFile);
+
+ assertTrue(connector.isInMatchingCloud());
+ assertEquals("testApp", connector.getApplicationInstanceInfo().getAppId());
+
+ List services = connector.getServicesData();
+ assertEquals(2, services.size());
+ for (KeyValuePair service : services)
+ if ("foo".equals(service.getKey()))
+ assertEquals("bar", service.getValue());
+ }
+
+ @Rule
+ public ProvideSystemProperty BAZ_PROPERTY = new ProvideSystemProperty("spring.cloud.baz", "inline!");
+
+ @Test
+ public void testLoadFromInputStreamWithOverride() throws IOException {
+ LocalConfigConnector.supplyProperties(propertiesFile);
+
+ assertTrue(connector.isInMatchingCloud());
+ assertEquals("testApp", connector.getApplicationInstanceInfo().getAppId());
+
+ List services = connector.getServicesData();
+ assertEquals(2, services.size());
+ for(KeyValuePair service: services)
+ if("baz".equals(service.getKey()))
+ assertEquals("inline!", service.getValue());
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigUtilTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigUtilTest.java
new file mode 100644
index 0000000..10eaa58
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigUtilTest.java
@@ -0,0 +1,74 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.*;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
+
+public class LocalConfigUtilTest {
+
+ private Properties first, second;
+
+ private LinkedHashMap propertySources;
+
+ @Before
+ public void initProperties(){
+ first = new Properties();
+ second = new Properties();
+
+ propertySources = new LinkedHashMap();
+ propertySources.put("first", first);
+ propertySources.put("second", second);
+ }
+
+ @Test
+ public void testPropertyParsing() {
+ first.setProperty("spring.cloud.appId", "should skip me because I'm meta");
+ first.setProperty("spring.cloud.service1", "one");
+ first.setProperty("spring.cloud.", "should skip me because I don't have an ID");
+ first.setProperty("spring.cloud.service.two", "two");
+ first.setProperty("foobar", "should skip me because I don't match the prefix");
+
+ Map services = LocalConfigUtil.readServices(first);
+ assertEquals(2, services.size());
+ assertEquals("one", services.get("service1"));
+ assertEquals("two", services.get("service.two"));
+ }
+
+ @Test
+ public void testCollation() {
+ first.setProperty("spring.cloud.first", "firstUri");
+ second.setProperty("spring.cloud.second", "secondUri");
+
+ List serviceData = LocalConfigUtil.readServicesData(propertySources);
+ assertEquals(2, serviceData.size());
+ boolean foundFirst = false;
+
+ for(KeyValuePair kvp : serviceData) {
+ if(kvp.getKey().equals("first")) {
+ assertEquals("firstUri", kvp.getValue());
+ foundFirst = true;
+ }
+ }
+
+ assertTrue(foundFirst);
+ }
+
+ @Test
+ public void testOverride() {
+ first.setProperty("spring.cloud.duplicate", "firstUri");
+ second.setProperty("spring.cloud.duplicate", "secondUri");
+
+ List serviceData = LocalConfigUtil.readServicesData(propertySources);
+ assertEquals(1, serviceData.size());
+ KeyValuePair kvp = serviceData.get(0);
+ assertEquals("duplicate", kvp.getKey());
+ assertEquals("secondUri", kvp.getValue());
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties b/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
new file mode 100644
index 0000000..bcc84c3
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
@@ -0,0 +1,3 @@
+spring.cloud.appId: testApp
+spring.cloud.foo: bar
+spring.cloud.baz: quux
\ No newline at end of file
From 0c9c2b5ad500525f6c03d5388ef1294f17f229b5 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Thu, 10 Jul 2014 16:23:37 -0500
Subject: [PATCH 17/52] typo in constant name
---
.../cloud/cloudfoundry/PostgresqlServiceInfoCreator.java | 2 +-
.../cloud/service/common/PostgresqlServiceInfo.java | 2 +-
.../cloud/heroku/PostgresqlServiceInfoCreator.java | 2 +-
.../cloud/heroku/HerokuConnectorPostgresqlServiceTest.java | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java
index 4b38fbf..abfbde1 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java
@@ -10,7 +10,7 @@ import org.springframework.cloud.service.common.PostgresqlServiceInfo;
public class PostgresqlServiceInfoCreator extends RelationalServiceInfoCreator {
public PostgresqlServiceInfoCreator() {
- super(new Tags("postgresql"), PostgresqlServiceInfo.URI_SCHEMA);
+ super(new Tags("postgresql"), PostgresqlServiceInfo.URI_SCHEME);
}
@Override
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java
index 2927782..edcace5 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java
@@ -13,7 +13,7 @@ public class PostgresqlServiceInfo extends RelationalServiceInfo {
public static final String JDBC_URL_TYPE = "postgresql";
- public static final String URI_SCHEMA = "postgres";
+ public static final String URI_SCHEME = "postgres";
public PostgresqlServiceInfo(String id, String url) {
super(id, url, JDBC_URL_TYPE);
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java
index 7a44ea0..70f47de 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java
@@ -10,7 +10,7 @@ import org.springframework.cloud.service.common.PostgresqlServiceInfo;
public class PostgresqlServiceInfoCreator extends RelationalServiceInfoCreator {
public PostgresqlServiceInfoCreator() {
- super(PostgresqlServiceInfo.URI_SCHEMA);
+ super(PostgresqlServiceInfo.URI_SCHEME);
}
@Override
diff --git a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java
index 9915ffa..52d7398 100644
--- a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java
+++ b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java
@@ -19,7 +19,7 @@ import org.springframework.cloud.service.common.PostgresqlServiceInfo;
*/
public class HerokuConnectorPostgresqlServiceTest extends AbstractHerokuConnectorRelationalServiceTest {
public HerokuConnectorPostgresqlServiceTest() {
- super(PostgresqlServiceInfo.URI_SCHEMA);
+ super(PostgresqlServiceInfo.URI_SCHEME);
}
@Test
From 7fd502d707a354130592c07f874709748249f8cb Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Thu, 10 Jul 2014 16:28:06 -0500
Subject: [PATCH 18/52] document Java version requirement
---
spring-cloud-core/README.md | 40 +++++++++++++++++++------------------
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/spring-cloud-core/README.md b/spring-cloud-core/README.md
index 52c4d45..80233e4 100644
--- a/spring-cloud-core/README.md
+++ b/spring-cloud-core/README.md
@@ -2,10 +2,12 @@ Spring Cloud Core Library
=========================
The core library to let cloud applications access application information and services.
-While Spring applications is one of the main target for this library, it may be used in
+While Spring applications is one of the main target for this library, it may be used in
non-Spring projects as well. In fact, **this library doesn't even depend on Spring**.
-This library is cloud-agnostic. Through connectors, it supports multiple clouds
+This library requires Java 6,
+
+This library is cloud-agnostic. Through connectors, it supports multiple clouds
(with Cloud Foundry and Heroku as the example clouds).
This library also supports an extension to create services connectors of user-desired types.
@@ -13,11 +15,11 @@ This library also supports an extension to create services connectors of user-de
Usage pattern: Application Developers
=====================================
-> **Note:** If you are using spring-cloud in a Spring application, you should consider using the
-[Java config](../spring-cloud-spring-service-connector#the-java-config) or the
+> **Note:** If you are using spring-cloud in a Spring application, you should consider using the
+[Java config](../spring-cloud-spring-service-connector#the-java-config) or the
[XML namespace support](../spring-cloud-spring-service-connector#the-cloud-namespace) instead.
-* Create a [`CloudFactory`](src/main/java/org/springframework/cloud/CloudFactory.java) instance.
+* Create a [`CloudFactory`](src/main/java/org/springframework/cloud/CloudFactory.java) instance.
Creation of a `CloudFactory` instance is a bit expensive, so caching such an instance is recommended.
If you are using a dependency injection frameworks such as Spring, creating a bean for `CloudFactory`
will achieve the caching effect.
@@ -25,45 +27,45 @@ Usage pattern: Application Developers
```java
CloudFactory cloudFactory = new CloudFactory();
```
-* Obtain a suitable [`Cloud`](src/main/java/org/springframework/cloud/Cloud.java) for the environment
+* Obtain a suitable [`Cloud`](src/main/java/org/springframework/cloud/Cloud.java) for the environment
in which the application is running.
-
+
```java
Cloud cloud = cloudFactory.getCloud();
```
Note that you must have a `CloudConnector` implementation suitable
for the environment in which the application is being deployed in your classpath. For example, if you are
- deploying the application in Cloud Foundry, you must add [cloudfoundry-connector](../spring-cloud-cloudfoundry-connector)
+ deploying the application in Cloud Foundry, you must add [cloudfoundry-connector](../spring-cloud-cloudfoundry-connector)
in your classpath. If no suitable `CloudConnctor` is found, the `getCloud()` method will throw a `CloudException`.
-* Use the `Cloud` instance to get access to application info, service infos, and create service
+* Use the `Cloud` instance to get access to application info, service infos, and create service
connectors.
```java
// ServiceInfo has all the information necessary to connect to the underlying service
cloud.getServiceInfos();
```
-
+
```java
// Alternatively, let the cloud create a service connector for you
DataSource ds = cloud.getServiceConnector("inventory-db", DataSource.class, null /* default config */);
```
-
+
Usage pattern: Cloud and Service Providers
==========================================
A cloud provider may extends the functionality in two ways:
-1. Add new [`CloudConnector`](src/main/java/org/springframework/cloud/CloudConnector.java)s to make
- spring-cloud related libraries work with a new cloud.
- See [cloudfoundry-connector](../spring-cloud-cloudfoundry-connector)
- or [heroku-connector](../spring-cloud-heroku-connector) for an example.
+1. Add new [`CloudConnector`](src/main/java/org/springframework/cloud/CloudConnector.java)s to make
+ spring-cloud related libraries work with a new cloud.
+ See [cloudfoundry-connector](../spring-cloud-cloudfoundry-connector)
+ or [heroku-connector](../spring-cloud-heroku-connector) for an example.
This is done declaratively by adding connector classes to:
```
META-INF/services/org.springframework.cloud.CloudConnector
```
-2. Add new [`ServiceConnectorCreator`](src/main/java/org/springframework/cloud/service/ServiceConnectorCreator.java)s
- to allow creation of service connector objects.
- See [spring-service-connector](../spring-cloud-spring-service-connector) for an example.
- This is done declaratively by adding creator classes to:
+2. Add new [`ServiceConnectorCreator`](src/main/java/org/springframework/cloud/service/ServiceConnectorCreator.java)s
+ to allow creation of service connector objects.
+ See [spring-service-connector](../spring-cloud-spring-service-connector) for an example.
+ This is done declaratively by adding creator classes to:
```
META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator
```
\ No newline at end of file
From 8afa0cdcbd7d3e30ad320b37ef8e419632bd8c49 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Thu, 10 Jul 2014 17:01:14 -0500
Subject: [PATCH 19/52] add ServiceInfoCreators and SPI control files
---
.../localconfig/AmqpServiceInfoCreator.java | 20 +++++++++++++++++++
.../localconfig/MongoServiceInfoCreator.java | 20 +++++++++++++++++++
.../localconfig/MysqlServiceInfoCreator.java | 20 +++++++++++++++++++
.../PostgresqlServiceInfoCreator.java | 20 +++++++++++++++++++
.../localconfig/RedisServiceInfoCreator.java | 20 +++++++++++++++++++
.../org.springframework.cloud.CloudConnector | 1 +
....localconfig.LocalConfigServiceInfoCreator | 5 +++++
7 files changed, 106 insertions(+)
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/AmqpServiceInfoCreator.java
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MongoServiceInfoCreator.java
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MysqlServiceInfoCreator.java
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/PostgresqlServiceInfoCreator.java
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/RedisServiceInfoCreator.java
create mode 100644 spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.CloudConnector
create mode 100644 spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/AmqpServiceInfoCreator.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/AmqpServiceInfoCreator.java
new file mode 100644
index 0000000..b9dc631
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/AmqpServiceInfoCreator.java
@@ -0,0 +1,20 @@
+package org.springframework.cloud.localconfig;
+
+import org.springframework.cloud.service.common.AmqpServiceInfo;
+
+/**
+ *
+ * @author Christopher Smith
+ *
+ */
+public class AmqpServiceInfoCreator extends LocalConfigServiceInfoCreator{
+
+ public AmqpServiceInfoCreator() {
+ super(AmqpServiceInfo.URI_SCHEME);
+ }
+
+ @Override
+ public AmqpServiceInfo createServiceInfo(String id, String uri) {
+ return new AmqpServiceInfo(id, uri);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MongoServiceInfoCreator.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MongoServiceInfoCreator.java
new file mode 100644
index 0000000..68671ac
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MongoServiceInfoCreator.java
@@ -0,0 +1,20 @@
+package org.springframework.cloud.localconfig;
+
+import org.springframework.cloud.service.common.MongoServiceInfo;
+
+/**
+ *
+ * @author Christopher Smith
+ *
+ */
+public class MongoServiceInfoCreator extends LocalConfigServiceInfoCreator{
+
+ public MongoServiceInfoCreator() {
+ super(MongoServiceInfo.URI_SCHEME);
+ }
+
+ @Override
+ public MongoServiceInfo createServiceInfo(String id, String uri) {
+ return new MongoServiceInfo(id, uri);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MysqlServiceInfoCreator.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MysqlServiceInfoCreator.java
new file mode 100644
index 0000000..0d39262
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MysqlServiceInfoCreator.java
@@ -0,0 +1,20 @@
+package org.springframework.cloud.localconfig;
+
+import org.springframework.cloud.service.common.MysqlServiceInfo;
+
+/**
+ *
+ * @author Christopher Smith
+ *
+ */
+public class MysqlServiceInfoCreator extends LocalConfigServiceInfoCreator{
+
+ public MysqlServiceInfoCreator() {
+ super(MysqlServiceInfo.URI_SCHEME);
+ }
+
+ @Override
+ public MysqlServiceInfo createServiceInfo(String id, String uri) {
+ return new MysqlServiceInfo(id, uri);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/PostgresqlServiceInfoCreator.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/PostgresqlServiceInfoCreator.java
new file mode 100644
index 0000000..282da2f
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/PostgresqlServiceInfoCreator.java
@@ -0,0 +1,20 @@
+package org.springframework.cloud.localconfig;
+
+import org.springframework.cloud.service.common.PostgresqlServiceInfo;
+
+/**
+ *
+ * @author Christopher Smith
+ *
+ */
+public class PostgresqlServiceInfoCreator extends LocalConfigServiceInfoCreator{
+
+ public PostgresqlServiceInfoCreator() {
+ super(PostgresqlServiceInfo.URI_SCHEME);
+ }
+
+ @Override
+ public PostgresqlServiceInfo createServiceInfo(String id, String uri) {
+ return new PostgresqlServiceInfo(id, uri);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/RedisServiceInfoCreator.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/RedisServiceInfoCreator.java
new file mode 100644
index 0000000..7a9e06f
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/RedisServiceInfoCreator.java
@@ -0,0 +1,20 @@
+package org.springframework.cloud.localconfig;
+
+import org.springframework.cloud.service.common.RedisServiceInfo;
+
+/**
+ *
+ * @author Christopher Smith
+ *
+ */
+public class RedisServiceInfoCreator extends LocalConfigServiceInfoCreator{
+
+ public RedisServiceInfoCreator() {
+ super(RedisServiceInfo.URI_SCHEME);
+ }
+
+ @Override
+ public RedisServiceInfo createServiceInfo(String id, String uri) {
+ return new RedisServiceInfo(id, uri);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.CloudConnector b/spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.CloudConnector
new file mode 100644
index 0000000..2a7adb6
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.CloudConnector
@@ -0,0 +1 @@
+org.springframework.cloud.localconfig.LocalConfigConnector
\ No newline at end of file
diff --git a/spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator b/spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator
new file mode 100644
index 0000000..f8a14d4
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator
@@ -0,0 +1,5 @@
+org.springframework.cloud.localconfig.AmqpServiceInfoCreator
+org.springframework.cloud.localconfig.MongoServiceInfoCreator
+org.springframework.cloud.localconfig.MysqlServiceInfoCreator
+org.springframework.cloud.localconfig.PostgresqlServiceInfoCreator
+org.springframework.cloud.localconfig.RedisServiceInfoCreator
\ No newline at end of file
From eb080ce4afc6e1503f748a9cf69b4bb01dfa55d0 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 15:34:38 -0500
Subject: [PATCH 20/52] rename test case for clarity
---
.../cloud/localconfig/LocalConfigConnectorTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
index 394e851..40b3913 100644
--- a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
@@ -32,7 +32,7 @@ public class LocalConfigConnectorTest {
public static final String PROPERTY_FILE_NAME = "propFile";
public static final String PROPERTY_FILE_PROPERTY = LocalConfigConnector.PROPERTIES_FILE_PROPERTY + ": " + PROPERTY_FILE_NAME;
- public static class AppIdTest {
+ public static class DetectAppIdTest {
private LocalConfigConnector connector;
From 7a686ab0c421e718dbc7c34a0d4af2af4510a30f Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 15:38:09 -0500
Subject: [PATCH 21/52] move property file name into constant, rename
---
.../cloud/localconfig/LocalConfigConnectorTest.java | 4 ++--
.../src/test/resources/localconfig.nonsense.properties | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
create mode 100644 spring-cloud-localconfig-connector/src/test/resources/localconfig.nonsense.properties
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
index 40b3913..dd75a33 100644
--- a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
@@ -29,7 +29,7 @@ public class LocalConfigConnectorTest {
public static final String APP_ID_2 = "appId2";
public static final String APP_ID_2_PROPERTY = LocalConfigConnector.APP_ID_PROPERTY + ": " + APP_ID_2;
- public static final String PROPERTY_FILE_NAME = "propFile";
+ public static final String PROPERTY_FILE_NAME = "localconfig.nonsense.properties";
public static final String PROPERTY_FILE_PROPERTY = LocalConfigConnector.PROPERTIES_FILE_PROPERTY + ": " + PROPERTY_FILE_NAME;
public static class DetectAppIdTest {
@@ -103,7 +103,7 @@ public class LocalConfigConnectorTest {
@Before
public void setup() {
connector = new LocalConfigConnector();
- propertiesFile = LocalConfigConnectorTest.class.getClassLoader().getResourceAsStream("localconfig.properties");
+ propertiesFile = LocalConfigConnectorTest.class.getClassLoader().getResourceAsStream(PROPERTY_FILE_NAME);
}
@After
diff --git a/spring-cloud-localconfig-connector/src/test/resources/localconfig.nonsense.properties b/spring-cloud-localconfig-connector/src/test/resources/localconfig.nonsense.properties
new file mode 100644
index 0000000..bcc84c3
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/resources/localconfig.nonsense.properties
@@ -0,0 +1,3 @@
+spring.cloud.appId: testApp
+spring.cloud.foo: bar
+spring.cloud.baz: quux
\ No newline at end of file
From 5b95a2b616595aff129a6e07e0ca2d40039699e0 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 16:00:08 -0500
Subject: [PATCH 22/52] constant wasn't final
---
.../cloud/heroku/AbstractHerokuConnectorTest.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/AbstractHerokuConnectorTest.java b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/AbstractHerokuConnectorTest.java
index 7b88bf9..576dcfc 100644
--- a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/AbstractHerokuConnectorTest.java
+++ b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/AbstractHerokuConnectorTest.java
@@ -10,7 +10,7 @@ import org.springframework.cloud.util.EnvironmentAccessor;
/**
* Base test class that provides setup and utility methods to generate test payload
- *
+ *
* @author Ramnivas Laddad
*
*/
@@ -20,7 +20,7 @@ public abstract class AbstractHerokuConnectorTest {
protected static final String hostname = "10.20.30.40";
protected static final int port = 1234;
- protected static String username = "myuser";
+ protected static final String username = "myuser";
protected static final String password = "mypass";
@Before
@@ -28,7 +28,7 @@ public abstract class AbstractHerokuConnectorTest {
MockitoAnnotations.initMocks(this);
testCloudConnector.setCloudEnvironment(mockEnvironment);
}
-
+
protected static ServiceInfo getServiceInfo(List serviceInfos, String serviceId) {
for (ServiceInfo serviceInfo : serviceInfos) {
if (serviceInfo.getId().equals(serviceId)) {
From 1a782670b1a8a7d2648a94b88b826ab104e27496 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 16:18:29 -0500
Subject: [PATCH 23/52] add getScheme() and a useful toString()
---
.../cloud/service/UriBasedServiceInfo.java | 146 ++++++++++--------
1 file changed, 79 insertions(+), 67 deletions(-)
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfo.java
index 78828de..fda552c 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfo.java
@@ -6,84 +6,96 @@ import org.springframework.cloud.util.UriInfoFactory;
/**
* Common class for all {@link ServiceInfo}s
- *
+ *
* @author Ramnivas Laddad
*
*/
public abstract class UriBasedServiceInfo extends BaseServiceInfo {
- private UriInfo uriInfo;
+ private UriInfo uriInfo;
- private static UriInfoFactory uriFactory = new StandardUriInfoFactory();
+ private static UriInfoFactory uriFactory = new StandardUriInfoFactory();
- public UriBasedServiceInfo(String id, String scheme, String host, int port, String username, String password, String path) {
- super(id);
- this.uriInfo = getUriInfoFactory().createUri(scheme, host, port, username, password, path);
- this.uriInfo = validateAndCleanUriInfo(uriInfo);
- }
-
- public UriBasedServiceInfo(String id, String uriString) {
- super(id);
- this.uriInfo = getUriInfoFactory().createUri(uriString);
- this.uriInfo = validateAndCleanUriInfo(uriInfo);
- }
+ public UriBasedServiceInfo(String id, String scheme, String host, int port, String username, String password, String path) {
+ super(id);
+ this.uriInfo = getUriInfoFactory().createUri(scheme, host, port, username, password, path);
+ this.uriInfo = validateAndCleanUriInfo(uriInfo);
+ }
- /**
- * For URI-based (@link ServiceInfo}s which don't conform to the standard URI
- * format, override this method in your own ServiceInfo class to return a
- * {@link UriInfoFactory} which will create the appropriate URIs.
- *
- * @return your special UriInfoFactory
- */
- public UriInfoFactory getUriInfoFactory() {
- return uriFactory;
- }
+ public UriBasedServiceInfo(String id, String uriString) {
+ super(id);
+ this.uriInfo = getUriInfoFactory().createUri(uriString);
+ this.uriInfo = validateAndCleanUriInfo(uriInfo);
+ }
- @ServiceProperty(category="connection")
- public String getUri() {
- return uriInfo.getUri().toString();
- }
-
- @ServiceProperty(category="connection")
- public String getUserName() {
- return uriInfo.getUserName();
- }
-
- @ServiceProperty(category="connection")
- public String getPassword() {
- return uriInfo.getPassword();
- }
+ /**
+ * For URI-based (@link ServiceInfo}s which don't conform to the standard URI
+ * format, override this method in your own ServiceInfo class to return a {@link UriInfoFactory} which will create the
+ * appropriate URIs.
+ *
+ * @return your special UriInfoFactory
+ */
+ public UriInfoFactory getUriInfoFactory() {
+ return uriFactory;
+ }
- @ServiceProperty(category="connection")
- public String getHost() {
- return uriInfo.getHost();
- }
+ @ServiceProperty(category = "connection")
+ public String getUri() {
+ return uriInfo.getUri().toString();
+ }
- @ServiceProperty(category="connection")
- public int getPort() {
- return uriInfo.getPort();
- }
+ @ServiceProperty(category = "connection")
+ public String getUserName() {
+ return uriInfo.getUserName();
+ }
- @ServiceProperty(category="connection")
- public String getPath() {
- return uriInfo.getPath();
- }
+ @ServiceProperty(category = "connection")
+ public String getPassword() {
+ return uriInfo.getPassword();
+ }
- @ServiceProperty(category="connection")
- public String getQuery() {
- return uriInfo.getQuery();
- }
+ @ServiceProperty(category = "connection")
+ public String getHost() {
+ return uriInfo.getHost();
+ }
- /**
- * Validate the URI and clean it up by using defaults for any missing information, if possible.
- *
- * @param uriInfo uri info based on parsed payload
- * @return cleaned up uri info
- */
- protected UriInfo validateAndCleanUriInfo(UriInfo uriInfo) {
- return uriInfo;
- }
-
- protected UriInfo getUriInfo() {
- return uriInfo;
- }
+ @ServiceProperty(category = "connection")
+ public int getPort() {
+ return uriInfo.getPort();
+ }
+
+ @ServiceProperty(category = "connection")
+ public String getPath() {
+ return uriInfo.getPath();
+ }
+
+ @ServiceProperty(category = "connection")
+ public String getQuery() {
+ return uriInfo.getQuery();
+ }
+
+ @ServiceProperty(category = "connection")
+ public String getScheme() {
+ return uriInfo.getScheme();
+ }
+
+ /**
+ * Validate the URI and clean it up by using defaults for any missing information, if possible.
+ *
+ * @param uriInfo
+ * uri info based on parsed payload
+ * @return cleaned up uri info
+ */
+ protected UriInfo validateAndCleanUriInfo(UriInfo uriInfo) {
+ return uriInfo;
+ }
+
+ protected UriInfo getUriInfo() {
+ return uriInfo;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "[" + getScheme() + "://" + getUserName() + ":****@" + getHost() + ":" + getPort()
+ + "/" + getPath() + "]";
+ }
}
From e7ddcadb9adc3c946d004521040a0bdeaab52449 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 16:28:09 -0500
Subject: [PATCH 24/52] tests for all ServiceInfoCreators
---
.../localconfig/LocalConfigConnector.java | 3 ++
.../cloud/localconfig/LocalConfigUtil.java | 6 ++-
.../AbstractLocalConfigConnectorTest.java | 54 +++++++++++++++++++
.../LocalConfigConnectorAmqpServiceTest.java | 23 ++++++++
.../LocalConfigConnectorMongoServiceTest.java | 23 ++++++++
.../LocalConfigConnectorMysqlServiceTest.java | 23 ++++++++
...lConfigConnectorPostgresqlServiceTest.java | 23 ++++++++
.../LocalConfigConnectorRedisServiceTest.java | 23 ++++++++
.../src/test/resources/localconfig.properties | 3 --
.../resources/localconfig.testuris.properties | 6 +++
10 files changed, 183 insertions(+), 4 deletions(-)
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/AbstractLocalConfigConnectorTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorAmqpServiceTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMongoServiceTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMysqlServiceTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorPostgresqlServiceTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorRedisServiceTest.java
delete mode 100644 spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
create mode 100644 spring-cloud-localconfig-connector/src/test/resources/localconfig.testuris.properties
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
index 93bb25f..babc2c0 100644
--- a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
@@ -79,6 +79,9 @@ public class LocalConfigConnector extends AbstractCloudConnector {
@Override
protected List getServicesData() {
+ if(fileProperties == null)
+ throw new IllegalStateException("isInMatchingCloud() must be called first to initialize connector");
+
LinkedHashMap propertySources = new LinkedHashMap();
propertySources.put("programmatic properties", programmaticProperties);
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
index bd4d9f3..c2a4e82 100644
--- a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
@@ -23,7 +23,11 @@ public final class LocalConfigUtil {
// iterate over the property sources in order, extracting matching properties
for (Map.Entry propertySource : propertySources.entrySet()) {
- logger.info("reading services from " + propertySource.getValue());
+ if(propertySource.getValue().isEmpty()) {
+ logger.info("no " + propertySource.getKey());
+ continue;
+ }
+ logger.info("reading services from " + propertySource.getKey());
Map services = readServices(propertySource.getValue());
// add each of the found services to the list, warning about duplicates
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/AbstractLocalConfigConnectorTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/AbstractLocalConfigConnectorTest.java
new file mode 100644
index 0000000..9313717
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/AbstractLocalConfigConnectorTest.java
@@ -0,0 +1,54 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Properties;
+
+import org.junit.After;
+import org.junit.Before;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.UriBasedServiceInfo;
+
+public class AbstractLocalConfigConnectorTest {
+
+ public static final String PROPERTIES_FILE = "localconfig.testuris.properties";
+
+ protected LocalConfigConnector connector = new LocalConfigConnector();
+
+ protected static final String HOSTNAME = "10.20.30.40";
+ protected static final int PORT = 1234;
+ protected static final String USERNAME = "myuser";
+ protected static final String PASSWORD = "mypass";
+
+ @Before
+ public void init() throws IOException {
+ InputStream propertiesFile = getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
+ LocalConfigConnector.supplyProperties(propertiesFile);
+ assertTrue(connector.isInMatchingCloud());
+ }
+
+ @After
+ public void clearProperties() {
+ LocalConfigConnector.programmaticProperties = new Properties();
+ }
+
+ protected static ServiceInfo getServiceInfo(List serviceInfos, String serviceId) {
+ for (ServiceInfo serviceInfo : serviceInfos) {
+ if (serviceInfo.getId().equals(serviceId)) {
+ return serviceInfo;
+ }
+ }
+ return null;
+ }
+
+ protected static void assertUriParameters(UriBasedServiceInfo serviceInfo) {
+ assertEquals(HOSTNAME, serviceInfo.getHost());
+ assertEquals(PORT, serviceInfo.getPort());
+ assertEquals(USERNAME, serviceInfo.getUserName());
+ assertEquals(PASSWORD, serviceInfo.getPassword());
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorAmqpServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorAmqpServiceTest.java
new file mode 100644
index 0000000..a515741
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorAmqpServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.AmqpServiceInfo;
+
+public class LocalConfigConnectorAmqpServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "rabbit");
+ assertNotNull(service);
+ assertTrue(service instanceof AmqpServiceInfo);
+ assertUriParameters((AmqpServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMongoServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMongoServiceTest.java
new file mode 100644
index 0000000..5fec86f
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMongoServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.MongoServiceInfo;
+
+public class LocalConfigConnectorMongoServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "candygram");
+ assertNotNull(service);
+ assertTrue(service instanceof MongoServiceInfo);
+ assertUriParameters((MongoServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMysqlServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMysqlServiceTest.java
new file mode 100644
index 0000000..4e305dd
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMysqlServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.MysqlServiceInfo;
+
+public class LocalConfigConnectorMysqlServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "maria");
+ assertNotNull(service);
+ assertTrue(service instanceof MysqlServiceInfo);
+ assertUriParameters((MysqlServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorPostgresqlServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorPostgresqlServiceTest.java
new file mode 100644
index 0000000..13123a5
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorPostgresqlServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.PostgresqlServiceInfo;
+
+public class LocalConfigConnectorPostgresqlServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "ingres");
+ assertNotNull(service);
+ assertTrue(service instanceof PostgresqlServiceInfo);
+ assertUriParameters((PostgresqlServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorRedisServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorRedisServiceTest.java
new file mode 100644
index 0000000..29dd550
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorRedisServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.RedisServiceInfo;
+
+public class LocalConfigConnectorRedisServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "blue");
+ assertNotNull(service);
+ assertTrue(service instanceof RedisServiceInfo);
+ assertUriParameters((RedisServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties b/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
deleted file mode 100644
index bcc84c3..0000000
--- a/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-spring.cloud.appId: testApp
-spring.cloud.foo: bar
-spring.cloud.baz: quux
\ No newline at end of file
diff --git a/spring-cloud-localconfig-connector/src/test/resources/localconfig.testuris.properties b/spring-cloud-localconfig-connector/src/test/resources/localconfig.testuris.properties
new file mode 100644
index 0000000..94bb5d9
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/resources/localconfig.testuris.properties
@@ -0,0 +1,6 @@
+spring.cloud.appId: testAppWithUris
+spring.cloud.rabbit: amqp://myuser:mypass@10.20.30.40:1234/queue
+spring.cloud.maria: mysql://myuser:mypass@10.20.30.40:1234/dbname
+spring.cloud.candygram: mongodb://myuser:mypass@10.20.30.40:1234/dbname
+spring.cloud.ingres: postgres://myuser:mypass@10.20.30.40:1234/dbname
+spring.cloud.blue: redis://myuser:mypass@10.20.30.40:1234/dbname
\ No newline at end of file
From 646a99fb34668b08becd56d7ede40de5d598cfc6 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 16:28:09 -0500
Subject: [PATCH 25/52] tests for all ServiceInfoCreators
fixes #45
---
.../localconfig/LocalConfigConnector.java | 3 ++
.../cloud/localconfig/LocalConfigUtil.java | 6 ++-
.../AbstractLocalConfigConnectorTest.java | 54 +++++++++++++++++++
.../LocalConfigConnectorAmqpServiceTest.java | 23 ++++++++
.../LocalConfigConnectorMongoServiceTest.java | 23 ++++++++
.../LocalConfigConnectorMysqlServiceTest.java | 23 ++++++++
...lConfigConnectorPostgresqlServiceTest.java | 23 ++++++++
.../LocalConfigConnectorRedisServiceTest.java | 23 ++++++++
.../src/test/resources/localconfig.properties | 3 --
.../resources/localconfig.testuris.properties | 6 +++
10 files changed, 183 insertions(+), 4 deletions(-)
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/AbstractLocalConfigConnectorTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorAmqpServiceTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMongoServiceTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMysqlServiceTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorPostgresqlServiceTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorRedisServiceTest.java
delete mode 100644 spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
create mode 100644 spring-cloud-localconfig-connector/src/test/resources/localconfig.testuris.properties
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
index 93bb25f..babc2c0 100644
--- a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
@@ -79,6 +79,9 @@ public class LocalConfigConnector extends AbstractCloudConnector {
@Override
protected List getServicesData() {
+ if(fileProperties == null)
+ throw new IllegalStateException("isInMatchingCloud() must be called first to initialize connector");
+
LinkedHashMap propertySources = new LinkedHashMap();
propertySources.put("programmatic properties", programmaticProperties);
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
index bd4d9f3..c2a4e82 100644
--- a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
@@ -23,7 +23,11 @@ public final class LocalConfigUtil {
// iterate over the property sources in order, extracting matching properties
for (Map.Entry propertySource : propertySources.entrySet()) {
- logger.info("reading services from " + propertySource.getValue());
+ if(propertySource.getValue().isEmpty()) {
+ logger.info("no " + propertySource.getKey());
+ continue;
+ }
+ logger.info("reading services from " + propertySource.getKey());
Map services = readServices(propertySource.getValue());
// add each of the found services to the list, warning about duplicates
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/AbstractLocalConfigConnectorTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/AbstractLocalConfigConnectorTest.java
new file mode 100644
index 0000000..9313717
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/AbstractLocalConfigConnectorTest.java
@@ -0,0 +1,54 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Properties;
+
+import org.junit.After;
+import org.junit.Before;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.UriBasedServiceInfo;
+
+public class AbstractLocalConfigConnectorTest {
+
+ public static final String PROPERTIES_FILE = "localconfig.testuris.properties";
+
+ protected LocalConfigConnector connector = new LocalConfigConnector();
+
+ protected static final String HOSTNAME = "10.20.30.40";
+ protected static final int PORT = 1234;
+ protected static final String USERNAME = "myuser";
+ protected static final String PASSWORD = "mypass";
+
+ @Before
+ public void init() throws IOException {
+ InputStream propertiesFile = getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
+ LocalConfigConnector.supplyProperties(propertiesFile);
+ assertTrue(connector.isInMatchingCloud());
+ }
+
+ @After
+ public void clearProperties() {
+ LocalConfigConnector.programmaticProperties = new Properties();
+ }
+
+ protected static ServiceInfo getServiceInfo(List serviceInfos, String serviceId) {
+ for (ServiceInfo serviceInfo : serviceInfos) {
+ if (serviceInfo.getId().equals(serviceId)) {
+ return serviceInfo;
+ }
+ }
+ return null;
+ }
+
+ protected static void assertUriParameters(UriBasedServiceInfo serviceInfo) {
+ assertEquals(HOSTNAME, serviceInfo.getHost());
+ assertEquals(PORT, serviceInfo.getPort());
+ assertEquals(USERNAME, serviceInfo.getUserName());
+ assertEquals(PASSWORD, serviceInfo.getPassword());
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorAmqpServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorAmqpServiceTest.java
new file mode 100644
index 0000000..a515741
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorAmqpServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.AmqpServiceInfo;
+
+public class LocalConfigConnectorAmqpServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "rabbit");
+ assertNotNull(service);
+ assertTrue(service instanceof AmqpServiceInfo);
+ assertUriParameters((AmqpServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMongoServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMongoServiceTest.java
new file mode 100644
index 0000000..5fec86f
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMongoServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.MongoServiceInfo;
+
+public class LocalConfigConnectorMongoServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "candygram");
+ assertNotNull(service);
+ assertTrue(service instanceof MongoServiceInfo);
+ assertUriParameters((MongoServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMysqlServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMysqlServiceTest.java
new file mode 100644
index 0000000..4e305dd
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMysqlServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.MysqlServiceInfo;
+
+public class LocalConfigConnectorMysqlServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "maria");
+ assertNotNull(service);
+ assertTrue(service instanceof MysqlServiceInfo);
+ assertUriParameters((MysqlServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorPostgresqlServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorPostgresqlServiceTest.java
new file mode 100644
index 0000000..13123a5
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorPostgresqlServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.PostgresqlServiceInfo;
+
+public class LocalConfigConnectorPostgresqlServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "ingres");
+ assertNotNull(service);
+ assertTrue(service instanceof PostgresqlServiceInfo);
+ assertUriParameters((PostgresqlServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorRedisServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorRedisServiceTest.java
new file mode 100644
index 0000000..29dd550
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorRedisServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.RedisServiceInfo;
+
+public class LocalConfigConnectorRedisServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "blue");
+ assertNotNull(service);
+ assertTrue(service instanceof RedisServiceInfo);
+ assertUriParameters((RedisServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties b/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
deleted file mode 100644
index bcc84c3..0000000
--- a/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-spring.cloud.appId: testApp
-spring.cloud.foo: bar
-spring.cloud.baz: quux
\ No newline at end of file
diff --git a/spring-cloud-localconfig-connector/src/test/resources/localconfig.testuris.properties b/spring-cloud-localconfig-connector/src/test/resources/localconfig.testuris.properties
new file mode 100644
index 0000000..94bb5d9
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/resources/localconfig.testuris.properties
@@ -0,0 +1,6 @@
+spring.cloud.appId: testAppWithUris
+spring.cloud.rabbit: amqp://myuser:mypass@10.20.30.40:1234/queue
+spring.cloud.maria: mysql://myuser:mypass@10.20.30.40:1234/dbname
+spring.cloud.candygram: mongodb://myuser:mypass@10.20.30.40:1234/dbname
+spring.cloud.ingres: postgres://myuser:mypass@10.20.30.40:1234/dbname
+spring.cloud.blue: redis://myuser:mypass@10.20.30.40:1234/dbname
\ No newline at end of file
From f392a80a90af9697df51ebf25a5a942f51281907 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 16:41:18 -0500
Subject: [PATCH 26/52] Add test to override programmatic definition from
system properties.
fixes #45
---
.../LocalConfigServiceOverrideTest.java | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigServiceOverrideTest.java
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigServiceOverrideTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigServiceOverrideTest.java
new file mode 100644
index 0000000..980067a
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigServiceOverrideTest.java
@@ -0,0 +1,34 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.ProvideSystemProperty;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.MongoServiceInfo;
+
+public class LocalConfigServiceOverrideTest extends AbstractLocalConfigConnectorTest {
+
+ @Rule
+ public final ProvideSystemProperty OVERRIDE_MYSQL =
+ new ProvideSystemProperty(
+ "spring.cloud.candygram",
+ "mongodb://youruser:yourpass@40.30.20.10:4321/dbname");
+
+ @Test
+ public void serviceOverride() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "candygram");
+ assertNotNull(service);
+ assertTrue(service instanceof MongoServiceInfo);
+ MongoServiceInfo mongo = (MongoServiceInfo) service;
+ assertEquals("youruser", mongo.getUserName());
+ assertEquals(4321, mongo.getPort());
+ }
+
+}
From ad74820e36fae2700b8f5be396578b0883bb00b6 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 16:57:17 -0500
Subject: [PATCH 27/52] improved documentation
---
spring-cloud-localconfig-connector/README.md | 22 ++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/spring-cloud-localconfig-connector/README.md b/spring-cloud-localconfig-connector/README.md
index 1f04dc9..128d2c3 100644
--- a/spring-cloud-localconfig-connector/README.md
+++ b/spring-cloud-localconfig-connector/README.md
@@ -6,6 +6,28 @@ The current implementation reads from Java properties only; in order to prevent
on the Spring Framework, the placeholder functionality is unavailable in the connector.
Pull requests for also inspecting environment variables are welcome.
+Quick start
+-----------
+Since service URIs contain passwords and should not be stored in code, this connector does not
+attempt to read properties out of the classpath. You can provide a filename with service definitions
+by setting the `spring.cloud.propertiesFile` property or by passing in an open `InputStream`:
+
+````java
+InputStream propertyStream = new FileInputStream("/path/to/spring-cloud.properties");
+LocalConfigConnector.supplyProperties(propertyStream);
+Cloud cloud = new CloudFactory().getCloud();
+````
+
+The property file should contain an application ID and the desired services in this format:
+
+````properties
+spring.cloud.appId: myApp
+; spring.cloud.{id}: URI
+spring.cloud.database: mysql://user:pass@host:1234/dbname
+````
+
+Service type is determined by the URI scheme.
+
Property sources
----------------
This connector first attempts to read the system properties generally and a system property named
From 99302432e94400d6f1c8dee2e04085ee970a44ef Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:06:07 -0500
Subject: [PATCH 28/52] pull up KeyValuePair class from HerokuConnector to
AbstractCloudConnector
---
.../cloud/AbstractCloudConnector.java | 34 ++++++++++---
.../cloud/heroku/HerokuConnector.java | 50 ++++++-------------
.../heroku/HerokuServiceInfoCreator.java | 20 ++++----
3 files changed, 52 insertions(+), 52 deletions(-)
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/AbstractCloudConnector.java b/spring-cloud-core/src/main/java/org/springframework/cloud/AbstractCloudConnector.java
index 6a73afa..a515766 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/AbstractCloudConnector.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/AbstractCloudConnector.java
@@ -10,25 +10,25 @@ import org.springframework.cloud.service.ServiceInfo;
/**
* Helper abstract class to simplify {@link CloudConnector} implementations.
- *
+ *
* User the {@link ServiceLoader} approach to looks for file name matching the class passed in constructor
* and registers {@link ServiceInfoCreator} found there.
- *
+ *
* Implementation of {@link CloudConnector}s that wish to support the recommended service scanning approach
* should extends this approach to gain that functionality automatically.
- *
+ *
* @author Ramnivas Laddad
*
*/
public abstract class AbstractCloudConnector implements CloudConnector {
private static Logger logger = Logger.getLogger(AbstractCloudConnector.class.getName());
-
+
protected List> serviceInfoCreators = new ArrayList>();
protected abstract List getServicesData();
protected abstract FallbackServiceInfoCreator,SD> getFallbackServiceInfoCreator();
-
+
public AbstractCloudConnector(Class extends ServiceInfoCreator extends ServiceInfo, ?>> serviceInfoCreatorClass) {
scanServiceInfoCreators(serviceInfoCreatorClass);
}
@@ -39,7 +39,7 @@ public abstract class AbstractCloudConnector implements CloudConnector {
for (SD serviceData : getServicesData()) {
serviceInfos.add(getServiceInfo(serviceData));
}
-
+
return serviceInfos;
}
@@ -54,18 +54,36 @@ public abstract class AbstractCloudConnector implements CloudConnector {
registerServiceInfoCreator(serviceInfoCreator);
}
}
-
+
private ServiceInfo getServiceInfo(SD serviceData) {
for (ServiceInfoCreator extends ServiceInfo,SD> serviceInfoCreator : serviceInfoCreators) {
if (serviceInfoCreator.accept(serviceData)) {
return serviceInfoCreator.createServiceInfo(serviceData);
}
}
-
+
// Fallback with a warning
ServiceInfo fallackServiceInfo = getFallbackServiceInfoCreator().createServiceInfo(serviceData);
logger.warning("No suitable service info creator found for service " + fallackServiceInfo.getId()
+ " Did you forget to add a ServiceInfoCreator?");
return fallackServiceInfo;
}
+
+ public static class KeyValuePair {
+ private final String key;
+ private final String value;
+
+ public KeyValuePair(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+ }
}
\ No newline at end of file
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java
index 374b7f8..ac39931 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java
@@ -6,30 +6,30 @@ import java.util.List;
import java.util.Map;
import org.springframework.cloud.AbstractCloudConnector;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
import org.springframework.cloud.CloudException;
import org.springframework.cloud.FallbackServiceInfoCreator;
import org.springframework.cloud.ServiceInfoCreator;
import org.springframework.cloud.app.ApplicationInstanceInfo;
-import org.springframework.cloud.heroku.HerokuConnector.KeyValuePair;
import org.springframework.cloud.service.BaseServiceInfo;
import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.util.EnvironmentAccessor;
/**
* Implementation of CloudConnector for Heroku
- *
+ *
* Currently support Postgres (default provided), Mysql (Cleardb), MongoDb (MongoLab, MongoHQ, MongoSoup),
* Redis (RedisToGo, RedisCloud, OpenRedis, RedisGreen), and AMQP (CloudAmqp).
- *
+ *
* @author Ramnivas Laddad
*
*/
-public class HerokuConnector extends AbstractCloudConnector {
+public class HerokuConnector extends AbstractCloudConnector {
private EnvironmentAccessor environment = new EnvironmentAccessor();
- private ApplicationInstanceInfoCreator applicationInstanceInfoCreator
+ private ApplicationInstanceInfoCreator applicationInstanceInfoCreator
= new ApplicationInstanceInfoCreator(environment);
-
+
private List serviceEnvPrefixes;
@SuppressWarnings({ "unchecked", "rawtypes" })
@@ -41,28 +41,28 @@ public class HerokuConnector extends AbstractCloudConnector serviceInfoCreator) {
+ protected void registerServiceInfoCreator(ServiceInfoCreator extends ServiceInfo, KeyValuePair> serviceInfoCreator) {
super.registerServiceInfoCreator(serviceInfoCreator);
HerokuServiceInfoCreator> herokuServiceInfoCreator = (HerokuServiceInfoCreator>)serviceInfoCreator;
String[] envPrefixes = herokuServiceInfoCreator.getEnvPrefixes();
-
+
// need to do this since this method gets called during construction and we cannot initialize serviceEnvPrefixes before this
if (serviceEnvPrefixes == null) {
serviceEnvPrefixes = new ArrayList();
@@ -75,17 +75,17 @@ public class HerokuConnector extends AbstractCloudConnector
* Returns map whose key is the env key and value is the associated url
*
- * @return information about services bound to the app
+ * @return information about services bound to the app
*/
protected List getServicesData() {
List serviceData = new ArrayList();
-
+
Map env = environment.getEnv();
-
+
for (Map.Entry envEntry : env.entrySet()) {
for (String envPrefix : serviceEnvPrefixes) {
if (envEntry.getKey().startsWith(envPrefix)) {
- serviceData.add(new KeyValuePair(envEntry.getKey(), envEntry.getValue()));
+ serviceData.add(new KeyValuePair(envEntry.getKey(), envEntry.getValue()));
}
}
}
@@ -97,24 +97,6 @@ public class HerokuConnector extends AbstractCloudConnector getFallbackServiceInfoCreator() {
return new HerokuFallbackServiceInfoCreator();
}
-
- public static class KeyValuePair {
- private String key;
- private String value;
-
- public KeyValuePair(String key, String value) {
- this.key = key;
- this.value = value;
- }
-
- public String getKey() {
- return key;
- }
-
- public String getValue() {
- return value;
- }
- }
}
class HerokuFallbackServiceInfoCreator extends FallbackServiceInfoCreator {
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java
index 15ed4aa..00b6c6b 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java
@@ -1,11 +1,11 @@
package org.springframework.cloud.heroku;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
import org.springframework.cloud.ServiceInfoCreator;
-import org.springframework.cloud.heroku.HerokuConnector.KeyValuePair;
import org.springframework.cloud.service.ServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@@ -16,25 +16,25 @@ public abstract class HerokuServiceInfoCreator implement
public HerokuServiceInfoCreator(String urlProtocol) {
this.urlProtocol = urlProtocol;
}
-
+
public boolean accept(KeyValuePair serviceData) {
return serviceData.getValue().toString().startsWith(urlProtocol + "://");
}
-
+
public abstract SI createServiceInfo(String id, String uri);
-
+
public SI createServiceInfo(KeyValuePair serviceData) {
return createServiceInfo(serviceData.getKey(), serviceData.getValue());
}
-
+
/**
* Get prefixes for env variable with which the associated {@link ServiceInfo} may be created.
- *
+ *
* Unlike CloudFoundry which exposes VCAP_SERVICES as a single environment to encompass all services bound
* to the app, Heroku expose one environment variable per app. This method allows each info creator to declare
- * appropriate env variables.
- *
- * @return prefixes for the relevant environment variables
+ * appropriate env variables.
+ *
+ * @return prefixes for the relevant environment variables
*/
public abstract String[] getEnvPrefixes();
}
From 83245841b362d670792a6b35e59ef635032535f9 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:13:49 -0500
Subject: [PATCH 29/52] pull up URI-based common functionality into core
abstract base class
---
.../service/UriBasedServiceInfoCreator.java | 26 +++++++++++++++++++
.../heroku/HerokuServiceInfoCreator.java | 21 +++------------
2 files changed, 30 insertions(+), 17 deletions(-)
create mode 100644 spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfoCreator.java
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfoCreator.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfoCreator.java
new file mode 100644
index 0000000..b856bc0
--- /dev/null
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfoCreator.java
@@ -0,0 +1,26 @@
+package org.springframework.cloud.service;
+
+import org.springframework.cloud.ServiceInfoCreator;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
+
+public abstract class UriBasedServiceInfoCreator implements
+ ServiceInfoCreator {
+
+ private final String uriScheme;
+
+ public UriBasedServiceInfoCreator(String uriScheme) {
+ this.uriScheme = uriScheme;
+ }
+
+ @Override
+ public boolean accept(KeyValuePair serviceData) {
+ return serviceData.getValue().toString().startsWith(uriScheme + "://");
+ }
+
+ public abstract SI createServiceInfo(String id, String uri);
+
+ @Override
+ public SI createServiceInfo(KeyValuePair serviceData) {
+ return createServiceInfo(serviceData.getKey(), serviceData.getValue());
+ }
+}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java
index 00b6c6b..81094eb 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuServiceInfoCreator.java
@@ -1,30 +1,17 @@
package org.springframework.cloud.heroku;
-import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
-import org.springframework.cloud.ServiceInfoCreator;
import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.UriBasedServiceInfoCreator;
/**
*
* @author Ramnivas Laddad
*
*/
-public abstract class HerokuServiceInfoCreator implements ServiceInfoCreator {
+public abstract class HerokuServiceInfoCreator extends UriBasedServiceInfoCreator {
- private String urlProtocol;
-
- public HerokuServiceInfoCreator(String urlProtocol) {
- this.urlProtocol = urlProtocol;
- }
-
- public boolean accept(KeyValuePair serviceData) {
- return serviceData.getValue().toString().startsWith(urlProtocol + "://");
- }
-
- public abstract SI createServiceInfo(String id, String uri);
-
- public SI createServiceInfo(KeyValuePair serviceData) {
- return createServiceInfo(serviceData.getKey(), serviceData.getValue());
+ public HerokuServiceInfoCreator(String uriScheme) {
+ super(uriScheme);
}
/**
From 5ce0b402bfc3b9269469252949669855099f97e1 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:23:36 -0500
Subject: [PATCH 30/52] constant for MongoDB URI scheme
---
.../cloud/cloudfoundry/MongoServiceInfoCreator.java | 4 ++--
.../cloud/service/common/MongoServiceInfo.java | 11 +++++++----
.../cloud/heroku/MongoServiceInfoCreator.java | 4 ++--
3 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MongoServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MongoServiceInfoCreator.java
index 5aeace5..ac963c5 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MongoServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MongoServiceInfoCreator.java
@@ -12,8 +12,8 @@ import org.springframework.cloud.service.common.MongoServiceInfo;
public class MongoServiceInfoCreator extends CloudFoundryServiceInfoCreator {
public MongoServiceInfoCreator() {
- super(new Tags("mongodb"), "mongodb");
-
+ // the literal in the tag is CloudFoundry-specific
+ super(new Tags("mongodb"), MongoServiceInfo.URI_SCHEME);
}
public MongoServiceInfo createServiceInfo(Map serviceData) {
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MongoServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MongoServiceInfo.java
index b45800f..a332b65 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MongoServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MongoServiceInfo.java
@@ -4,23 +4,26 @@ import org.springframework.cloud.service.UriBasedServiceInfo;
import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@ServiceLabel("mongo")
public class MongoServiceInfo extends UriBasedServiceInfo {
+
+ public static final String URI_SCHEME = "mongodb";
+
public MongoServiceInfo(String id, String host, int port, String username, String password, String db) {
- super(id, "mongodb", host, port, username, password, db);
+ super(id, URI_SCHEME, host, port, username, password, db);
}
public MongoServiceInfo(String id, String uri) {
super(id, uri);
}
-
+
@ServiceProperty(category="connection")
public String getDatabase() {
return getUriInfo().getPath();
}
-
+
}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MongoServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MongoServiceInfoCreator.java
index bb1e11e..d75299e 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MongoServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MongoServiceInfoCreator.java
@@ -3,14 +3,14 @@ package org.springframework.cloud.heroku;
import org.springframework.cloud.service.common.MongoServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class MongoServiceInfoCreator extends HerokuServiceInfoCreator {
public MongoServiceInfoCreator() {
- super("mongodb");
+ super(MongoServiceInfo.URI_SCHEME);
}
@Override
From 5987c05c6e614d69d1892bb011cd88c626d71e6f Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:25:57 -0500
Subject: [PATCH 31/52] pull up URI scheme for RabbitMQ
---
.../cloudfoundry/AmqpServiceInfoCreator.java | 6 +++---
.../cloud/service/common/AmqpServiceInfo.java | 19 +++++++++++--------
.../cloud/heroku/AmqpServiceInfoCreator.java | 4 ++--
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/AmqpServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/AmqpServiceInfoCreator.java
index 1753c11..af68eee 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/AmqpServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/AmqpServiceInfoCreator.java
@@ -5,20 +5,20 @@ import java.util.Map;
import org.springframework.cloud.service.common.AmqpServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class AmqpServiceInfoCreator extends CloudFoundryServiceInfoCreator {
public AmqpServiceInfoCreator() {
- super(new Tags("rabbitmq"), "amqp");
+ super(new Tags("rabbitmq"), AmqpServiceInfo.URI_SCHEME);
}
public AmqpServiceInfo createServiceInfo(Map serviceData) {
@SuppressWarnings("unchecked")
Map credentials = (Map) serviceData.get("credentials");
-
+
String id = (String) serviceData.get("name");
String uri = getStringFromCredentials(credentials, "uri", "url");
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/AmqpServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/AmqpServiceInfo.java
index 5ae72bb..aa7bb98 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/AmqpServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/AmqpServiceInfo.java
@@ -1,8 +1,8 @@
package org.springframework.cloud.service.common;
import org.springframework.cloud.CloudException;
-import org.springframework.cloud.service.UriBasedServiceInfo;
import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
+import org.springframework.cloud.service.UriBasedServiceInfo;
import org.springframework.cloud.util.UriInfo;
/**
@@ -13,29 +13,32 @@ import org.springframework.cloud.util.UriInfo;
*/
@ServiceLabel("rabbitmq")
public class AmqpServiceInfo extends UriBasedServiceInfo {
+
+ public static final String URI_SCHEME = "amqp";
+
public AmqpServiceInfo(String id, String host, int port, String username, String password, String virtualHost) {
- super(id, "amqp", host, port, username, password, virtualHost);
+ super(id, URI_SCHEME, host, port, username, password, virtualHost);
}
-
+
public AmqpServiceInfo(String id, String uri) throws CloudException {
super(id, uri);
}
-
+
@ServiceProperty(category="connection")
public String getVirtualHost() {
return getUriInfo().getPath();
}
-
+
@Override
protected UriInfo validateAndCleanUriInfo(UriInfo uriInfo) {
- if (!"amqp".equals(uriInfo.getScheme())) {
+ if (!URI_SCHEME.equals(uriInfo.getScheme())) {
throw new IllegalArgumentException("wrong scheme in amqp URI: " + uriInfo);
}
if (uriInfo.getHost() == null) {
throw new IllegalArgumentException("missing authority in amqp URI: " + uriInfo);
}
-
+
int port = uriInfo.getPort();
if (port == -1) {
port = 5672;
@@ -43,7 +46,7 @@ public class AmqpServiceInfo extends UriBasedServiceInfo {
String userName = uriInfo.getUserName();
String password = uriInfo.getPassword();
-
+
if (userName == null || password == null) {
throw new IllegalArgumentException("missing userinfo in amqp URI: " + uriInfo);
}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/AmqpServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/AmqpServiceInfoCreator.java
index a139bd6..86621f8 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/AmqpServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/AmqpServiceInfoCreator.java
@@ -3,14 +3,14 @@ package org.springframework.cloud.heroku;
import org.springframework.cloud.service.common.AmqpServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class AmqpServiceInfoCreator extends HerokuServiceInfoCreator {
public AmqpServiceInfoCreator() {
- super("amqp");
+ super(AmqpServiceInfo.URI_SCHEME);
}
@Override
From a5e6d6ad72367336c788c21b54362abf22cb22ff Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:26:45 -0500
Subject: [PATCH 32/52] make jdbcUrlDatabaseType final
---
.../cloud/service/common/RelationalServiceInfo.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RelationalServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RelationalServiceInfo.java
index 49fe00d..bac6236 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RelationalServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RelationalServiceInfo.java
@@ -7,7 +7,7 @@ import org.springframework.cloud.service.UriBasedServiceInfo;
*/
public abstract class RelationalServiceInfo extends UriBasedServiceInfo {
- protected String jdbcUrlDatabaseType;
+ protected final String jdbcUrlDatabaseType;
public RelationalServiceInfo(String id, String uriString, String jdbcUrlDatabaseType) {
super(id, uriString);
From 9ef5d5da70864e33a3dcd118d3c1b909cb66dae9 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:29:07 -0500
Subject: [PATCH 33/52] pull up MySQL URI scheme
---
.../cloud/cloudfoundry/MysqlServiceInfoCreator.java | 5 +++--
.../cloud/service/common/MysqlServiceInfo.java | 6 ++++--
.../cloud/heroku/MysqlServiceInfoCreator.java | 4 ++--
.../cloud/heroku/HerokuConnectorMysqlServiceTest.java | 6 +++---
4 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MysqlServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MysqlServiceInfoCreator.java
index aca803e..b5c6e15 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MysqlServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/MysqlServiceInfoCreator.java
@@ -3,14 +3,15 @@ package org.springframework.cloud.cloudfoundry;
import org.springframework.cloud.service.common.MysqlServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class MysqlServiceInfoCreator extends RelationalServiceInfoCreator {
public MysqlServiceInfoCreator() {
- super(new Tags("mysql"), "mysql");
+ // the literal in the tag is CloudFoundry-specific
+ super(new Tags("mysql"), MysqlServiceInfo.URI_SCHEME);
}
@Override
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java
index 467a59c..2eccab0 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java
@@ -3,14 +3,16 @@ package org.springframework.cloud.service.common;
import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@ServiceLabel("mysql")
public class MysqlServiceInfo extends RelationalServiceInfo {
+ public static final String URI_SCHEME = "mysql";
+
public MysqlServiceInfo(String id, String url) {
- super(id, url, "mysql");
+ super(id, url, URI_SCHEME);
}
}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MysqlServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MysqlServiceInfoCreator.java
index 4318cb0..73bb8eb 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MysqlServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/MysqlServiceInfoCreator.java
@@ -3,14 +3,14 @@ package org.springframework.cloud.heroku;
import org.springframework.cloud.service.common.MysqlServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class MysqlServiceInfoCreator extends RelationalServiceInfoCreator {
public MysqlServiceInfoCreator() {
- super("mysql");
+ super(MysqlServiceInfo.URI_SCHEME);
}
@Override
diff --git a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorMysqlServiceTest.java b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorMysqlServiceTest.java
index 349c738..439a854 100644
--- a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorMysqlServiceTest.java
+++ b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorMysqlServiceTest.java
@@ -13,15 +13,15 @@ import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.service.common.MysqlServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class HerokuConnectorMysqlServiceTest extends AbstractHerokuConnectorRelationalServiceTest {
public HerokuConnectorMysqlServiceTest() {
- super("mysql");
+ super(MysqlServiceInfo.URI_SCHEME);
}
-
+
@Test
public void mysqlServiceCreation() {
Map env = new HashMap();
From dfa8b87670ffb3039a1854d4311a488b2e4b1571 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:30:06 -0500
Subject: [PATCH 34/52] pull up Oracle URI scheme
---
.../cloud/cloudfoundry/OracleServiceInfoCreator.java | 2 +-
.../cloud/service/common/OracleServiceInfo.java | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/OracleServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/OracleServiceInfoCreator.java
index 1b8159f..1d82ab3 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/OracleServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/OracleServiceInfoCreator.java
@@ -4,7 +4,7 @@ import org.springframework.cloud.service.common.OracleServiceInfo;
public class OracleServiceInfoCreator extends RelationalServiceInfoCreator {
public OracleServiceInfoCreator() {
- super(new Tags(), "oracle");
+ super(new Tags(), OracleServiceInfo.URI_SCHEME);
}
@Override
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java
index 13e0f49..8aef0c4 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java
@@ -5,8 +5,10 @@ import org.springframework.cloud.service.ServiceInfo;
@ServiceInfo.ServiceLabel("oracle")
public class OracleServiceInfo extends RelationalServiceInfo {
+ public static final String URI_SCHEME = "oracle";
+
public OracleServiceInfo(String id, String url) {
- super(id, url, "oracle");
+ super(id, url, URI_SCHEME);
}
@Override
From eb732d792e8212218401b8085c74942a995fd2d5 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:37:23 -0500
Subject: [PATCH 35/52] pull up Postgres URI schema, split out JDBC URL
types--this should probably be done in the interface instead of ad-hocky
---
.../cloudfoundry/PostgresqlServiceInfoCreator.java | 4 ++--
...ractCloudFoundryConnectorRelationalServiceTest.java | 5 +++--
.../cloud/service/common/MysqlServiceInfo.java | 10 ++++++----
.../cloud/service/common/OracleServiceInfo.java | 6 ++++--
.../cloud/service/common/PostgresqlServiceInfo.java | 9 +++++++--
.../cloud/heroku/PostgresqlServiceInfoCreator.java | 4 ++--
.../heroku/HerokuConnectorPostgresqlServiceTest.java | 6 +++---
7 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java
index da8be3e..4b38fbf 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java
@@ -3,14 +3,14 @@ package org.springframework.cloud.cloudfoundry;
import org.springframework.cloud.service.common.PostgresqlServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class PostgresqlServiceInfoCreator extends RelationalServiceInfoCreator {
public PostgresqlServiceInfoCreator() {
- super(new Tags("postgresql"), "postgres");
+ super(new Tags("postgresql"), PostgresqlServiceInfo.URI_SCHEMA);
}
@Override
diff --git a/spring-cloud-cloudfoundry-connector/src/test/java/org/springframework/cloud/cloudfoundry/AbstractCloudFoundryConnectorRelationalServiceTest.java b/spring-cloud-cloudfoundry-connector/src/test/java/org/springframework/cloud/cloudfoundry/AbstractCloudFoundryConnectorRelationalServiceTest.java
index 35a790a..9588e50 100644
--- a/spring-cloud-cloudfoundry-connector/src/test/java/org/springframework/cloud/cloudfoundry/AbstractCloudFoundryConnectorRelationalServiceTest.java
+++ b/spring-cloud-cloudfoundry-connector/src/test/java/org/springframework/cloud/cloudfoundry/AbstractCloudFoundryConnectorRelationalServiceTest.java
@@ -1,7 +1,7 @@
package org.springframework.cloud.cloudfoundry;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@@ -20,12 +20,13 @@ public abstract class AbstractCloudFoundryConnectorRelationalServiceTest extends
}
protected static String getJdbcUrl(String databaseType, String name) {
+ // this should be cleaned up more broadly; pull into RelationalServiceInfo interface?
String jdbcUrlDatabaseType = databaseType;
if (databaseType.equals("postgres")) {
jdbcUrlDatabaseType = "postgresql";
}
- return "jdbc:" + jdbcUrlDatabaseType + "://" + hostname + ":" + port + "/" + name +
+ return "jdbc:" + jdbcUrlDatabaseType + "://" + hostname + ":" + port + "/" + name +
"?user=" + username + "&password=" + password;
}
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java
index 2eccab0..f4609eb 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/MysqlServiceInfo.java
@@ -10,9 +10,11 @@ import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
@ServiceLabel("mysql")
public class MysqlServiceInfo extends RelationalServiceInfo {
- public static final String URI_SCHEME = "mysql";
+ public static final String JDBC_URL_TYPE = "mysql";
- public MysqlServiceInfo(String id, String url) {
- super(id, url, URI_SCHEME);
- }
+ public static final String URI_SCHEME = JDBC_URL_TYPE;
+
+ public MysqlServiceInfo(String id, String url) {
+ super(id, url, URI_SCHEME);
+ }
}
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java
index 8aef0c4..6d2289d 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/OracleServiceInfo.java
@@ -5,10 +5,12 @@ import org.springframework.cloud.service.ServiceInfo;
@ServiceInfo.ServiceLabel("oracle")
public class OracleServiceInfo extends RelationalServiceInfo {
- public static final String URI_SCHEME = "oracle";
+ public static final String JDBC_URL_TYPE = "oracle";
+
+ public static final String URI_SCHEME = JDBC_URL_TYPE;
public OracleServiceInfo(String id, String url) {
- super(id, url, URI_SCHEME);
+ super(id, url, JDBC_URL_TYPE);
}
@Override
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java
index 98e478c..2927782 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java
@@ -4,13 +4,18 @@ import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@ServiceLabel("postgresql")
public class PostgresqlServiceInfo extends RelationalServiceInfo {
+
+ public static final String JDBC_URL_TYPE = "postgresql";
+
+ public static final String URI_SCHEMA = "postgres";
+
public PostgresqlServiceInfo(String id, String url) {
- super(id, url, "postgresql");
+ super(id, url, JDBC_URL_TYPE);
}
}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java
index 57a4e67..7a44ea0 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java
@@ -3,14 +3,14 @@ package org.springframework.cloud.heroku;
import org.springframework.cloud.service.common.PostgresqlServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class PostgresqlServiceInfoCreator extends RelationalServiceInfoCreator {
public PostgresqlServiceInfoCreator() {
- super("postgres");
+ super(PostgresqlServiceInfo.URI_SCHEMA);
}
@Override
diff --git a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java
index 35bf83b..9915ffa 100644
--- a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java
+++ b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java
@@ -13,15 +13,15 @@ import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.service.common.PostgresqlServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class HerokuConnectorPostgresqlServiceTest extends AbstractHerokuConnectorRelationalServiceTest {
public HerokuConnectorPostgresqlServiceTest() {
- super("postgres");
+ super(PostgresqlServiceInfo.URI_SCHEMA);
}
-
+
@Test
public void postgresqlServiceCreation() {
Map env = new HashMap();
From 0fcfa7c653bfbc8c81a22aa7e0c390259df41650 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:38:52 -0500
Subject: [PATCH 36/52] pull up Redis URI scheme
---
.../cloud/cloudfoundry/RedisServiceInfoCreator.java | 3 ++-
.../cloud/service/common/RedisServiceInfo.java | 9 ++++++---
.../cloud/heroku/RedisServiceInfoCreator.java | 4 ++--
3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/RedisServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/RedisServiceInfoCreator.java
index 75e6df1..f8fcfa3 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/RedisServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/RedisServiceInfoCreator.java
@@ -12,7 +12,8 @@ import org.springframework.cloud.service.common.RedisServiceInfo;
public class RedisServiceInfoCreator extends CloudFoundryServiceInfoCreator {
public RedisServiceInfoCreator() {
- super(new Tags("redis"), "redis");
+ // the literal in the tag is CloudFoundry-specific
+ super(new Tags("redis"), RedisServiceInfo.URI_SCHEME);
}
public RedisServiceInfo createServiceInfo(Map serviceData) {
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RedisServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RedisServiceInfo.java
index d31be25..ab35a8e 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RedisServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/RedisServiceInfo.java
@@ -4,16 +4,19 @@ import org.springframework.cloud.service.UriBasedServiceInfo;
import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@ServiceLabel("redis")
public class RedisServiceInfo extends UriBasedServiceInfo {
+
+ public static final String URI_SCHEME = "redis";
+
public RedisServiceInfo(String id, String host, int port, String password) {
- super(id, "redis", host, port, null, password, null);
+ super(id, URI_SCHEME, host, port, null, password, null);
}
-
+
public RedisServiceInfo(String id, String uri) {
super(id, uri);
}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/RedisServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/RedisServiceInfoCreator.java
index cfa88ad..1757bd7 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/RedisServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/RedisServiceInfoCreator.java
@@ -3,14 +3,14 @@ package org.springframework.cloud.heroku;
import org.springframework.cloud.service.common.RedisServiceInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
public class RedisServiceInfoCreator extends HerokuServiceInfoCreator {
public RedisServiceInfoCreator() {
- super("redis");
+ super(RedisServiceInfo.URI_SCHEME);
}
@Override
From a184e7b0d825b50bf6eba7baddb7e06dc788e82b Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Wed, 9 Jul 2014 19:40:42 -0500
Subject: [PATCH 37/52] pull up SMTP URI scheme
---
.../cloud/cloudfoundry/SmtpServiceInfoCreator.java | 13 +++++++------
.../cloud/service/common/SmtpServiceInfo.java | 6 ++++--
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/SmtpServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/SmtpServiceInfoCreator.java
index ccf7560..10bd6e5 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/SmtpServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/SmtpServiceInfoCreator.java
@@ -6,7 +6,7 @@ import org.springframework.cloud.service.common.SmtpServiceInfo;
import org.springframework.cloud.util.UriInfo;
/**
- *
+ *
* @author Ramnivas Laddad
*
*/
@@ -15,16 +15,17 @@ public class SmtpServiceInfoCreator extends CloudFoundryServiceInfoCreator serviceData) {
String id = (String) serviceData.get("name");
-
+
@SuppressWarnings("unchecked")
Map credentials = (Map) serviceData.get("credentials");
String host = (String) credentials.get("hostname");
-
+
int port = DEFAULT_SMTP_PORT;
if (credentials.containsKey("port")) {
port = Integer.parseInt(credentials.get("port").toString());
@@ -33,8 +34,8 @@ public class SmtpServiceInfoCreator extends CloudFoundryServiceInfoCreator
Date: Thu, 10 Jul 2014 12:34:45 -0500
Subject: [PATCH 38/52] blank new module
---
settings.gradle | 3 +-
spring-cloud-localconfig-connector/.gitignore | 1 +
spring-cloud-localconfig-connector/README.md | 59 +++++++++++++++++++
.../build.gradle | 5 ++
4 files changed, 67 insertions(+), 1 deletion(-)
create mode 100644 spring-cloud-localconfig-connector/.gitignore
create mode 100644 spring-cloud-localconfig-connector/README.md
create mode 100644 spring-cloud-localconfig-connector/build.gradle
diff --git a/settings.gradle b/settings.gradle
index c22faa4..bc6b88f 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -3,4 +3,5 @@ rootProject.name = "spring-cloud"
include "${rootProject.name}-core"
include "${rootProject.name}-cloudfoundry-connector"
include "${rootProject.name}-spring-service-connector"
-include "${rootProject.name}-heroku-connector"
\ No newline at end of file
+include "${rootProject.name}-heroku-connector"
+include "${rootProject.name}-localconfig-connector"
diff --git a/spring-cloud-localconfig-connector/.gitignore b/spring-cloud-localconfig-connector/.gitignore
new file mode 100644
index 0000000..5e56e04
--- /dev/null
+++ b/spring-cloud-localconfig-connector/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/spring-cloud-localconfig-connector/README.md b/spring-cloud-localconfig-connector/README.md
new file mode 100644
index 0000000..f9788aa
--- /dev/null
+++ b/spring-cloud-localconfig-connector/README.md
@@ -0,0 +1,59 @@
+Local-configuration connector for Spring Cloud
+=======================================
+
+Provides the ability to configure Spring Cloud services locally for development or testing.
+The current implementation reads from Java properties only; in order to prevent dependencies
+on the Spring Framework, the placeholder functionality is unavailable in the connector.
+Pull requests for also inspecting environment variables are welcome.
+
+Property sources
+----------------
+This connector first attempts to read the system properties generally and a property named
+`spring.cloud.propertiesFile` specifically. If the system properties are not readable
+(the security manager denies `checkPropertiesAccess`), then they will be treated as empty.
+If a system property named `spring.cloud.propertiesFile` is found, that file will be loaded
+as a property list.
+
+###Programmatically supplying properties
+You can programmatically supply a property source by calling the static method
+`LocalConfigConnector.supplyProperties(InputStream)` before invoking `getCloud()`.
+Calling this method will cause the connector to read the stream as a property list
+and then close the stream. Calling this method after invoking `getCloud()` will
+still read the stream, but the properties will have no effect on the connector
+service configuration. Calling this method multiple times will load the supplied
+streams onto the same `Properties` object, overwriting duplicates.
+
+###Property order
+To provide the maximum configuration flexibility, the connector will scan the available
+property sources in this order:
+
+- programmatically-supplied properties
+- properties read from `spring.cloud.propertiesFile`
+- system properties
+
+The last definition of a specific service ID wins. The connector will log a message at
+`INFO` to notify of service overrides for the same type of service and at `WARN` if you
+override a service ID with a URI to a different type of service.
+
+Activating the connector
+------------------------
+The Spring Cloud core expects exactly one cloud connector to return `true` for
+`isInMatchingCloud()`. This connector identifies the "local cloud" by the presence of
+a property named `spring.cloud.appId`, which will be used in the `ApplicationInstanceInfo`.
+
+Service definitions
+-------------------
+If the connector is activated, it will iterate through all the available properties
+for keys matching the pattern `spring.cloud.{serviceId}`. Each value is interpreted as a URI
+to the services, and the type of service is determined from the scheme. All of the standard
+`UriBasedServiceInfo`s are supported.
+
+Supporting additional services
+------------------------------
+Please see the documentation for [cloudfoundry-connector](../spring-cloud-cloudfoundry-connector), since the same
+mechanism applies to any cloud connector.
+
+Instance ID
+-----------
+This connector will create a UUID for use as the instance ID, as Java does not provide
+any portable mechanism for reliably determining hostnames or PIDs.
\ No newline at end of file
diff --git a/spring-cloud-localconfig-connector/build.gradle b/spring-cloud-localconfig-connector/build.gradle
new file mode 100644
index 0000000..eb5f5b6
--- /dev/null
+++ b/spring-cloud-localconfig-connector/build.gradle
@@ -0,0 +1,5 @@
+description = 'Spring Cloud local-configuration connector'
+
+dependencies {
+ compile project(':spring-cloud-core')
+}
From f7269144bd9deb156dcd06b46101f354bccf2af8 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Thu, 10 Jul 2014 13:17:43 -0500
Subject: [PATCH 39/52] pull up fallback BaseServiceInfo creator (just a
generic KVP creator)
---
.../service/FallbackBaseServiceInfoCreator.java | 11 +++++++++++
.../cloud/heroku/HerokuConnector.java | 12 +++---------
2 files changed, 14 insertions(+), 9 deletions(-)
create mode 100644 spring-cloud-core/src/main/java/org/springframework/cloud/service/FallbackBaseServiceInfoCreator.java
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/FallbackBaseServiceInfoCreator.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/FallbackBaseServiceInfoCreator.java
new file mode 100644
index 0000000..23a815a
--- /dev/null
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/FallbackBaseServiceInfoCreator.java
@@ -0,0 +1,11 @@
+package org.springframework.cloud.service;
+
+import org.springframework.cloud.FallbackServiceInfoCreator;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
+
+public class FallbackBaseServiceInfoCreator extends FallbackServiceInfoCreator {
+ @Override
+ public BaseServiceInfo createServiceInfo(KeyValuePair serviceData) {
+ return new BaseServiceInfo(serviceData.getKey());
+ }
+}
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java
index ac39931..ab91ba0 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/HerokuConnector.java
@@ -12,6 +12,7 @@ import org.springframework.cloud.FallbackServiceInfoCreator;
import org.springframework.cloud.ServiceInfoCreator;
import org.springframework.cloud.app.ApplicationInstanceInfo;
import org.springframework.cloud.service.BaseServiceInfo;
+import org.springframework.cloud.service.FallbackBaseServiceInfoCreator;
import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.util.EnvironmentAccessor;
@@ -95,13 +96,6 @@ public class HerokuConnector extends AbstractCloudConnector {
@Override
protected FallbackServiceInfoCreator getFallbackServiceInfoCreator() {
- return new HerokuFallbackServiceInfoCreator();
+ return new FallbackBaseServiceInfoCreator();
}
-}
-
-class HerokuFallbackServiceInfoCreator extends FallbackServiceInfoCreator {
- @Override
- public BaseServiceInfo createServiceInfo(KeyValuePair serviceData) {
- return new BaseServiceInfo(serviceData.getKey());
- }
-}
+}
\ No newline at end of file
From c9cd0c9e64b4151b2809e5eb99711f1c23d3d24c Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Thu, 10 Jul 2014 16:18:31 -0500
Subject: [PATCH 40/52] initial local-config connector implementation; provides
ServiceData, still needs converters to ServiceInfo
---
spring-cloud-localconfig-connector/README.md | 5 +-
.../build.gradle | 1 +
.../localconfig/LocalConfigConnector.java | 187 ++++++++++++++++++
.../LocalConfigServiceInfoCreator.java | 11 ++
.../cloud/localconfig/LocalConfigUtil.java | 81 ++++++++
.../localconfig/LocalConfigConnectorTest.java | 145 ++++++++++++++
.../localconfig/LocalConfigUtilTest.java | 74 +++++++
.../src/test/resources/localconfig.properties | 3 +
8 files changed, 504 insertions(+), 3 deletions(-)
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigServiceInfoCreator.java
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigUtilTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
diff --git a/spring-cloud-localconfig-connector/README.md b/spring-cloud-localconfig-connector/README.md
index f9788aa..1f04dc9 100644
--- a/spring-cloud-localconfig-connector/README.md
+++ b/spring-cloud-localconfig-connector/README.md
@@ -8,7 +8,7 @@ Pull requests for also inspecting environment variables are welcome.
Property sources
----------------
-This connector first attempts to read the system properties generally and a property named
+This connector first attempts to read the system properties generally and a system property named
`spring.cloud.propertiesFile` specifically. If the system properties are not readable
(the security manager denies `checkPropertiesAccess`), then they will be treated as empty.
If a system property named `spring.cloud.propertiesFile` is found, that file will be loaded
@@ -32,8 +32,7 @@ property sources in this order:
- system properties
The last definition of a specific service ID wins. The connector will log a message at
-`INFO` to notify of service overrides for the same type of service and at `WARN` if you
-override a service ID with a URI to a different type of service.
+`WARN` if you override a service ID.
Activating the connector
------------------------
diff --git a/spring-cloud-localconfig-connector/build.gradle b/spring-cloud-localconfig-connector/build.gradle
index eb5f5b6..d020bde 100644
--- a/spring-cloud-localconfig-connector/build.gradle
+++ b/spring-cloud-localconfig-connector/build.gradle
@@ -2,4 +2,5 @@ description = 'Spring Cloud local-configuration connector'
dependencies {
compile project(':spring-cloud-core')
+ testCompile 'com.github.stefanbirkner:system-rules:1.5.0'
}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
new file mode 100644
index 0000000..93bb25f
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
@@ -0,0 +1,187 @@
+package org.springframework.cloud.localconfig;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+import org.springframework.cloud.AbstractCloudConnector;
+import org.springframework.cloud.FallbackServiceInfoCreator;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
+import org.springframework.cloud.app.ApplicationInstanceInfo;
+import org.springframework.cloud.app.BasicApplicationInstanceInfo;
+import org.springframework.cloud.service.BaseServiceInfo;
+import org.springframework.cloud.service.FallbackBaseServiceInfoCreator;
+
+/**
+ *
+ * @author Christopher Smith
+ *
+ */
+public class LocalConfigConnector extends AbstractCloudConnector {
+
+ private static final Logger logger = Logger.getLogger(LocalConfigConnector.class.getName());
+
+ /*--------------- String constants for property keys ---------------*/
+
+ public static final String PROPERTY_PREFIX = "spring.cloud.";
+
+ public static final Pattern SERVICE_PROPERTY_PATTERN = Pattern.compile("\\A" + Pattern.quote(PROPERTY_PREFIX) + "(.+)" + "\\Z");
+
+ public static final String APP_ID_PROPERTY = PROPERTY_PREFIX + "appId";
+
+ public static final String PROPERTIES_FILE_PROPERTY = PROPERTY_PREFIX + "propertiesFile";
+
+ /**
+ * These properties configure the connector itself and aren't service definitions.
+ */
+ public static final List META_PROPERTIES = Collections.unmodifiableList(
+ Arrays.asList(new String[] { APP_ID_PROPERTY, PROPERTIES_FILE_PROPERTY }));
+
+ /*--------------- sources for service-definition properties ---------------*/
+
+ static Properties programmaticProperties = new Properties();
+
+ private Properties fileProperties = null;
+
+ /*--------------- API implementation ---------------*/
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public LocalConfigConnector() {
+ super((Class) LocalConfigServiceInfoCreator.class);
+ }
+
+ /**
+ * Returns {@code true} if a property named {@code spring.cloud.appId} is present in any of the property sources.
+ * On the first call, attempts to load properties from a file specified in {@code spring.cloud.propertiesFile}.
+ */
+ @Override
+ public boolean isInMatchingCloud() {
+ if (fileProperties == null)
+ readFileProperties();
+
+ return findProperty(APP_ID_PROPERTY) != null;
+ }
+
+ @Override
+ public ApplicationInstanceInfo getApplicationInstanceInfo() {
+ return new BasicApplicationInstanceInfo(UUID.randomUUID().toString(), findProperty(APP_ID_PROPERTY),
+ Collections. emptyMap());
+ }
+
+ @Override
+ protected List getServicesData() {
+ LinkedHashMap propertySources = new LinkedHashMap();
+
+ propertySources.put("programmatic properties", programmaticProperties);
+ propertySources.put("properties from file", fileProperties);
+ try {
+ propertySources.put("system properties", System.getProperties());
+ } catch (SecurityException e) {
+ logger.log(Level.WARNING,
+ "couldn't read system properties; no service definitions from system properties will be applied", e);
+ }
+
+ return LocalConfigUtil.readServicesData(propertySources);
+ }
+
+ @Override
+ protected FallbackServiceInfoCreator getFallbackServiceInfoCreator() {
+ return new FallbackBaseServiceInfoCreator();
+ }
+
+ /*--------------- methods for manipulating properties and sources ---------------*/
+
+ /**
+ * Adds properties to be scanned from the supplied {@link InputStream}, overwriting
+ * existing properties with the same name. Closes the stream after loading.
+ *
+ * @param propertiesInputStream
+ * a property list
+ * @throws IOException
+ * if the underlying load operation throws an exception
+ */
+ public static void supplyProperties(final InputStream propertiesInputStream) throws IOException {
+ programmaticProperties.load(propertiesInputStream);
+ propertiesInputStream.close();
+ }
+
+ /**
+ * Checks for the presence of a supplied or system property named {@code spring.cloud.propertiesFile}. If the property
+ * is present, load its contents into {@link #fileProperties}. If there's a problem, log but continue.
+ */
+ private void readFileProperties() {
+ fileProperties = new Properties();
+ logger.fine("looking for a properties file");
+
+ String filename = null;
+
+ filename = programmaticProperties.getProperty(PROPERTIES_FILE_PROPERTY);
+
+ try {
+ filename = System.getProperty(PROPERTIES_FILE_PROPERTY, filename);
+ } catch (SecurityException e) {
+ logSystemReadException(PROPERTIES_FILE_PROPERTY, e);
+ return;
+ }
+
+ if (filename == null) {
+ logger.info("did not find a system property " + PROPERTIES_FILE_PROPERTY);
+ return;
+ }
+
+ logger.info("loading properties from file " + filename);
+
+ try {
+ InputStream fis = openFile(filename);
+ fileProperties.load(fis);
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "exception while loading properties from file " + filename, e);
+ return;
+ }
+
+ logger.info("properties loaded successfully");
+ }
+
+ /**
+ * Broken out into a separate method for mocking the filesystem.
+ * @param filename the file to open
+ * @return a {@code FileInputStream} to the file
+ * @throws IOException if opening the file throws
+ */
+ InputStream openFile(String filename) throws IOException {
+ return new FileInputStream(filename);
+ }
+
+ /**
+ * Look for a specific property in programmatically-supplied properties, properties from a file,
+ * or the system properties. Last source wins.
+ *
+ * @param key
+ * the property to look for
+ * @return the highest-priority value for the key, or {@code null} if the key is not found
+ */
+ private String findProperty(String key) {
+ String value = programmaticProperties.getProperty(key);
+ value = fileProperties.getProperty(key, value);
+ try {
+ value = System.getProperty(key, value);
+ } catch (SecurityException e) {
+ logSystemReadException(key, e);
+ }
+
+ return value;
+ }
+
+ private static void logSystemReadException(String key, SecurityException e) {
+ logger.log(Level.WARNING, "couldn't read system property " + key, e);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigServiceInfoCreator.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigServiceInfoCreator.java
new file mode 100644
index 0000000..98a8669
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigServiceInfoCreator.java
@@ -0,0 +1,11 @@
+package org.springframework.cloud.localconfig;
+
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.UriBasedServiceInfoCreator;
+
+public abstract class LocalConfigServiceInfoCreator extends UriBasedServiceInfoCreator {
+
+ protected LocalConfigServiceInfoCreator(String uriScheme) {
+ super(uriScheme);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
new file mode 100644
index 0000000..bd4d9f3
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
@@ -0,0 +1,81 @@
+package org.springframework.cloud.localconfig;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
+
+public final class LocalConfigUtil {
+ private static final Logger logger = Logger.getLogger(LocalConfigConnector.class.getName());
+
+ private LocalConfigUtil() {
+ }
+
+ static List readServicesData(LinkedHashMap propertySources) {
+ // we'll turn this into KVPs to return but need to eliminate duplicates first
+ Map collectedServices = new HashMap();
+
+ // iterate over the property sources in order, extracting matching properties
+ for (Map.Entry propertySource : propertySources.entrySet()) {
+ logger.info("reading services from " + propertySource.getValue());
+ Map services = readServices(propertySource.getValue());
+
+ // add each of the found services to the list, warning about duplicates
+ for (Map.Entry service : services.entrySet()) {
+ String oldUri = collectedServices.put(service.getKey(), service.getValue());
+ if (oldUri == null)
+ logger.info("added service '" + service.getKey() + "' from " + propertySource.getKey());
+ else
+ logger.warning("replaced service '" + service.getKey() + "' with new URI from " + propertySource.getKey());
+ }
+ }
+
+ // now we have a collated set of service IDs and URIs
+ List serviceData = new ArrayList(collectedServices.size());
+ for (Map.Entry serviceInfo : collectedServices.entrySet()) {
+ serviceData.add(new KeyValuePair(serviceInfo.getKey(), serviceInfo.getValue()));
+ }
+
+ return serviceData;
+ }
+
+ /**
+ * Goes through a {@code Properties} object, finding all service definitions (properties
+ * prefixed with {@code spring.cloud.} but not in {@code META_PROPERTIES}) and collects {@code (id,URI)} pairs.
+ *
+ * @param properties
+ * the {@code Properties} object to read
+ * @return all of the service definitions found
+ */
+ static Map readServices(Properties properties) {
+ Map services = new HashMap();
+
+ for (String propertyName : properties.stringPropertyNames()) {
+ if (LocalConfigConnector.META_PROPERTIES.contains(propertyName)) {
+ logger.finer("skipping meta property " + propertyName);
+ continue;
+ }
+
+ Matcher m = LocalConfigConnector.SERVICE_PROPERTY_PATTERN.matcher(propertyName);
+ if (!m.matches()) {
+ logger.finest("skipping non-Spring-Cloud property " + propertyName);
+ continue;
+ }
+
+ String serviceId = m.group(1);
+ String serviceUri = properties.getProperty(propertyName);
+
+ // no URI here because they will contain passwords
+ logger.fine("found service URI for service " + serviceId);
+ services.put(serviceId, serviceUri);
+ }
+
+ return services;
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
new file mode 100644
index 0000000..394e851
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
@@ -0,0 +1,145 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Properties;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.ClearSystemProperties;
+import org.junit.contrib.java.lang.system.ProvideSystemProperty;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
+
+public class LocalConfigConnectorTest {
+
+ static final Charset UTF_8 = Charset.forName("UTF-8");
+
+ public static final String APP_ID_1 = "appId1";
+ public static final String APP_ID_1_PROPERTY = LocalConfigConnector.APP_ID_PROPERTY + ": " + APP_ID_1;
+
+ public static final String APP_ID_2 = "appId2";
+ public static final String APP_ID_2_PROPERTY = LocalConfigConnector.APP_ID_PROPERTY + ": " + APP_ID_2;
+
+ public static final String PROPERTY_FILE_NAME = "propFile";
+ public static final String PROPERTY_FILE_PROPERTY = LocalConfigConnector.PROPERTIES_FILE_PROPERTY + ": " + PROPERTY_FILE_NAME;
+
+ public static class AppIdTest {
+
+ private LocalConfigConnector connector;
+
+ @Before
+ public void setup() {
+ connector = new LocalConfigConnector();
+ }
+
+ @After
+ public void clearProperties() {
+ LocalConfigConnector.programmaticProperties = new Properties();
+ }
+
+ @Rule
+ public final ClearSystemProperties NO_APP_ID_PROPERTY = new ClearSystemProperties(LocalConfigConnector.APP_ID_PROPERTY);
+
+ @Test
+ public void testNoAppIdAnywhere() {
+ assertFalse(connector.isInMatchingCloud());
+ }
+
+ @Test
+ public void testProgrammaticAppId() throws IOException {
+ LocalConfigConnector.supplyProperties(new ByteArrayInputStream(APP_ID_1_PROPERTY.getBytes(UTF_8)));
+ assertTrue(connector.isInMatchingCloud());
+ assertEquals(APP_ID_1, connector.getApplicationInstanceInfo().getAppId());
+ }
+
+ @Test
+ public void testProgrammaticAndFileAppIds() throws IOException {
+ LocalConfigConnector.supplyProperties(new ByteArrayInputStream(APP_ID_1_PROPERTY.getBytes(UTF_8)));
+ LocalConfigConnector.supplyProperties(new ByteArrayInputStream(PROPERTY_FILE_PROPERTY.getBytes(UTF_8)));
+
+ LocalConfigConnector stubConnector = new LocalConfigConnector() {
+ @Override
+ InputStream openFile(String filename) throws IOException {
+ assertEquals(PROPERTY_FILE_NAME, filename);
+ return new ByteArrayInputStream(APP_ID_2_PROPERTY.getBytes(UTF_8));
+ };
+ };
+
+ assertTrue(stubConnector.isInMatchingCloud());
+ assertEquals(APP_ID_2, stubConnector.getApplicationInstanceInfo().getAppId());
+ }
+
+ @Test
+ public void testProgrammaticFilenamePlusSystemAppId() throws IOException {
+ LocalConfigConnector.supplyProperties(new ByteArrayInputStream(PROPERTY_FILE_PROPERTY.getBytes(UTF_8)));
+
+ LocalConfigConnector stubConnector = new LocalConfigConnector() {
+ @Override
+ InputStream openFile(String filename) throws IOException {
+ assertEquals(PROPERTY_FILE_NAME, filename);
+ return new ByteArrayInputStream(APP_ID_2_PROPERTY.getBytes(UTF_8));
+ };
+ };
+
+ System.setProperty(LocalConfigConnector.APP_ID_PROPERTY, "helloApp");
+ assertTrue(stubConnector.isInMatchingCloud());
+ assertEquals("helloApp", stubConnector.getApplicationInstanceInfo().getAppId());
+ }
+ }
+
+ private LocalConfigConnector connector;
+
+ InputStream propertiesFile;
+
+ @Before
+ public void setup() {
+ connector = new LocalConfigConnector();
+ propertiesFile = LocalConfigConnectorTest.class.getClassLoader().getResourceAsStream("localconfig.properties");
+ }
+
+ @After
+ public void cleanup() throws IOException {
+ LocalConfigConnector.programmaticProperties = new Properties();
+ propertiesFile.close();
+ }
+
+ @Test
+ public void testLoadFromFile() throws IOException {
+ LocalConfigConnector.supplyProperties(propertiesFile);
+
+ assertTrue(connector.isInMatchingCloud());
+ assertEquals("testApp", connector.getApplicationInstanceInfo().getAppId());
+
+ List services = connector.getServicesData();
+ assertEquals(2, services.size());
+ for (KeyValuePair service : services)
+ if ("foo".equals(service.getKey()))
+ assertEquals("bar", service.getValue());
+ }
+
+ @Rule
+ public ProvideSystemProperty BAZ_PROPERTY = new ProvideSystemProperty("spring.cloud.baz", "inline!");
+
+ @Test
+ public void testLoadFromInputStreamWithOverride() throws IOException {
+ LocalConfigConnector.supplyProperties(propertiesFile);
+
+ assertTrue(connector.isInMatchingCloud());
+ assertEquals("testApp", connector.getApplicationInstanceInfo().getAppId());
+
+ List services = connector.getServicesData();
+ assertEquals(2, services.size());
+ for(KeyValuePair service: services)
+ if("baz".equals(service.getKey()))
+ assertEquals("inline!", service.getValue());
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigUtilTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigUtilTest.java
new file mode 100644
index 0000000..10eaa58
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigUtilTest.java
@@ -0,0 +1,74 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.*;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.cloud.AbstractCloudConnector.KeyValuePair;
+
+public class LocalConfigUtilTest {
+
+ private Properties first, second;
+
+ private LinkedHashMap propertySources;
+
+ @Before
+ public void initProperties(){
+ first = new Properties();
+ second = new Properties();
+
+ propertySources = new LinkedHashMap();
+ propertySources.put("first", first);
+ propertySources.put("second", second);
+ }
+
+ @Test
+ public void testPropertyParsing() {
+ first.setProperty("spring.cloud.appId", "should skip me because I'm meta");
+ first.setProperty("spring.cloud.service1", "one");
+ first.setProperty("spring.cloud.", "should skip me because I don't have an ID");
+ first.setProperty("spring.cloud.service.two", "two");
+ first.setProperty("foobar", "should skip me because I don't match the prefix");
+
+ Map services = LocalConfigUtil.readServices(first);
+ assertEquals(2, services.size());
+ assertEquals("one", services.get("service1"));
+ assertEquals("two", services.get("service.two"));
+ }
+
+ @Test
+ public void testCollation() {
+ first.setProperty("spring.cloud.first", "firstUri");
+ second.setProperty("spring.cloud.second", "secondUri");
+
+ List serviceData = LocalConfigUtil.readServicesData(propertySources);
+ assertEquals(2, serviceData.size());
+ boolean foundFirst = false;
+
+ for(KeyValuePair kvp : serviceData) {
+ if(kvp.getKey().equals("first")) {
+ assertEquals("firstUri", kvp.getValue());
+ foundFirst = true;
+ }
+ }
+
+ assertTrue(foundFirst);
+ }
+
+ @Test
+ public void testOverride() {
+ first.setProperty("spring.cloud.duplicate", "firstUri");
+ second.setProperty("spring.cloud.duplicate", "secondUri");
+
+ List serviceData = LocalConfigUtil.readServicesData(propertySources);
+ assertEquals(1, serviceData.size());
+ KeyValuePair kvp = serviceData.get(0);
+ assertEquals("duplicate", kvp.getKey());
+ assertEquals("secondUri", kvp.getValue());
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties b/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
new file mode 100644
index 0000000..bcc84c3
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
@@ -0,0 +1,3 @@
+spring.cloud.appId: testApp
+spring.cloud.foo: bar
+spring.cloud.baz: quux
\ No newline at end of file
From 488cd6aaeb34fd5adfe2c4a9cb0fc865bdf4464c Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Thu, 10 Jul 2014 16:23:37 -0500
Subject: [PATCH 41/52] typo in constant name
---
.../cloud/cloudfoundry/PostgresqlServiceInfoCreator.java | 2 +-
.../cloud/service/common/PostgresqlServiceInfo.java | 2 +-
.../cloud/heroku/PostgresqlServiceInfoCreator.java | 2 +-
.../cloud/heroku/HerokuConnectorPostgresqlServiceTest.java | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java
index 4b38fbf..abfbde1 100644
--- a/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java
+++ b/spring-cloud-cloudfoundry-connector/src/main/java/org/springframework/cloud/cloudfoundry/PostgresqlServiceInfoCreator.java
@@ -10,7 +10,7 @@ import org.springframework.cloud.service.common.PostgresqlServiceInfo;
public class PostgresqlServiceInfoCreator extends RelationalServiceInfoCreator {
public PostgresqlServiceInfoCreator() {
- super(new Tags("postgresql"), PostgresqlServiceInfo.URI_SCHEMA);
+ super(new Tags("postgresql"), PostgresqlServiceInfo.URI_SCHEME);
}
@Override
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java
index 2927782..edcace5 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/common/PostgresqlServiceInfo.java
@@ -13,7 +13,7 @@ public class PostgresqlServiceInfo extends RelationalServiceInfo {
public static final String JDBC_URL_TYPE = "postgresql";
- public static final String URI_SCHEMA = "postgres";
+ public static final String URI_SCHEME = "postgres";
public PostgresqlServiceInfo(String id, String url) {
super(id, url, JDBC_URL_TYPE);
diff --git a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java
index 7a44ea0..70f47de 100644
--- a/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java
+++ b/spring-cloud-heroku-connector/src/main/java/org/springframework/cloud/heroku/PostgresqlServiceInfoCreator.java
@@ -10,7 +10,7 @@ import org.springframework.cloud.service.common.PostgresqlServiceInfo;
public class PostgresqlServiceInfoCreator extends RelationalServiceInfoCreator {
public PostgresqlServiceInfoCreator() {
- super(PostgresqlServiceInfo.URI_SCHEMA);
+ super(PostgresqlServiceInfo.URI_SCHEME);
}
@Override
diff --git a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java
index 9915ffa..52d7398 100644
--- a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java
+++ b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/HerokuConnectorPostgresqlServiceTest.java
@@ -19,7 +19,7 @@ import org.springframework.cloud.service.common.PostgresqlServiceInfo;
*/
public class HerokuConnectorPostgresqlServiceTest extends AbstractHerokuConnectorRelationalServiceTest {
public HerokuConnectorPostgresqlServiceTest() {
- super(PostgresqlServiceInfo.URI_SCHEMA);
+ super(PostgresqlServiceInfo.URI_SCHEME);
}
@Test
From 21489526b5d6bf950b1baffab521359af5de4d37 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Thu, 10 Jul 2014 16:28:06 -0500
Subject: [PATCH 42/52] document Java version requirement
---
spring-cloud-core/README.md | 40 +++++++++++++++++++------------------
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/spring-cloud-core/README.md b/spring-cloud-core/README.md
index 52c4d45..80233e4 100644
--- a/spring-cloud-core/README.md
+++ b/spring-cloud-core/README.md
@@ -2,10 +2,12 @@ Spring Cloud Core Library
=========================
The core library to let cloud applications access application information and services.
-While Spring applications is one of the main target for this library, it may be used in
+While Spring applications is one of the main target for this library, it may be used in
non-Spring projects as well. In fact, **this library doesn't even depend on Spring**.
-This library is cloud-agnostic. Through connectors, it supports multiple clouds
+This library requires Java 6,
+
+This library is cloud-agnostic. Through connectors, it supports multiple clouds
(with Cloud Foundry and Heroku as the example clouds).
This library also supports an extension to create services connectors of user-desired types.
@@ -13,11 +15,11 @@ This library also supports an extension to create services connectors of user-de
Usage pattern: Application Developers
=====================================
-> **Note:** If you are using spring-cloud in a Spring application, you should consider using the
-[Java config](../spring-cloud-spring-service-connector#the-java-config) or the
+> **Note:** If you are using spring-cloud in a Spring application, you should consider using the
+[Java config](../spring-cloud-spring-service-connector#the-java-config) or the
[XML namespace support](../spring-cloud-spring-service-connector#the-cloud-namespace) instead.
-* Create a [`CloudFactory`](src/main/java/org/springframework/cloud/CloudFactory.java) instance.
+* Create a [`CloudFactory`](src/main/java/org/springframework/cloud/CloudFactory.java) instance.
Creation of a `CloudFactory` instance is a bit expensive, so caching such an instance is recommended.
If you are using a dependency injection frameworks such as Spring, creating a bean for `CloudFactory`
will achieve the caching effect.
@@ -25,45 +27,45 @@ Usage pattern: Application Developers
```java
CloudFactory cloudFactory = new CloudFactory();
```
-* Obtain a suitable [`Cloud`](src/main/java/org/springframework/cloud/Cloud.java) for the environment
+* Obtain a suitable [`Cloud`](src/main/java/org/springframework/cloud/Cloud.java) for the environment
in which the application is running.
-
+
```java
Cloud cloud = cloudFactory.getCloud();
```
Note that you must have a `CloudConnector` implementation suitable
for the environment in which the application is being deployed in your classpath. For example, if you are
- deploying the application in Cloud Foundry, you must add [cloudfoundry-connector](../spring-cloud-cloudfoundry-connector)
+ deploying the application in Cloud Foundry, you must add [cloudfoundry-connector](../spring-cloud-cloudfoundry-connector)
in your classpath. If no suitable `CloudConnctor` is found, the `getCloud()` method will throw a `CloudException`.
-* Use the `Cloud` instance to get access to application info, service infos, and create service
+* Use the `Cloud` instance to get access to application info, service infos, and create service
connectors.
```java
// ServiceInfo has all the information necessary to connect to the underlying service
cloud.getServiceInfos();
```
-
+
```java
// Alternatively, let the cloud create a service connector for you
DataSource ds = cloud.getServiceConnector("inventory-db", DataSource.class, null /* default config */);
```
-
+
Usage pattern: Cloud and Service Providers
==========================================
A cloud provider may extends the functionality in two ways:
-1. Add new [`CloudConnector`](src/main/java/org/springframework/cloud/CloudConnector.java)s to make
- spring-cloud related libraries work with a new cloud.
- See [cloudfoundry-connector](../spring-cloud-cloudfoundry-connector)
- or [heroku-connector](../spring-cloud-heroku-connector) for an example.
+1. Add new [`CloudConnector`](src/main/java/org/springframework/cloud/CloudConnector.java)s to make
+ spring-cloud related libraries work with a new cloud.
+ See [cloudfoundry-connector](../spring-cloud-cloudfoundry-connector)
+ or [heroku-connector](../spring-cloud-heroku-connector) for an example.
This is done declaratively by adding connector classes to:
```
META-INF/services/org.springframework.cloud.CloudConnector
```
-2. Add new [`ServiceConnectorCreator`](src/main/java/org/springframework/cloud/service/ServiceConnectorCreator.java)s
- to allow creation of service connector objects.
- See [spring-service-connector](../spring-cloud-spring-service-connector) for an example.
- This is done declaratively by adding creator classes to:
+2. Add new [`ServiceConnectorCreator`](src/main/java/org/springframework/cloud/service/ServiceConnectorCreator.java)s
+ to allow creation of service connector objects.
+ See [spring-service-connector](../spring-cloud-spring-service-connector) for an example.
+ This is done declaratively by adding creator classes to:
```
META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator
```
\ No newline at end of file
From 7d894c2c082b8422cb67b1f788218094073362fe Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Thu, 10 Jul 2014 17:01:14 -0500
Subject: [PATCH 43/52] add ServiceInfoCreators and SPI control files
---
.../localconfig/AmqpServiceInfoCreator.java | 20 +++++++++++++++++++
.../localconfig/MongoServiceInfoCreator.java | 20 +++++++++++++++++++
.../localconfig/MysqlServiceInfoCreator.java | 20 +++++++++++++++++++
.../PostgresqlServiceInfoCreator.java | 20 +++++++++++++++++++
.../localconfig/RedisServiceInfoCreator.java | 20 +++++++++++++++++++
.../org.springframework.cloud.CloudConnector | 1 +
....localconfig.LocalConfigServiceInfoCreator | 5 +++++
7 files changed, 106 insertions(+)
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/AmqpServiceInfoCreator.java
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MongoServiceInfoCreator.java
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MysqlServiceInfoCreator.java
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/PostgresqlServiceInfoCreator.java
create mode 100644 spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/RedisServiceInfoCreator.java
create mode 100644 spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.CloudConnector
create mode 100644 spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/AmqpServiceInfoCreator.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/AmqpServiceInfoCreator.java
new file mode 100644
index 0000000..b9dc631
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/AmqpServiceInfoCreator.java
@@ -0,0 +1,20 @@
+package org.springframework.cloud.localconfig;
+
+import org.springframework.cloud.service.common.AmqpServiceInfo;
+
+/**
+ *
+ * @author Christopher Smith
+ *
+ */
+public class AmqpServiceInfoCreator extends LocalConfigServiceInfoCreator{
+
+ public AmqpServiceInfoCreator() {
+ super(AmqpServiceInfo.URI_SCHEME);
+ }
+
+ @Override
+ public AmqpServiceInfo createServiceInfo(String id, String uri) {
+ return new AmqpServiceInfo(id, uri);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MongoServiceInfoCreator.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MongoServiceInfoCreator.java
new file mode 100644
index 0000000..68671ac
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MongoServiceInfoCreator.java
@@ -0,0 +1,20 @@
+package org.springframework.cloud.localconfig;
+
+import org.springframework.cloud.service.common.MongoServiceInfo;
+
+/**
+ *
+ * @author Christopher Smith
+ *
+ */
+public class MongoServiceInfoCreator extends LocalConfigServiceInfoCreator{
+
+ public MongoServiceInfoCreator() {
+ super(MongoServiceInfo.URI_SCHEME);
+ }
+
+ @Override
+ public MongoServiceInfo createServiceInfo(String id, String uri) {
+ return new MongoServiceInfo(id, uri);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MysqlServiceInfoCreator.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MysqlServiceInfoCreator.java
new file mode 100644
index 0000000..0d39262
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/MysqlServiceInfoCreator.java
@@ -0,0 +1,20 @@
+package org.springframework.cloud.localconfig;
+
+import org.springframework.cloud.service.common.MysqlServiceInfo;
+
+/**
+ *
+ * @author Christopher Smith
+ *
+ */
+public class MysqlServiceInfoCreator extends LocalConfigServiceInfoCreator{
+
+ public MysqlServiceInfoCreator() {
+ super(MysqlServiceInfo.URI_SCHEME);
+ }
+
+ @Override
+ public MysqlServiceInfo createServiceInfo(String id, String uri) {
+ return new MysqlServiceInfo(id, uri);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/PostgresqlServiceInfoCreator.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/PostgresqlServiceInfoCreator.java
new file mode 100644
index 0000000..282da2f
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/PostgresqlServiceInfoCreator.java
@@ -0,0 +1,20 @@
+package org.springframework.cloud.localconfig;
+
+import org.springframework.cloud.service.common.PostgresqlServiceInfo;
+
+/**
+ *
+ * @author Christopher Smith
+ *
+ */
+public class PostgresqlServiceInfoCreator extends LocalConfigServiceInfoCreator{
+
+ public PostgresqlServiceInfoCreator() {
+ super(PostgresqlServiceInfo.URI_SCHEME);
+ }
+
+ @Override
+ public PostgresqlServiceInfo createServiceInfo(String id, String uri) {
+ return new PostgresqlServiceInfo(id, uri);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/RedisServiceInfoCreator.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/RedisServiceInfoCreator.java
new file mode 100644
index 0000000..7a9e06f
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/RedisServiceInfoCreator.java
@@ -0,0 +1,20 @@
+package org.springframework.cloud.localconfig;
+
+import org.springframework.cloud.service.common.RedisServiceInfo;
+
+/**
+ *
+ * @author Christopher Smith
+ *
+ */
+public class RedisServiceInfoCreator extends LocalConfigServiceInfoCreator{
+
+ public RedisServiceInfoCreator() {
+ super(RedisServiceInfo.URI_SCHEME);
+ }
+
+ @Override
+ public RedisServiceInfo createServiceInfo(String id, String uri) {
+ return new RedisServiceInfo(id, uri);
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.CloudConnector b/spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.CloudConnector
new file mode 100644
index 0000000..2a7adb6
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.CloudConnector
@@ -0,0 +1 @@
+org.springframework.cloud.localconfig.LocalConfigConnector
\ No newline at end of file
diff --git a/spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator b/spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator
new file mode 100644
index 0000000..f8a14d4
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/main/resources/META-INF/services/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator
@@ -0,0 +1,5 @@
+org.springframework.cloud.localconfig.AmqpServiceInfoCreator
+org.springframework.cloud.localconfig.MongoServiceInfoCreator
+org.springframework.cloud.localconfig.MysqlServiceInfoCreator
+org.springframework.cloud.localconfig.PostgresqlServiceInfoCreator
+org.springframework.cloud.localconfig.RedisServiceInfoCreator
\ No newline at end of file
From bbe8c6728d7846a6df7582027e854a4573f6eb9f Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 15:34:38 -0500
Subject: [PATCH 44/52] rename test case for clarity
---
.../cloud/localconfig/LocalConfigConnectorTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
index 394e851..40b3913 100644
--- a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
@@ -32,7 +32,7 @@ public class LocalConfigConnectorTest {
public static final String PROPERTY_FILE_NAME = "propFile";
public static final String PROPERTY_FILE_PROPERTY = LocalConfigConnector.PROPERTIES_FILE_PROPERTY + ": " + PROPERTY_FILE_NAME;
- public static class AppIdTest {
+ public static class DetectAppIdTest {
private LocalConfigConnector connector;
From 3c4b5196f9fc1622993a1c3dfd94ee7103a7d40a Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 15:38:09 -0500
Subject: [PATCH 45/52] move property file name into constant, rename
---
.../cloud/localconfig/LocalConfigConnectorTest.java | 4 ++--
.../src/test/resources/localconfig.nonsense.properties | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
create mode 100644 spring-cloud-localconfig-connector/src/test/resources/localconfig.nonsense.properties
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
index 40b3913..dd75a33 100644
--- a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorTest.java
@@ -29,7 +29,7 @@ public class LocalConfigConnectorTest {
public static final String APP_ID_2 = "appId2";
public static final String APP_ID_2_PROPERTY = LocalConfigConnector.APP_ID_PROPERTY + ": " + APP_ID_2;
- public static final String PROPERTY_FILE_NAME = "propFile";
+ public static final String PROPERTY_FILE_NAME = "localconfig.nonsense.properties";
public static final String PROPERTY_FILE_PROPERTY = LocalConfigConnector.PROPERTIES_FILE_PROPERTY + ": " + PROPERTY_FILE_NAME;
public static class DetectAppIdTest {
@@ -103,7 +103,7 @@ public class LocalConfigConnectorTest {
@Before
public void setup() {
connector = new LocalConfigConnector();
- propertiesFile = LocalConfigConnectorTest.class.getClassLoader().getResourceAsStream("localconfig.properties");
+ propertiesFile = LocalConfigConnectorTest.class.getClassLoader().getResourceAsStream(PROPERTY_FILE_NAME);
}
@After
diff --git a/spring-cloud-localconfig-connector/src/test/resources/localconfig.nonsense.properties b/spring-cloud-localconfig-connector/src/test/resources/localconfig.nonsense.properties
new file mode 100644
index 0000000..bcc84c3
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/resources/localconfig.nonsense.properties
@@ -0,0 +1,3 @@
+spring.cloud.appId: testApp
+spring.cloud.foo: bar
+spring.cloud.baz: quux
\ No newline at end of file
From b4fc3cc62453d371e4a60df9940bf8834f936ebb Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 16:00:08 -0500
Subject: [PATCH 46/52] constant wasn't final
---
.../cloud/heroku/AbstractHerokuConnectorTest.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/AbstractHerokuConnectorTest.java b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/AbstractHerokuConnectorTest.java
index 7b88bf9..576dcfc 100644
--- a/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/AbstractHerokuConnectorTest.java
+++ b/spring-cloud-heroku-connector/src/test/java/org/springframework/cloud/heroku/AbstractHerokuConnectorTest.java
@@ -10,7 +10,7 @@ import org.springframework.cloud.util.EnvironmentAccessor;
/**
* Base test class that provides setup and utility methods to generate test payload
- *
+ *
* @author Ramnivas Laddad
*
*/
@@ -20,7 +20,7 @@ public abstract class AbstractHerokuConnectorTest {
protected static final String hostname = "10.20.30.40";
protected static final int port = 1234;
- protected static String username = "myuser";
+ protected static final String username = "myuser";
protected static final String password = "mypass";
@Before
@@ -28,7 +28,7 @@ public abstract class AbstractHerokuConnectorTest {
MockitoAnnotations.initMocks(this);
testCloudConnector.setCloudEnvironment(mockEnvironment);
}
-
+
protected static ServiceInfo getServiceInfo(List serviceInfos, String serviceId) {
for (ServiceInfo serviceInfo : serviceInfos) {
if (serviceInfo.getId().equals(serviceId)) {
From 7cf18cce1b3577c90ce11dced08bf5bf9de141e9 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 16:18:29 -0500
Subject: [PATCH 47/52] add getScheme() and a useful toString()
---
.../cloud/service/UriBasedServiceInfo.java | 146 ++++++++++--------
1 file changed, 79 insertions(+), 67 deletions(-)
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfo.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfo.java
index 78828de..fda552c 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfo.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/UriBasedServiceInfo.java
@@ -6,84 +6,96 @@ import org.springframework.cloud.util.UriInfoFactory;
/**
* Common class for all {@link ServiceInfo}s
- *
+ *
* @author Ramnivas Laddad
*
*/
public abstract class UriBasedServiceInfo extends BaseServiceInfo {
- private UriInfo uriInfo;
+ private UriInfo uriInfo;
- private static UriInfoFactory uriFactory = new StandardUriInfoFactory();
+ private static UriInfoFactory uriFactory = new StandardUriInfoFactory();
- public UriBasedServiceInfo(String id, String scheme, String host, int port, String username, String password, String path) {
- super(id);
- this.uriInfo = getUriInfoFactory().createUri(scheme, host, port, username, password, path);
- this.uriInfo = validateAndCleanUriInfo(uriInfo);
- }
-
- public UriBasedServiceInfo(String id, String uriString) {
- super(id);
- this.uriInfo = getUriInfoFactory().createUri(uriString);
- this.uriInfo = validateAndCleanUriInfo(uriInfo);
- }
+ public UriBasedServiceInfo(String id, String scheme, String host, int port, String username, String password, String path) {
+ super(id);
+ this.uriInfo = getUriInfoFactory().createUri(scheme, host, port, username, password, path);
+ this.uriInfo = validateAndCleanUriInfo(uriInfo);
+ }
- /**
- * For URI-based (@link ServiceInfo}s which don't conform to the standard URI
- * format, override this method in your own ServiceInfo class to return a
- * {@link UriInfoFactory} which will create the appropriate URIs.
- *
- * @return your special UriInfoFactory
- */
- public UriInfoFactory getUriInfoFactory() {
- return uriFactory;
- }
+ public UriBasedServiceInfo(String id, String uriString) {
+ super(id);
+ this.uriInfo = getUriInfoFactory().createUri(uriString);
+ this.uriInfo = validateAndCleanUriInfo(uriInfo);
+ }
- @ServiceProperty(category="connection")
- public String getUri() {
- return uriInfo.getUri().toString();
- }
-
- @ServiceProperty(category="connection")
- public String getUserName() {
- return uriInfo.getUserName();
- }
-
- @ServiceProperty(category="connection")
- public String getPassword() {
- return uriInfo.getPassword();
- }
+ /**
+ * For URI-based (@link ServiceInfo}s which don't conform to the standard URI
+ * format, override this method in your own ServiceInfo class to return a {@link UriInfoFactory} which will create the
+ * appropriate URIs.
+ *
+ * @return your special UriInfoFactory
+ */
+ public UriInfoFactory getUriInfoFactory() {
+ return uriFactory;
+ }
- @ServiceProperty(category="connection")
- public String getHost() {
- return uriInfo.getHost();
- }
+ @ServiceProperty(category = "connection")
+ public String getUri() {
+ return uriInfo.getUri().toString();
+ }
- @ServiceProperty(category="connection")
- public int getPort() {
- return uriInfo.getPort();
- }
+ @ServiceProperty(category = "connection")
+ public String getUserName() {
+ return uriInfo.getUserName();
+ }
- @ServiceProperty(category="connection")
- public String getPath() {
- return uriInfo.getPath();
- }
+ @ServiceProperty(category = "connection")
+ public String getPassword() {
+ return uriInfo.getPassword();
+ }
- @ServiceProperty(category="connection")
- public String getQuery() {
- return uriInfo.getQuery();
- }
+ @ServiceProperty(category = "connection")
+ public String getHost() {
+ return uriInfo.getHost();
+ }
- /**
- * Validate the URI and clean it up by using defaults for any missing information, if possible.
- *
- * @param uriInfo uri info based on parsed payload
- * @return cleaned up uri info
- */
- protected UriInfo validateAndCleanUriInfo(UriInfo uriInfo) {
- return uriInfo;
- }
-
- protected UriInfo getUriInfo() {
- return uriInfo;
- }
+ @ServiceProperty(category = "connection")
+ public int getPort() {
+ return uriInfo.getPort();
+ }
+
+ @ServiceProperty(category = "connection")
+ public String getPath() {
+ return uriInfo.getPath();
+ }
+
+ @ServiceProperty(category = "connection")
+ public String getQuery() {
+ return uriInfo.getQuery();
+ }
+
+ @ServiceProperty(category = "connection")
+ public String getScheme() {
+ return uriInfo.getScheme();
+ }
+
+ /**
+ * Validate the URI and clean it up by using defaults for any missing information, if possible.
+ *
+ * @param uriInfo
+ * uri info based on parsed payload
+ * @return cleaned up uri info
+ */
+ protected UriInfo validateAndCleanUriInfo(UriInfo uriInfo) {
+ return uriInfo;
+ }
+
+ protected UriInfo getUriInfo() {
+ return uriInfo;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "[" + getScheme() + "://" + getUserName() + ":****@" + getHost() + ":" + getPort()
+ + "/" + getPath() + "]";
+ }
}
From 14272c8b104eb757d50a6a7fa0b3bfa71bf6334a Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 16:28:09 -0500
Subject: [PATCH 48/52] tests for all ServiceInfoCreators
---
.../localconfig/LocalConfigConnector.java | 3 ++
.../cloud/localconfig/LocalConfigUtil.java | 6 ++-
.../AbstractLocalConfigConnectorTest.java | 54 +++++++++++++++++++
.../LocalConfigConnectorAmqpServiceTest.java | 23 ++++++++
.../LocalConfigConnectorMongoServiceTest.java | 23 ++++++++
.../LocalConfigConnectorMysqlServiceTest.java | 23 ++++++++
...lConfigConnectorPostgresqlServiceTest.java | 23 ++++++++
.../LocalConfigConnectorRedisServiceTest.java | 23 ++++++++
.../src/test/resources/localconfig.properties | 3 --
.../resources/localconfig.testuris.properties | 6 +++
10 files changed, 183 insertions(+), 4 deletions(-)
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/AbstractLocalConfigConnectorTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorAmqpServiceTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMongoServiceTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMysqlServiceTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorPostgresqlServiceTest.java
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorRedisServiceTest.java
delete mode 100644 spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
create mode 100644 spring-cloud-localconfig-connector/src/test/resources/localconfig.testuris.properties
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
index 93bb25f..babc2c0 100644
--- a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigConnector.java
@@ -79,6 +79,9 @@ public class LocalConfigConnector extends AbstractCloudConnector {
@Override
protected List getServicesData() {
+ if(fileProperties == null)
+ throw new IllegalStateException("isInMatchingCloud() must be called first to initialize connector");
+
LinkedHashMap propertySources = new LinkedHashMap();
propertySources.put("programmatic properties", programmaticProperties);
diff --git a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
index bd4d9f3..c2a4e82 100644
--- a/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
+++ b/spring-cloud-localconfig-connector/src/main/java/org/springframework/cloud/localconfig/LocalConfigUtil.java
@@ -23,7 +23,11 @@ public final class LocalConfigUtil {
// iterate over the property sources in order, extracting matching properties
for (Map.Entry propertySource : propertySources.entrySet()) {
- logger.info("reading services from " + propertySource.getValue());
+ if(propertySource.getValue().isEmpty()) {
+ logger.info("no " + propertySource.getKey());
+ continue;
+ }
+ logger.info("reading services from " + propertySource.getKey());
Map services = readServices(propertySource.getValue());
// add each of the found services to the list, warning about duplicates
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/AbstractLocalConfigConnectorTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/AbstractLocalConfigConnectorTest.java
new file mode 100644
index 0000000..9313717
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/AbstractLocalConfigConnectorTest.java
@@ -0,0 +1,54 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Properties;
+
+import org.junit.After;
+import org.junit.Before;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.UriBasedServiceInfo;
+
+public class AbstractLocalConfigConnectorTest {
+
+ public static final String PROPERTIES_FILE = "localconfig.testuris.properties";
+
+ protected LocalConfigConnector connector = new LocalConfigConnector();
+
+ protected static final String HOSTNAME = "10.20.30.40";
+ protected static final int PORT = 1234;
+ protected static final String USERNAME = "myuser";
+ protected static final String PASSWORD = "mypass";
+
+ @Before
+ public void init() throws IOException {
+ InputStream propertiesFile = getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
+ LocalConfigConnector.supplyProperties(propertiesFile);
+ assertTrue(connector.isInMatchingCloud());
+ }
+
+ @After
+ public void clearProperties() {
+ LocalConfigConnector.programmaticProperties = new Properties();
+ }
+
+ protected static ServiceInfo getServiceInfo(List serviceInfos, String serviceId) {
+ for (ServiceInfo serviceInfo : serviceInfos) {
+ if (serviceInfo.getId().equals(serviceId)) {
+ return serviceInfo;
+ }
+ }
+ return null;
+ }
+
+ protected static void assertUriParameters(UriBasedServiceInfo serviceInfo) {
+ assertEquals(HOSTNAME, serviceInfo.getHost());
+ assertEquals(PORT, serviceInfo.getPort());
+ assertEquals(USERNAME, serviceInfo.getUserName());
+ assertEquals(PASSWORD, serviceInfo.getPassword());
+ }
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorAmqpServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorAmqpServiceTest.java
new file mode 100644
index 0000000..a515741
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorAmqpServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.AmqpServiceInfo;
+
+public class LocalConfigConnectorAmqpServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "rabbit");
+ assertNotNull(service);
+ assertTrue(service instanceof AmqpServiceInfo);
+ assertUriParameters((AmqpServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMongoServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMongoServiceTest.java
new file mode 100644
index 0000000..5fec86f
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMongoServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.MongoServiceInfo;
+
+public class LocalConfigConnectorMongoServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "candygram");
+ assertNotNull(service);
+ assertTrue(service instanceof MongoServiceInfo);
+ assertUriParameters((MongoServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMysqlServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMysqlServiceTest.java
new file mode 100644
index 0000000..4e305dd
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorMysqlServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.MysqlServiceInfo;
+
+public class LocalConfigConnectorMysqlServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "maria");
+ assertNotNull(service);
+ assertTrue(service instanceof MysqlServiceInfo);
+ assertUriParameters((MysqlServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorPostgresqlServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorPostgresqlServiceTest.java
new file mode 100644
index 0000000..13123a5
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorPostgresqlServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.PostgresqlServiceInfo;
+
+public class LocalConfigConnectorPostgresqlServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "ingres");
+ assertNotNull(service);
+ assertTrue(service instanceof PostgresqlServiceInfo);
+ assertUriParameters((PostgresqlServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorRedisServiceTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorRedisServiceTest.java
new file mode 100644
index 0000000..29dd550
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigConnectorRedisServiceTest.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.RedisServiceInfo;
+
+public class LocalConfigConnectorRedisServiceTest extends AbstractLocalConfigConnectorTest {
+
+ @Test
+ public void serviceCreation() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "blue");
+ assertNotNull(service);
+ assertTrue(service instanceof RedisServiceInfo);
+ assertUriParameters((RedisServiceInfo) service);
+ }
+
+}
diff --git a/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties b/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
deleted file mode 100644
index bcc84c3..0000000
--- a/spring-cloud-localconfig-connector/src/test/resources/localconfig.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-spring.cloud.appId: testApp
-spring.cloud.foo: bar
-spring.cloud.baz: quux
\ No newline at end of file
diff --git a/spring-cloud-localconfig-connector/src/test/resources/localconfig.testuris.properties b/spring-cloud-localconfig-connector/src/test/resources/localconfig.testuris.properties
new file mode 100644
index 0000000..94bb5d9
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/resources/localconfig.testuris.properties
@@ -0,0 +1,6 @@
+spring.cloud.appId: testAppWithUris
+spring.cloud.rabbit: amqp://myuser:mypass@10.20.30.40:1234/queue
+spring.cloud.maria: mysql://myuser:mypass@10.20.30.40:1234/dbname
+spring.cloud.candygram: mongodb://myuser:mypass@10.20.30.40:1234/dbname
+spring.cloud.ingres: postgres://myuser:mypass@10.20.30.40:1234/dbname
+spring.cloud.blue: redis://myuser:mypass@10.20.30.40:1234/dbname
\ No newline at end of file
From c42a8e3ba7ffe9cb043bc4e869cb90a2ab17d5f4 Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 16:41:18 -0500
Subject: [PATCH 49/52] Add test to override programmatic definition from
system properties.
fixes #45
---
.../LocalConfigServiceOverrideTest.java | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
create mode 100644 spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigServiceOverrideTest.java
diff --git a/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigServiceOverrideTest.java b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigServiceOverrideTest.java
new file mode 100644
index 0000000..980067a
--- /dev/null
+++ b/spring-cloud-localconfig-connector/src/test/java/org/springframework/cloud/localconfig/LocalConfigServiceOverrideTest.java
@@ -0,0 +1,34 @@
+package org.springframework.cloud.localconfig;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.ProvideSystemProperty;
+import org.springframework.cloud.service.ServiceInfo;
+import org.springframework.cloud.service.common.MongoServiceInfo;
+
+public class LocalConfigServiceOverrideTest extends AbstractLocalConfigConnectorTest {
+
+ @Rule
+ public final ProvideSystemProperty OVERRIDE_MYSQL =
+ new ProvideSystemProperty(
+ "spring.cloud.candygram",
+ "mongodb://youruser:yourpass@40.30.20.10:4321/dbname");
+
+ @Test
+ public void serviceOverride() {
+ List services = connector.getServiceInfos();
+ ServiceInfo service = getServiceInfo(services, "candygram");
+ assertNotNull(service);
+ assertTrue(service instanceof MongoServiceInfo);
+ MongoServiceInfo mongo = (MongoServiceInfo) service;
+ assertEquals("youruser", mongo.getUserName());
+ assertEquals(4321, mongo.getPort());
+ }
+
+}
From 73ba54d3d29b5b29cb15ff4c13ded4ef8741518b Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Fri, 11 Jul 2014 16:57:17 -0500
Subject: [PATCH 50/52] improved documentation
---
spring-cloud-localconfig-connector/README.md | 22 ++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/spring-cloud-localconfig-connector/README.md b/spring-cloud-localconfig-connector/README.md
index 1f04dc9..128d2c3 100644
--- a/spring-cloud-localconfig-connector/README.md
+++ b/spring-cloud-localconfig-connector/README.md
@@ -6,6 +6,28 @@ The current implementation reads from Java properties only; in order to prevent
on the Spring Framework, the placeholder functionality is unavailable in the connector.
Pull requests for also inspecting environment variables are welcome.
+Quick start
+-----------
+Since service URIs contain passwords and should not be stored in code, this connector does not
+attempt to read properties out of the classpath. You can provide a filename with service definitions
+by setting the `spring.cloud.propertiesFile` property or by passing in an open `InputStream`:
+
+````java
+InputStream propertyStream = new FileInputStream("/path/to/spring-cloud.properties");
+LocalConfigConnector.supplyProperties(propertyStream);
+Cloud cloud = new CloudFactory().getCloud();
+````
+
+The property file should contain an application ID and the desired services in this format:
+
+````properties
+spring.cloud.appId: myApp
+; spring.cloud.{id}: URI
+spring.cloud.database: mysql://user:pass@host:1234/dbname
+````
+
+Service type is determined by the URI scheme.
+
Property sources
----------------
This connector first attempts to read the system properties generally and a system property named
From 40b2f647be425ce1b4a295556b0d4eb90732195a Mon Sep 17 00:00:00 2001
From: Christopher Smith
Date: Mon, 14 Jul 2014 15:28:59 -0500
Subject: [PATCH 51/52] pull out KeyValuePair as top-level class
---
.../cloud/AbstractCloudConnector.java | 18 ------------------
.../springframework/cloud/KeyValuePair.java | 19 +++++++++++++++++++
.../FallbackBaseServiceInfoCreator.java | 2 +-
.../service/UriBasedServiceInfoCreator.java | 2 +-
.../cloud/heroku/HerokuConnector.java | 2 +-
.../localconfig/LocalConfigConnector.java | 2 +-
.../cloud/localconfig/LocalConfigUtil.java | 2 +-
.../localconfig/LocalConfigConnectorTest.java | 2 +-
.../localconfig/LocalConfigUtilTest.java | 2 +-
9 files changed, 26 insertions(+), 25 deletions(-)
create mode 100644 spring-cloud-core/src/main/java/org/springframework/cloud/KeyValuePair.java
diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/AbstractCloudConnector.java b/spring-cloud-core/src/main/java/org/springframework/cloud/AbstractCloudConnector.java
index a515766..eb8291d 100644
--- a/spring-cloud-core/src/main/java/org/springframework/cloud/AbstractCloudConnector.java
+++ b/spring-cloud-core/src/main/java/org/springframework/cloud/AbstractCloudConnector.java
@@ -68,22 +68,4 @@ public abstract class AbstractCloudConnector