pull up KeyValuePair class from HerokuConnector to

AbstractCloudConnector
This commit is contained in:
Christopher Smith
2014-07-09 19:06:07 -05:00
parent 3f15f8546d
commit 99302432e9
3 changed files with 52 additions and 52 deletions

View File

@@ -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<SD> implements CloudConnector {
private static Logger logger = Logger.getLogger(AbstractCloudConnector.class.getName());
protected List<ServiceInfoCreator<?,SD>> serviceInfoCreators = new ArrayList<ServiceInfoCreator<?,SD>>();
protected abstract List<SD> getServicesData();
protected abstract FallbackServiceInfoCreator<?,SD> getFallbackServiceInfoCreator();
public AbstractCloudConnector(Class<? extends ServiceInfoCreator<? extends ServiceInfo, ?>> serviceInfoCreatorClass) {
scanServiceInfoCreators(serviceInfoCreatorClass);
}
@@ -39,7 +39,7 @@ public abstract class AbstractCloudConnector<SD> implements CloudConnector {
for (SD serviceData : getServicesData()) {
serviceInfos.add(getServiceInfo(serviceData));
}
return serviceInfos;
}
@@ -54,18 +54,36 @@ public abstract class AbstractCloudConnector<SD> 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;
}
}
}

View File

@@ -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<HerokuConnector.KeyValuePair> {
public class HerokuConnector extends AbstractCloudConnector<KeyValuePair> {
private EnvironmentAccessor environment = new EnvironmentAccessor();
private ApplicationInstanceInfoCreator applicationInstanceInfoCreator
private ApplicationInstanceInfoCreator applicationInstanceInfoCreator
= new ApplicationInstanceInfoCreator(environment);
private List<String> serviceEnvPrefixes;
@SuppressWarnings({ "unchecked", "rawtypes" })
@@ -41,28 +41,28 @@ public class HerokuConnector extends AbstractCloudConnector<HerokuConnector.KeyV
public boolean isInMatchingCloud() {
return environment.getEnvValue("DYNO") != null;
}
@Override
public ApplicationInstanceInfo getApplicationInstanceInfo() {
try {
return applicationInstanceInfoCreator.createApplicationInstanceInfo();
} catch (Exception e) {
throw new CloudException(e);
}
}
}
/* package for testing purpose */
void setCloudEnvironment(EnvironmentAccessor environment) {
this.environment = environment;
this.applicationInstanceInfoCreator = new ApplicationInstanceInfoCreator(environment);
}
@Override
protected void registerServiceInfoCreator(ServiceInfoCreator<? extends ServiceInfo, HerokuConnector.KeyValuePair> 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<String>();
@@ -75,17 +75,17 @@ public class HerokuConnector extends AbstractCloudConnector<HerokuConnector.KeyV
* <p>
* Returns map whose key is the env key and value is the associated url
* </p>
* @return information about services bound to the app
* @return information about services bound to the app
*/
protected List<KeyValuePair> getServicesData() {
List<KeyValuePair> serviceData = new ArrayList<KeyValuePair>();
Map<String,String> env = environment.getEnv();
for (Map.Entry<String, String> 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<HerokuConnector.KeyV
protected FallbackServiceInfoCreator<BaseServiceInfo,KeyValuePair> 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<BaseServiceInfo,KeyValuePair> {

View File

@@ -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<SI extends ServiceInfo> 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();
}