Lazy init for activemq datasource - java

I was wondering if there is any way for lazy init of activemq persistence. The problem is that I don't want to specify user and password of the database beforehand, but rather let user enter these values after application's initialization. So, for example user starts application and then is required to enter database username and password. After he does so, the application initializes activemq persistence using database connection provided by user.
<amq:persistenceFactory>
<amq:journalPersistenceAdapterFactory journalLogFiles="4" dataDirectory="./journal-data" dataSource="#postgre-ds">
<amq:statements>
<amq:statements binaryDataType="VARCHAR(250)"/>
</amq:statements>
</amq:journalPersistenceAdapterFactory>
</amq:persistenceFactory>
wherere postgre-ds
<bean id="postgre-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:someURL"/>
<property name="username" value="username"/>
<property name="password" value="pa55w0rd"/>
<property name="maxActive" value="200"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
so I want first get values for username and password and after that initialize persistence. Thanks )

The whole idea with spring is to wire up these things at startup, which covers 99% of the usecases.
There is nothing magical about it. It's just plain java objects anyway. If you need more control over the life cycle and input parameters, then go ahead and do the things manually.
DataSource ds = new BasicDataSource();
ds.setUsername( getInput() );
// ... set all parameters needed
JournalPersistenceAdapterFactory factory = new JournalPersistenceAdapterFactory();
factory.setDataDirectoryFile(data);
//.. set all parameters needed
BrokerService broker = new BrokerService();
broker.setPersistenceFactory(factory);
broker.addConnector(ActiveMQConnectionFactory.DEFAULT_BROKER_BIND_URL);
// More config goes here
broker.start();

Related

Configure Apache Commons Pool to create objects on start up

I'm configuring a pool of objects using apache commons pool2. It seems the objects in the pool are only created when an attempt is made to borrow an object. I'd like the objects to be created up front, so I have a minimum number of objects ready when the first one needs to be borrowed.
My spring configuration looks something like this:
<bean id="webSocketConnectionPool" class="org.apache.commons.pool2.impl.GenericObjectPool">
<constructor-arg ref="webSocketConnectionFactory"/>
<constructor-arg ref="webSocketConnectionPoolConfig"/>
</bean>
<bean id="webSocketConnectionFactory" class="com.blah.WebSocketConnectionFactory" />
<bean id="webSocketConnectionPoolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig">
<property name="maxIdle" value="300"/>
<property name="maxTotal" value="1000"/>
<property name="minIdle" value="10"/>
</bean>
I can see the pool is created when the app starts, but the minIdle setting doesn't seem to result in my desired behaviour. The create() method on the factory is only called when the first object is borrowed.
Any tips would be appreciated.
Thanks
My solution was to add some logic to the init method of the class with the connection pool as a member, to add objects. Hopefully this will help someone else in the future.
connectionPool.addObjects(connectionPool.getMinIdle());

Reading value from file into applicationContext.xml file

I have a spring based web application and in my application context xml file, I have defined a bean which has all the parameters to connect to database. As part of this bean, for one of the parameters, I have a password key, as shown in the below example and I wanted the value should come from a /vault/password file. This /vault/password is not part of the project/application. This /vault/password will be there in host machine by default.
What is the syntax in applicationContext.xml bean definition, to read a value from a file outside of application context.
<bean class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" id="dataSource">
<property name="url" value="jdbc:postgresql://postgres:5432/" />
<property name="username" value="postgres" />
<property name="password" value="/vault/password" />
</bean>
Something like this is probably your best bet:
How to correctly override BasicDataSource for Spring and Hibernate
PROBLEM:
Now I need to provide custom data source based on server environment
(not config), for which I need to calculate driverClassName and url
fields based on some condition.
SOLUTION:
Create a factory (since you need to customize only the creation phase
of the object, you don't need to control the whole lifetime of it).
public class MyDataSourceFactory {
public DataSource createDataSource() {
BasicDataSource target = new BasicDataSource();
if (condition) {
target.setDriverClassName("com.mysql.jdbc.Driver");
target.setUrl("jdbc:mysql://localhost/test?relaxAutoCommit=true");
} else { ... }
return target;
}
}
In your case, your customization would do some I/O to set target.password.

How to dynamically change database password used by a DataSource, which is in turn used by a spring transaction manager

How can I dynamically (at run time) change the DB username and password used by a DataSource when using a Spring transaction manager?
We are using Spring and have a BasicDataSource and a TransactionManager defined as follows for handling database connections and transactions:
<bean id="myDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="url" ref="dbUrl"/>
<property name="username" ref="someUsername"/>
<property name="password" ref="somePassword"/>
<property name="driverClassName" value="org.postgresql.Driver" />
...
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="myDataSource" />
<tx:annotation-driven transaction-manager="transactionManager" />
We need to support dynamically changing the password that we are using at runtime. Note that I am not trying to change the password in the DB; that has already happened outside of the application. I am trying to tell my application to switch passwords that it is using to connect to the DB.
I tried extending BasicDataSource and calling setUsername() and setPassword(), but it appears that changing the username and password have no effect. I can see by looking into the implementation of BasicDataSource that the username and password appear to only be used when it initially constructs the connection pool.
I then found org.apache.commons.dbcp2.datasources.SharedPoolDataSource and thought that would be the answer to my problems. But it looks like DataSourceTransactionManager takes a javax.sql.DataSource, which surprisingly SharedPoolDataSource is not.
I can't find any other transaction managers that would take a SharedPoolDataSource or even a javax.sql.ConnectionPoolDataSource.
Is there a way to use a transaction manager and a connection pool and dynamically change the DB password that is used?

C3PO connection pooling - connections not being released

I have a web application running under Tomcat 7 using Spring with c3po as the connection pool manager. I have also used dbcp and have the same result.
I initiate a long running single threaded process which makes a large number of database calls using jdbcTemplate.update(), etc, in various dao's. As each of these updates is simple and independent, no transaction manager is being used.
For some reason, I am running out of connections. What appears to be happening is that each dao is holding onto its own connection and not returning it to the pool.
Is this normal behaviour? I had expected that the connection was tied to the jdbcTemplate.update() and released back as soon as this had finished.
...
In the context file...
<bean id="enquiryDataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${enquiry.drivername}"/>
<property name="url" value="${enquiry.jdbc}"/>
<property name="username" value="${enquiry.username}"/>
<property name="password" value="${enquiry.password}"/>
<property name="maxWait" value="30000"/>
<property name="maxActive" value="50"/>
</bean>
In a typical dao constructor...
#Autowired
public XXXCountryDao(#Qualifier("enquiryDataSource") DataSource dataSource,
#Qualifier("sqlUpdaterFactoryImpl") SqlUpdaterFactory sqlUpdaterFactory, #Qualifier("sqlFormatterFactoryImpl") SqlFormatterFactory sqlFormatterFactory) {
super("Country", dataSource, sqlUpdaterFactory, sqlFormatterFactory);
// ...other constructor stuff
}
All dao's inherit from...
public abstract class AbstractFileProcessorDao<ImportRecType, QueryRecType> extends JdbcDaoSupport {
// ...
}
In a typical dao method...
protected boolean runUpdateToSqlDatabase(Map<String, Object> values, Map<String, Object> whereValues) {
if (values.isEmpty())
return true;
String sql = updateUpdaterServer.getSql(values, whereValues);
if (logger.isDebugEnabled())
logger.debug("Server SQL -> " + sql);
getJdbcTemplate().update(sql);
return false;
}
Please check your application for "rogue" calls to DataSource#getConnection (you can use your IDE to search for method references). Connection leaks are usually caused by obtaining a connection which is then never closed via Connection#close.
When working with Spring's JdbcTemplate all JDBC resource handling (opening / closing connections, statements, result sets) is done automatically. But with legacy code you never know.

using JDBC with persistence.xml

I am building a framework that manage the access to the database.
the framework getting tasks from the user and handle a connection pooling that manage the access to the database. the user just send me SQL commands.
One of the feature that i would like to support is working with JPA, in this case i will provide entity manager. in some cases i would like to provide JDBC access as well as JPA access. the arguments for the database are written in XML file.
so for JPA i need to write the property in persistence.xml so it will be not so smart to write again the same arguments for JDBC. do you know if i can get the arguments of the database from persistence.xml, do you know if there is a source code that do it. or should i parse persistence.xml by myself?
Do you know if I can get the arguments of the database from persistence.xml, do you know if there is a source code that do it. Or should I parse persistence.xml by myself?
I'm not aware of anything in the standard JPA API allowing to retrieve the driver class name, the jdbc url, the username and password.
Second problem, the keys for those properties are not standardized in JPA 1.0. For example, Hibernate will use:
<property name="hibernate.connection.driver_class" value=""/>
<property name="hibernate.connection.url" value=""/>
<property name="hibernate.connection.username" value=""/>
<property name="hibernate.connection.password" value=""/>
While EclipseLink will use:
<property name="eclipselink.jdbc.driver" value=""/>
<property name="eclipselink.jdbc.url" value=""/>
<property name="eclipselink.jdbc.user" value=""/>
<property name="eclipselink.jdbc.password" value=""/>
This may make the parsing fragile.
If this is an option, maybe you could use a properties file to store both the provider specific keys and the values (I'd recommend using the standardized JPA 2.0 properties as keys). For example:
# keys for JPA
javax.persistence.jdbc.driver = hibernate.connection.driver_class
javax.persistence.jdbc.url = hibernate.connection.url
javax.persistence.jdbc.user = hibernate.connection.username
javax.persistence.jdbc.password = hibernate.connection.password
# values common to JPA and JDBC
driver = org.h2.Driver
url = jdbc:h2:mem:test
username = scott
password = tiger
And use Persistence.createEntityManagerFactory(String, Map) and pass a Map that you'll feed with the properties from the file to create the EntityManagerFactory:
Map map = new HashMap();
map.put(...);
...
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MyPu", map);

Categories