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 41fd035..2d5804d 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 @@ -22,320 +22,346 @@ import org.springframework.cloud.service.ServiceInfo.ServiceProperty; /** * The main user-level API access to application and services for the app in which this instance is embedded in. - * - * The class connects application and the underlying cloud. Besides passing along information about the application - * instance, it allows simple access for using services. It uses {@link ServiceInfo}s obtained using the + * + * The class connects application and the underlying cloud. Besides passing along information about the application + * instance, it allows simple access for using services. It uses {@link ServiceInfo}s obtained using the * underlying {@link CloudConnector} and allows translating those to service connector such as a {@link DataSource}. - * + * * It also passes along information obtained through {@link CloudConnector} to let application take control on how * to use bound services. - * - *

NOTE: Users or cloud providers shouldn't need to instantiate an instance of this class - * (constructor has package-access only for unit-testing purpose). Instead, they can obtain an appropriate - * instance through {@link CloudFactory}

- * + * + *

+ * NOTE: Users or cloud providers shouldn't need to instantiate an instance of this class (constructor has package-access only for + * unit-testing purpose). Instead, they can obtain an appropriate instance through {@link CloudFactory} + *

+ * * @author Ramnivas Laddad * */ public class Cloud { - 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> serviceConnectorCreators) { - this.cloudConnector = cloudConnector; - - for (ServiceConnectorCreator serviceCreator: serviceConnectorCreators) { - registerServiceConnectorCreator(serviceCreator); - } - } - - /** - * @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"); - } - - /** - * @see CloudConnector#getServiceInfos() - * @return information about all services bound to the application - */ - public List getServiceInfos() { - return cloudConnector.getServiceInfos(); - } - - /** - * Get {@link ServiceInfo}s for the bound services that could be mapped to the given service connector type. - * - *

- * For example, if the connector type is {@link DataSource}, then the method will return - * all {@link ServiceInfo} objects matching bound relational database services. - *

- * - * @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 List getServiceInfos(Class serviceConnectorType) { - List allServiceInfos = getServiceInfos(); - List matchingServiceInfos = new ArrayList(); - - for (ServiceInfo serviceInfo: allServiceInfos) { - if (serviceConnectorCreatorRegistry.canCreate(serviceConnectorType, serviceInfo)) { - matchingServiceInfos.add(serviceInfo); - } - } - - return matchingServiceInfos; - } - - /** - * Get a service connector for the given service id, the connector type, configured with the given config - * - * @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). - * - */ - public SC getServiceConnector(String serviceId, Class serviceConnectorType, ServiceConnectorConfig serviceConnectorConfig) { - ServiceInfo serviceInfo = getServiceInfo(serviceId); - - return getServiceConnector(serviceInfo, serviceConnectorType, serviceConnectorConfig); - } + private CloudConnector cloudConnector; + private ServiceConnectorCreatorRegistry serviceConnectorCreatorRegistry = new ServiceConnectorCreatorRegistry(); - /** - * Get the singleton service connector for the given connector type, configured with the given config - * - * @param serviceConnectorType The expected class of service connector such as, DataSource.class. - * @param serviceConnectorConfig service connector configuration (such as pooling parameters). - * - */ - public SC getSingletonServiceConnector(Class serviceConnectorType, ServiceConnectorConfig serviceConnectorConfig) { - List matchingServiceInfos = getServiceInfos(serviceConnectorType); - - if (matchingServiceInfos.size() != 1) { - throw new CloudException("No unique service matching " + serviceConnectorType + " found. Expected 1, found " + matchingServiceInfos.size()); - } - - ServiceInfo matchingServiceInfo = matchingServiceInfos.get(0); - - return getServiceConnector(matchingServiceInfo, serviceConnectorType, serviceConnectorConfig); - } + /** + * Package-access constructor. + * + * @param cloudConnector + * the underlying connector + * @param serviceConnectorCreators + * service connector creators + */ + Cloud(CloudConnector cloudConnector, List> serviceConnectorCreators) { + this.cloudConnector = cloudConnector; - /** - * Register a new service connector creator - * - * @param serviceConnectorCreator - */ - public void registerServiceConnectorCreator(ServiceConnectorCreator serviceConnectorCreator) { - serviceConnectorCreatorRegistry.registerCreator(serviceConnectorCreator); - } + for (ServiceConnectorCreator serviceCreator : serviceConnectorCreators) { + registerServiceConnectorCreator(serviceCreator); + } + } - /** - * Get properties for app and services. - * - * - * - *

Application properties always include cloud.application.app-id - * and cloud.application.instance-id with values bound to application id and - * instance id. The rest of the properties are cloud-provider specific, but take the - * cloud.application.<property-name> form. - *

-	 * cloud.application.app-id = helloworld
-	 * cloud.application.instance-id = instance-0-0fab098f
-	 * cloud.application.<property-name> = <property-value>
-	 * 
- * - *

Service specific properties are exposed for each bound service, with each key starting - * in cloud.services. Like application properties, these too are cloud and service specific. - * Each key for a specific service starts with cloud.services.<service-id> - *

-	 * cloud.services.customerDb.type = mysql-5.1
-	 * cloud.services.customerDb.plan = free
-	 * cloud.services.customerDb.connection.hostname = ...
-	 * cloud.services.customerDb.connection.port = ...
-	 * etc...
-	 * 
- * - *

If a there is only a single service of a given type, that service is - * aliased to the service type. Keys for such properties start in cloud.services.<service-type>. - * For example, if there is only a single MySQL service bound to the application, the service properties will also be - * exposed starting with 'cloud.services.mysql' key: - *

-	 * cloud.services.mysql.type = mysql-5.1
-	 * cloud.services.mysql.plan = free
-	 * cloud.services.mysql.connection.hostname = ...
-	 * cloud.services.mysql.connection.port = ...
-	 * etc...
-	 * 
- * - * @return the properties object - */ - public Properties getCloudProperties() { - Map> mappedServiceInfos = new HashMap>(); - for (ServiceInfo serviceInfo : getServiceInfos()) { - String key = getServiceLabel(serviceInfo); - List serviceInfosForLabel = mappedServiceInfos.get(key); - if (serviceInfosForLabel == null) { - serviceInfosForLabel = new ArrayList(); - mappedServiceInfos.put(key, serviceInfosForLabel); - } - serviceInfosForLabel.add(serviceInfo); - } - - final String servicePropKeyLead = "cloud.services."; - Properties cloudProperties = new Properties(); - for (Entry> mappedServiceInfo : mappedServiceInfos.entrySet()) { - List serviceInfos = mappedServiceInfo.getValue(); - - 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)); - } - } - } - - cloudProperties.putAll(getAppProperties()); - - return cloudProperties; - } - - private SC getServiceConnector(ServiceInfo serviceInfo, Class serviceConnectorType, ServiceConnectorConfig serviceConnectorConfig) { - ServiceConnectorCreator serviceConnectorCreator = serviceConnectorCreatorRegistry.getServiceCreator(serviceConnectorType, serviceInfo); - return serviceConnectorCreator.create(serviceInfo, serviceConnectorConfig); - } - - 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 entry : getApplicationInstanceInfo().getProperties().entrySet()) { - if (entry.getValue() != null) { - appProperties.put(appPropLeadKey + entry.getKey(), entry.getValue()); - } - } + /** + * @see CloudConnector#getApplicationInstanceInfo() + * + * @return information about the application instance + */ + public ApplicationInstanceInfo getApplicationInstanceInfo() { + return cloudConnector.getApplicationInstanceInfo(); + } - return appProperties; - } - - 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; - - 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); - - if (value != null) { - cloudProperties.put(key, value); - } - } - } - } catch (Exception e) { - throw new CloudException(e); - } - - return cloudProperties; - } - - private static String getServiceLabel(ServiceInfo serviceInfo) { - Class serviceInfoClass = serviceInfo.getClass(); - - ServiceLabel labelAnnotation = serviceInfoClass.getAnnotation(ServiceInfo.ServiceLabel.class); - - if (labelAnnotation == null) { - return null; - } else { - return labelAnnotation.value(); - } - } + /** + * 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 getServiceInfos() { + return cloudConnector.getServiceInfos(); + } + + /** + * Get {@link ServiceInfo}s for the bound services that could be mapped to the given service connector type. + * + *

+ * For example, if the connector type is {@link DataSource}, then the method will return all {@link ServiceInfo} objects + * matching bound relational database services. + *

+ * + * @param + * 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 List getServiceInfos(Class serviceConnectorType) { + List allServiceInfos = getServiceInfos(); + List matchingServiceInfos = new ArrayList(); + + for (ServiceInfo serviceInfo : allServiceInfos) { + if (serviceConnectorCreatorRegistry.canCreate(serviceConnectorType, serviceInfo)) { + matchingServiceInfos.add(serviceInfo); + } + } + + return matchingServiceInfos; + } + + /** + * Get a service connector for the given service id, the connector type, configured with the given config + * + * + * @param + * 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 getServiceConnector(String serviceId, Class serviceConnectorType, + ServiceConnectorConfig serviceConnectorConfig) { + ServiceInfo serviceInfo = getServiceInfo(serviceId); + + return getServiceConnector(serviceInfo, serviceConnectorType, serviceConnectorConfig); + } + + /** + * Get the singleton service connector for the given connector type, configured with the given config + * + * @param + * 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 getSingletonServiceConnector(Class serviceConnectorType, ServiceConnectorConfig serviceConnectorConfig) { + List matchingServiceInfos = getServiceInfos(serviceConnectorType); + + if (matchingServiceInfos.size() != 1) { + throw new CloudException("No unique service matching " + serviceConnectorType + " found. Expected 1, found " + + matchingServiceInfos.size()); + } + + ServiceInfo matchingServiceInfo = matchingServiceInfos.get(0); + + return getServiceConnector(matchingServiceInfo, serviceConnectorType, serviceConnectorConfig); + } + + /** + * Register a new service connector creator + * + * @param serviceConnectorCreator the service connector to register + */ + public void registerServiceConnectorCreator(ServiceConnectorCreator serviceConnectorCreator) { + serviceConnectorCreatorRegistry.registerCreator(serviceConnectorCreator); + } + + /** + * Get properties for app and services. + * + * + * + *

+ * Application properties always include cloud.application.app-id and cloud.application.instance-id + * with values bound to application id and instance id. The rest of the properties are cloud-provider specific, but take the + * cloud.application.<property-name> form.

+     * cloud.application.app-id = helloworld
+     * cloud.application.instance-id = instance-0-0fab098f
+     * cloud.application.<property-name> = <property-value>
+     * 
+ * + *

+ * Service specific properties are exposed for each bound service, with each key starting in cloud.services. Like + * application properties, these too are cloud and service specific. Each key for a specific service starts with + * cloud.services.<service-id>

+     * cloud.services.customerDb.type = mysql-5.1
+     * cloud.services.customerDb.plan = free
+     * cloud.services.customerDb.connection.hostname = ...
+     * cloud.services.customerDb.connection.port = ...
+     * etc...
+     * 
+ * + *

+ * If a there is only a single service of a given type, that service is aliased to the service type. Keys for such properties + * start in cloud.services.<service-type>. For example, if there is only a single MySQL service bound to the + * application, the service properties will also be exposed starting with 'cloud.services.mysql' key:

+     * cloud.services.mysql.type = mysql-5.1
+     * cloud.services.mysql.plan = free
+     * cloud.services.mysql.connection.hostname = ...
+     * cloud.services.mysql.connection.port = ...
+     * etc...
+     * 
+ * + * @return the properties object + */ + public Properties getCloudProperties() { + Map> mappedServiceInfos = new HashMap>(); + for (ServiceInfo serviceInfo : getServiceInfos()) { + String key = getServiceLabel(serviceInfo); + List serviceInfosForLabel = mappedServiceInfos.get(key); + if (serviceInfosForLabel == null) { + serviceInfosForLabel = new ArrayList(); + mappedServiceInfos.put(key, serviceInfosForLabel); + } + serviceInfosForLabel.add(serviceInfo); + } + + final String servicePropKeyLead = "cloud.services."; + Properties cloudProperties = new Properties(); + for (Entry> mappedServiceInfo : mappedServiceInfos.entrySet()) { + List serviceInfos = mappedServiceInfo.getValue(); + + 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)); + } + } + } + + cloudProperties.putAll(getAppProperties()); + + return cloudProperties; + } + + private SC getServiceConnector(ServiceInfo serviceInfo, Class serviceConnectorType, + ServiceConnectorConfig serviceConnectorConfig) { + ServiceConnectorCreator serviceConnectorCreator = serviceConnectorCreatorRegistry.getServiceCreator( + serviceConnectorType, serviceInfo); + return serviceConnectorCreator.create(serviceInfo, serviceConnectorConfig); + } + + 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 entry : getApplicationInstanceInfo().getProperties().entrySet()) { + if (entry.getValue() != null) { + appProperties.put(appPropLeadKey + entry.getKey(), entry.getValue()); + } + } + + return appProperties; + } + + 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; + + 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); + + if (value != null) { + cloudProperties.put(key, value); + } + } + } + } catch (Exception e) { + throw new CloudException(e); + } + + return cloudProperties; + } + + private static String getServiceLabel(ServiceInfo serviceInfo) { + Class serviceInfoClass = serviceInfo.getClass(); + + ServiceLabel labelAnnotation = serviceInfoClass.getAnnotation(ServiceInfo.ServiceLabel.class); + + if (labelAnnotation == null) { + return null; + } else { + return labelAnnotation.value(); + } + } } class ServiceConnectorCreatorRegistry { - private static Logger logger = Logger.getLogger(Cloud.class.getName()); + private static Logger logger = Logger.getLogger(Cloud.class.getName()); - private List> serviceConnectorCreators = new ArrayList>(); - - public void registerCreator(ServiceConnectorCreator serviceConnectorCreator) { - serviceConnectorCreators.add(serviceConnectorCreator); - } - - public ServiceConnectorCreator getServiceCreator(Class serviceConnectorType, SI serviceInfo) { - ServiceConnectorCreator serviceConnectorCreator = getServiceCreatorOrNull(serviceConnectorType, serviceInfo); + private List> serviceConnectorCreators = new ArrayList>(); - 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 boolean canCreate(Class serviceConnectorType, SI serviceInfo) { - return getServiceCreatorOrNull(serviceConnectorType, serviceInfo) != null; - } + public void registerCreator(ServiceConnectorCreator serviceConnectorCreator) { + serviceConnectorCreators.add(serviceConnectorCreator); + } - public boolean accept(ServiceConnectorCreator creator, Class serviceConnectorType, ServiceInfo serviceInfo) { - boolean typeBasedAccept = serviceConnectorType == null ? true : serviceConnectorType.isAssignableFrom(creator.getServiceConnectorType()); - boolean infoBasedAccept = serviceInfo == null ? true : creator.getServiceInfoType().isAssignableFrom(serviceInfo.getClass()); - - return typeBasedAccept && infoBasedAccept; - } + public ServiceConnectorCreator getServiceCreator(Class serviceConnectorType, + SI serviceInfo) { + ServiceConnectorCreator serviceConnectorCreator = getServiceCreatorOrNull(serviceConnectorType, serviceInfo); - @SuppressWarnings("unchecked") - private ServiceConnectorCreator getServiceCreatorOrNull(Class serviceConnectorType, SI serviceInfo) { - for (ServiceConnectorCreator serviceConnectorCreator : serviceConnectorCreators) { - logger.info("Trying connector creator type " + serviceConnectorCreator); - if (accept(serviceConnectorCreator, serviceConnectorType, serviceInfo)) { - return (ServiceConnectorCreator) serviceConnectorCreator; - } - } - return null; - } + 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 boolean canCreate(Class serviceConnectorType, SI serviceInfo) { + return getServiceCreatorOrNull(serviceConnectorType, serviceInfo) != null; + } + + public boolean accept(ServiceConnectorCreator creator, Class serviceConnectorType, + ServiceInfo serviceInfo) { + boolean typeBasedAccept = serviceConnectorType == null ? true : serviceConnectorType.isAssignableFrom(creator + .getServiceConnectorType()); + boolean infoBasedAccept = serviceInfo == null ? true : creator.getServiceInfoType() + .isAssignableFrom(serviceInfo.getClass()); + + return typeBasedAccept && infoBasedAccept; + } + + @SuppressWarnings("unchecked") + private ServiceConnectorCreator getServiceCreatorOrNull(Class serviceConnectorType, + SI serviceInfo) { + for (ServiceConnectorCreator serviceConnectorCreator : serviceConnectorCreators) { + logger.info("Trying connector creator type " + serviceConnectorCreator); + if (accept(serviceConnectorCreator, serviceConnectorType, serviceInfo)) { + return (ServiceConnectorCreator) serviceConnectorCreator; + } + } + return null; + } } diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/CloudFactory.java b/spring-cloud-core/src/main/java/org/springframework/cloud/CloudFactory.java index 20dfafd..69b4561 100644 --- a/spring-cloud-core/src/main/java/org/springframework/cloud/CloudFactory.java +++ b/spring-cloud-core/src/main/java/org/springframework/cloud/CloudFactory.java @@ -10,95 +10,96 @@ import org.springframework.cloud.util.ServiceLoaderWithExceptionControl; /** * Factory for the cloud. - * + * *

- * The main entry point for user code. Typical code directly using this class (as opposed to using a dependency-injection - * framework) will look like: + * The main entry point for user code. Typical code directly using this class (as opposed to using a dependency-injection framework) + * will look like: + * *

  * CloudFactory cloudFactory = new CloudFactory();
  * Cloud cloud = cloudFoundry.getCloud();
  * 
- * - * Creating object of this class is somewhat expensive (due to scanning of various files to load connectors), - * so consider caching such an object if you create it manually. If you use a dependency-injection framework such as - * Spring, simply creating a bean for either CloudFactory or using this class as a factory-bean for {@link Cloud} will - * suffice. - * + * + * Creating object of this class is somewhat expensive (due to scanning of various files to load connectors), so consider caching + * such an object if you create it manually. If you use a dependency-injection framework such as Spring, simply creating a bean for + * either CloudFactory or using this class as a factory-bean for {@link Cloud} will suffice. + * * @author Ramnivas Laddad * */ public class CloudFactory { - private List cloudConnectors = new ArrayList(); - private List> serviceCreators = new ArrayList>(); + private List cloudConnectors = new ArrayList(); + private List> serviceCreators = new ArrayList>(); - 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. - * - *

- * CloudConnector developers should prefer the declarative mechanism described in README.MD - * instead of calling this method. - *

- * - * @param cloudConnector - */ - public void registerCloudConnector(CloudConnector cloudConnector) { - cloudConnectors.add(cloudConnector); - } - - /* package access for testing */ - List getCloudConnectors() { - return cloudConnectors; - } + /** + * Register a cloud connector. + * + *

+ * CloudConnector developers should prefer the declarative mechanism described in README.MD instead of calling this method. + *

+ * + * @param cloudConnector + * the cloud connector to register for discovery + */ + public void registerCloudConnector(CloudConnector cloudConnector) { + cloudConnectors.add(cloudConnector); + } - /* package access for testing */ - List> getServiceCreators() { - return serviceCreators; - } + /* package access for testing */ + List getCloudConnectors() { + return cloudConnectors; + } - private void registerServiceCreator(ServiceConnectorCreator serviceConnectorCreator) { - serviceCreators.add(serviceConnectorCreator); - } + /* package access for testing */ + List> getServiceCreators() { + return serviceCreators; + } - private void scanCloudConnectors() { - Iterable loader = ServiceLoader.load(CloudConnector.class); - for (CloudConnector cloudConnector: loader) { - registerCloudConnector(cloudConnector); - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void scanServiceConnectorCreators() { - Iterable loader = ServiceLoaderWithExceptionControl.load(ServiceConnectorCreator.class); - for (ServiceConnectorCreator serviceConnectorCreator: loader) { - if (serviceConnectorCreator != null) { - registerServiceCreator(serviceConnectorCreator); - } - } - } + private void registerServiceCreator(ServiceConnectorCreator serviceConnectorCreator) { + serviceCreators.add(serviceConnectorCreator); + } + + private void scanCloudConnectors() { + Iterable loader = ServiceLoader.load(CloudConnector.class); + for (CloudConnector cloudConnector : loader) { + registerCloudConnector(cloudConnector); + } + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private void scanServiceConnectorCreators() { + Iterable loader = ServiceLoaderWithExceptionControl.load(ServiceConnectorCreator.class); + for (ServiceConnectorCreator serviceConnectorCreator : loader) { + if (serviceConnectorCreator != null) { + registerServiceCreator(serviceConnectorCreator); + } + } + } } diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/FallbackServiceInfoCreator.java b/spring-cloud-core/src/main/java/org/springframework/cloud/FallbackServiceInfoCreator.java index 33807b0..58625ce 100644 --- a/spring-cloud-core/src/main/java/org/springframework/cloud/FallbackServiceInfoCreator.java +++ b/spring-cloud-core/src/main/java/org/springframework/cloud/FallbackServiceInfoCreator.java @@ -3,25 +3,28 @@ package org.springframework.cloud; import org.springframework.cloud.service.ServiceInfo; /** - * Fallback service info creator to deal with situations there is no {@link ServiceInfoCreator} that can + * Fallback service info creator to deal with situations there is no {@link ServiceInfoCreator} that can * accept service data. - * - * A fallback mechanism is needed, for example, when a services is bound to an app, but there is no - * {@link ServiceInfoCreator} implemented to handle it or the {@link ServiceInfoCreator} implementation - * 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. - * + * + * A fallback mechanism is needed, for example, when a services is bound to an app, but there is no {@link ServiceInfoCreator} + * implemented to handle it or the {@link ServiceInfoCreator} implementation + * 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. + * * @author Ramnivas Laddad * * @param + * the type of {@link ServiceInfo} that this fallback creator will return + * @param + * the type of service definition data that this creator will consume */ -public abstract class FallbackServiceInfoCreator implements ServiceInfoCreator{ +public abstract class FallbackServiceInfoCreator implements ServiceInfoCreator { - /* - * 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; + } } diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/service/ServiceConnectorCreator.java b/spring-cloud-core/src/main/java/org/springframework/cloud/service/ServiceConnectorCreator.java index e6cd03f..0143008 100644 --- a/spring-cloud-core/src/main/java/org/springframework/cloud/service/ServiceConnectorCreator.java +++ b/spring-cloud-core/src/main/java/org/springframework/cloud/service/ServiceConnectorCreator.java @@ -1,24 +1,28 @@ package org.springframework.cloud.service; /** - * + * * @author Ramnivas Laddad * - * @param service connector type - * @param service info type + * @param + * service connector type + * @param + * service info type */ public interface ServiceConnectorCreator { - /** - * Create service for the given service info and configured with the given - * configuration - * - * @param serviceInfo - * @param serviceConnectorConfig - * @return service connector - */ - SC create(SI serviceInfo, ServiceConnectorConfig serviceConnectorConfig); - - Class getServiceConnectorType(); + /** + * 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); - Class getServiceInfoType(); + Class getServiceConnectorType(); + + Class getServiceInfoType(); } diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/util/ServiceLoaderWithExceptionControl.java b/spring-cloud-core/src/main/java/org/springframework/cloud/util/ServiceLoaderWithExceptionControl.java index 0617f77..dbb5544 100644 --- a/spring-cloud-core/src/main/java/org/springframework/cloud/util/ServiceLoaderWithExceptionControl.java +++ b/spring-cloud-core/src/main/java/org/springframework/cloud/util/ServiceLoaderWithExceptionControl.java @@ -10,66 +10,66 @@ import org.springframework.cloud.service.ServiceConnectorCreator; /** * A variation of {@link ServiceLoader} that ignores exception encountered when loading services. - * + * *

- * The {@link ServiceLoader} class throws an error when it encounters a service that it cannot load. - * For {@link ServiceConnectorCreator}, this can be a common occurrence due to missing dependencies. - * For example, if an app isn't using MongoDB, thus not declaring dependencies on relevant classes, - * will cause {@link ServiceConnectorCreator} for MongoDB to fail. We don't want to abandon other service - * connector creators in such cases. + * The {@link ServiceLoader} class throws an error when it encounters a service that it cannot load. For + * {@link ServiceConnectorCreator}, this can be a common occurrence due to missing dependencies. For example, if an app isn't using + * MongoDB, thus not declaring dependencies on relevant classes, will cause {@link ServiceConnectorCreator} for MongoDB to fail. We + * don't want to abandon other service connector creators in such cases. *

- * + * * @author Ramnivas Laddad * * @param + * the type of the service being loaded */ public class ServiceLoaderWithExceptionControl implements Iterable { - private Iterable underlying; - - private static Logger logger = Logger.getLogger(ServiceLoaderWithExceptionControl.class.getName()); + private Iterable underlying; - public static Iterable load(Class serviceType) { - ServiceLoader loader = ServiceLoader.load(serviceType); - return new ServiceLoaderWithExceptionControl(loader); - } + private static Logger logger = Logger.getLogger(ServiceLoaderWithExceptionControl.class.getName()); - private ServiceLoaderWithExceptionControl(Iterable underlying) { - this.underlying = underlying; - } + public static Iterable load(Class serviceType) { + ServiceLoader loader = ServiceLoader.load(serviceType); + return new ServiceLoaderWithExceptionControl(loader); + } - @Override - public Iterator iterator() { - return new ServiceLoaderIterator(underlying.iterator()); - } - - private class ServiceLoaderIterator implements Iterator { - private Iterator underlying; - - public ServiceLoaderIterator(Iterator underlying) { - this.underlying = underlying; - } - - @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 void remove() { - underlying.remove(); - } - } + private ServiceLoaderWithExceptionControl(Iterable underlying) { + this.underlying = underlying; + } + + @Override + public Iterator iterator() { + return new ServiceLoaderIterator(underlying.iterator()); + } + + private class ServiceLoaderIterator implements Iterator { + private Iterator underlying; + + public ServiceLoaderIterator(Iterator underlying) { + this.underlying = underlying; + } + + @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 void remove() { + underlying.remove(); + } + } } \ No newline at end of file diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/util/StandardUriInfoFactory.java b/spring-cloud-core/src/main/java/org/springframework/cloud/util/StandardUriInfoFactory.java index 398ca88..8032b55 100644 --- a/spring-cloud-core/src/main/java/org/springframework/cloud/util/StandardUriInfoFactory.java +++ b/spring-cloud-core/src/main/java/org/springframework/cloud/util/StandardUriInfoFactory.java @@ -5,9 +5,9 @@ import java.net.URISyntaxException; import java.net.URLDecoder; /** - * Factory for standard Cloud Foundry URIs which all conform to the format: - *

- * [jdbc:]scheme://[user:pass]@authority[:port]/path + * Factory for standard Cloud Foundry URIs, which all conform to the format: + *

+ * {@code [jdbc:]scheme://[user:pass]@authority[:port]/path} */ public class StandardUriInfoFactory implements UriInfoFactory { diff --git a/spring-cloud-core/src/main/java/org/springframework/cloud/util/UriInfoFactory.java b/spring-cloud-core/src/main/java/org/springframework/cloud/util/UriInfoFactory.java index a08a910..98ad79b 100644 --- a/spring-cloud-core/src/main/java/org/springframework/cloud/util/UriInfoFactory.java +++ b/spring-cloud-core/src/main/java/org/springframework/cloud/util/UriInfoFactory.java @@ -2,31 +2,40 @@ package org.springframework.cloud.util; /** * An interface implemented in order to create {@link UriInfo}s. - * + * * If your {@link org.springframework.cloud.service.ServiceInfo} needs to deal with special URIs and you are extending * {@link org.springframework.cloud.service.UriBasedServiceInfo} then you can implement this factory interface in order * to return a custom factory from your ServiceInfo by overriding * {@link org.springframework.cloud.service.UriBasedServiceInfo#getUriInfoFactory()}. - * + * * @author Jens Deppe */ public interface UriInfoFactory { /** * Create a {@link UriInfo} based on a URI string - * @param uriString the URI string to parse + * + * @param uriString + * the URI string to parse * @return a {@link UriInfo} */ public UriInfo createUri(String uriString); /** * Create a {@link UriInfo} based on explicit components of the URI + * * @param scheme + * the URI scheme for this service * @param host + * the host for this service * @param port + * the port for this service * @param username + * the authentication username for this service * @param password + * the authentication password for this service * @param path + * the path to this service resource on the server * @return a {@link UriInfo} */ public UriInfo createUri(String scheme, String host, int port, String username, String password, String path); diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/java/AbstractCloudConfig.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/java/AbstractCloudConfig.java index d91233e..7156a59 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/java/AbstractCloudConfig.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/java/AbstractCloudConfig.java @@ -24,350 +24,400 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; /** * JavaConfig base class for simplified access to the bound services. - * + * * Note that this class doesn't directly expose low-level methods such as getServiceInfo() - * to keep focus on typical needs of a Spring application. But, since it exposes the cloud object itself, + * to keep focus on typical needs of a Spring application. But, since it exposes the cloud object itself, * you can always call methods on it to get that kind of information. - * + * * @author Ramnivas Laddad * */ @Configuration public abstract class AbstractCloudConfig implements BeanFactoryAware { - private static final String CLOUD_FACTORY_BEAN_NAME = "__cloud_factory__"; - - private CloudFactory cloudFactory; + private static final String CLOUD_FACTORY_BEAN_NAME = "__cloud_factory__"; - private Cloud cloud; + private CloudFactory cloudFactory; - private ServiceConnectionFactory connectionFactory; + private Cloud cloud; - /** - * Get the cloud factory. - * - * Most applications will never need this method, but provided here to cover corner cases. - * - * @return cloud factory - */ - protected CloudFactory cloudFactory() { - return cloudFactory; - } + private ServiceConnectionFactory connectionFactory; - /** - * Get the underlying cloud object. - * - * @return the cloud object appropriate for the current environment - */ - @Bean - public Cloud cloud() { - return cloud; - } - - public ServiceConnectionFactory connectionFactory() { - return connectionFactory; - } - - /** - * Get the object containing service and app properties - * - */ - public Properties properties() { - return cloud().getCloudProperties(); - } + /** + * Get the cloud factory. + * + * Most applications will never need this method, but provided here to cover corner cases. + * + * @return cloud factory + */ + protected CloudFactory cloudFactory() { + return cloudFactory; + } - /** + /** + * Get the underlying cloud object. + * + * @return the cloud object appropriate for the current environment + */ + @Bean + public Cloud cloud() { + return cloud; + } + + public ServiceConnectionFactory connectionFactory() { + return connectionFactory; + } + + /** + * Get the object containing service and app properties + * + * @return the properties of the discovered runtime environment + */ + public Properties properties() { + return cloud().getCloudProperties(); + } + + /** * Implementation note: This roundabout way of implementation is required to ensure that * a {@link CloudFactory} bean if created in some other configuration is available, we should use * that. - */ - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - if (cloudFactory == null) { - try { - cloudFactory = beanFactory.getBean(CloudFactory.class); - } catch (NoSuchBeanDefinitionException ex) { - cloudFactory = new CloudFactory(); - ((SingletonBeanRegistry)beanFactory).registerSingleton(CLOUD_FACTORY_BEAN_NAME, cloudFactory); - } - } - this.cloud = cloudFactory.getCloud(); - this.connectionFactory = new ServiceConnectionFactory(); - } + */ + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + if (cloudFactory == null) { + try { + cloudFactory = beanFactory.getBean(CloudFactory.class); + } catch (NoSuchBeanDefinitionException ex) { + cloudFactory = new CloudFactory(); + ((SingletonBeanRegistry) beanFactory).registerSingleton(CLOUD_FACTORY_BEAN_NAME, cloudFactory); + } + } + this.cloud = cloudFactory.getCloud(); + this.connectionFactory = new ServiceConnectionFactory(); + } - - public class ServiceConnectionFactory { - // Relational database - - /** - * Get the {@link DataSource} object associated with the only relational database service bound to the app. - * - * This is equivalent to the element. - * - * @return data source - * @throws CloudException if there are either 0 or more than 1 relational database services. - */ - public DataSource dataSource() { - return dataSource((DataSourceConfig)null); - } - - /** - * Get the {@link DataSource} object associated with the only relational database service bound to the app - * configured as specified. - * - * This is equivalent to the element with a nested - * and/or elements. - * - * @param dataSourceConfig configuration for the data source created - * @return data source - * @throws CloudException if there are either 0 or more than 1 relational database services. - */ - public DataSource dataSource(DataSourceConfig dataSourceConfig) { - return cloud.getSingletonServiceConnector(DataSource.class, dataSourceConfig); - } - - /** - * Get the {@link DataSource} object for the specified relational database service. - * - * This is equivalent to the - * - * @param serviceId the name of the service - * @return data source - * @throws CloudException if the specified service doesn't exist - */ - public DataSource dataSource(String serviceId) { - return dataSource(serviceId, null); - } - - /** - * Get the {@link DataSource} object for the specified relational database service configured as specified. - * - * This is equivalent to the element with a - * nested and/or elements. - * - * @param serviceId the name of the service - * @param dataSourceConfig configuration for the data source created - * @return data source - * @throws CloudException if the specified service doesn't exist - */ - public DataSource dataSource(String serviceId, DataSourceConfig dataSourceConfig) { - return cloud.getServiceConnector(serviceId, DataSource.class, dataSourceConfig); - } - - // Mongodb - /** - * Get the {@link MongoDbFactory} object associated with the only MongoDB service bound to the app. - * - * This is equivalent to the element. - * - * @return mongo db factory - * @throws CloudException if there are either 0 or more than 1 mongodb services. - */ - public MongoDbFactory mongoDbFactory() { - return mongoDbFactory((MongoDbFactoryConfig)null); - } - - /** - * Get the {@link MongoDbFactory} object associated with the only MongoDB service bound to the app - * configured as specified. - * - * This is equivalent to the element with a nested element. - * - * @param mongoDbFactoryConfig configuration for the mondo db factory created - * @return mongo db factory - * @throws CloudException if there are either 0 or more than 1 mongodb services. - */ - public MongoDbFactory mongoDbFactory(MongoDbFactoryConfig mongoDbFactoryConfig) { - return cloud.getSingletonServiceConnector(MongoDbFactory.class, mongoDbFactoryConfig); - } - - /** - * Get the {@link MongoDbFactory} object for the specified MongoDB service. - * - * This is equivalent to the element. - * - * @param serviceId the name of the service - * @return mongo db factory - * @throws CloudException if the specified service doesn't exist - */ - public MongoDbFactory mongoDbFactory(String serviceId) { - return mongoDbFactory(serviceId, null); - } - - /** - * Get the {@link MongoDbFactory} object for the specified MongoDB service configured as specified. - * - * This is equivalent to the element - * with a nested element. - * - * @param serviceId the name of the service - * @param mongoDbFactoryConfig configuration for the mongo db factory created - * @return mongo db factory - * @throws CloudException if the specified service doesn't exist - */ - public MongoDbFactory mongoDbFactory(String serviceId, MongoDbFactoryConfig mongoDbFactoryConfig) { - return cloud.getServiceConnector(serviceId, MongoDbFactory.class, mongoDbFactoryConfig); - } - - // RabbitMQ - /** - * Get the {@link ConnectionFactory} object associated with the only RabbitMQ service bound to the app. - * - * This is equivalent to the element. - * - * @return rabbit connection factory - * @throws CloudException if there are either 0 or more than 1 RabbitMQ services. - */ - public ConnectionFactory rabbitConnectionFactory() { - return rabbitConnectionFactory((RabbitConnectionFactoryConfig)null); - } - - /** - * Get the {@link ConnectionFactory} object associated with the only RabbitMQ service bound to the app - * configured as specified. - * - * This is equivalent to the element - * with a nested element. - * - * @param rabbitConnectionFactoryConfig configuration for the rabbit connection factory created - * @return rabbit connection factory - * @throws CloudException if there are either 0 or more than 1 RabbitMQ services. - */ - public ConnectionFactory rabbitConnectionFactory(RabbitConnectionFactoryConfig rabbitConnectionFactoryConfig) { - return cloud.getSingletonServiceConnector(ConnectionFactory.class, rabbitConnectionFactoryConfig); - } - - /** - * Get the {@link ConnectionFactory} object for the specified RabbitMQ service. - * - * This is equivalent to the element. - * - * @param serviceId the name of the service - * @return rabbit connection factory - * @throws CloudException if the specified service doesn't exist - */ - public ConnectionFactory rabbitConnectionFactory(String serviceId) { - return rabbitConnectionFactory(serviceId, null); - } - - /** - * Get the {@link ConnectionFactory} object for the specified RabbitMQ service configured as specified. - * - * This is equivalent to the element - * with a nested element. - * - * @param serviceId the name of the service - * @param rabbitConnectionFactoryConfig configuration for the {@link ConnectionFactory} created - * @return rabbit connection factory - * @throws CloudException if the specified service doesn't exist - */ - public ConnectionFactory rabbitConnectionFactory(String serviceId, RabbitConnectionFactoryConfig rabbitConnectionFactoryConfig) { - return cloud.getServiceConnector(serviceId, ConnectionFactory.class, rabbitConnectionFactoryConfig); - } - - // Redis - /** - * Get the {@link RedisConnectionFactory} object associated with the only Redis service bound to the app. - * - * This is equivalent to the element - * - * @return redis connection factory - * @throws CloudException if there are either 0 or more than 1 redis services. - */ - public RedisConnectionFactory redisConnectionFactory() { - return redisConnectionFactory((PooledServiceConnectorConfig)null); - } - - /** - * Get the {@link RedisConnectionFactory} object associated with the only Redis service bound to the app - * configured as specified. - * - * This is equivalent to the element - * with a nested element. - * - * @param redisConnectionFactoryConfig configuration for the {@link RedisConnectionFactory} created - * @return redis connection factory - * @throws CloudException if there are either 0 or more than 1 redis services. - */ - public RedisConnectionFactory redisConnectionFactory(PooledServiceConnectorConfig redisConnectionFactoryConfig) { - return cloud.getSingletonServiceConnector(RedisConnectionFactory.class, redisConnectionFactoryConfig); - } - - /** - * Get the {@link RedisConnectionFactory} object for the specified Redis service. - * - * This is equivalent to the element. - * - * @param serviceId the name of the service - * @return redis connection factory - * @throws CloudException if the specified service doesn't exist - */ - public RedisConnectionFactory redisConnectionFactory(String serviceId) { - return redisConnectionFactory(serviceId, null); - } - - /** - * Get the {@link RedisConnectionFactory} object for the specified Redis service configured as specified. - * - * This is equivalent to the element - * with a nested element. - * - * @param serviceId the name of the service - * @param redisConnectionFactoryConfig configuration for the {@link RedisConnectionFactory} created - * @return redis connection factory - * @throws CloudException if the specified service doesn't exist - */ - public RedisConnectionFactory redisConnectionFactory(String serviceId, PooledServiceConnectorConfig redisConnectionFactoryConfig) { - return cloud.getServiceConnector(serviceId, RedisConnectionFactory.class, redisConnectionFactoryConfig); - } - - // Generic service - /** - * Get the service connector object associated with the only service bound to the app. - * - * This is equivalent to the element. - * - * @return service connector object - * @throws CloudException if there are either 0 or more than 1 services. - */ - public Object service() { - return service(Object.class); - } - - /** - * Get the service connector object of the specified type if there is only one such candidate service - * - * This is equivalent to the element. - * - * @return service connector object - * @throws CloudException if there are either 0 or more than 1 candidate services. - */ - public T service(Class serviceConnectorType) { - return cloud.getSingletonServiceConnector(serviceConnectorType, null); - } - - /** - * Get the service connector object for the specified service. - * - * This is equivalent to the element. - * - * @return service connector object - * @throws CloudException if the specified service doesn't exist - */ - public Object service(String serviceId) { - return service(serviceId, Object.class); - } - - /** - * Get the service connector object of the specified type and service id - * - * This is equivalent to the element. - * - * @return service connector object - * @throws CloudException if the specified service doesn't exist - */ - public T service(String serviceId, Class serviceConnectorType) { - return cloud.getServiceConnector(serviceId, serviceConnectorType, null); - } - } + public class ServiceConnectionFactory { + // Relational database + + /** + * Get the {@link DataSource} object associated with the only relational database service bound to the app. + * + * This is equivalent to the {@code } element. + * + * @return data source + * @throws CloudException + * if there are either 0 or more than 1 relational database services. + */ + public DataSource dataSource() { + return dataSource((DataSourceConfig) null); + } + + /** + * Get the {@link DataSource} object associated with the only relational database service bound to the app + * configured as specified. + * + * This is equivalent to the {@code } element with nested {@code } and/or + * {@code } elements. + * + * @param dataSourceConfig + * configuration for the data source created + * @return data source + * @throws CloudException + * if there are either 0 or more than 1 relational database services. + */ + public DataSource dataSource(DataSourceConfig dataSourceConfig) { + return cloud.getSingletonServiceConnector(DataSource.class, dataSourceConfig); + } + + /** + * Get the {@link DataSource} object for the specified relational database service. + * + * This is equivalent to the {@code } + * + * @param serviceId + * the name of the service + * @return data source + * @throws CloudException + * if the specified service doesn't exist + */ + public DataSource dataSource(String serviceId) { + return dataSource(serviceId, null); + } + + /** + * Get the {@link DataSource} object for the specified relational database service configured as specified. + * + * This is equivalent to the {@code } element with + * nested {@code } and/or {@code } elements. + * + * @param serviceId + * the name of the service + * @param dataSourceConfig + * configuration for the data source created + * @return data source + * @throws CloudException + * if the specified service doesn't exist + */ + public DataSource dataSource(String serviceId, DataSourceConfig dataSourceConfig) { + return cloud.getServiceConnector(serviceId, DataSource.class, dataSourceConfig); + } + + // Mongodb + /** + * Get the {@link MongoDbFactory} object associated with the only MongoDB service bound to the app. + * + * This is equivalent to the {@code } element. + * + * @return mongo db factory + * @throws CloudException + * if there are either 0 or more than 1 mongodb services. + */ + public MongoDbFactory mongoDbFactory() { + return mongoDbFactory((MongoDbFactoryConfig) null); + } + + /** + * Get the {@link MongoDbFactory} object associated with the only MongoDB service bound to the app + * configured as specified. + * + * This is equivalent to the {@code } element with a nested {@code } element. + * + * @param mongoDbFactoryConfig + * configuration for the mondo db factory created + * @return mongo db factory + * @throws CloudException + * if there are either 0 or more than 1 mongodb services. + */ + public MongoDbFactory mongoDbFactory(MongoDbFactoryConfig mongoDbFactoryConfig) { + return cloud.getSingletonServiceConnector(MongoDbFactory.class, mongoDbFactoryConfig); + } + + /** + * Get the {@link MongoDbFactory} object for the specified MongoDB service. + * + * This is equivalent to the {@code } element. + * + * @param serviceId + * the name of the service + * @return mongo db factory + * @throws CloudException + * if the specified service doesn't exist + */ + public MongoDbFactory mongoDbFactory(String serviceId) { + return mongoDbFactory(serviceId, null); + } + + /** + * Get the {@link MongoDbFactory} object for the specified MongoDB service configured as specified. + * + * This is equivalent to the {@code } element + * with a nested {@code } element. + * + * @param serviceId + * the name of the service + * @param mongoDbFactoryConfig + * configuration for the mongo db factory created + * @return mongo db factory + * @throws CloudException + * if the specified service doesn't exist + */ + public MongoDbFactory mongoDbFactory(String serviceId, MongoDbFactoryConfig mongoDbFactoryConfig) { + return cloud.getServiceConnector(serviceId, MongoDbFactory.class, mongoDbFactoryConfig); + } + + // RabbitMQ + /** + * Get the {@link ConnectionFactory} object associated with the only RabbitMQ service bound to the app. + * + * This is equivalent to the {@code } element. + * + * @return rabbit connection factory + * @throws CloudException + * if there are either 0 or more than 1 RabbitMQ services. + */ + public ConnectionFactory rabbitConnectionFactory() { + return rabbitConnectionFactory((RabbitConnectionFactoryConfig) null); + } + + /** + * Get the {@link ConnectionFactory} object associated with the only RabbitMQ service bound to the app + * configured as specified. + * + * This is equivalent to the {@code } element + * with a nested {@code } element. + * + * @param rabbitConnectionFactoryConfig + * configuration for the rabbit connection factory created + * @return rabbit connection factory + * @throws CloudException + * if there are either 0 or more than 1 RabbitMQ services. + */ + public ConnectionFactory rabbitConnectionFactory(RabbitConnectionFactoryConfig rabbitConnectionFactoryConfig) { + return cloud.getSingletonServiceConnector(ConnectionFactory.class, rabbitConnectionFactoryConfig); + } + + /** + * Get the {@link ConnectionFactory} object for the specified RabbitMQ service. + * + * This is equivalent to the {@code } element. + * + * @param serviceId + * the name of the service + * @return rabbit connection factory + * @throws CloudException + * if the specified service doesn't exist + */ + public ConnectionFactory rabbitConnectionFactory(String serviceId) { + return rabbitConnectionFactory(serviceId, null); + } + + /** + * Get the {@link ConnectionFactory} object for the specified RabbitMQ service configured as specified. + * + * This is equivalent to the {@code } element + * with a nested {@code } element. + * + * @param serviceId + * the name of the service + * @param rabbitConnectionFactoryConfig + * configuration for the {@link ConnectionFactory} created + * @return rabbit connection factory + * @throws CloudException + * if the specified service doesn't exist + */ + public ConnectionFactory rabbitConnectionFactory(String serviceId, + RabbitConnectionFactoryConfig rabbitConnectionFactoryConfig) { + return cloud.getServiceConnector(serviceId, ConnectionFactory.class, rabbitConnectionFactoryConfig); + } + + // Redis + /** + * Get the {@link RedisConnectionFactory} object associated with the only Redis service bound to the app. + * + * This is equivalent to the {@code } element + * + * @return redis connection factory + * @throws CloudException + * if there are either 0 or more than 1 redis services. + */ + public RedisConnectionFactory redisConnectionFactory() { + return redisConnectionFactory((PooledServiceConnectorConfig) null); + } + + /** + * Get the {@link RedisConnectionFactory} object associated with the only Redis service bound to the app + * configured as specified. + * + * This is equivalent to the {@code } element + * with a nested {@code } element. + * + * @param redisConnectionFactoryConfig + * configuration for the {@link RedisConnectionFactory} created + * @return redis connection factory + * @throws CloudException + * if there are either 0 or more than 1 redis services. + */ + public RedisConnectionFactory redisConnectionFactory(PooledServiceConnectorConfig redisConnectionFactoryConfig) { + return cloud.getSingletonServiceConnector(RedisConnectionFactory.class, redisConnectionFactoryConfig); + } + + /** + * Get the {@link RedisConnectionFactory} object for the specified Redis service. + * + * This is equivalent to the {@code } element. + * + * @param serviceId + * the name of the service + * @return redis connection factory + * @throws CloudException + * if the specified service doesn't exist + */ + public RedisConnectionFactory redisConnectionFactory(String serviceId) { + return redisConnectionFactory(serviceId, null); + } + + /** + * Get the {@link RedisConnectionFactory} object for the specified Redis service configured as specified. + * + * This is equivalent to the {@code } element + * with a nested {@code } element. + * + * @param serviceId + * the name of the service + * @param redisConnectionFactoryConfig + * configuration for the {@link RedisConnectionFactory} created + * @return redis connection factory + * @throws CloudException + * if the specified service doesn't exist + */ + public RedisConnectionFactory redisConnectionFactory(String serviceId, + PooledServiceConnectorConfig redisConnectionFactoryConfig) { + return cloud.getServiceConnector(serviceId, RedisConnectionFactory.class, redisConnectionFactoryConfig); + } + + // Generic service + /** + * Get the service connector object associated with the only service bound to the app. + * + * This is equivalent to the {@code } element. + * + * @return service connector object + * @throws CloudException + * if there are either 0 or more than 1 services. + */ + public Object service() { + return service(Object.class); + } + + /** + * Get the service connector object of the specified type if there is only one such candidate service + * + * This is equivalent to the {@code } element. + * + * @param + * the type of the service connector to be returned + * @param serviceConnectorType + * the class of the service connector to be returned + * @return service connector object + * @throws CloudException + * if there are either 0 or more than 1 candidate services. + */ + public T service(Class serviceConnectorType) { + return cloud.getSingletonServiceConnector(serviceConnectorType, null); + } + + /** + * Get the service connector object for the specified service. + * + * This is equivalent to the {@code } element. + * + * @param serviceId + * the service ID of the service to be returned + * @return service connector object + * @throws CloudException + * if the specified service doesn't exist + */ + public Object service(String serviceId) { + return service(serviceId, Object.class); + } + + /** + * Get the service connector object of the specified type and service ID + * + * This is equivalent to the {@code } element. + * + * @param serviceId + * the service ID of the service to be returned + * @param + * the type of the service connector to be returned + * @param serviceConnectorType + * the class of the service connector to be returned + * @return service connector object + * @throws CloudException + * if the specified service doesn't exist + */ + public T service(String serviceId, Class serviceConnectorType) { + return cloud.getServiceConnector(serviceId, serviceConnectorType, null); + } + } } diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudDataSourceFactoryParser.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudDataSourceFactoryParser.java index ae4a773..96c1f07 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudDataSourceFactoryParser.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudDataSourceFactoryParser.java @@ -10,7 +10,7 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** - * Parser for the namespace element + * Parser for the {@code } namespace element * * @author Ramnivas Laddad * @author Thomas Risberg @@ -38,7 +38,7 @@ public class CloudDataSourceFactoryParser extends AbstractPoolingCloudServiceFac cloudPoolConfiguration = parsePoolElement((Element) child, parserContext); } } - + BeanDefinitionBuilder dataSourceConfigBeanBuilder = BeanDefinitionBuilder.genericBeanDefinition("org.springframework.cloud.service.relational.DataSourceConfig"); dataSourceConfigBeanBuilder.addConstructorArgValue(cloudPoolConfiguration); diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudMongoDbFactoryParser.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudMongoDbFactoryParser.java index 5d055e9..7f7ff30 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudMongoDbFactoryParser.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudMongoDbFactoryParser.java @@ -12,7 +12,7 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** - * Parser for the namespace element + * Parser for the {@code } namespace element * * @author Thomas Risberg * @author Ramnivas Laddad @@ -31,7 +31,7 @@ public class CloudMongoDbFactoryParser extends AbstractNestedElementCloudService @Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { super.doParse(element, parserContext, builder); - + Map attributeMap = new HashMap(); parseWriteConcern(element, attributeMap); parseMongoOptionsElement(element, parserContext, attributeMap); @@ -40,9 +40,9 @@ public class CloudMongoDbFactoryParser extends AbstractNestedElementCloudService BeanDefinitionBuilder.genericBeanDefinition("org.springframework.cloud.service.document.MongoDbFactoryConfig"); for (String key : new String[]{WRITE_CONCERN, CONNECTIONS_PER_HOST, MAX_WAIT_TIME}) { String value = attributeMap.get(key); - cloudMongoConfigurationBeanBuilder.addConstructorArgValue(value); + cloudMongoConfigurationBeanBuilder.addConstructorArgValue(value); } - + builder.addConstructorArgValue(cloudMongoConfigurationBeanBuilder.getBeanDefinition()); } @@ -55,7 +55,7 @@ public class CloudMongoDbFactoryParser extends AbstractNestedElementCloudService private void parseMongoOptionsElement(Element element, ParserContext parserContext, Map attributeMap) { NodeList childNodes = element.getChildNodes(); - + for (int i = 0; i < childNodes.getLength(); i++) { Node child = childNodes.item(i); if (isElement(child, parserContext, ELEMENT_MONGO_OPTIONS)) { diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudRabbitConnectionFactoryParser.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudRabbitConnectionFactoryParser.java index 70143de..63a38dd 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudRabbitConnectionFactoryParser.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudRabbitConnectionFactoryParser.java @@ -9,7 +9,7 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** - * Parser for the namespace element + * Parser for the {@code } namespace element * * @author Thomas Risberg * @author Ramnivas Laddad diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudRedisConnectionFactoryParser.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudRedisConnectionFactoryParser.java index 2a735a6..b1649c9 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudRedisConnectionFactoryParser.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/CloudRedisConnectionFactoryParser.java @@ -9,8 +9,8 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** - * Parser for the namespace element - * + * Parser for the {@code } namespace element + * * @author Ramnivas Laddad * */ @@ -33,11 +33,11 @@ public class CloudRedisConnectionFactoryParser extends AbstractPoolingCloudServi cloudPoolConfiguration = parsePoolElement((Element) child, parserContext); } } - + BeanDefinitionBuilder redisConfigBeanBuilder = BeanDefinitionBuilder.genericBeanDefinition("org.springframework.cloud.service.PooledServiceConnectorConfig"); redisConfigBeanBuilder.addConstructorArgValue(cloudPoolConfiguration); builder.addConstructorArgValue(redisConfigBeanBuilder.getBeanDefinition()); - } + } } \ No newline at end of file diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/GenericCloudServiceFactoryParser.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/GenericCloudServiceFactoryParser.java index 85f81f6..cf9cbf0 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/GenericCloudServiceFactoryParser.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/config/xml/GenericCloudServiceFactoryParser.java @@ -9,8 +9,8 @@ import org.w3c.dom.Element; /** - * Support for the catch-all namespace - * + * Support for the catch-all {@code } namespace + * * @author Ramnivas Laddad * */ @@ -26,7 +26,7 @@ public class GenericCloudServiceFactoryParser extends AbstractCloudServiceFactor @Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { super.doParse(element, parserContext, builder); - + String connectorTypeName = element.getAttribute(CONNECTOR_TYPE); if (StringUtils.hasText(connectorTypeName)) { try { @@ -36,7 +36,7 @@ public class GenericCloudServiceFactoryParser extends AbstractCloudServiceFactor throw new CloudException("Failed to load " + connectorTypeName, ex); } } - + // TBD: Support generic (map-based?) service config builder.addConstructorArgValue(null); } diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/AbstractCloudServiceConnectorFactory.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/AbstractCloudServiceConnectorFactory.java index 5db3031..02c06e9 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/AbstractCloudServiceConnectorFactory.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/AbstractCloudServiceConnectorFactory.java @@ -13,111 +13,118 @@ import org.springframework.util.StringUtils; /** * Abstract base factory class. *

- * This factory uses the service creator provided through the constructor to - * create services. If the service name is provided it creates a service object - * based on the service bound to that name. Otherwise, it creates a singleton - * service and fails if it doesn't find a unique service of the expected type. + * This factory uses the service creator provided through the constructor to create services. If the service name is provided it + * creates a service object based on the service bound to that name. Otherwise, it creates a singleton service and fails if it + * doesn't find a unique service of the expected type. * * @author Ramnivas Laddad * - * @param The service type + * @param + * The service type */ -public abstract class AbstractCloudServiceConnectorFactory extends AbstractFactoryBean implements CloudServiceConnectorFactory { +public abstract class AbstractCloudServiceConnectorFactory extends AbstractFactoryBean implements + CloudServiceConnectorFactory { - private static final String CLOUD_FACTORY_BEAN_NAME = "__cloud_factory__"; + private static final String CLOUD_FACTORY_BEAN_NAME = "__cloud_factory__"; - private Cloud cloud; + private Cloud cloud; - protected String serviceId; - private Class serviceConnectorType; - private ServiceConnectorConfig serviceConnectorConfiguration; - - private S serviceInstance; + protected String serviceId; + private Class serviceConnectorType; + private ServiceConnectorConfig serviceConnectorConfiguration; - /** - * - * @param serviceId Optional service name property. If this property is null, a unique service of the expected type - * (redis, for example) needs to be bound to the application. - * @param serviceConnectorType - * @param serviceConnectorConfiguration - */ - public AbstractCloudServiceConnectorFactory(String serviceId, Class serviceConnectorType, ServiceConnectorConfig serviceConnectorConfiguration) { - this.serviceId = serviceId; - this.serviceConnectorType = serviceConnectorType; - this.serviceConnectorConfiguration = serviceConnectorConfiguration; - } + private S serviceInstance; - public AbstractCloudServiceConnectorFactory(Class serviceConnectorType, ServiceConnectorConfig serviceConnectorConfiguration) { - this(null, serviceConnectorType, serviceConnectorConfiguration); - } + /** + * + * @param serviceId + * Optional service name property. If this property is null, a unique service of the expected type + * (redis, for example) needs to be bound to the application. + * @param serviceConnectorType + * the class of the service connector that will be returned + * @param serviceConnectorConfiguration + * configuration to be applied to the service connector + */ + public AbstractCloudServiceConnectorFactory(String serviceId, Class serviceConnectorType, + ServiceConnectorConfig serviceConnectorConfiguration) { + this.serviceId = serviceId; + this.serviceConnectorType = serviceConnectorType; + this.serviceConnectorConfiguration = serviceConnectorConfiguration; + } - /** - * Set the cloud, for internal testing purpose only. - * - *

- * For normal usage, the {@link InitializingBean} approach will create (if needed) a {@link CloudFactory} and obtain a {@link Cloud} from it. - * - * @param cloud - */ - public void setCloud(Cloud cloud) { - this.cloud = cloud; - } - - @Override - public void afterPropertiesSet() throws Exception { - ConfigurableListableBeanFactory beanFactory = (ConfigurableListableBeanFactory) getBeanFactory(); - - if (cloud == null) { - if(beanFactory.getBeansOfType(CloudFactory.class).isEmpty()) { - beanFactory.registerSingleton(CLOUD_FACTORY_BEAN_NAME, new CloudFactory()); - } - CloudFactory cloudFactory = beanFactory.getBeansOfType(CloudFactory.class).values().iterator().next(); - cloud = cloudFactory.getCloud(); - } - if (!StringUtils.hasText(serviceId)) { - List infos = cloud.getServiceInfos(serviceConnectorType); - if (infos.size() != 1) { - throw new CloudException("Expected 1 service matching " + serviceConnectorType.getName() + " type, but found " + infos.size()); - } - serviceId = infos.get(0).getId(); - } - - super.afterPropertiesSet(); - } - - @Override - protected S createInstance() throws Exception { - return createService(); - } - - public S createService() { - if (serviceInstance == null && cloud != null) { - serviceInstance = cloud.getServiceConnector(serviceId, serviceConnectorType, serviceConnectorConfiguration); - } - return serviceInstance; - } - - @SuppressWarnings("unchecked") - @Override - public Class getObjectType() { - if (serviceConnectorType == null) { - try { - serviceConnectorType = (Class) createService().getClass(); - } - catch (Exception e) { - return null; - } - } - return serviceConnectorType; - } + public AbstractCloudServiceConnectorFactory(Class serviceConnectorType, ServiceConnectorConfig serviceConnectorConfiguration) { + this(null, serviceConnectorType, serviceConnectorConfiguration); + } - public String getServiceId() { - return serviceId; - } + /** + * Set the cloud, for internal testing purpose only. + * + *

+ * For normal usage, the {@link InitializingBean} approach will create (if needed) a {@link CloudFactory} and obtain a + * {@link Cloud} from it. + * + * @param cloud + * the {@link Cloud} instance describing the discovered runtime environment + */ + public void setCloud(Cloud cloud) { + this.cloud = cloud; + } - public void setServiceConnectorType(Class serviceConnectorType) { - if (serviceConnectorType != null) { - this.serviceConnectorType = serviceConnectorType; - } - } + @Override + public void afterPropertiesSet() throws Exception { + ConfigurableListableBeanFactory beanFactory = (ConfigurableListableBeanFactory) getBeanFactory(); + + if (cloud == null) { + if (beanFactory.getBeansOfType(CloudFactory.class).isEmpty()) { + beanFactory.registerSingleton(CLOUD_FACTORY_BEAN_NAME, new CloudFactory()); + } + CloudFactory cloudFactory = beanFactory.getBeansOfType(CloudFactory.class).values().iterator().next(); + cloud = cloudFactory.getCloud(); + } + if (!StringUtils.hasText(serviceId)) { + List infos = cloud.getServiceInfos(serviceConnectorType); + if (infos.size() != 1) { + throw new CloudException("Expected 1 service matching " + serviceConnectorType.getName() + " type, but found " + + infos.size()); + } + serviceId = infos.get(0).getId(); + } + + super.afterPropertiesSet(); + } + + @Override + protected S createInstance() throws Exception { + return createService(); + } + + public S createService() { + if (serviceInstance == null && cloud != null) { + serviceInstance = cloud.getServiceConnector(serviceId, serviceConnectorType, serviceConnectorConfiguration); + } + return serviceInstance; + } + + @SuppressWarnings("unchecked") + @Override + public Class getObjectType() { + if (serviceConnectorType == null) { + try { + serviceConnectorType = (Class) createService().getClass(); + } catch (Exception e) { + return null; + } + } + return serviceConnectorType; + } + + public String getServiceId() { + return serviceId; + } + + public void setServiceConnectorType(Class serviceConnectorType) { + if (serviceConnectorType != null) { + this.serviceConnectorType = serviceConnectorType; + } + } } diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/PooledServiceConnectorConfig.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/PooledServiceConnectorConfig.java index c6dc3d5..60c1efa 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/PooledServiceConnectorConfig.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/PooledServiceConnectorConfig.java @@ -4,7 +4,7 @@ import org.springframework.util.StringUtils; /** * Configuration for pooling - * + * * @author Ramnivas Laddad * @author Mark Fisher * @author Thomas Risberg @@ -20,7 +20,7 @@ public class PooledServiceConnectorConfig implements ServiceConnectorConfig { public PoolConfig getPoolConfig() { return poolConfig; } - + public static class PoolConfig { private int minPoolSize; private int maxPoolSize; @@ -31,54 +31,60 @@ public class PooledServiceConnectorConfig implements ServiceConnectorConfig { this.maxPoolSize = maxPoolSize; this.maxWaitTime = maxWaitTime; } - + public PoolConfig(int maxPoolSize, int maxWaitTime) { this(0, maxPoolSize, maxWaitTime); - } - + } + public PoolConfig(String poolSize, int maxWaitTime) { determinePoolSizeRange(poolSize); this.maxWaitTime = maxWaitTime; } - + /** - * Getter corresponding to the DBCP initialSize property + * @return property corresponding to DBCP {@code initialSize} */ public int getInitialSize() { return minPoolSize; } /** - * Getter corresponding to the DBCP minIdle property + * @return property corresponding to DBCP {@code minIdle} */ public int getMinIdle() { return minPoolSize; } /** - * Getter corresponding to the DBCP maxActive property + * @return property corresponding to DBCP {@code maxActive} */ public int getMaxActive() { return maxPoolSize; } // For commons-pool2 + /** + * @return property corresponding to commons-pool {@code maxTotal} + */ public int getMaxTotal() { return maxPoolSize; } /** - * Getter corresponding to the DBCP maxWait property + * @return property corresponding to DBCP {@code maxWait} */ public int getMaxWait() { return maxWaitTime; } - // For commons-pool2 + // For commons-pool2 + /** + * @return property corresponding to commons-pool {@code maxWaitMillis} + */ public int getMaxWaitMillis() { return maxWaitTime; } - + private void determinePoolSizeRange(String poolSize) { if (StringUtils.hasText(poolSize)) { try { diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/document/MongoDbFactoryConfig.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/document/MongoDbFactoryConfig.java index 8460efc..43e659d 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/document/MongoDbFactoryConfig.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/document/MongoDbFactoryConfig.java @@ -12,7 +12,7 @@ public class MongoDbFactoryConfig implements ServiceConnectorConfig { private String writeConcern; private Integer connectionsPerHost; private Integer maxWaitTime; - + public MongoDbFactoryConfig(String writeConcern, Integer connectionsPerHost, Integer maxWaitTime) { this.writeConcern = writeConcern; this.connectionsPerHost = connectionsPerHost; @@ -24,14 +24,14 @@ public class MongoDbFactoryConfig implements ServiceConnectorConfig { } /** - * Getter corresponding to the MongoOptions connectionsPerHost field + * @return property corresponding to MongoOptions {@code connectionsPerHost} */ public Integer getConnectionsPerHost() { return connectionsPerHost; } /** - * Getter corresponding to the MongoOptions maxWaitTime field + * @return property corresponding to the MongoOptions {@code maxWaitTime} */ public Integer getMaxWaitTime () { return maxWaitTime ; diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/BasicDbcpPooledDataSourceCreator.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/BasicDbcpPooledDataSourceCreator.java index 7f67266..56d3f5d 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/BasicDbcpPooledDataSourceCreator.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/BasicDbcpPooledDataSourceCreator.java @@ -8,10 +8,10 @@ import org.springframework.cloud.service.ServiceConnectorConfig; import org.springframework.cloud.service.common.RelationalServiceInfo; /** - * + * * @author Ramnivas Laddad * - * @param + * @param the {@link RelationalServiceInfo} type for the underlying database service */ public class BasicDbcpPooledDataSourceCreator extends DbcpLikePooledDataSourceCreator { diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DataSourceCreator.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DataSourceCreator.java index 43008cd..654799f 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DataSourceCreator.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DataSourceCreator.java @@ -15,10 +15,10 @@ import org.springframework.cloud.service.common.RelationalServiceInfo; import org.springframework.jdbc.datasource.SimpleDriverDataSource; /** - * + * * @author Ramnivas Laddad * - * @param + * @param the {@link RelationalServiceInfo} for the backing database service */ public abstract class DataSourceCreator extends AbstractServiceConnectorCreator { @@ -34,20 +34,20 @@ public abstract class DataSourceCreator extend this.driverSystemPropKey = driverSystemPropKey; this.driverClasses = driverClasses; this.validationQuery = validationQuery; - + if (pooledDataSourceCreators.size() == 0) { pooledDataSourceCreators.add(new BasicDbcpPooledDataSourceCreator()); pooledDataSourceCreators.add(new TomcatDbcpPooledDataSourceCreator()); pooledDataSourceCreators.add(new TomcatHighPerformancePooledDataSourceCreator()); } } - + @Override public DataSource create(SI serviceInfo, ServiceConnectorConfig serviceConnectorConfig) { try { for (PooledDataSourceCreator delegate: pooledDataSourceCreators) { DataSource ds = delegate.create(serviceInfo, serviceConnectorConfig, getDriverClassName(serviceInfo), validationQuery); - + if (ds != null) { return ds; } @@ -61,10 +61,10 @@ public abstract class DataSourceCreator extend + serviceInfo.getId() + " service", e); } } - + public String getDriverClassName(SI serviceInfo) { String userSpecifiedDriver = System.getProperty(driverSystemPropKey); - + if (userSpecifiedDriver != null && !userSpecifiedDriver.isEmpty()) { return userSpecifiedDriver; } else { diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DbcpLikePooledDataSourceCreator.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DbcpLikePooledDataSourceCreator.java index 572dac9..06177b5 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DbcpLikePooledDataSourceCreator.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/DbcpLikePooledDataSourceCreator.java @@ -12,13 +12,13 @@ import org.springframework.cloud.service.common.RelationalServiceInfo; /** * Common implementation that assumes DBCP connection pool properties. - * + * * @author Ramnivas Laddad * - * @param + * @param the {@link RelationalServiceInfo} type for the underlying database service */ public abstract class DbcpLikePooledDataSourceCreator implements PooledDataSourceCreator { - + protected static Logger logger = Logger.getLogger(PooledDataSourceCreator.class.getName()); private DataSourceConfigurer configurer = new DataSourceConfigurer(); @@ -33,9 +33,9 @@ public abstract class DbcpLikePooledDataSourceCreator + * @param the {@link RelationalServiceInfo} type for the underlying database service */ public interface PooledDataSourceCreator { public abstract DataSource create(RelationalServiceInfo serviceInfo, ServiceConnectorConfig serviceConnectorConfig, diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatDbcpPooledDataSourceCreator.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatDbcpPooledDataSourceCreator.java index 74709e1..7ce9c48 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatDbcpPooledDataSourceCreator.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatDbcpPooledDataSourceCreator.java @@ -8,10 +8,10 @@ import org.springframework.cloud.service.ServiceConnectorConfig; import org.springframework.cloud.service.common.RelationalServiceInfo; /** - * + * * @author Ramnivas Laddad * - * @param + * @param the {@link RelationalServiceInfo} type for the underlying database service */ public class TomcatDbcpPooledDataSourceCreator extends DbcpLikePooledDataSourceCreator { diff --git a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatHighPerformancePooledDataSourceCreator.java b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatHighPerformancePooledDataSourceCreator.java index 5f7aea2..b68a647 100644 --- a/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatHighPerformancePooledDataSourceCreator.java +++ b/spring-cloud-spring-service-connector/src/main/java/org/springframework/cloud/service/relational/TomcatHighPerformancePooledDataSourceCreator.java @@ -8,12 +8,10 @@ import org.springframework.cloud.service.ServiceConnectorConfig; import org.springframework.cloud.service.common.RelationalServiceInfo; /** - * - * @author Ramnivas Laddad * - * @param + * @author Ramnivas Laddad */ -public class TomcatHighPerformancePooledDataSourceCreator +public class TomcatHighPerformancePooledDataSourceCreator extends DbcpLikePooledDataSourceCreator { @Override