package org.cloudfoundry.runtime.service;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import org.cloudfoundry.runtime.env.CloudEnvironment;
import org.cloudfoundry.runtime.env.CloudServiceException;
import org.cloudfoundry.runtime.service.AbstractServiceCreator.ServiceNameTuple;
import org.cloudfoundry.runtime.service.document.MongoServiceCreator;
import org.cloudfoundry.runtime.service.keyvalue.RedisServiceCreator;
import org.cloudfoundry.runtime.service.messaging.RabbitServiceCreator;
import org.cloudfoundry.runtime.service.relational.MysqlServiceCreator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
/**
* Bean factory post processor that adds a bean for each service bound to the application.
*
* <p>
* Each service populated by this bean has the same name as the service it is bound to.
* </p>
*
* Usage:
* <p>
* An application may add a bean of this type:
* <pre>
* <bean class="org.cloudfoundry.runtime.service.CloudServicesAutoPopulator"/>
* </pre>
* to have an easy access to all the services.
*
* If there is unique bean of a type, you can inject beans using the following
* code (shows Redis, but the same scheme works for all services):
* <pre>
* @Autowired RedisConnectionFactory redisConnectionFactory;
* </pre>
*
* If there are more than one services of a type, you can use the @Qualifier
* as in the following code:
* <pre>
* @Autowired @Qualifier("service-name1") RedisConnectionFactory redisConnectionFactory;
* @Autowired @Qualifier("service-name2") RedisConnectionFactory redisConnectionFactory;
* </pre>
*
* You may, of course, use XML-based configuration.
*
* @author Ramnivas Laddad
*
*/
public class CloudServicesAutoPopulator implements BeanFactoryPostProcessor {
Logger logger = Logger.getLogger(CloudServicesAutoPopulator.class.getName());
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
CloudEnvironment cloudEnvironment;
String[] envBeans = beanFactory.getBeanNamesForType(CloudEnvironment.class);
if (envBeans.length == 0) {
cloudEnvironment = new CloudEnvironment();
beanFactory.registerSingleton("cloud-environment", cloudEnvironment);
} else if (envBeans.length == 1){
cloudEnvironment = beanFactory.getBean(CloudEnvironment.class);
} else {
throw new CloudServiceException("CloudServicesAutoPopulator expects 0 or 1 bean of CloudEnvironment, found "
+ envBeans.length);
}
List<AbstractServiceCreator> serviceCreators = new ArrayList<AbstractServiceCreator>();
serviceCreators.add(new MysqlServiceCreator(cloudEnvironment));
serviceCreators.add(new RedisServiceCreator(cloudEnvironment));
serviceCreators.add(new RabbitServiceCreator(cloudEnvironment));
serviceCreators.add(new MongoServiceCreator(cloudEnvironment));
logger.info("Auto-creating service beans");
for (AbstractServiceCreator serviceCreator : serviceCreators) {
List<ServiceNameTuple<Object>> serviceNamePairs = serviceCreator.createServices();
for (ServiceNameTuple<Object> serviceNamePair : serviceNamePairs) {
logger.info("Auto-creating service bean for " + serviceNamePair.name);
beanFactory.registerSingleton(serviceNamePair.name, serviceNamePair.service);
}
}
}
}