package org.springframework.cloud; import java.util.ArrayList; import java.util.List; import java.util.ServiceLoader; import org.springframework.cloud.service.ServiceConnectorCreator; import org.springframework.cloud.service.ServiceInfo; import org.springframework.cloud.util.ServiceLoaderWithExceptionControl; /** * Factory for the cloud. * * <p> * The main entry point for user code. Typical code directly using this class (as opposed to using a dependency-injection framework) * will look like: * * <pre> * CloudFactory cloudFactory = new CloudFactory(); * Cloud cloud = cloudFoundry.getCloud(); * </pre> * * 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<CloudConnector> cloudConnectors = new ArrayList<CloudConnector>(); private List<ServiceConnectorCreator<?, ? extends ServiceInfo>> serviceCreators = new ArrayList<ServiceConnectorCreator<?, ? extends ServiceInfo>>(); 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; } } if (suitableCloudConnector == null) { throw new CloudException("No suitable cloud connector found"); } 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); } /* package access for testing */ List<CloudConnector> getCloudConnectors() { return cloudConnectors; } /* package access for testing */ List<ServiceConnectorCreator<?, ? extends ServiceInfo>> getServiceCreators() { return serviceCreators; } 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); } } @SuppressWarnings({ "rawtypes", "unchecked" }) private void scanServiceConnectorCreators() { Iterable<ServiceConnectorCreator> loader = ServiceLoaderWithExceptionControl.load(ServiceConnectorCreator.class); for (ServiceConnectorCreator serviceConnectorCreator : loader) { if (serviceConnectorCreator != null) { registerServiceCreator(serviceConnectorCreator); } } } }