Use tabs for indentation consistently.
This commit is contained in:
@@ -40,349 +40,337 @@ import org.springframework.cloud.service.ServiceInfo.ServiceProperty;
|
||||
*
|
||||
*/
|
||||
public class Cloud {
|
||||
private CloudConnector cloudConnector;
|
||||
private ServiceConnectorCreatorRegistry serviceConnectorCreatorRegistry = new ServiceConnectorCreatorRegistry();
|
||||
private CloudConnector cloudConnector;
|
||||
private ServiceConnectorCreatorRegistry serviceConnectorCreatorRegistry = new ServiceConnectorCreatorRegistry();
|
||||
|
||||
/**
|
||||
* Package-access constructor.
|
||||
*
|
||||
* @param cloudConnector
|
||||
* the underlying connector
|
||||
* @param serviceConnectorCreators
|
||||
* service connector creators
|
||||
*/
|
||||
Cloud(CloudConnector cloudConnector, List<ServiceConnectorCreator<?, ? extends ServiceInfo>> serviceConnectorCreators) {
|
||||
this.cloudConnector = cloudConnector;
|
||||
/**
|
||||
* Package-access constructor.
|
||||
*
|
||||
* @param cloudConnector the underlying connector
|
||||
* @param serviceConnectorCreators service connector creators
|
||||
*/
|
||||
Cloud(CloudConnector cloudConnector, List<ServiceConnectorCreator<?, ? extends ServiceInfo>> serviceConnectorCreators) {
|
||||
this.cloudConnector = cloudConnector;
|
||||
|
||||
for (ServiceConnectorCreator<?, ? extends ServiceInfo> serviceCreator : serviceConnectorCreators) {
|
||||
registerServiceConnectorCreator(serviceCreator);
|
||||
}
|
||||
}
|
||||
for (ServiceConnectorCreator<?, ? extends ServiceInfo> serviceCreator : serviceConnectorCreators) {
|
||||
registerServiceConnectorCreator(serviceCreator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CloudConnector#getApplicationInstanceInfo()
|
||||
*
|
||||
* @return information about the application instance
|
||||
*/
|
||||
public ApplicationInstanceInfo getApplicationInstanceInfo() {
|
||||
return cloudConnector.getApplicationInstanceInfo();
|
||||
}
|
||||
/**
|
||||
* @see CloudConnector#getApplicationInstanceInfo()
|
||||
*
|
||||
* @return information about the application instance
|
||||
*/
|
||||
public ApplicationInstanceInfo getApplicationInstanceInfo() {
|
||||
return cloudConnector.getApplicationInstanceInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link ServiceInfo} for the given service id
|
||||
*
|
||||
* @param serviceId
|
||||
* service id
|
||||
* @return info for the serviceId
|
||||
*/
|
||||
public ServiceInfo getServiceInfo(String serviceId) {
|
||||
for (ServiceInfo serviceInfo : getServiceInfos()) {
|
||||
if (serviceInfo.getId().equals(serviceId)) {
|
||||
return serviceInfo;
|
||||
}
|
||||
}
|
||||
throw new CloudException("No service with id " + serviceId + " found");
|
||||
}
|
||||
/**
|
||||
* Get {@link ServiceInfo} for the given service id
|
||||
*
|
||||
* @param serviceId service id
|
||||
* @return info for the serviceId
|
||||
*/
|
||||
public ServiceInfo getServiceInfo(String serviceId) {
|
||||
for (ServiceInfo serviceInfo : getServiceInfos()) {
|
||||
if (serviceInfo.getId().equals(serviceId)) {
|
||||
return serviceInfo;
|
||||
}
|
||||
}
|
||||
throw new CloudException("No service with id " + serviceId + " found");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CloudConnector#getServiceInfos()
|
||||
* @return information about all services bound to the application
|
||||
*/
|
||||
public List<ServiceInfo> getServiceInfos() {
|
||||
return flatten(cloudConnector.getServiceInfos());
|
||||
}
|
||||
/**
|
||||
* @see CloudConnector#getServiceInfos()
|
||||
* @return information about all services bound to the application
|
||||
*/
|
||||
public List<ServiceInfo> getServiceInfos() {
|
||||
return flatten(cloudConnector.getServiceInfos());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link ServiceInfo}s for the bound services that could be mapped to the given service connector type.
|
||||
*
|
||||
* <p>
|
||||
* For example, if the connector type is {@link DataSource}, then the method will return all {@link ServiceInfo} objects
|
||||
* matching bound relational database services.
|
||||
* <p>
|
||||
*
|
||||
* @param <T>
|
||||
* The class of the connector to find services for.
|
||||
* @param serviceConnectorType
|
||||
* service connector type.
|
||||
* Passing null returns all {@link ServiceInfo}s (matching that of {@link Cloud#getServiceInfos()}
|
||||
* @return information about services bound to the application that could be transformed into the given connector type
|
||||
*/
|
||||
public <T> List<ServiceInfo> getServiceInfos(Class<T> serviceConnectorType) {
|
||||
List<ServiceInfo> allServiceInfos = getServiceInfos();
|
||||
List<ServiceInfo> matchingServiceInfos = new ArrayList<ServiceInfo>();
|
||||
/**
|
||||
* Get {@link ServiceInfo}s for the bound services that could be mapped to the given service connector type.
|
||||
*
|
||||
* <p>
|
||||
* For example, if the connector type is {@link DataSource}, then the method will return all {@link ServiceInfo} objects
|
||||
* matching bound relational database services.
|
||||
* <p>
|
||||
*
|
||||
* @param <T> The class of the connector to find services for.
|
||||
* @param serviceConnectorType service connector type.
|
||||
* Passing null returns all {@link ServiceInfo}s (matching that of {@link Cloud#getServiceInfos()}
|
||||
* @return information about services bound to the application that could be transformed into the given connector type
|
||||
*/
|
||||
public <T> List<ServiceInfo> getServiceInfos(Class<T> serviceConnectorType) {
|
||||
List<ServiceInfo> allServiceInfos = getServiceInfos();
|
||||
List<ServiceInfo> matchingServiceInfos = new ArrayList<ServiceInfo>();
|
||||
|
||||
for (ServiceInfo serviceInfo : allServiceInfos) {
|
||||
if (serviceConnectorCreatorRegistry.canCreate(serviceConnectorType, serviceInfo)) {
|
||||
matchingServiceInfos.add(serviceInfo);
|
||||
}
|
||||
}
|
||||
for (ServiceInfo serviceInfo : allServiceInfos) {
|
||||
if (serviceConnectorCreatorRegistry.canCreate(serviceConnectorType, serviceInfo)) {
|
||||
matchingServiceInfos.add(serviceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return matchingServiceInfos;
|
||||
}
|
||||
return matchingServiceInfos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a service connector for the given service id, the connector type, configured with the given config
|
||||
*
|
||||
*
|
||||
* @param <SC>
|
||||
* The class of the service connector to return.
|
||||
* @param serviceId
|
||||
* the service id
|
||||
* @param serviceConnectorType
|
||||
* The expected class of service connector such as, DataSource.class.
|
||||
* @param serviceConnectorConfig
|
||||
* service connector configuration (such as pooling parameters).
|
||||
* @return a service connector of the specified type with the given configuration applied
|
||||
*
|
||||
*/
|
||||
public <SC> SC getServiceConnector(String serviceId, Class<SC> serviceConnectorType,
|
||||
ServiceConnectorConfig serviceConnectorConfig) {
|
||||
ServiceInfo serviceInfo = getServiceInfo(serviceId);
|
||||
/**
|
||||
* Get a service connector for the given service id, the connector type, configured with the given config
|
||||
*
|
||||
*
|
||||
* @param <SC> The class of the service connector to return.
|
||||
* @param serviceId the service id
|
||||
* @param serviceConnectorType The expected class of service connector such as, DataSource.class.
|
||||
* @param serviceConnectorConfig service connector configuration (such as pooling parameters).
|
||||
* @return a service connector of the specified type with the given configuration applied
|
||||
*
|
||||
*/
|
||||
public <SC> SC getServiceConnector(String serviceId, Class<SC> serviceConnectorType,
|
||||
ServiceConnectorConfig serviceConnectorConfig) {
|
||||
ServiceInfo serviceInfo = getServiceInfo(serviceId);
|
||||
|
||||
return getServiceConnector(serviceInfo, serviceConnectorType, serviceConnectorConfig);
|
||||
}
|
||||
return getServiceConnector(serviceInfo, serviceConnectorType, serviceConnectorConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the singleton service connector for the given connector type, configured with the given config
|
||||
*
|
||||
* @param <SC>
|
||||
* The class of the service connector to return.
|
||||
* @param serviceConnectorType
|
||||
* The expected class of service connector such as, DataSource.class.
|
||||
* @param serviceConnectorConfig
|
||||
* service connector configuration (such as pooling parameters).
|
||||
* @return the single service connector of the specified type with the given configuration applied
|
||||
*
|
||||
*/
|
||||
public <SC> SC getSingletonServiceConnector(Class<SC> serviceConnectorType, ServiceConnectorConfig serviceConnectorConfig) {
|
||||
List<ServiceInfo> matchingServiceInfos = getServiceInfos(serviceConnectorType);
|
||||
/**
|
||||
* Get the singleton service connector for the given connector type, configured with the given config
|
||||
*
|
||||
* @param <SC> The class of the service connector to return.
|
||||
* @param serviceConnectorType The expected class of service connector such as, DataSource.class.
|
||||
* @param serviceConnectorConfig service connector configuration (such as pooling parameters).
|
||||
* @return the single service connector of the specified type with the given configuration applied
|
||||
*
|
||||
*/
|
||||
public <SC> SC getSingletonServiceConnector(Class<SC> serviceConnectorType, ServiceConnectorConfig serviceConnectorConfig) {
|
||||
List<ServiceInfo> matchingServiceInfos = getServiceInfos(serviceConnectorType);
|
||||
|
||||
if (matchingServiceInfos.size() != 1) {
|
||||
throw new CloudException("No unique service matching " + serviceConnectorType + " found. Expected 1, found "
|
||||
+ matchingServiceInfos.size());
|
||||
}
|
||||
if (matchingServiceInfos.size() != 1) {
|
||||
throw new CloudException("No unique service matching " + serviceConnectorType + " found. Expected 1, found "
|
||||
+ matchingServiceInfos.size());
|
||||
}
|
||||
|
||||
ServiceInfo matchingServiceInfo = matchingServiceInfos.get(0);
|
||||
ServiceInfo matchingServiceInfo = matchingServiceInfos.get(0);
|
||||
|
||||
return getServiceConnector(matchingServiceInfo, serviceConnectorType, serviceConnectorConfig);
|
||||
}
|
||||
return getServiceConnector(matchingServiceInfo, serviceConnectorType, serviceConnectorConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new service connector creator
|
||||
*
|
||||
* @param serviceConnectorCreator the service connector to register
|
||||
*/
|
||||
public void registerServiceConnectorCreator(ServiceConnectorCreator<?, ? extends ServiceInfo> serviceConnectorCreator) {
|
||||
serviceConnectorCreatorRegistry.registerCreator(serviceConnectorCreator);
|
||||
}
|
||||
/**
|
||||
* Register a new service connector creator
|
||||
*
|
||||
* @param serviceConnectorCreator the service connector to register
|
||||
*/
|
||||
public void registerServiceConnectorCreator(ServiceConnectorCreator<?, ? extends ServiceInfo> serviceConnectorCreator) {
|
||||
serviceConnectorCreatorRegistry.registerCreator(serviceConnectorCreator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get properties for app and services.
|
||||
*
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Application properties always include <code>cloud.application.app-id</code> and <code>cloud.application.instance-id</code>
|
||||
* with values bound to application id and instance id. The rest of the properties are cloud-provider specific, but take the
|
||||
* <code>cloud.application.<property-name></code> form. <pre>
|
||||
* cloud.application.app-id = helloworld
|
||||
* cloud.application.instance-id = instance-0-0fab098f
|
||||
* cloud.application.<property-name> = <property-value>
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* Service specific properties are exposed for each bound service, with each key starting in <code>cloud.services</code>. Like
|
||||
* application properties, these too are cloud and service specific. Each key for a specific service starts with
|
||||
* <code>cloud.services.<service-id></code> <pre>
|
||||
* cloud.services.customerDb.type = mysql-5.1
|
||||
* cloud.services.customerDb.plan = free
|
||||
* cloud.services.customerDb.connection.hostname = ...
|
||||
* cloud.services.customerDb.connection.port = ...
|
||||
* etc...
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* If a there is only a single service of a given type (as defined by the {link ServiceInfo.ServiceLabel}
|
||||
* annoation's value of the corresponding {@link ServiceInfo} class), that service is aliased
|
||||
* to the service type. Keys for such properties start in <code>cloud.services.<service-type></code>.
|
||||
* For example, if there is only a single MySQL service bound to the application, the service properties
|
||||
* will also be exposed starting with '<code>cloud.services.mysql</code>' key: <pre>
|
||||
* cloud.services.mysql.type = mysql-5.1
|
||||
* cloud.services.mysql.plan = free
|
||||
* cloud.services.mysql.connection.hostname = ...
|
||||
* cloud.services.mysql.connection.port = ...
|
||||
* etc...
|
||||
* </pre>
|
||||
*
|
||||
* @return the properties object
|
||||
*/
|
||||
public Properties getCloudProperties() {
|
||||
Map<String, List<ServiceInfo>> mappedServiceInfos = new HashMap<String, List<ServiceInfo>>();
|
||||
for (ServiceInfo serviceInfo : getServiceInfos()) {
|
||||
String key = getServiceLabel(serviceInfo);
|
||||
List<ServiceInfo> serviceInfosForLabel = mappedServiceInfos.get(key);
|
||||
if (serviceInfosForLabel == null) {
|
||||
serviceInfosForLabel = new ArrayList<ServiceInfo>();
|
||||
mappedServiceInfos.put(key, serviceInfosForLabel);
|
||||
}
|
||||
serviceInfosForLabel.add(serviceInfo);
|
||||
}
|
||||
/**
|
||||
* Get properties for app and services.
|
||||
*
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Application properties always include <code>cloud.application.app-id</code> and <code>cloud.application.instance-id</code>
|
||||
* with values bound to application id and instance id. The rest of the properties are cloud-provider specific, but take the
|
||||
* <code>cloud.application.<property-name></code> form. <pre>
|
||||
* cloud.application.app-id = helloworld
|
||||
* cloud.application.instance-id = instance-0-0fab098f
|
||||
* cloud.application.<property-name> = <property-value>
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* Service specific properties are exposed for each bound service, with each key starting in <code>cloud.services</code>. Like
|
||||
* application properties, these too are cloud and service specific. Each key for a specific service starts with
|
||||
* <code>cloud.services.<service-id></code> <pre>
|
||||
* cloud.services.customerDb.type = mysql-5.1
|
||||
* cloud.services.customerDb.plan = free
|
||||
* cloud.services.customerDb.connection.hostname = ...
|
||||
* cloud.services.customerDb.connection.port = ...
|
||||
* etc...
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* If a there is only a single service of a given type (as defined by the {link ServiceInfo.ServiceLabel}
|
||||
* annoation's value of the corresponding {@link ServiceInfo} class), that service is aliased
|
||||
* to the service type. Keys for such properties start in <code>cloud.services.<service-type></code>.
|
||||
* For example, if there is only a single MySQL service bound to the application, the service properties
|
||||
* will also be exposed starting with '<code>cloud.services.mysql</code>' key: <pre>
|
||||
* cloud.services.mysql.type = mysql-5.1
|
||||
* cloud.services.mysql.plan = free
|
||||
* cloud.services.mysql.connection.hostname = ...
|
||||
* cloud.services.mysql.connection.port = ...
|
||||
* etc...
|
||||
* </pre>
|
||||
*
|
||||
* @return the properties object
|
||||
*/
|
||||
public Properties getCloudProperties() {
|
||||
Map<String, List<ServiceInfo>> mappedServiceInfos = new HashMap<String, List<ServiceInfo>>();
|
||||
for (ServiceInfo serviceInfo : getServiceInfos()) {
|
||||
String key = getServiceLabel(serviceInfo);
|
||||
List<ServiceInfo> serviceInfosForLabel = mappedServiceInfos.get(key);
|
||||
if (serviceInfosForLabel == null) {
|
||||
serviceInfosForLabel = new ArrayList<ServiceInfo>();
|
||||
mappedServiceInfos.put(key, serviceInfosForLabel);
|
||||
}
|
||||
serviceInfosForLabel.add(serviceInfo);
|
||||
}
|
||||
|
||||
final String servicePropKeyLead = "cloud.services.";
|
||||
Properties cloudProperties = new Properties();
|
||||
for (Entry<String, List<ServiceInfo>> mappedServiceInfo : mappedServiceInfos.entrySet()) {
|
||||
List<ServiceInfo> serviceInfos = mappedServiceInfo.getValue();
|
||||
final String servicePropKeyLead = "cloud.services.";
|
||||
Properties cloudProperties = new Properties();
|
||||
for (Entry<String, List<ServiceInfo>> mappedServiceInfo : mappedServiceInfos.entrySet()) {
|
||||
List<ServiceInfo> serviceInfos = mappedServiceInfo.getValue();
|
||||
|
||||
for (ServiceInfo serviceInfo : serviceInfos) {
|
||||
String idBasedKey = servicePropKeyLead + serviceInfo.getId();
|
||||
cloudProperties.putAll(getServiceProperties(idBasedKey, serviceInfo));
|
||||
for (ServiceInfo serviceInfo : serviceInfos) {
|
||||
String idBasedKey = servicePropKeyLead + serviceInfo.getId();
|
||||
cloudProperties.putAll(getServiceProperties(idBasedKey, serviceInfo));
|
||||
|
||||
// If there is only one service for a given label, put props with that label instead of just id
|
||||
if (serviceInfos.size() == 1) {
|
||||
String labelBasedKey = servicePropKeyLead + mappedServiceInfo.getKey();
|
||||
cloudProperties.putAll(getServiceProperties(labelBasedKey, serviceInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
// If there is only one service for a given label, put props with that label instead of just id
|
||||
if (serviceInfos.size() == 1) {
|
||||
String labelBasedKey = servicePropKeyLead + mappedServiceInfo.getKey();
|
||||
cloudProperties.putAll(getServiceProperties(labelBasedKey, serviceInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cloudProperties.putAll(getAppProperties());
|
||||
cloudProperties.putAll(getAppProperties());
|
||||
|
||||
return cloudProperties;
|
||||
}
|
||||
return cloudProperties;
|
||||
}
|
||||
|
||||
private <SC> SC getServiceConnector(ServiceInfo serviceInfo, Class<SC> serviceConnectorType,
|
||||
ServiceConnectorConfig serviceConnectorConfig) {
|
||||
ServiceConnectorCreator<SC, ServiceInfo> serviceConnectorCreator = serviceConnectorCreatorRegistry.getServiceCreator(
|
||||
serviceConnectorType, serviceInfo);
|
||||
return serviceConnectorCreator.create(serviceInfo, serviceConnectorConfig);
|
||||
}
|
||||
private <SC> SC getServiceConnector(ServiceInfo serviceInfo, Class<SC> serviceConnectorType,
|
||||
ServiceConnectorConfig serviceConnectorConfig) {
|
||||
ServiceConnectorCreator<SC, ServiceInfo> serviceConnectorCreator = serviceConnectorCreatorRegistry.getServiceCreator(
|
||||
serviceConnectorType, serviceInfo);
|
||||
return serviceConnectorCreator.create(serviceInfo, serviceConnectorConfig);
|
||||
}
|
||||
|
||||
private Properties getAppProperties() {
|
||||
final String appPropLeadKey = "cloud.application.";
|
||||
private Properties getAppProperties() {
|
||||
final String appPropLeadKey = "cloud.application.";
|
||||
|
||||
Properties appProperties = new Properties();
|
||||
appProperties.put(appPropLeadKey + "instance-id", getApplicationInstanceInfo().getInstanceId());
|
||||
appProperties.put(appPropLeadKey + "app-id", getApplicationInstanceInfo().getAppId());
|
||||
for (Map.Entry<String, Object> entry : getApplicationInstanceInfo().getProperties().entrySet()) {
|
||||
if (entry.getValue() != null) {
|
||||
appProperties.put(appPropLeadKey + entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
Properties appProperties = new Properties();
|
||||
appProperties.put(appPropLeadKey + "instance-id", getApplicationInstanceInfo().getInstanceId());
|
||||
appProperties.put(appPropLeadKey + "app-id", getApplicationInstanceInfo().getAppId());
|
||||
for (Map.Entry<String, Object> entry : getApplicationInstanceInfo().getProperties().entrySet()) {
|
||||
if (entry.getValue() != null) {
|
||||
appProperties.put(appPropLeadKey + entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return appProperties;
|
||||
}
|
||||
return appProperties;
|
||||
}
|
||||
|
||||
private Properties getServiceProperties(String keyLead, ServiceInfo serviceInfo) {
|
||||
Properties cloudProperties = new Properties();
|
||||
private Properties getServiceProperties(String keyLead, ServiceInfo serviceInfo) {
|
||||
Properties cloudProperties = new Properties();
|
||||
|
||||
try {
|
||||
BeanInfo beanInfo = Introspector.getBeanInfo(serviceInfo.getClass());
|
||||
PropertyDescriptor[] propDescriptors = beanInfo.getPropertyDescriptors();
|
||||
for (PropertyDescriptor propDescriptor : propDescriptors) {
|
||||
ServiceProperty propAnnotation = propDescriptor.getReadMethod().getAnnotation(ServiceProperty.class);
|
||||
String key = keyLead;
|
||||
try {
|
||||
BeanInfo beanInfo = Introspector.getBeanInfo(serviceInfo.getClass());
|
||||
PropertyDescriptor[] propDescriptors = beanInfo.getPropertyDescriptors();
|
||||
for (PropertyDescriptor propDescriptor : propDescriptors) {
|
||||
ServiceProperty propAnnotation = propDescriptor.getReadMethod().getAnnotation(ServiceProperty.class);
|
||||
String key = keyLead;
|
||||
|
||||
if (propAnnotation != null) {
|
||||
if (!propAnnotation.category().isEmpty()) {
|
||||
key = key + "." + propAnnotation.category();
|
||||
}
|
||||
if (!propAnnotation.name().isEmpty()) {
|
||||
key = key + "." + propAnnotation.name();
|
||||
} else {
|
||||
key = key + "." + propDescriptor.getName().toLowerCase();
|
||||
}
|
||||
if (propAnnotation != null) {
|
||||
if (!propAnnotation.category().isEmpty()) {
|
||||
key = key + "." + propAnnotation.category();
|
||||
}
|
||||
if (!propAnnotation.name().isEmpty()) {
|
||||
key = key + "." + propAnnotation.name();
|
||||
} else {
|
||||
key = key + "." + propDescriptor.getName().toLowerCase();
|
||||
}
|
||||
|
||||
Object value = propDescriptor.getReadMethod().invoke(serviceInfo);
|
||||
Object value = propDescriptor.getReadMethod().invoke(serviceInfo);
|
||||
|
||||
if (value != null) {
|
||||
cloudProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new CloudException(e);
|
||||
}
|
||||
if (value != null) {
|
||||
cloudProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new CloudException(e);
|
||||
}
|
||||
|
||||
return cloudProperties;
|
||||
}
|
||||
return cloudProperties;
|
||||
}
|
||||
|
||||
private static String getServiceLabel(ServiceInfo serviceInfo) {
|
||||
Class<? extends ServiceInfo> serviceInfoClass = serviceInfo.getClass();
|
||||
private static String getServiceLabel(ServiceInfo serviceInfo) {
|
||||
Class<? extends ServiceInfo> serviceInfoClass = serviceInfo.getClass();
|
||||
|
||||
ServiceLabel labelAnnotation = serviceInfoClass.getAnnotation(ServiceInfo.ServiceLabel.class);
|
||||
ServiceLabel labelAnnotation = serviceInfoClass.getAnnotation(ServiceInfo.ServiceLabel.class);
|
||||
|
||||
if (labelAnnotation == null) {
|
||||
return null;
|
||||
} else {
|
||||
return labelAnnotation.value();
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ServiceInfo> flatten(List<ServiceInfo> serviceInfos) {
|
||||
List<ServiceInfo> flattened = new ArrayList<ServiceInfo>();
|
||||
|
||||
for (ServiceInfo serviceInfo : serviceInfos) {
|
||||
if (serviceInfo instanceof CompositeServiceInfo) {
|
||||
// recursively flatten any CompositeServiceInfos
|
||||
CompositeServiceInfo compositeServiceInfo = (CompositeServiceInfo)serviceInfo;
|
||||
flattened.addAll(flatten(compositeServiceInfo.getServiceInfos()));
|
||||
} else {
|
||||
flattened.add(serviceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return flattened;
|
||||
}
|
||||
if (labelAnnotation == null) {
|
||||
return null;
|
||||
} else {
|
||||
return labelAnnotation.value();
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ServiceInfo> flatten(List<ServiceInfo> serviceInfos) {
|
||||
List<ServiceInfo> flattened = new ArrayList<ServiceInfo>();
|
||||
|
||||
for (ServiceInfo serviceInfo : serviceInfos) {
|
||||
if (serviceInfo instanceof CompositeServiceInfo) {
|
||||
// recursively flatten any CompositeServiceInfos
|
||||
CompositeServiceInfo compositeServiceInfo = (CompositeServiceInfo)serviceInfo;
|
||||
flattened.addAll(flatten(compositeServiceInfo.getServiceInfos()));
|
||||
} else {
|
||||
flattened.add(serviceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return flattened;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class ServiceConnectorCreatorRegistry {
|
||||
private static Logger logger = Logger.getLogger(Cloud.class.getName());
|
||||
private static Logger logger = Logger.getLogger(Cloud.class.getName());
|
||||
|
||||
private List<ServiceConnectorCreator<?, ? extends ServiceInfo>> serviceConnectorCreators = new ArrayList<ServiceConnectorCreator<?, ? extends ServiceInfo>>();
|
||||
private List<ServiceConnectorCreator<?, ? extends ServiceInfo>> serviceConnectorCreators = new ArrayList<ServiceConnectorCreator<?, ? extends ServiceInfo>>();
|
||||
|
||||
public void registerCreator(ServiceConnectorCreator<?, ? extends ServiceInfo> serviceConnectorCreator) {
|
||||
serviceConnectorCreators.add(serviceConnectorCreator);
|
||||
}
|
||||
public void registerCreator(ServiceConnectorCreator<?, ? extends ServiceInfo> serviceConnectorCreator) {
|
||||
serviceConnectorCreators.add(serviceConnectorCreator);
|
||||
}
|
||||
|
||||
public <SC, SI extends ServiceInfo> ServiceConnectorCreator<SC, SI> getServiceCreator(Class<SC> serviceConnectorType,
|
||||
SI serviceInfo) {
|
||||
ServiceConnectorCreator<SC, SI> serviceConnectorCreator = getServiceCreatorOrNull(serviceConnectorType, serviceInfo);
|
||||
public <SC, SI extends ServiceInfo> ServiceConnectorCreator<SC, SI> getServiceCreator(Class<SC> serviceConnectorType,
|
||||
SI serviceInfo) {
|
||||
ServiceConnectorCreator<SC, SI> serviceConnectorCreator = getServiceCreatorOrNull(serviceConnectorType, serviceInfo);
|
||||
|
||||
if (serviceConnectorCreator != null) {
|
||||
return serviceConnectorCreator;
|
||||
} else {
|
||||
throw new CloudException("No suitable ServiceConnectorCreator found: "
|
||||
+ "service id=" + serviceInfo.getId() + ", "
|
||||
+ "service info type=" + serviceInfo.getClass().getName() + ", "
|
||||
+ "connector type=" + serviceConnectorType);
|
||||
}
|
||||
}
|
||||
if (serviceConnectorCreator != null) {
|
||||
return serviceConnectorCreator;
|
||||
} else {
|
||||
throw new CloudException("No suitable ServiceConnectorCreator found: "
|
||||
+ "service id=" + serviceInfo.getId() + ", "
|
||||
+ "service info type=" + serviceInfo.getClass().getName() + ", "
|
||||
+ "connector type=" + serviceConnectorType);
|
||||
}
|
||||
}
|
||||
|
||||
public <SC, SI extends ServiceInfo> boolean canCreate(Class<SC> serviceConnectorType, SI serviceInfo) {
|
||||
return getServiceCreatorOrNull(serviceConnectorType, serviceInfo) != null;
|
||||
}
|
||||
public <SC, SI extends ServiceInfo> boolean canCreate(Class<SC> serviceConnectorType, SI serviceInfo) {
|
||||
return getServiceCreatorOrNull(serviceConnectorType, serviceInfo) != null;
|
||||
}
|
||||
|
||||
public boolean accept(ServiceConnectorCreator<?, ? extends ServiceInfo> creator, Class<?> serviceConnectorType,
|
||||
ServiceInfo serviceInfo) {
|
||||
boolean typeBasedAccept = serviceConnectorType == null ? true : serviceConnectorType.isAssignableFrom(creator
|
||||
.getServiceConnectorType());
|
||||
boolean infoBasedAccept = serviceInfo == null ? true : creator.getServiceInfoType()
|
||||
.isAssignableFrom(serviceInfo.getClass());
|
||||
public boolean accept(ServiceConnectorCreator<?, ? extends ServiceInfo> creator, Class<?> serviceConnectorType,
|
||||
ServiceInfo serviceInfo) {
|
||||
boolean typeBasedAccept = serviceConnectorType == null ||
|
||||
serviceConnectorType.isAssignableFrom(creator.getServiceConnectorType());
|
||||
boolean infoBasedAccept = serviceInfo == null ||
|
||||
creator.getServiceInfoType().isAssignableFrom(serviceInfo.getClass());
|
||||
|
||||
return typeBasedAccept && infoBasedAccept;
|
||||
}
|
||||
return typeBasedAccept && infoBasedAccept;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <SC, SI extends ServiceInfo> ServiceConnectorCreator<SC, SI> getServiceCreatorOrNull(Class<SC> serviceConnectorType,
|
||||
SI serviceInfo) {
|
||||
for (ServiceConnectorCreator<?, ? extends ServiceInfo> serviceConnectorCreator : serviceConnectorCreators) {
|
||||
logger.fine("Trying connector creator type " + serviceConnectorCreator);
|
||||
if (accept(serviceConnectorCreator, serviceConnectorType, serviceInfo)) {
|
||||
return (ServiceConnectorCreator<SC, SI>) serviceConnectorCreator;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
private <SC, SI extends ServiceInfo> ServiceConnectorCreator<SC, SI> getServiceCreatorOrNull(Class<SC> serviceConnectorType,
|
||||
SI serviceInfo) {
|
||||
for (ServiceConnectorCreator<?, ? extends ServiceInfo> serviceConnectorCreator : serviceConnectorCreators) {
|
||||
logger.fine("Trying connector creator type " + serviceConnectorCreator);
|
||||
if (accept(serviceConnectorCreator, serviceConnectorType, serviceInfo)) {
|
||||
return (ServiceConnectorCreator<SC, SI>) serviceConnectorCreator;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,78 +28,78 @@ import org.springframework.cloud.util.ServiceLoaderWithExceptionControl;
|
||||
*
|
||||
*/
|
||||
public class CloudFactory {
|
||||
private List<CloudConnector> cloudConnectors = new ArrayList<CloudConnector>();
|
||||
private List<ServiceConnectorCreator<?, ? extends ServiceInfo>> serviceCreators = new ArrayList<ServiceConnectorCreator<?, ? extends ServiceInfo>>();
|
||||
private List<CloudConnector> cloudConnectors = new ArrayList<CloudConnector>();
|
||||
private List<ServiceConnectorCreator<?, ? extends ServiceInfo>> serviceCreators = new ArrayList<ServiceConnectorCreator<?, ? extends ServiceInfo>>();
|
||||
|
||||
public CloudFactory() {
|
||||
scanCloudConnectors();
|
||||
scanServiceConnectorCreators();
|
||||
}
|
||||
public CloudFactory() {
|
||||
scanCloudConnectors();
|
||||
scanServiceConnectorCreators();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return a cloud suitable for the current environment
|
||||
* @throws CloudException
|
||||
* if no suitable cloud found
|
||||
*/
|
||||
public Cloud getCloud() {
|
||||
CloudConnector suitableCloudConnector = null;
|
||||
for (CloudConnector cloudConnector : cloudConnectors) {
|
||||
if (cloudConnector.isInMatchingCloud()) {
|
||||
suitableCloudConnector = cloudConnector;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return a cloud suitable for the current environment
|
||||
* @throws CloudException
|
||||
* if no suitable cloud found
|
||||
*/
|
||||
public Cloud getCloud() {
|
||||
CloudConnector suitableCloudConnector = null;
|
||||
for (CloudConnector cloudConnector : cloudConnectors) {
|
||||
if (cloudConnector.isInMatchingCloud()) {
|
||||
suitableCloudConnector = cloudConnector;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (suitableCloudConnector == null) {
|
||||
throw new CloudException("No suitable cloud connector found");
|
||||
}
|
||||
if (suitableCloudConnector == null) {
|
||||
throw new CloudException("No suitable cloud connector found");
|
||||
}
|
||||
|
||||
return new Cloud(suitableCloudConnector, serviceCreators);
|
||||
}
|
||||
return new Cloud(suitableCloudConnector, serviceCreators);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a cloud connector.
|
||||
*
|
||||
* <p>
|
||||
* CloudConnector developers should prefer the declarative mechanism described in README.MD instead of calling this method.
|
||||
* </p>
|
||||
*
|
||||
* @param cloudConnector
|
||||
* the cloud connector to register for discovery
|
||||
*/
|
||||
public void registerCloudConnector(CloudConnector cloudConnector) {
|
||||
cloudConnectors.add(cloudConnector);
|
||||
}
|
||||
/**
|
||||
* Register a cloud connector.
|
||||
*
|
||||
* <p>
|
||||
* CloudConnector developers should prefer the declarative mechanism described in README.MD instead of calling this method.
|
||||
* </p>
|
||||
*
|
||||
* @param cloudConnector
|
||||
* the cloud connector to register for discovery
|
||||
*/
|
||||
public void registerCloudConnector(CloudConnector cloudConnector) {
|
||||
cloudConnectors.add(cloudConnector);
|
||||
}
|
||||
|
||||
/* package access for testing */
|
||||
List<CloudConnector> getCloudConnectors() {
|
||||
return cloudConnectors;
|
||||
}
|
||||
/* package access for testing */
|
||||
List<CloudConnector> getCloudConnectors() {
|
||||
return cloudConnectors;
|
||||
}
|
||||
|
||||
/* package access for testing */
|
||||
List<ServiceConnectorCreator<?, ? extends ServiceInfo>> getServiceCreators() {
|
||||
return serviceCreators;
|
||||
}
|
||||
/* package access for testing */
|
||||
List<ServiceConnectorCreator<?, ? extends ServiceInfo>> getServiceCreators() {
|
||||
return serviceCreators;
|
||||
}
|
||||
|
||||
private void registerServiceCreator(ServiceConnectorCreator<?, ? extends ServiceInfo> serviceConnectorCreator) {
|
||||
serviceCreators.add(serviceConnectorCreator);
|
||||
}
|
||||
private void registerServiceCreator(ServiceConnectorCreator<?, ? extends ServiceInfo> serviceConnectorCreator) {
|
||||
serviceCreators.add(serviceConnectorCreator);
|
||||
}
|
||||
|
||||
private void scanCloudConnectors() {
|
||||
Iterable<CloudConnector> loader = ServiceLoader.load(CloudConnector.class);
|
||||
for (CloudConnector cloudConnector : loader) {
|
||||
registerCloudConnector(cloudConnector);
|
||||
}
|
||||
}
|
||||
private void scanCloudConnectors() {
|
||||
Iterable<CloudConnector> loader = ServiceLoader.load(CloudConnector.class);
|
||||
for (CloudConnector cloudConnector : loader) {
|
||||
registerCloudConnector(cloudConnector);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private void scanServiceConnectorCreators() {
|
||||
Iterable<ServiceConnectorCreator> loader = ServiceLoaderWithExceptionControl.load(ServiceConnectorCreator.class);
|
||||
for (ServiceConnectorCreator serviceConnectorCreator : loader) {
|
||||
if (serviceConnectorCreator != null) {
|
||||
registerServiceCreator(serviceConnectorCreator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private void scanServiceConnectorCreators() {
|
||||
Iterable<ServiceConnectorCreator> loader = ServiceLoaderWithExceptionControl.load(ServiceConnectorCreator.class);
|
||||
for (ServiceConnectorCreator serviceConnectorCreator : loader) {
|
||||
if (serviceConnectorCreator != null) {
|
||||
registerServiceCreator(serviceConnectorCreator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,20 +11,17 @@ import org.springframework.cloud.service.ServiceInfo;
|
||||
* for it isn't placed properly to be picked up by scanning. By having a fallback mechanism, we can
|
||||
* extract as much info from the service data as possible (minimally, the service id) and issue a warning.
|
||||
*
|
||||
* @param <SI> the type of {@link ServiceInfo} that this fallback creator will return
|
||||
* @param <SD> the type of service definition data that this creator will consume
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
* @param <SI>
|
||||
* the type of {@link ServiceInfo} that this fallback creator will return
|
||||
* @param <SD>
|
||||
* the type of service definition data that this creator will consume
|
||||
*/
|
||||
public abstract class FallbackServiceInfoCreator<SI extends ServiceInfo, SD> implements ServiceInfoCreator<SI, SD> {
|
||||
|
||||
/*
|
||||
* Override to ensure that it accepts all service data
|
||||
*/
|
||||
@Override
|
||||
public final boolean accept(SD serviceData) {
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
* Override to ensure that it accepts all service data
|
||||
*/
|
||||
@Override
|
||||
public final boolean accept(SD serviceData) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,16 +10,16 @@ import java.util.List;
|
||||
*
|
||||
*/
|
||||
public class BaseCompositeServiceInfo extends BaseServiceInfo implements CompositeServiceInfo {
|
||||
|
||||
private List<ServiceInfo> constituents;
|
||||
|
||||
public BaseCompositeServiceInfo(String id, ServiceInfo... constituents) {
|
||||
super(id);
|
||||
this.constituents = Arrays.asList(constituents);
|
||||
}
|
||||
private List<ServiceInfo> constituents;
|
||||
|
||||
@Override
|
||||
public List<ServiceInfo> getServiceInfos() {
|
||||
return constituents;
|
||||
}
|
||||
public BaseCompositeServiceInfo(String id, ServiceInfo... constituents) {
|
||||
super(id);
|
||||
this.constituents = Arrays.asList(constituents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceInfo> getServiceInfos() {
|
||||
return constituents;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ import org.springframework.cloud.Cloud;
|
||||
*/
|
||||
public interface CompositeServiceInfo extends ServiceInfo {
|
||||
|
||||
List<ServiceInfo> getServiceInfos();
|
||||
|
||||
List<ServiceInfo> getServiceInfos();
|
||||
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package org.springframework.cloud.service;
|
||||
import org.springframework.cloud.FallbackServiceInfoCreator;
|
||||
|
||||
public class FallbackBaseServiceInfoCreator extends FallbackServiceInfoCreator<BaseServiceInfo, UriBasedServiceData> {
|
||||
@Override
|
||||
public BaseServiceInfo createServiceInfo(UriBasedServiceData serviceData) {
|
||||
return new BaseServiceInfo(serviceData.getKey());
|
||||
}
|
||||
@Override
|
||||
public BaseServiceInfo createServiceInfo(UriBasedServiceData serviceData) {
|
||||
return new BaseServiceInfo(serviceData.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,35 +8,31 @@ import org.springframework.cloud.service.common.MysqlServiceInfo;
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
* @param <SC>
|
||||
* service connector type
|
||||
* @param <SI>
|
||||
* service info type
|
||||
* @param <SC> service connector type
|
||||
* @param <SI> service info type
|
||||
*/
|
||||
public interface ServiceConnectorCreator<SC, SI extends ServiceInfo> {
|
||||
/**
|
||||
* Create service for the given service info and configured with the given
|
||||
* configuration
|
||||
*
|
||||
* @param serviceInfo
|
||||
* the {@link ServiceInfo} object containing the information necessary to connect to the service
|
||||
* @param serviceConnectorConfig
|
||||
* configuration information to be applied to the connection
|
||||
* @return service connector
|
||||
*/
|
||||
SC create(SI serviceInfo, ServiceConnectorConfig serviceConnectorConfig);
|
||||
/**
|
||||
* Create service for the given service info and configured with the given
|
||||
* configuration
|
||||
*
|
||||
* @param serviceInfo the {@link ServiceInfo} object containing the information necessary to connect to the service
|
||||
* @param serviceConnectorConfig configuration information to be applied to the connection
|
||||
* @return service connector
|
||||
*/
|
||||
SC create(SI serviceInfo, ServiceConnectorConfig serviceConnectorConfig);
|
||||
|
||||
/**
|
||||
* Get the type of connector created (such as {@link DataSource})
|
||||
*
|
||||
* @return service connector type
|
||||
*/
|
||||
Class<SC> getServiceConnectorType();
|
||||
/**
|
||||
* Get the type of connector created (such as {@link DataSource})
|
||||
*
|
||||
* @return service connector type
|
||||
*/
|
||||
Class<SC> getServiceConnectorType();
|
||||
|
||||
/**
|
||||
* Get the service info type this creator can work with (such as {@link MysqlServiceInfo})
|
||||
*
|
||||
* @return service info type
|
||||
*/
|
||||
Class<?> getServiceInfoType();
|
||||
/**
|
||||
* Get the service info type this creator can work with (such as {@link MysqlServiceInfo})
|
||||
*
|
||||
* @return service info type
|
||||
*/
|
||||
Class<?> getServiceInfoType();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
|
||||
@ServiceLabel("mongo")
|
||||
public class MongoServiceInfo extends UriBasedServiceInfo {
|
||||
|
||||
public static final String MONGODB_SCHEME = "mongodb";
|
||||
public static final String MONGODB_SCHEME = "mongodb";
|
||||
|
||||
public MongoServiceInfo(String id, String host, int port, String username, String password, String db) {
|
||||
super(id, MONGODB_SCHEME, host, port, username, password, db);
|
||||
|
||||
@@ -10,11 +10,11 @@ import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
|
||||
@ServiceLabel("mysql")
|
||||
public class MysqlServiceInfo extends RelationalServiceInfo {
|
||||
|
||||
private static final String JDBC_URL_TYPE = "mysql";
|
||||
private static final String JDBC_URL_TYPE = "mysql";
|
||||
|
||||
public static final String MYSQL_SCHEME = JDBC_URL_TYPE;
|
||||
public static final String MYSQL_SCHEME = JDBC_URL_TYPE;
|
||||
|
||||
public MysqlServiceInfo(String id, String url) {
|
||||
super(id, url, MYSQL_SCHEME);
|
||||
}
|
||||
public MysqlServiceInfo(String id, String url) {
|
||||
super(id, url, MYSQL_SCHEME);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import org.springframework.cloud.service.ServiceInfo;
|
||||
@ServiceInfo.ServiceLabel("oracle")
|
||||
public class OracleServiceInfo extends RelationalServiceInfo {
|
||||
|
||||
private static final String JDBC_URL_TYPE = "oracle";
|
||||
private static final String JDBC_URL_TYPE = "oracle";
|
||||
|
||||
public static final String ORACLE_SCHEME = JDBC_URL_TYPE;
|
||||
public static final String ORACLE_SCHEME = JDBC_URL_TYPE;
|
||||
|
||||
public OracleServiceInfo(String id, String url) {
|
||||
super(id, url, JDBC_URL_TYPE);
|
||||
|
||||
@@ -11,9 +11,9 @@ import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
|
||||
@ServiceLabel("postgresql")
|
||||
public class PostgresqlServiceInfo extends RelationalServiceInfo {
|
||||
|
||||
private static final String JDBC_URL_TYPE = "postgresql";
|
||||
private static final String JDBC_URL_TYPE = "postgresql";
|
||||
|
||||
public static final String POSTGRES_SCHEME = "postgres";
|
||||
public static final String POSTGRES_SCHEME = "postgres";
|
||||
|
||||
public PostgresqlServiceInfo(String id, String url) {
|
||||
super(id, url, JDBC_URL_TYPE);
|
||||
|
||||
@@ -11,13 +11,13 @@ import org.springframework.cloud.service.ServiceInfo.ServiceLabel;
|
||||
@ServiceLabel("redis")
|
||||
public class RedisServiceInfo extends UriBasedServiceInfo {
|
||||
|
||||
public static final String REDIS_SCHEME = "redis";
|
||||
public static final String REDIS_SCHEME = "redis";
|
||||
|
||||
public RedisServiceInfo(String id, String host, int port, String password) {
|
||||
super(id, REDIS_SCHEME, host, port, null, password, null);
|
||||
}
|
||||
|
||||
public RedisServiceInfo(String id, String uri) {
|
||||
super(id, uri);
|
||||
}
|
||||
super(id, uri);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,56 +20,55 @@ import org.springframework.cloud.service.ServiceConnectorCreator;
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
* @param <T>
|
||||
* the type of the service being loaded
|
||||
* @param <T> the type of the service being loaded
|
||||
*/
|
||||
public class ServiceLoaderWithExceptionControl<T> implements Iterable<T> {
|
||||
private Iterable<T> underlying;
|
||||
private Iterable<T> underlying;
|
||||
|
||||
private static Logger logger = Logger.getLogger(ServiceLoaderWithExceptionControl.class.getName());
|
||||
private static Logger logger = Logger.getLogger(ServiceLoaderWithExceptionControl.class.getName());
|
||||
|
||||
public static <T> Iterable<T> load(Class<T> serviceType) {
|
||||
ServiceLoader<T> loader = ServiceLoader.load(serviceType);
|
||||
return new ServiceLoaderWithExceptionControl<T>(loader);
|
||||
}
|
||||
public static <T> Iterable<T> load(Class<T> serviceType) {
|
||||
ServiceLoader<T> loader = ServiceLoader.load(serviceType);
|
||||
return new ServiceLoaderWithExceptionControl<T>(loader);
|
||||
}
|
||||
|
||||
private ServiceLoaderWithExceptionControl(Iterable<T> underlying) {
|
||||
this.underlying = underlying;
|
||||
}
|
||||
private ServiceLoaderWithExceptionControl(Iterable<T> underlying) {
|
||||
this.underlying = underlying;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new ServiceLoaderIterator(underlying.iterator());
|
||||
}
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new ServiceLoaderIterator(underlying.iterator());
|
||||
}
|
||||
|
||||
private class ServiceLoaderIterator implements Iterator<T> {
|
||||
private Iterator<T> underlying;
|
||||
private class ServiceLoaderIterator implements Iterator<T> {
|
||||
private Iterator<T> underlying;
|
||||
|
||||
public ServiceLoaderIterator(Iterator<T> underlying) {
|
||||
this.underlying = underlying;
|
||||
}
|
||||
public ServiceLoaderIterator(Iterator<T> underlying) {
|
||||
this.underlying = underlying;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return underlying.hasNext();
|
||||
}
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return underlying.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
try {
|
||||
return underlying.next();
|
||||
} catch (ServiceConfigurationError e) {
|
||||
logger.log(Level.CONFIG, "Failed to load " + e);
|
||||
if (hasNext()) {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public T next() {
|
||||
try {
|
||||
return underlying.next();
|
||||
} catch (ServiceConfigurationError e) {
|
||||
logger.log(Level.CONFIG, "Failed to load " + e);
|
||||
if (hasNext()) {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
underlying.remove();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void remove() {
|
||||
underlying.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,8 @@ public class AmqpServiceInfoCreator extends HerokuServiceInfoCreator<AmqpService
|
||||
return new AmqpServiceInfo(HerokuUtil.computeServiceName(id), uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getEnvPrefixes() {
|
||||
return new String[]{ "CLOUDAMQP_URL" };
|
||||
}
|
||||
@Override
|
||||
public String[] getEnvPrefixes() {
|
||||
return new String[]{ "CLOUDAMQP_URL" };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package org.springframework.cloud.heroku;
|
||||
|
||||
public class HerokuUtil {
|
||||
public static String computeServiceName(String envVar) {
|
||||
String[] stripSuffices = new String[]{"_URL", "_URI"};
|
||||
|
||||
for (String suffix: stripSuffices) {
|
||||
if (envVar.endsWith(suffix)) {
|
||||
return envVar.substring(0, envVar.length() - suffix.length());
|
||||
}
|
||||
}
|
||||
|
||||
return envVar;
|
||||
}
|
||||
public static String computeServiceName(String envVar) {
|
||||
String[] stripSuffices = new String[]{"_URL", "_URI"};
|
||||
|
||||
for (String suffix: stripSuffices) {
|
||||
if (envVar.endsWith(suffix)) {
|
||||
return envVar.substring(0, envVar.length() - suffix.length());
|
||||
}
|
||||
}
|
||||
|
||||
return envVar;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ public class MongoServiceInfoCreator extends HerokuServiceInfoCreator<MongoServi
|
||||
return new MongoServiceInfo(HerokuUtil.computeServiceName(id), uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getEnvPrefixes() {
|
||||
return new String[]{ "MONGOLAB_URI", "MONGOHQ_URL", "MONGOSOUP_URL" };
|
||||
}
|
||||
@Override
|
||||
public String[] getEnvPrefixes() {
|
||||
return new String[]{ "MONGOLAB_URI", "MONGOHQ_URL", "MONGOSOUP_URL" };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ public class MysqlServiceInfoCreator extends RelationalServiceInfoCreator<MysqlS
|
||||
return new MysqlServiceInfo(HerokuUtil.computeServiceName(id), uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getEnvPrefixes() {
|
||||
return new String[]{"CLEARDB_DATABASE_URL"};
|
||||
}
|
||||
@Override
|
||||
public String[] getEnvPrefixes() {
|
||||
return new String[]{"CLEARDB_DATABASE_URL"};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ public class PostgresqlServiceInfoCreator extends RelationalServiceInfoCreator<P
|
||||
return new PostgresqlServiceInfo(HerokuUtil.computeServiceName(id), uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getEnvPrefixes() {
|
||||
return new String[]{"HEROKU_POSTGRESQL_"};
|
||||
}
|
||||
@Override
|
||||
public String[] getEnvPrefixes() {
|
||||
return new String[]{"HEROKU_POSTGRESQL_"};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ public class RedisServiceInfoCreator extends HerokuServiceInfoCreator<RedisServi
|
||||
return new RedisServiceInfo(HerokuUtil.computeServiceName(id), uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getEnvPrefixes() {
|
||||
return new String[]{ "REDISTOGO_URL", "REDISCLOUD_URL", "OPENREDIS_URL", "REDISGREEN_URL" };
|
||||
}
|
||||
@Override
|
||||
public String[] getEnvPrefixes() {
|
||||
return new String[]{ "REDISTOGO_URL", "REDISCLOUD_URL", "OPENREDIS_URL", "REDISGREEN_URL" };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,43 +5,41 @@ import static org.junit.Assert.assertEquals;
|
||||
import org.springframework.cloud.service.common.RelationalServiceInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractHerokuConnectorRelationalServiceTest extends AbstractHerokuConnectorTest {
|
||||
private String databaseType;
|
||||
private String databaseType;
|
||||
|
||||
public AbstractHerokuConnectorRelationalServiceTest(String databaseType) {
|
||||
this.databaseType = databaseType;
|
||||
}
|
||||
|
||||
public AbstractHerokuConnectorRelationalServiceTest(String databaseType) {
|
||||
this.databaseType = databaseType;
|
||||
}
|
||||
|
||||
protected String getJdbcUrl(String name) {
|
||||
String jdbcUrlDatabaseType = databaseType;
|
||||
if (databaseType.equals("postgres")) {
|
||||
jdbcUrlDatabaseType = "postgresql";
|
||||
}
|
||||
|
||||
return "jdbc:" + jdbcUrlDatabaseType + "://" + hostname + ":" + port + "/" + name +
|
||||
"?user=" + username + "&password=" + password;
|
||||
return "jdbc:" + jdbcUrlDatabaseType + "://" + hostname + ":" + port + "/" + name +
|
||||
"?user=" + username + "&password=" + password;
|
||||
}
|
||||
|
||||
protected String getRelationalServiceUrl(String name) {
|
||||
String template = "$databaseType://$username:$password@$host:$port/$database";
|
||||
protected String getRelationalServiceUrl(String name) {
|
||||
String template = "$databaseType://$username:$password@$host:$port/$database";
|
||||
|
||||
return template.replace("$databaseType", databaseType).
|
||||
replace("$username", username).
|
||||
replace("$password", password).
|
||||
replace("$host", hostname).
|
||||
replace("$port", Integer.toString(port)).
|
||||
replace("$database", name);
|
||||
}
|
||||
|
||||
protected void assertReleationServiceInfo(RelationalServiceInfo serviceInfo, String databaseName) {
|
||||
assertEquals(hostname, serviceInfo.getHost());
|
||||
assertEquals(port, serviceInfo.getPort());
|
||||
assertEquals(username, serviceInfo.getUserName());
|
||||
assertEquals(password, serviceInfo.getPassword());
|
||||
assertEquals(getJdbcUrl(databaseName), serviceInfo.getJdbcUrl());
|
||||
}
|
||||
return template.replace("$databaseType", databaseType).
|
||||
replace("$username", username).
|
||||
replace("$password", password).
|
||||
replace("$host", hostname).
|
||||
replace("$port", Integer.toString(port)).
|
||||
replace("$database", name);
|
||||
}
|
||||
|
||||
protected void assertReleationServiceInfo(RelationalServiceInfo serviceInfo, String databaseName) {
|
||||
assertEquals(hostname, serviceInfo.getHost());
|
||||
assertEquals(port, serviceInfo.getPort());
|
||||
assertEquals(username, serviceInfo.getUserName());
|
||||
assertEquals(password, serviceInfo.getPassword());
|
||||
assertEquals(getJdbcUrl(databaseName), serviceInfo.getJdbcUrl());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@ import org.springframework.cloud.util.EnvironmentAccessor;
|
||||
* Base test class that provides setup and utility methods to generate test payload
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractHerokuConnectorTest {
|
||||
protected HerokuConnector testCloudConnector = new HerokuConnector();
|
||||
@Mock protected EnvironmentAccessor mockEnvironment;
|
||||
@Mock
|
||||
protected EnvironmentAccessor mockEnvironment;
|
||||
|
||||
protected static final String hostname = "10.20.30.40";
|
||||
protected static final int port = 1234;
|
||||
|
||||
@@ -14,43 +14,41 @@ import org.springframework.cloud.service.ServiceInfo;
|
||||
import org.springframework.cloud.service.common.AmqpServiceInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public class HerokuConnectorAmqpServiceTest extends AbstractHerokuConnectorTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void amqpServiceCreation() {
|
||||
Map<String, String> env = new HashMap<String, String>();
|
||||
String amqpUrl = getAmqpServiceUrl("db");
|
||||
env.put("CLOUDAMQP_URL", amqpUrl);
|
||||
when(mockEnvironment.getEnv()).thenReturn(env);
|
||||
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
ServiceInfo serviceInfo = getServiceInfo(serviceInfos, "CLOUDAMQP");
|
||||
assertNotNull(serviceInfo);
|
||||
assertTrue(serviceInfo instanceof AmqpServiceInfo);
|
||||
assertAmqpServiceInfo((AmqpServiceInfo)serviceInfo, "db");
|
||||
}
|
||||
|
||||
private String getAmqpServiceUrl(String name) {
|
||||
String template = "amqp://$username:$password@$hostname:$port/$virtualHost";
|
||||
@Test
|
||||
public void amqpServiceCreation() {
|
||||
Map<String, String> env = new HashMap<String, String>();
|
||||
String amqpUrl = getAmqpServiceUrl("db");
|
||||
env.put("CLOUDAMQP_URL", amqpUrl);
|
||||
when(mockEnvironment.getEnv()).thenReturn(env);
|
||||
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
ServiceInfo serviceInfo = getServiceInfo(serviceInfos, "CLOUDAMQP");
|
||||
assertNotNull(serviceInfo);
|
||||
assertTrue(serviceInfo instanceof AmqpServiceInfo);
|
||||
assertAmqpServiceInfo((AmqpServiceInfo) serviceInfo, "db");
|
||||
}
|
||||
|
||||
private String getAmqpServiceUrl(String name) {
|
||||
String template = "amqp://$username:$password@$hostname:$port/$virtualHost";
|
||||
|
||||
return template.replace("$username", username).
|
||||
replace("$password", password).
|
||||
replace("$hostname", hostname).
|
||||
replace("$port", Integer.toString(port)).
|
||||
replace("$virtualHost", name);
|
||||
}
|
||||
|
||||
protected void assertAmqpServiceInfo(AmqpServiceInfo serviceInfo, String virtualHost) {
|
||||
assertEquals(hostname, serviceInfo.getHost());
|
||||
assertEquals(port, serviceInfo.getPort());
|
||||
assertEquals(username, serviceInfo.getUserName());
|
||||
assertEquals(password, serviceInfo.getPassword());
|
||||
assertEquals(virtualHost, serviceInfo.getPath());
|
||||
}
|
||||
|
||||
return template.replace("$username", username).
|
||||
replace("$password", password).
|
||||
replace("$hostname", hostname).
|
||||
replace("$port", Integer.toString(port)).
|
||||
replace("$virtualHost", name);
|
||||
}
|
||||
|
||||
protected void assertAmqpServiceInfo(AmqpServiceInfo serviceInfo, String virtualHost) {
|
||||
assertEquals(hostname, serviceInfo.getHost());
|
||||
assertEquals(port, serviceInfo.getPort());
|
||||
assertEquals(username, serviceInfo.getUserName());
|
||||
assertEquals(password, serviceInfo.getPassword());
|
||||
assertEquals(virtualHost, serviceInfo.getPath());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,35 +10,33 @@ import java.util.Map;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public class HerokuConnectorApplicationTest extends AbstractHerokuConnectorTest {
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void isInMatchingEnvironment() {
|
||||
when(mockEnvironment.getEnvValue("DYNO")).thenReturn("web.1");
|
||||
assertTrue(testCloudConnector.isInMatchingCloud());
|
||||
|
||||
|
||||
when(mockEnvironment.getEnvValue("DYNO")).thenReturn(null);
|
||||
assertFalse(testCloudConnector.isInMatchingCloud());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void applicationInstanceInfo() {
|
||||
when(mockEnvironment.getEnvValue("SPRING_CLOUD_APP_NAME")).thenReturn("myapp");
|
||||
when(mockEnvironment.getEnvValue("DYNO")).thenReturn("web.1");
|
||||
when(mockEnvironment.getEnvValue("PORT")).thenReturn(Integer.toString(port));
|
||||
when(mockEnvironment.getHost()).thenReturn(hostname);
|
||||
|
||||
|
||||
assertEquals("myapp", testCloudConnector.getApplicationInstanceInfo().getAppId());
|
||||
assertEquals("web.1", testCloudConnector.getApplicationInstanceInfo().getInstanceId());
|
||||
Map<String,Object> appProps = testCloudConnector.getApplicationInstanceInfo().getProperties();
|
||||
Map<String, Object> appProps = testCloudConnector.getApplicationInstanceInfo().getProperties();
|
||||
assertEquals(hostname, appProps.get("host"));
|
||||
assertEquals(Integer.toString(port), appProps.get("port"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void applicationInstanceInfoNoSpringCloudAppName() {
|
||||
when(mockEnvironment.getEnvValue("DYNO")).thenReturn("web.1");
|
||||
|
||||
@@ -14,45 +14,43 @@ import org.springframework.cloud.service.ServiceInfo;
|
||||
import org.springframework.cloud.service.common.MongoServiceInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public class HerokuConnectorMongoServiceTest extends AbstractHerokuConnectorTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void mongoServiceCreation() {
|
||||
for (String mongoEnv: new String[]{"MONGOLAB_URI", "MONGOHQ_URL", "MONGOSOUP_URL"}) {
|
||||
Map<String, String> env = new HashMap<String, String>();
|
||||
String mongoUrl = getMongoServiceUrl("db");
|
||||
env.put(mongoEnv, mongoUrl);
|
||||
when(mockEnvironment.getEnv()).thenReturn(env);
|
||||
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
ServiceInfo serviceInfo = getServiceInfo(serviceInfos, mongoEnv.substring(0, mongoEnv.length()-4));
|
||||
assertNotNull(serviceInfo);
|
||||
assertTrue(serviceInfo instanceof MongoServiceInfo);
|
||||
assertMongoServiceInfo((MongoServiceInfo)serviceInfo, "db");
|
||||
}
|
||||
}
|
||||
|
||||
private String getMongoServiceUrl(String name) {
|
||||
String template = "mongodb://$username:$password@$hostname:$port/$db";
|
||||
|
||||
return template.replace("$username", username).
|
||||
replace("$password", password).
|
||||
replace("$hostname", hostname).
|
||||
replace("$port", Integer.toString(port)).
|
||||
replace("$db", name);
|
||||
}
|
||||
|
||||
protected void assertMongoServiceInfo(MongoServiceInfo serviceInfo, String databaseName) {
|
||||
assertEquals(hostname, serviceInfo.getHost());
|
||||
assertEquals(port, serviceInfo.getPort());
|
||||
assertEquals(username, serviceInfo.getUserName());
|
||||
assertEquals(password, serviceInfo.getPassword());
|
||||
assertEquals(databaseName, serviceInfo.getPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mongoServiceCreation() {
|
||||
for (String mongoEnv : new String[]{"MONGOLAB_URI", "MONGOHQ_URL", "MONGOSOUP_URL"}) {
|
||||
Map<String, String> env = new HashMap<String, String>();
|
||||
String mongoUrl = getMongoServiceUrl("db");
|
||||
env.put(mongoEnv, mongoUrl);
|
||||
when(mockEnvironment.getEnv()).thenReturn(env);
|
||||
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
ServiceInfo serviceInfo = getServiceInfo(serviceInfos, mongoEnv.substring(0, mongoEnv.length() - 4));
|
||||
assertNotNull(serviceInfo);
|
||||
assertTrue(serviceInfo instanceof MongoServiceInfo);
|
||||
assertMongoServiceInfo((MongoServiceInfo) serviceInfo, "db");
|
||||
}
|
||||
}
|
||||
|
||||
private String getMongoServiceUrl(String name) {
|
||||
String template = "mongodb://$username:$password@$hostname:$port/$db";
|
||||
|
||||
return template.replace("$username", username).
|
||||
replace("$password", password).
|
||||
replace("$hostname", hostname).
|
||||
replace("$port", Integer.toString(port)).
|
||||
replace("$db", name);
|
||||
}
|
||||
|
||||
protected void assertMongoServiceInfo(MongoServiceInfo serviceInfo, String databaseName) {
|
||||
assertEquals(hostname, serviceInfo.getHost());
|
||||
assertEquals(port, serviceInfo.getPort());
|
||||
assertEquals(username, serviceInfo.getUserName());
|
||||
assertEquals(password, serviceInfo.getPassword());
|
||||
assertEquals(databaseName, serviceInfo.getPath());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,26 +13,24 @@ import org.springframework.cloud.service.ServiceInfo;
|
||||
import org.springframework.cloud.service.common.MysqlServiceInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public class HerokuConnectorMysqlServiceTest extends AbstractHerokuConnectorRelationalServiceTest {
|
||||
public HerokuConnectorMysqlServiceTest() {
|
||||
super(MysqlServiceInfo.MYSQL_SCHEME);
|
||||
}
|
||||
public HerokuConnectorMysqlServiceTest() {
|
||||
super(MysqlServiceInfo.MYSQL_SCHEME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mysqlServiceCreation() {
|
||||
Map<String, String> env = new HashMap<String, String>();
|
||||
String mysqlUrl = getRelationalServiceUrl("db");
|
||||
env.put("CLEARDB_DATABASE_URL", mysqlUrl);
|
||||
when(mockEnvironment.getEnv()).thenReturn(env);
|
||||
@Test
|
||||
public void mysqlServiceCreation() {
|
||||
Map<String, String> env = new HashMap<String, String>();
|
||||
String mysqlUrl = getRelationalServiceUrl("db");
|
||||
env.put("CLEARDB_DATABASE_URL", mysqlUrl);
|
||||
when(mockEnvironment.getEnv()).thenReturn(env);
|
||||
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
ServiceInfo serviceInfo = getServiceInfo(serviceInfos, "CLEARDB_DATABASE");
|
||||
assertNotNull(serviceInfo);
|
||||
assertTrue(serviceInfo instanceof MysqlServiceInfo);
|
||||
assertReleationServiceInfo((MysqlServiceInfo)serviceInfo, "db");
|
||||
}
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
ServiceInfo serviceInfo = getServiceInfo(serviceInfos, "CLEARDB_DATABASE");
|
||||
assertNotNull(serviceInfo);
|
||||
assertTrue(serviceInfo instanceof MysqlServiceInfo);
|
||||
assertReleationServiceInfo((MysqlServiceInfo) serviceInfo, "db");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,26 +13,24 @@ import org.springframework.cloud.service.ServiceInfo;
|
||||
import org.springframework.cloud.service.common.PostgresqlServiceInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public class HerokuConnectorPostgresqlServiceTest extends AbstractHerokuConnectorRelationalServiceTest {
|
||||
public HerokuConnectorPostgresqlServiceTest() {
|
||||
super(PostgresqlServiceInfo.POSTGRES_SCHEME);
|
||||
}
|
||||
public HerokuConnectorPostgresqlServiceTest() {
|
||||
super(PostgresqlServiceInfo.POSTGRES_SCHEME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postgresqlServiceCreation() {
|
||||
Map<String, String> env = new HashMap<String, String>();
|
||||
String postgresUrl = getRelationalServiceUrl("db");
|
||||
env.put("HEROKU_POSTGRESQL_YELLOW_URL", postgresUrl);
|
||||
when(mockEnvironment.getEnv()).thenReturn(env);
|
||||
@Test
|
||||
public void postgresqlServiceCreation() {
|
||||
Map<String, String> env = new HashMap<String, String>();
|
||||
String postgresUrl = getRelationalServiceUrl("db");
|
||||
env.put("HEROKU_POSTGRESQL_YELLOW_URL", postgresUrl);
|
||||
when(mockEnvironment.getEnv()).thenReturn(env);
|
||||
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
ServiceInfo serviceInfo = getServiceInfo(serviceInfos, "HEROKU_POSTGRESQL_YELLOW");
|
||||
assertNotNull(serviceInfo);
|
||||
assertTrue(serviceInfo instanceof PostgresqlServiceInfo);
|
||||
assertReleationServiceInfo((PostgresqlServiceInfo)serviceInfo, "db");
|
||||
}
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
ServiceInfo serviceInfo = getServiceInfo(serviceInfos, "HEROKU_POSTGRESQL_YELLOW");
|
||||
assertNotNull(serviceInfo);
|
||||
assertTrue(serviceInfo instanceof PostgresqlServiceInfo);
|
||||
assertReleationServiceInfo((PostgresqlServiceInfo) serviceInfo, "db");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,42 +14,40 @@ import org.springframework.cloud.service.ServiceInfo;
|
||||
import org.springframework.cloud.service.common.RedisServiceInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public class HerokuConnectorRedisServiceTest extends AbstractHerokuConnectorTest {
|
||||
|
||||
@Test
|
||||
public void redisServiceCreation() {
|
||||
for (String redisEnv: new String[]{"REDISTOGO_URL", "REDISCLOUD_URL", "OPENREDIS_URL", "REDISGREEN_URL"}) {
|
||||
Map<String, String> env = new HashMap<String, String>();
|
||||
String redisUrl = getRedisServiceUrl();
|
||||
env.put(redisEnv, redisUrl);
|
||||
when(mockEnvironment.getEnv()).thenReturn(env);
|
||||
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
ServiceInfo serviceInfo = getServiceInfo(serviceInfos, redisEnv.substring(0, redisEnv.length()-4));
|
||||
assertNotNull(serviceInfo);
|
||||
assertTrue(serviceInfo instanceof RedisServiceInfo);
|
||||
assertRedisServiceInfo((RedisServiceInfo)serviceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private String getRedisServiceUrl() {
|
||||
String template = "redis://$username:$password@$hostname:$port";
|
||||
@Test
|
||||
public void redisServiceCreation() {
|
||||
for (String redisEnv : new String[]{"REDISTOGO_URL", "REDISCLOUD_URL", "OPENREDIS_URL", "REDISGREEN_URL"}) {
|
||||
Map<String, String> env = new HashMap<String, String>();
|
||||
String redisUrl = getRedisServiceUrl();
|
||||
env.put(redisEnv, redisUrl);
|
||||
when(mockEnvironment.getEnv()).thenReturn(env);
|
||||
|
||||
List<ServiceInfo> serviceInfos = testCloudConnector.getServiceInfos();
|
||||
ServiceInfo serviceInfo = getServiceInfo(serviceInfos, redisEnv.substring(0, redisEnv.length() - 4));
|
||||
assertNotNull(serviceInfo);
|
||||
assertTrue(serviceInfo instanceof RedisServiceInfo);
|
||||
assertRedisServiceInfo((RedisServiceInfo) serviceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private String getRedisServiceUrl() {
|
||||
String template = "redis://$username:$password@$hostname:$port";
|
||||
|
||||
return template.replace("$username", username).
|
||||
replace("$password", password).
|
||||
replace("$hostname", hostname).
|
||||
replace("$port", Integer.toString(port));
|
||||
}
|
||||
|
||||
protected void assertRedisServiceInfo(RedisServiceInfo serviceInfo) {
|
||||
assertEquals(hostname, serviceInfo.getHost());
|
||||
assertEquals(port, serviceInfo.getPort());
|
||||
assertEquals(username, serviceInfo.getUserName());
|
||||
assertEquals(password, serviceInfo.getPassword());
|
||||
}
|
||||
|
||||
return template.replace("$username", username).
|
||||
replace("$password", password).
|
||||
replace("$hostname", hostname).
|
||||
replace("$port", Integer.toString(port));
|
||||
}
|
||||
|
||||
protected void assertRedisServiceInfo(RedisServiceInfo serviceInfo) {
|
||||
assertEquals(hostname, serviceInfo.getHost());
|
||||
assertEquals(port, serviceInfo.getPort());
|
||||
assertEquals(username, serviceInfo.getUserName());
|
||||
assertEquals(password, serviceInfo.getPassword());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,21 +15,21 @@ import org.springframework.cloud.service.common.RelationalServiceInfo;
|
||||
*/
|
||||
public class BasicDbcpPooledDataSourceCreator<SI extends RelationalServiceInfo> extends DbcpLikePooledDataSourceCreator<SI> {
|
||||
|
||||
@Override
|
||||
public DataSource create(RelationalServiceInfo serviceInfo, ServiceConnectorConfig serviceConnectorConfig,
|
||||
String driverClassName, String validationQuery) {
|
||||
if (hasClass("org.apache.commons.dbcp2.BasicDataSource")) {
|
||||
logger.info("Found DBCP2 on the classpath. Using it for DataSource connection pooling.");
|
||||
org.apache.commons.dbcp2.BasicDataSource ds = new org.apache.commons.dbcp2.BasicDataSource();
|
||||
setBasicDataSourceProperties(ds, serviceInfo, serviceConnectorConfig, driverClassName, validationQuery);
|
||||
return ds;
|
||||
} else if (hasClass("org.apache.commons.dbcp.BasicDataSource")) {
|
||||
logger.info("Found DBCP on the classpath. Using it for DataSource connection pooling.");
|
||||
org.apache.commons.dbcp.BasicDataSource ds = new org.apache.commons.dbcp.BasicDataSource();
|
||||
setBasicDataSourceProperties(ds, serviceInfo, serviceConnectorConfig, driverClassName, validationQuery);
|
||||
return ds;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public DataSource create(RelationalServiceInfo serviceInfo, ServiceConnectorConfig serviceConnectorConfig,
|
||||
String driverClassName, String validationQuery) {
|
||||
if (hasClass("org.apache.commons.dbcp2.BasicDataSource")) {
|
||||
logger.info("Found DBCP2 on the classpath. Using it for DataSource connection pooling.");
|
||||
org.apache.commons.dbcp2.BasicDataSource ds = new org.apache.commons.dbcp2.BasicDataSource();
|
||||
setBasicDataSourceProperties(ds, serviceInfo, serviceConnectorConfig, driverClassName, validationQuery);
|
||||
return ds;
|
||||
} else if (hasClass("org.apache.commons.dbcp.BasicDataSource")) {
|
||||
logger.info("Found DBCP on the classpath. Using it for DataSource connection pooling.");
|
||||
org.apache.commons.dbcp.BasicDataSource ds = new org.apache.commons.dbcp.BasicDataSource();
|
||||
setBasicDataSourceProperties(ds, serviceInfo, serviceConnectorConfig, driverClassName, validationQuery);
|
||||
return ds;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,21 +5,21 @@ import static org.junit.Assert.assertEquals;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
public class CommonPoolCloudConfigTestHelper {
|
||||
|
||||
public static void assertCommonsPoolProperties(Object pool, int maxActive, int minIdle, long maxWait) {
|
||||
assertEquals(maxActive, getValue(pool, "maxActive", "maxTotal"));
|
||||
assertEquals(minIdle, getValue(pool, "minIdle"));
|
||||
assertEquals(maxWait, getValue(pool, "maxWait", "maxWaitMillis"));
|
||||
}
|
||||
|
||||
protected static Object getValue(Object object, String... fieldNames) {
|
||||
for (String fieldName : fieldNames) {
|
||||
try {
|
||||
return ReflectionTestUtils.getField(object, fieldName);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void assertCommonsPoolProperties(Object pool, int maxActive, int minIdle, long maxWait) {
|
||||
assertEquals(maxActive, getValue(pool, "maxActive", "maxTotal"));
|
||||
assertEquals(minIdle, getValue(pool, "minIdle"));
|
||||
assertEquals(maxWait, getValue(pool, "maxWait", "maxWaitMillis"));
|
||||
}
|
||||
|
||||
protected static Object getValue(Object object, String... fieldNames) {
|
||||
for (String fieldName : fieldNames) {
|
||||
try {
|
||||
return ReflectionTestUtils.getField(object, fieldName);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,11 +21,11 @@ public class CloudScanJavaConfigTest extends AbstractCloudConfigServiceScanTest
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cloudScanIntroducesApplicationInstanceInfo() {
|
||||
ApplicationContext testContext = getTestApplicationContext();
|
||||
|
||||
assertNotNull(testContext.getBean(ApplicationInstanceInfo.class));
|
||||
}
|
||||
public void cloudScanIntroducesApplicationInstanceInfo() {
|
||||
ApplicationContext testContext = getTestApplicationContext();
|
||||
|
||||
assertNotNull(testContext.getBean(ApplicationInstanceInfo.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -7,8 +7,8 @@ package org.springframework.cloud.service.relational;
|
||||
*
|
||||
*/
|
||||
public class MysqlServiceCreatorWithDefaultDriverTest extends MysqlServiceCreatorTest {
|
||||
private static final String MYSQL_DRIVER_CLASS_NAME = "org.mariadb.jdbc.Driver";
|
||||
|
||||
private static final String MYSQL_DRIVER_CLASS_NAME = "org.mariadb.jdbc.Driver";
|
||||
|
||||
@Override
|
||||
public String getDriverName() {
|
||||
return MYSQL_DRIVER_CLASS_NAME;
|
||||
|
||||
@@ -9,17 +9,17 @@ import org.junit.Before;
|
||||
*
|
||||
*/
|
||||
public class MysqlServiceCreatorWithMysqlDriverTest extends MysqlServiceCreatorTest {
|
||||
private static final String MYSQL_DRIVER_CLASS_NAME = "com.mysql.jdbc.Driver";
|
||||
|
||||
private static final String MYSQL_DRIVER_CLASS_NAME = "com.mysql.jdbc.Driver";
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
super.setup();
|
||||
System.setProperty("spring-cloud.mysql.driver", MYSQL_DRIVER_CLASS_NAME);
|
||||
System.setProperty("spring-cloud.mysql.driver", MYSQL_DRIVER_CLASS_NAME);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
System.setProperty("spring-cloud.mysql.driver", "");
|
||||
System.setProperty("spring-cloud.mysql.driver", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user