spring-cloud / spring-cloud-connectors

Library to let cloud applications connect to services
Apache License 2.0
185 stars 161 forks source link

MongoDbFactory binding doesn't work with Spring Data Mongo 1.8 #129

Closed dsyer closed 9 years ago

dsyer commented 9 years ago

The latest version of Spring Data Mongo (and hence Spring Boot 1.3) breaks with spring-cloud-connectors because of the way the SimpleMongoDbFactory is created:

...
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.core.MongoTemplate]: Factory method 'mongoTemplate' threw exception; nested exception is org.springframework.data.mongodb.UncategorizedMongoDbException: { "serverUsed" : "ds047762-a.mongolab.com:47762" , "ok" : 0.0 , "errmsg" : "not authorized on CloudFoundry_4ahipg1b_9bdp4c7f to execute command { createIndexes: \"store\", indexes: [ { name: \"address.location\", ns: \"CloudFoundry_4ahipg1b_9bdp4c7f.store\", min: -180, max: 180, bits: 26, key: { address.location: \"2d\" } } ] }" , "code" : 13}; nested exception is com.mongodb.CommandFailureException: { "serverUsed" : "ds047762-a.mongolab.com:47762" , "ok" : 0.0 , "errmsg" : "not authorized on CloudFoundry_4ahipg1b_9bdp4c7f to execute command { createIndexes: \"store\", indexes: [ { name: \"address.location\", ns: \"CloudFoundry_4ahipg1b_9bdp4c7f.store\", min: -180, max: 180, bits: 26, key: { address.location: \"2d\" } } ] }" , "code" : 13}
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    ... 61 more
Caused by: org.springframework.data.mongodb.UncategorizedMongoDbException: { "serverUsed" : "ds047762-a.mongolab.com:47762" , "ok" : 0.0 , "errmsg" : "not authorized on CloudFoundry_4ahipg1b_9bdp4c7f to execute command { createIndexes: \"store\", indexes: [ { name: \"address.location\", ns: \"CloudFoundry_4ahipg1b_9bdp4c7f.store\", min: -180, max: 180, bits: 26, key: { address.location: \"2d\" } } ] }" , "code" : 13}; nested exception is com.mongodb.CommandFailureException: { "serverUsed" : "ds047762-a.mongolab.com:47762" , "ok" : 0.0 , "errmsg" : "not authorized on CloudFoundry_4ahipg1b_9bdp4c7f to execute command { createIndexes: \"store\", indexes: [ { name: \"address.location\", ns: \"CloudFoundry_4ahipg1b_9bdp4c7f.store\", min: -180, max: 180, bits: 26, key: { address.location: \"2d\" } } ] }" , "code" : 13}
    at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:101)
    at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.createIndex(MongoPersistentEntityIndexCreator.java:162)
    at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.checkForAndCreateIndexes(MongoPersistentEntityIndexCreator.java:133)
    at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.checkForIndexes(MongoPersistentEntityIndexCreator.java:125)
    at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.<init>(MongoPersistentEntityIndexCreator.java:91)
    at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.<init>(MongoPersistentEntityIndexCreator.java:68)
    at org.springframework.data.mongodb.core.MongoTemplate.<init>(MongoTemplate.java:225)
    at org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration.mongoTemplate(MongoDataAutoConfiguration.java:115)
    at org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration$$EnhancerBySpringCGLIB$$e87cdac1.CGLIB$mongoTemplate$2(<generated>)
    at org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration$$EnhancerBySpringCGLIB$$e87cdac1$$FastClassBySpringCGLIB$$14048274.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:318)
    at org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration$$EnhancerBySpringCGLIB$$e87cdac1.mongoTemplate(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 62 more
Caused by: com.mongodb.CommandFailureException: { "serverUsed" : "ds047762-a.mongolab.com:47762" , "ok" : 0.0 , "errmsg" : "not authorized on CloudFoundry_4ahipg1b_9bdp4c7f to execute command { createIndexes: \"store\", indexes: [ { name: \"address.location\", ns: \"CloudFoundry_4ahipg1b_9bdp4c7f.store\", min: -180, max: 180, bits: 26, key: { address.location: \"2d\" } } ] }" , "code" : 13}
    at com.mongodb.CommandResult.getException(CommandResult.java:76)
    at com.mongodb.CommandResult.throwOnError(CommandResult.java:140)
    at com.mongodb.DBCollectionImpl.createIndex(DBCollectionImpl.java:399)
    at com.mongodb.DBCollection.createIndex(DBCollection.java:597)
    at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.createIndex(MongoPersistentEntityIndexCreator.java:142)
    ... 78 more
dsyer commented 9 years ago

As far as I can tell, the correct way to do it now is to just use the URI as it is and not try to extract credentials from it. So Spring Boot out of the box works fine and they changed the MongoDataAutoConfiguration to just do this:

    @Bean
    @ConditionalOnMissingBean(MongoDbFactory.class)
    public SimpleMongoDbFactory mongoDbFactory(MongoClient mongo) throws Exception {
        String database = this.properties.getMongoClientDatabase();
        return new SimpleMongoDbFactory(mongo, database);
    }

i.e. no messing around with the URI to extract credentials.