Как расширить c3p0 ComboPooledDataSource - PullRequest
4 голосов
/ 16 ноября 2010

Хорошо. У меня есть ресурс в Tomcat 5.5 в файле server.xml для подключения к базе данных, например:

<Resource name="jdbc/MyApp" auth="Container" type="com.mchange.v2.c3p0.ComboPooledDataSource" driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver"  maxPoolSize="100"  minPoolSize="5"   
acquireIncrement="5"    
 user="username" 
password="password"
factory="org.apache.naming.factory.BeanFactory"  
jdbcUrl="jdbc:sqlserver://localhost:1433;databaseName=myDatabase;autoReconnect=true" />

Кто-нибудь пытался расширить вышеуказанный ComboPooledDataSource?Проблема в том, что пароль базы данных находится в открытом тексте.Идея состоит в том, чтобы сначала зашифровать пароль и поместить зашифрованный ключ в server.xml.У меня есть утилита расшифровки, поэтому я могу расшифровать ключ перед попыткой подключения к базе данных.

Я нашел пример решения моей проблемы для org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory, но я неиспользуя этот пул соединений.Я использую C3P0.Кто-нибудь пробовал это раньше с C3P0?

Ответы [ 4 ]

1 голос
/ 12 ноября 2013

Да, вы не можете расширить com.mchange.v2.c3p0.ComboPooledDataSource, потому что это общедоступно. Вот обходной путь, с помощью которого я достиг этого.

Я расширил org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy и передал источник данных com.mchange.v2.c3p0.ComboPooledDataSource в качестве аргумента конструктора.

Вот моя hibernate.cfg.xml конфигурация вышеуказанного источника данных:

<bean id="dataSource" class="MyDataSource"> 
        <constructor-arg ref="c3p0DataSource" />
    </bean>

    <bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="${jdbc.driver.className}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="acquireIncrement" value="${dataSource.acquireIncrement}" />
        <property name="acquireRetryAttempts" value="${dataSource.acquireRetryAttempts}" />
        <property name="acquireRetryDelay" value="${dataSource.acquireRetryDelay}" />
        <property name="autoCommitOnClose" value="${dataSource.autoCommitOnClose}" />
        <property name="breakAfterAcquireFailure" value="${dataSource.breakAfterAcquireFailure}" />
        <property name="checkoutTimeout" value="${dataSource.checkoutTimeout}" />
        <property name="debugUnreturnedConnectionStackTraces"
            value="${dataSource.debugUnreturnedConnectionStackTraces}" />
        <property name="forceIgnoreUnresolvedTransactions"
            value="${dataSource.forceIgnoreUnresolvedTransactions}" />
        <property name="idleConnectionTestPeriod" value="${dataSource.idleConnectionTestPeriod}" />
        <property name="initialPoolSize" value="${dataSource.initialPoolSize}" />
        <property name="maxAdministrativeTaskTime" value="${dataSource.maxAdministrativeTaskTime}" />
        <property name="maxConnectionAge" value="${dataSource.maxConnectionAge}" />
        <property name="maxIdleTime" value="${dataSource.maxIdleTime}" />
        <property name="maxIdleTimeExcessConnections" value="${dataSource.maxIdleTimeExcessConnections}" />
        <property name="maxPoolSize" value="${dataSource.maxPoolSize}" />
        <property name="maxStatements" value="${dataSource.maxStatements}" />
        <property name="maxStatementsPerConnection" value="${dataSource.maxStatementsPerConnection}" />
        <property name="minPoolSize" value="${dataSource.minPoolSize}" />
        <property name="numHelperThreads" value="${dataSource.numHelperThreads}" />
        <property name="propertyCycle" value="${dataSource.propertyCycle}" />
        <property name="testConnectionOnCheckin" value="${dataSource.testConnectionOnCheckin}" />
        <property name="testConnectionOnCheckout" value="${dataSource.testConnectionOnCheckout}" />
        <property name="unreturnedConnectionTimeout" value="${dataSource.unreturnedConnectionTimeout}" />
    </bean>

Mine jdbc.properties file:


jdbc.driver.className=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=xxxxx
jdbc.username=xxx
jdbc.password=xxxxxxxxx #Encrytped password here
jdbc.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=update

dataSource.acquireIncrement=3
dataSource.acquireRetryAttempts=30
dataSource.acquireRetryDelay=60000
dataSource.autoCommitOnClose=false
dataSource.breakAfterAcquireFailure=false
dataSource.checkoutTimeout=0
dataSource.debugUnreturnedConnectionStackTraces=false
dataSource.forceIgnoreUnresolvedTransactions=false
dataSource.idleConnectionTestPeriod=0
dataSource.initialPoolSize=10
dataSource.maxAdministrativeTaskTime=0
dataSource.maxConnectionAge=0
dataSource.maxIdleTime=0
dataSource.maxIdleTimeExcessConnections=0
dataSource.maxPoolSize=10
dataSource.maxStatements=0
dataSource.maxStatementsPerConnection=0
dataSource.minPoolSize=10
dataSource.numHelperThreads=3
dataSource.propertyCycle=0
dataSource.testConnectionOnCheckin=false
dataSource.testConnectionOnCheckout=false
dataSource.unreturnedConnectionTimeout=0


Mine extended class where I decrypt the password before passing the datasource to transaction Proxy wrapper.

import javax.sql.DataSource;

import org.jasypt.util.text.BasicTextEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;

import com.csc.emms.common.EMMSConstraints;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class MyDataSource extends TransactionAwareDataSourceProxy
{
    private static char[] appName =
    {
            'B', 'I', 'N', 'G', 'O', 'D', 'I', 'N', 'G', 'O'
    };

    @Autowired
    // Inject your class by constructor
    MyDataSource(ComboPooledDataSource dataSource)
    {
        super.setTargetDataSource(decryptPassword(dataSource));
    }

    private DataSource decryptPassword(ComboPooledDataSource dataSource)
    {
        dataSource.setPassword(decode(dataSource.getPassword()));
        return dataSource;
    }

    private String decode(String encodedPassword)
    {
        BasicTextEncryptor decoder = new BasicTextEncryptor();
        decoder.setPasswordCharArray(appName);
        return decoder.decrypt(encodedPassword);
    }

    private String encode(String password)
    {
        BasicTextEncryptor encoder = new BasicTextEncryptor();
        encoder.setPasswordCharArray(appName);
        return encoder.encrypt(password);
    }
}
Hope this resolved your issue.
0 голосов
/ 27 июля 2017

Вы не можете расширить ComboPooledDataSource, но вы можете дублировать его, расширив родительский класс, AbstractComboPooledDataSource. Вы можете действительно, очень близко к дублированию, либо получить исходный код из Github , либо декомпилировать файл класса. Результат будет выглядеть примерно так:

import com.mchange.v2.c3p0.AbstractComboPooledDataSource;

public final class YourC3p0DataSource extends AbstractComboPooledDataSource
        implements Serializable, Referenceable {

    public void setPassword(String encryptedPassword) {
        try {
            String decryptedPassword
                    = yourDecryption(encryptedPassword);
            super.setPassword(decryptedPassword);
        } catch (Exception e) { /* ... */ }
    }
    /* Increment a few other methods found in ComboPooledDataSource. */
}
0 голосов
/ 21 августа 2013

С com.mchange.v2.c3p0.ComboPooledDataSource является public final class, вы не можете его расширить.

0 голосов
/ 04 марта 2011

вы можете использовать jasypt для шифрования файла свойств, а затем использовать зашифрованные свойства в bean-источнике данных.

jasypt также поддерживает Spring, и его очень легко использовать.прочитайте это для более подробной информации.

...