I am having problems in using Spring to access MongoDB with credentials. While without credentials it works like a charme, using them just fails saying
F
Here is xml version to connect MongoDB 3.0.7 with Spring (parameters are passed from a property file):
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<mongo:mongo-client host="${mongo.url}" port="${mongo.port}" credentials="${mongo.user}:${mongo.pass}@${mongo.dbname}">
<mongo:client-options write-concern="NORMAL" />
</mongo:mongo-client>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongo" ref="mongo"/>
<constructor-arg name="databaseName" value="${mongo.dbname}"/>
</bean>
Then in Java, you get mongoTemplate like this:
@Autowired
MongoTemplate mongoTemplate;
public String mongoTest() {
DBCollection dc = mongoTemplate.getCollection("yourCollection");
logger.debug("--get collection name=" + dc.getFullName());
}
There are two of possibilities how to make Mongodb 3 work with Spring data. Both involve downgrading of authentication schema:
start with mongodb 2.x and upgrade to 3.0; works as authentication system stays the same
if you have a new installation of mongo 3.0, you can downgrade the authentication schema before creating the users.
To downgrade the authentication mechanism:
var schema = db.system.version.findOne({"_id" : "authSchema"})
schema.currentVersion = 3
db.system.version.save(schema)
Or you can even have mixed users, some created with version 5 (that of mongo 3) and some with version 3. Except you will be able to connect (from Spring data) only with users created using version 3.
You could try 3.0 + mongo 3 beta drivers: in general this combination works with "legacy code", but I did not manage to make it work with Spring Data.
spring.data.mongodb.host
and spring.data.mongodb.port
are not supported if you’re using the Mongo 3.0 Java driver. In such cases, spring.data.mongodb.uri
should be used to provide all of the configuration, like this:
spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:12345
Just add the spring.data.mongodb.uri
to your application.yml
and you'll get the auto configured MongoDbFactory
and MongoTemplate
.
using this versions in your pom:
<!-- mongodb java driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.2.1</version>
</dependency>
<!-- Spring data mongodb -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.8.2.RELEASE</version>
</dependency>
And this configuration in spring:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<!-- Seeds -->
<bean id="mongoSeedListID" class="java.util.ArrayList">
<constructor-arg>
<list>
<ref bean="mongoSeedlID" />
</list>
</constructor-arg>
</bean>
<bean id="mongoSeedlID" class="com.mongodb.ServerAddress">
<constructor-arg type="java.lang.String" name="host" value="DATABASE_HOST" />
<constructor-arg type="int" name="port" value="DATABASE_PORT" />
</bean>
<!-- Credentials -->
<bean id="mongoCredentialListID" class="java.util.ArrayList">
<constructor-arg>
<list>
<ref bean="mongoCredentialID" />
</list>
</constructor-arg>
</bean>
<bean id="mongoCredentialID" class="com.mongodb.MongoCredential">
<constructor-arg name="mechanism" value = "#{T(com.mongodb.AuthenticationMechanism).SCRAM_SHA_1}" />
<constructor-arg type="java.lang.String" name="userName" value="DATABASE_USERNAME" />
<constructor-arg type="java.lang.String" name="source" value="DATABASE_SOURCE" />
<constructor-arg type="char[]" name="password" value="DB_USER_PASS" />
</bean>
<!-- MongoClient -->
<bean id="mongoClientID" class="com.mongodb.MongoClient">
<constructor-arg ref="mongoSeedListID" />
<constructor-arg ref="mongoCredentialID" />
</bean>
<!-- MongoDbFactory -->
<bean id="simpleMongoDbFactoryID" class="org.springframework.data.mongodb.core.SimpleMongoDbFactory">
<constructor-arg ref="mongoClientID" />
<constructor-arg name="databaseName" value="APP_DATABASENAME" />
</bean>
<!-- MongoTemplate -->
<bean id="mongoTemplateID" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="simpleMongoDbFactoryID" />
</bean>
<bean id="log4jInitializationID" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="org.springframework.util.Log4jConfigurer" />
<property name="targetMethod" value="initLogging" />
<property name="arguments">
<list>
<value>classpath:log4j/log4j_test.properties</value>
</list>
</property>
</bean>
</beans>
With this configuration you only have to inject the MongoTemplate:
@Autowired
@Qualifier("mongoTemplateID")
private MongoTemplate mongoTemplate;
This should work fine =)
After a lot of attempts and reading, I found a way to make MongoDB 3.0 work with authentication.
This was a new installation of MongoDB 3.0, no upgrade involved.
I used these maven dependencies:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.6.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.0.0</version>
</dependency>
having as parent
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.2.RELEASE</version>
</parent>
Then in my Configuration file I had
/**
* DB connection Factory
*
* @return a ready to use MongoDbFactory
*/
@Bean
public MongoDbFactory mongoDbFactory() throws Exception {
// Set credentials
MongoCredential credential = MongoCredential.createCredential(mongoUser, databaseName, mongoPass.toCharArray());
ServerAddress serverAddress = new ServerAddress(mongoHost, mongoPort);
// Mongo Client
MongoClient mongoClient = new MongoClient(serverAddress,Arrays.asList(credential));
// Mongo DB Factory
SimpleMongoDbFactory simpleMongoDbFactory = new SimpleMongoDbFactory(
mongoClient, databaseName);
return simpleMongoDbFactory;
}
/**
* Template ready to use to operate on the database
*
* @return Mongo Template ready to use
*/
@Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongoDbFactory());
}
And finally wherever you have access to the MongoTemplate bean you'll be able to do
mongoTemplate.insert(objectToStore, collectionName);