package org.springframework.cloud.service.document; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.UnknownHostException; import org.springframework.cloud.service.AbstractServiceConnectorCreator; import org.springframework.cloud.service.ServiceConnectorConfig; import org.springframework.cloud.service.ServiceConnectorCreationException; import org.springframework.cloud.service.common.MongoServiceInfo; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; import com.mongodb.MongoClient; import com.mongodb.MongoClientOptions; import com.mongodb.MongoClientOptions.Builder; import com.mongodb.MongoClientURI; import com.mongodb.MongoException; import com.mongodb.WriteConcern; /** * Simplified access to creating MongoDB service objects. * * @author Ramnivas Laddad * @author Thomas Risberg * @author Chris Schaefer */ public class MongoDbFactoryCreator extends AbstractServiceConnectorCreator<MongoDbFactory, MongoServiceInfo> { @Override public MongoDbFactory create(MongoServiceInfo serviceInfo, ServiceConnectorConfig config) { try { MongoClientOptions.Builder mongoOptionsToUse = getMongoOptions((MongoDbFactoryConfig) config); SimpleMongoDbFactory mongoDbFactory = createMongoDbFactory(serviceInfo, mongoOptionsToUse); return configure(mongoDbFactory, (MongoDbFactoryConfig) config); } catch (UnknownHostException e) { throw new ServiceConnectorCreationException(e); } catch (MongoException e) { throw new ServiceConnectorCreationException(e); } } private SimpleMongoDbFactory createMongoDbFactory(MongoServiceInfo serviceInfo, MongoClientOptions.Builder mongoOptionsToUse) throws UnknownHostException { MongoClientURI mongoClientURI = new MongoClientURI(serviceInfo.getUri(), mongoOptionsToUse); MongoClient mongo = new MongoClient(mongoClientURI); return new SimpleMongoDbFactory(mongo, mongoClientURI.getDatabase()); } private MongoClientOptions.Builder getMongoOptions(MongoDbFactoryConfig config) { MongoClientOptions.Builder builder; Method builderMethod = ClassUtils.getMethodIfAvailable(MongoClientOptions.class, "builder"); if (builderMethod != null) { builder = (Builder) ReflectionUtils.invokeMethod(builderMethod, null); } else { Constructor<Builder> builderConstructor = ClassUtils.getConstructorIfAvailable(MongoClientOptions.Builder.class); try { builder = builderConstructor.newInstance(new Object[0]); } catch (InstantiationException e) { throw new IllegalStateException(e); } catch (IllegalAccessException e) { throw new IllegalStateException(e); } catch (IllegalArgumentException e) { throw new IllegalStateException(e); } catch (InvocationTargetException e) { throw new IllegalStateException(e); } } if (config != null) { if (config.getConnectionsPerHost() != null) { builder.connectionsPerHost(config.getConnectionsPerHost()); } if (config.getMaxWaitTime() != null) { builder.maxWaitTime(config.getMaxWaitTime()); } if (config.getWriteConcern() != null) { builder.writeConcern(new WriteConcern(config.getWriteConcern())); } } return builder; } public SimpleMongoDbFactory configure(SimpleMongoDbFactory mongoDbFactory, MongoDbFactoryConfig config) { if (config != null && config.getWriteConcern() != null) { WriteConcern writeConcern = WriteConcern.valueOf(config.getWriteConcern()); if (writeConcern != null) { mongoDbFactory.setWriteConcern(writeConcern); } } return mongoDbFactory; } }