To learn (spring/mongoBD/CLoudBees), I have created a mongoDB instance on CloudBees, and I am trying to connect my spring app using spring Data.
I get the following error:
Caused by: org.springframework.data.mongodb.CannotGetMongoDbConnectionException:
Failed to authenticate to database [appDB], username = [MY_DB_USERNAME], password = [b**********1]
at org.springframework.data.mongodb.core.MongoDbUtils.doGetDB(MongoDbUtils.java:114)
at org.springframework.data.mongodb.core.MongoDbUtils.getDB(MongoDbUtils.java:74)
at org.springframework.data.mongodb.core.SimpleMongoDbFactory.getDb(SimpleMongoDbFactory.java:118)
at org.springframework.data.mongodb.core.SimpleMongoDbFactory.getDb(SimpleMongoDbFactory.java:107)
at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.ensureIndex(MongoPersistentEntityIndexCreator.java:213)
at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator$1.doWithPersistentProperty(MongoPersistentEntityIndexCreator.java:146)
at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator$1.doWithPersistentProperty(MongoPersistentEntityIndexCreator.java:120)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:257)
at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.checkForIndexes(MongoPersistentEntityIndexCreator.java:120)
at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.onApplicationEvent(MongoPersistentEntityIndexCreator.java:92)
at org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator.onApplicationEvent(MongoPersistentEntityIndexCreator.java:49)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:96)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:334)
at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:268)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:168)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:137)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:63)
at org.springframework.data.mongodb.repository.support.MongoRepositoryFactory.getEntityInformation(MongoRepositoryFactory.java:141)
at org.springframework.data.mongodb.repository.support.MongoRepositoryFactory.getTargetRepository(MongoRepositoryFactory.java:83)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:147)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:162)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:44)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
... 46 more
My XML config for Spring Data:
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongo" ref="mongo"/>
<constructor-arg name="databaseName" value="appDB"/>
<constructor-arg name="userCredentials" ref="mongoCredentials"/>
</bean>
<bean id="mongoCredentials" class="org.springframework.data.authentication.UserCredentials">
<constructor-arg name="username" value="#{mongoUri.username}" />
<constructor-arg name="password" value="#{new java.lang.String(mongoUri.password)}" />
</bean>
<bean id="mongoUri" class="com.mongodb.MongoURI">
<constructor-arg value="mongodb://MY_DB_USERNAME:MY_DB_PASS#paulo.mongohq.com:10048/xxxxxxxxxxxxx"/>
</bean>
<bean class="com.mongodb.Mongo" id="mongo">
<constructor-arg ref="mongoUri" />
</bean>
When I test my URI mongodb://MY_DB_USERNAME:MY_DB_PASS#paulo.mongohq.com:10048/xxxxxxxxxxxxx using umongo, it connects correctly.
Maven dependencies:
spring data mongodb version: 1.3.1.RELEASE
mongodb driver version: 2.10.1
spring core version: 3.2.3.RELEASE
Any idea about what I am doing wrong ?
I solved the problem by replacing my DB name "appDB" by #{mongoUri.database} so the new Bean def for mongoTemplate is:
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongo" ref="mongo"/>
<constructor-arg name="databaseName" value="#{mongoUri.database}"/>
<constructor-arg name="userCredentials" ref="mongoCredentials"/>
</bean>
I don't understand why putting the DB name directly as String is wrong, but anyway for me it works with this XML config.
Related
I'm using Facebook login to authenticate in my application. I use the authentication filter.
The authentication goes OK, but when it redirects back to homepage the filter doesn't seem to set the Authentication object, so calling SecurityContextHolder.getContext().getAuthentication() returns null. This only happens the first time when the user authorizes our app. It doesn't happen after that.
Currently to get the Authentication object set, the user has to 'login with facebook' twice. The second time it doesn't actually do any logins, the filter looks like it's picking up the cookie and does the authentication and doesn't even need to go to Facebook anymore.
So my question is why do I need to go through the filter twice? Or how can I avoid that?
Configuration looks like this:
<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<constructor-arg value="/login"/>
<property name="useForward" value="true"/>
</bean>
<bean class="com.gigi.web.SpringDataUserDetailsService" id="userService"/>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="userService"/>
<security:authentication-provider ref="socialAuthenticationProvider" />
</security:authentication-manager>
<bean class="org.springframework.social.security.SocialAuthenticationFilter" id="socialAuthenticationFilter">
<constructor-arg ref="authenticationManager" />
<constructor-arg ref="userIdSource" />
<constructor-arg ref="usersConnectionRepository" />
<constructor-arg ref="connectionRegistry" />
<property name="postLoginUrl" value="/home" />
<property name="defaultFailureUrl" value="/login?error&social" />
<property name="signupUrl" value="/user/signup" />
</bean>
<bean class="org.springframework.social.connect.web.ProviderSignInUtils">
<constructor-arg ref="connectionRegistry"/>
<constructor-arg ref="usersConnectionRepository"/>
</bean>
<bean id="userIdSource" class="org.springframework.social.security.AuthenticationNameUserIdSource" />
<bean id="socialAuthenticationProvider"
class="org.springframework.social.security.SocialAuthenticationProvider">
<constructor-arg ref="usersConnectionRepository" />
<constructor-arg ref="userService" />
</bean>
<bean id="userSocialConnectionService" class="com.gigi.web.UserSocialConnectionController"></bean>
<bean id="usersConnectionRepository" class="com.gigi.social.SpringDataUsersConnectionRepository">
<constructor-arg ref="connectionRegistry" />
</bean>
<bean id="connectionRegistry"
class="org.springframework.social.security.SocialAuthenticationServiceRegistry">
<property name="authenticationServices">
<list>
<bean class="org.springframework.social.facebook.security.FacebookAuthenticationService">
<constructor-arg value="${facebook.app.id}" />
<constructor-arg value="${facebook.app.secret}" />
<constructor-arg value="${facebook.app.namespace}" />
</bean>
</list>
</property>
</bean>
It looks like spring doesn't handle that on it's own, which kinda makes sense though I feel like it should be possible for the config, rather than having to write code for it. Anyway, here's how we've done it:
#RequestMapping("/signup")
public String signUp(WebRequest request) {
Connection<?> connection = providerSignInUtils.getConnectionFromSession(request);
User user = usersConnectionRepository.createUser(connection);
getRepository().save(user);
providerSignInUtils.doPostSignUp(user.getId().toString(), request);
// the following will automatically log in the user after sign up
SecurityContextHolder.getContext().setAuthentication(new SocialAuthenticationToken(connection, user, null, user.getAuthorities()));
return "redirect:/home";
}
I have a Spring Integration WAR component that I'm updating to run in private PCF. I have two DataSources and a RabbitMQ connection factory defined in the application.
I see an article from Thomas Risberg on using the cloud namespace and handling multiple services of the same time - https://spring.io/blog/2011/11/09/using-cloud-foundry-services-with-spring-part-3-the-cloud-namespace. This is handled by using #Autowired and #Qualifier annotations.
I'm wondering how this can be achieved though when we're not #Autowired and #Qualifier annotations, e.g. wiring a DataSource into a JdbcTemplate. Here we do not have the ability to specify a #Qualifier annotation.
My application is Spring XML config based. I do have ability to use #Autowired and #Qualifier annotations on one of the DataSources, but the other is JPA entity manager. See code snippet.
Any help is much appreciated.
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="activity-monitor" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaProperties">
<value>
hibernate.format_sql=true
</value>
</property>
</bean>
<beans profile="cloud">
<cloud:data-source id="dataSource" service-name="actmon-db-service" />
</beans>
Java Build Pack: java_buildpack_offline java-buildpack-offline-v2.4.zip
Spring Auto-reconfiguration version 1.4.0.
UPDATE: This is the full config for both data sources, including PropertySourcesPlaceholderConfigurer with properties loaded from data source using DAO.
<bean id="cic.application.ppc" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="properties" ref="cic.application.properties"/>
<property name="locations" ref="cic.application.propertyLocations"/>
</bean>
<bean id="cic.application.properties" class="java.util.Properties">
<constructor-arg value="#{cicPropertiesService.properties}"></constructor-arg>
</bean>
<bean id="cic.properties.propertiesService" name="cicPropertiesService"
class="com.emc.it.eis.properties.service.DefaultPropertiesService">
<constructor-arg index="0"
ref="cic.properties.propertiesDao" />
</bean>
<bean id="cic.properties.propertiesDao" class="com.emc.it.eis.properties.dao.JdbcPropertiesDao">
<constructor-arg ref="cic.properties.dataSource" />
</bean>
<beans profile="default">
<jee:jndi-lookup id="cic.properties.dataSource"
jndi-name="jdbc/intdb" />
</beans>
<beans profile="cloud">
<cloud:data-source id="cic.properties.dataSource" service-name="oracle-cicadm-db-service" />
</beans>
<beans>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="actmonDataSource" />
<property name="persistenceUnitName" value="activity-monitor" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaProperties">
<value>
hibernate.format_sql=true
</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
<beans profile="default">
<jee:jndi-lookup id="dataSource"
jndi-name="jdbc/actmon" />
</beans>
<beans profile="cloud">
<cloud:data-source id="actmonDataSource" service-name="postgres-actmon-db-service" />
</beans>
<beans profile="default,cloud">
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="POSTGRESQL" />
</bean>
</beans>
Output from CF when I deploy https://gist.github.com/anonymous/3986a1a7cea4f20c096e. Note it is skipping auto re-configuration of javax.sql.DataSources
First of all, the post from Thomas is pretty old, and references a deprecated support library. Instead of the org.cloudfoundry:cloudfoundry-runtime:0.8.1 dependency, you should use Spring Cloud Connectors dependencies instead.
You can then follow the instructions provided for using XML configuration with Spring Cloud Connectors. With multiple services of the same type, you will need to specify the name of the service for each bean. Following your example, and assuming you created two CF database services named inventory-db and customer-db, that might look something like this:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="inventory-dataSource" />
<property name="persistenceUnitName" value="activity-monitor" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaProperties">
<value>
hibernate.format_sql=true
</value>
</property>
</bean>
<beans profile="cloud">
<cloud:data-source id="inventory-dataSource" service-name="inventory-db">
<cloud:data-source id="customer-dataSource" service-name="customer-db">
</beans>
I've managed to resolve the issue by using the factory bean used by the spring cloud:data-source, CloudDataSourceFactory. Creating an instance of this and wiring up the config including the service-name of the CF service. This avoids the issue of our PropertySourcesPlaceholderConfigurer trying to use the data source before our the bean has even been defined.
<!--
configure cloud data source for using CloudDataSourceFactory; this is what spring cloud:data-source is using;
required to manually wire this data source bean as cloud:data-source bean gets defined in a phase after our
PropertySourcesPlaceholderConfigurer bean.
-->
<bean id="cic.properties.dataSource" class="org.springframework.cloud.service.relational.CloudDataSourceFactory">
<constructor-arg value="oracle-cicadm-db-service" />
<constructor-arg>
<!-- configuring minimal data source as it is used only to bootstrap properties on app start-up -->
<bean class="org.springframework.cloud.service.relational.DataSourceConfig">
<constructor-arg>
<bean class="org.springframework.cloud.service.PooledServiceConnectorConfig.PoolConfig">
<constructor-arg value="0" />
<constructor-arg value="2" />
<constructor-arg value="180" />
</bean>
</constructor-arg>
<!-- ConnectionConfig not required for cic.properties.dataSource so setting to null -->
<constructor-arg value="#{ null }" />
</bean>
</constructor-arg>
</bean>
i build async jersey web services, and now i need to make some operations with ldap.
I have configure Spring beam.xml in this mode:
<bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="${ldap.url}" />
<property name="base" value="${ldap.base}" />
<property name="userDn" value="${ldap.userDn}" />
<property name="password" value="${ldap.password}" />
<property name="pooled" value="false" />
</bean>
<bean id="contextSource"
class="org.springframework.ldap.pool.factory.PoolingContextSource">
<property name="contextSource" ref="contextSourceTarget" />
</bean>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="contextSource" />
</bean>
<bean id="ldapTreeBuilder" class="com.me.ldap.LdapTreeBuilder">
<constructor-arg ref="ldapTemplate" />
</bean>
<bean id="personDao" class="com.me.ldap.PersonDaoImpl">
<property name="ldapTemplate" ref="ldapTemplate" />
</bean>
But when i try to use ldap i have this error:
Error creating bean with name 'contextSource' defined in class path resource [config/Beans.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/pool/KeyedPoolableObjectFactory
In my project i have commons-pool2-2.2.jar lib, but still i have this error..i try to add commons-pool2-2.2.jar in TOMCAT_PATH/lib but not works..
UPDATE:
If i put commons-pool-1.6.jar it works.. but if i want to use pool2 how i can do? only i must change class inn commons-pool2-2.2.jar?
Updated Answer:
Since at least Spring LDAP 2.3.2 you can now use commons-pool2. Spring LDAP now provides two classes:
For commons-pool 1.x:
org.springframework.ldap.pool.factory.PoolingContextSource
For commons-pool 2.x:
org.springframework.ldap.pool2.factory.PooledContextSource
Details can be found here:
https://github.com/spring-projects/spring-ldap/issues/351#issuecomment-586551591
Original Answer:
Unfortunately Spring-Ldap uses commons-pool and not commons-pool2. As you have found the class org.apache.commons.pool.KeyedPoolableObjectFactory does not exist in commons-pool2 (it has a different package structure), hence the error.
There is a Jira issue for the Spring-ldap project asking them to upgrade/support commons-pool2:
https://jira.spring.io/browse/LDAP-316
Until that has been completed you will have to use commons-pool 1.6.
I was trying to share My in-memory jobRepository to the jobExplorer. But it throws an error as,
Nested exception is
org.springframework.beans.ConversionNotSupportedException:
Failed to convert property value of type '$Proxy1 implementing
org.springframework.batch.core.repository.JobRepository,org.
springframework.aop.SpringProxy,org.springframework.aop.framework.Advised'
to required type
Even i tried putting '&' sign before jobRepository when passing to jobExplorer for sharing.But attempt end in vain.
I am using Spring Batch 2.2.1
Is the dependency for jobExplorer is only database not in-memory?
Definition is,
<bean id="jobRepository"
class="com.test.repository.BatchRepositoryFactoryBean">
<property name="cache" ref="cache" />
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="jobOperator" class="test.batch.LauncherTest.TestBatchOperator">
<property name="jobExplorer" ref="jobExplorer" />
<property name="jobRepository" ref="jobRepository" />
<property name="jobRegistry" ref="jobRegistry" />
<property name="jobLauncher" ref="jobLauncher" />
</bean>
<bean id="jobExplorer" class="test.batch.LauncherTest.TestBatchExplorerFactoryBean">
<property name="repositoryFactory" ref="&jobRepository" />
</bean>
<bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="jobLauncher" class="com.scb.smartbatch.core.BatchLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<!-- To store Batch details -->
<bean id="jobRegistry" class="com.scb.smartbatch.repository.SmartBatchRegistry" />
<bean id="jobRegistryBeanPostProcessor"
class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
<!--Runtime cache of batch executions -->
<bean id="cache" class="com.scb.cache.TCRuntimeCache" />
thanks for your valuable inputs.
But I used '&' before the job repository reference, which allowed me to use it for my job explorer as a shared resource.
problem solved.
kudos.
Usually you have to wire interface instead of implementation.
Else, probably, you have to add <aop:config proxy-target-class="true"> to create CGLIB-based proxy instead of standard Java-based proxy.
Read Spring official documentation about that
I created a RESTful web service, and I want to send binary files to this service without SOAP.
There are some information on CXF website:
XOP
But I can't find a way to get the CXF JAX-RS endpoints, and set an mtom-enabled property.
My Spring config is:
<jaxrs:server id="fis" address="http://172.20.41.40:8080/fis">
<jaxrs:serviceBeans>
<ref bean="FaultInfoResource" />
<ref bean="ExplorationResultResource" />
</jaxrs:serviceBeans>
</jaxrs:server>
<bean id="FaultInfoService" parent="baseService" class="com.dfe.demo.FaultInfoService">
</bean>
<bean id="FaultInfoResource" class="com.dfe.demo.FaultInfoResource">
<property name="faultInfoService" ref="FaultInfoService"/>
</bean>
<bean id="ExplorationResultService" parent="baseService" class="com.dfe.demo.ExplorationResultService">
</bean>
<bean id="ExplorationResultResource" class="com.dfe.demo.ExplorationResultResource">
<property name="explorationResultService" ref="ExplorationResultService"/>
</bean>
And my server class is:
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"com/dfe/iss/config/applicationContext.xml","com/dfe/demo/yearlyplan/cxf-servlet.xml"});
JAXRSServerFactoryBean fib = (JAXRSServerFactoryBean) ctx.getBean("fis");
fib.create();
Try this:
<beans>
<jaxrs:server id="bookstore1">
<jaxrs:properties>
<entry key="mtom-enabled" value="true"/>
</jaxrs:properties>
</jaxrs:server>
</beans>