org.apache.torque.JndiConfigurationTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.torque.JndiConfigurationTest.java

Source

package org.apache.torque;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.sql.Connection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import junit.framework.TestCase;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.torque.criteria.Criteria;
import org.apache.torque.dsfactory.AbstractDataSourceFactory;
import org.apache.torque.dsfactory.DataSourceFactory;
import org.apache.torque.dsfactory.JndiDataSourceFactory;
import org.apache.torque.test.peer.BookPeer;

/**
 * Test for configuration using JNDI. The test assumes that we have a
 * non-jndi configuration, and creates the data source configuration from it.
 * It is tested whether we can bind a data source manually into jndi and
 * retrieve it in Torque, and also it is tested whether we can bind a
 * data source using Torque.
 * Note: This test does not extend BaseRuntimeTestCase as we do not want Torque
 * to be initialized.
 *
 * @author <a href="mailto:fischer@seitenbau.de">Thomas Fischer</a>
 * @version $Id $
 */
public class JndiConfigurationTest extends TestCase {
    /**
     * The subcontext where the data source is bound.
     */
    protected static final String JNDI_SUBCONTEXT = "jdbc";

    /**
     * the full jndi path to the data source.
     */
    protected static final String JNDI_PATH = JNDI_SUBCONTEXT + "/" + "jndiTestDataSource";

    public void setUp() {
        // super.setUp() initializes torque, but here we want to
        // do that ourselves
    }

    /**
     * Tests whether our home-made Data Source works.
     * @throws Exception if the test fails.
     */
    public void testDataSource() throws Exception {
        BasicDataSource dataSource = null;
        try {
            dataSource = getDataSource();
            dataSourceConnect(dataSource);
        } finally {
            if (dataSource != null) {
                dataSource.close();
            }
        }
    }

    /**
     * Binds a DataSource to the jndi and checks that we have successfully
     * bound it. Then Torque is configured to lookup the DataSource in jndi,
     * and it is checked if Torque can read from the database. Finally,
     * the DataSource is closed and unbound.
     * @throws Exception if the test fails
     */
    public void testExternalBindTorqueLookup() throws Exception {
        // compose the correct configuration
        Configuration torqueConfiguration = getTorqueConfiguraton();
        String defaultDatabase = getDefaultDatabase(torqueConfiguration);

        // remove the dsfactory configuration from the configuration
        {
            Configuration dsfactoryConfiguration = torqueConfiguration
                    .subset(Torque.TORQUE_KEY + "." + DataSourceFactory.DSFACTORY_KEY + "." + defaultDatabase);
            dsfactoryConfiguration.clear();
        }

        // add the jndi configuration to the configuration
        torqueConfiguration.setProperty(Torque.TORQUE_KEY + "." + DataSourceFactory.DSFACTORY_KEY + "."
                + defaultDatabase + "." + DataSourceFactory.FACTORY_KEY, JndiDataSourceFactory.class.getName());
        torqueConfiguration.setProperty(Torque.TORQUE_KEY + "." + DataSourceFactory.DSFACTORY_KEY + "."
                + defaultDatabase + "." + JndiDataSourceFactory.JNDI_KEY + "." + JndiDataSourceFactory.PATH_KEY,
                JNDI_PATH);
        torqueConfiguration.setProperty(
                Torque.TORQUE_KEY + "." + DataSourceFactory.DSFACTORY_KEY + "." + defaultDatabase + "."
                        + JndiDataSourceFactory.JNDI_KEY + "." + Context.INITIAL_CONTEXT_FACTORY,
                org.apache.naming.java.javaURLContextFactory.class.getName());

        //System.out.println("Configuration for testExternalBindTorqueLookup:");
        //debugConfiguration(torqueConfiguration);
        //System.out.println();

        try {
            // bind datasource and check bind.
            bindDataSource();
            BasicDataSource dataSource = retrieveDataSource();
            dataSourceConnect(dataSource);

            if (Torque.isInit()) {
                Torque.shutdown();
            }
            // initialize torque with the created configuration
            // and check that we can connect to the database.
            try {
                Torque.init(torqueConfiguration);
                torqueConnect();
            } finally {
                Torque.shutdown();
            }
        } finally {
            unbindDataSource();
        }
    }

    /**
     * Binds a DataSource to the jndi and checks that we have successfully
     * bound it. Then Torque is configured to lookup the DataSource in jndi,
     * and it is checked if Torque can read from the database. Finally,
     * the DataSource is closed and unbound.
     * @throws Exception if the test fails
     */
    public void testTorqueBindTorqueLookup() throws Exception {
        // compose the correct configuration
        Configuration torqueConfiguration = getTorqueConfiguraton();
        String defaultDatabase = getDefaultDatabase(torqueConfiguration);

        // add the jndi configuration to the configuration
        torqueConfiguration.setProperty(Torque.TORQUE_KEY + "." + DataSourceFactory.DSFACTORY_KEY + "."
                + defaultDatabase + "." + DataSourceFactory.FACTORY_KEY, JndiDataSourceFactory.class.getName());
        torqueConfiguration.setProperty(Torque.TORQUE_KEY + "." + DataSourceFactory.DSFACTORY_KEY + "."
                + defaultDatabase + "." + JndiDataSourceFactory.JNDI_KEY + "." + JndiDataSourceFactory.PATH_KEY,
                JNDI_PATH);
        torqueConfiguration.setProperty(
                Torque.TORQUE_KEY + "." + DataSourceFactory.DSFACTORY_KEY + "." + defaultDatabase + "."
                        + JndiDataSourceFactory.JNDI_KEY + "." + Context.INITIAL_CONTEXT_FACTORY,
                org.apache.naming.java.javaURLContextFactory.class.getName());

        // add the datasource configuration
        torqueConfiguration.setProperty(
                Torque.TORQUE_KEY + "." + DataSourceFactory.DSFACTORY_KEY + "." + defaultDatabase + "."
                        + JndiDataSourceFactory.DATASOURCE_KEY + "." + JndiDataSourceFactory.CLASSNAME_KEY,
                BasicDataSource.class.getName());
        {
            Map tempStore = new HashMap();
            Configuration connectionConfiguration = torqueConfiguration
                    .subset(Torque.TORQUE_KEY + "." + DataSourceFactory.DSFACTORY_KEY + "." + defaultDatabase + "."
                            + AbstractDataSourceFactory.CONNECTION_KEY);
            for (Iterator keyIt = connectionConfiguration.getKeys(); keyIt.hasNext();) {
                String key = (String) keyIt.next();
                String value = connectionConfiguration.getString(key);

                if ("user".equals(key)) {
                    // setUser() in SharedPoolDataSouce corresponds to
                    // setUsername() in BasicDataSourceFactory
                    key = "username";
                } else if ("driver".equals(key)) {
                    // setDriver() in SharedPoolDataSouce corresponds to
                    // setDriverClassName() in BasicDataSourceFactory
                    key = "driverClassName";
                }
                tempStore.put(Torque.TORQUE_KEY + "." + DataSourceFactory.DSFACTORY_KEY + "." + defaultDatabase
                        + "." + JndiDataSourceFactory.DATASOURCE_KEY + "." + key, value);
            }
            // add the new keys
            for (Iterator keyIt = tempStore.keySet().iterator(); keyIt.hasNext();) {
                String key = (String) keyIt.next();
                String value = (String) tempStore.get(key);
                torqueConfiguration.setProperty(key, value);
            }

            // remove the configuration for the original datasource
            connectionConfiguration.clear();
            Configuration poolConfiguration = torqueConfiguration
                    .subset(Torque.TORQUE_KEY + "." + DataSourceFactory.DSFACTORY_KEY + "." + defaultDatabase + "."
                            + AbstractDataSourceFactory.POOL_KEY);
            poolConfiguration.clear();
        }

        //System.out.println("Configuration for testTorqueBindTorqueLookup:");
        //debugConfiguration(torqueConfiguration);
        //System.out.println();

        try {
            // initialize torque with the created configuration
            // and check that we can connect to the database.
            try {
                Torque.init(torqueConfiguration);
                torqueConnect();
            } finally {
                Torque.shutdown();
            }
        } finally {
            unbindDataSource();
        }
    }

    /**
     * creates and binds a BasicDataSource into jndi.
     * @throws Exception if DataSource creation or binding fails.
     */
    protected void bindDataSource() throws Exception {
        BasicDataSource dataSource = getDataSource();
        Context context = getInitialContext();
        context.createSubcontext(JNDI_SUBCONTEXT);
        context.bind(JNDI_PATH, dataSource);
    }

    /**
     * Retrieves a BasicDataSource from jndi.
     * @throws Exception if the jndi lookup fails or no DataSource is bound.
     */
    protected BasicDataSource retrieveDataSource() throws Exception {
        Context context = getInitialContext();
        BasicDataSource dataSource = (BasicDataSource) context.lookup(JNDI_PATH);

        if (dataSource == null) {
            fail("DataSource should not be null");
        }
        return dataSource;
    }

    /**
     * unbinds and closes the BasicDataSource in jndi.
     * @throws Exception if creation or binfding fails.
     */
    protected void unbindDataSource() throws Exception {
        Context context = getInitialContext();
        BasicDataSource dataSource = (BasicDataSource) context.lookup(JNDI_PATH);

        try {
            if (dataSource != null) {
                dataSource.close();
            }
        } finally {
            context.unbind(JNDI_PATH);
        }
    }

    /**
     * Creates a Data Source from the Torque configuration without using Torque.
     * @return a SharedPoolDataSource source.
     * @throws Exception if we cannot create a Data source.
     */
    protected BasicDataSource getDataSource() throws Exception {
        Configuration torqueConfiguration = getTorqueConfiguraton();
        String defaultDatabase = getDefaultDatabase(torqueConfiguration);
        Configuration dsfactoryConfiguration = torqueConfiguration
                .subset(Torque.TORQUE_KEY + "." + DataSourceFactory.DSFACTORY_KEY + "." + defaultDatabase + "."
                        + AbstractDataSourceFactory.CONNECTION_KEY);

        BasicDataSource dataSource = new BasicDataSource();
        for (Iterator i = dsfactoryConfiguration.getKeys(); i.hasNext();) {
            String key = (String) i.next();
            String stringValue = dsfactoryConfiguration.getString(key);

            if ("user".equals(key)) {
                // setUser() in SharedPoolDataSouce corresponds to
                // setUsername() in BasicDataSourceFactory
                key = "username";
            } else if ("driver".equals(key)) {
                // setDriver() in SharedPoolDataSouce corresponds to
                // setDriverClassName() in BasicDataSourceFactory
                key = "driverClassName";
            }

            Class propertyType = PropertyUtils.getPropertyType(dataSource, key);
            Object value = ConvertUtils.convert(stringValue, propertyType);
            PropertyUtils.setSimpleProperty(dataSource, key, value);
        }

        return dataSource;
    }

    /**
     * checks whether we can retrieve a connection from a DataSource.
     * @throws Exception if no connection can be established.
     */
    protected void dataSourceConnect(DataSource dataSource) throws Exception {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            connection.close();
            connection = null;
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    /**
     * checks whether we can connect to the database via Torque.
     * @throws Exception if no connection can be established.
     */
    protected void torqueConnect() throws Exception {
        Connection connection = null;
        try {
            connection = Torque.getConnection();
            BookPeer.doSelect(new Criteria(), connection);
            connection.close();
            connection = null;
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    /**
     * Retrieves (or creates if it does not exist) an InitialContext.
     * @return the InitialContext.
     * @throws NamingException if the InitialContext cannot be retrieved
     *         or created.
     */
    protected InitialContext getInitialContext() throws NamingException {
        Hashtable environment = new Hashtable();
        environment.put(Context.INITIAL_CONTEXT_FACTORY,
                org.apache.naming.java.javaURLContextFactory.class.getName());
        InitialContext context = new InitialContext(environment);
        return context;
    }

    /**
     * Retrieves the path for Torque's configuration from the System Properties,
     * loads the configuration and returns it.
     * @return Torque's configuration.
     * @throws ConfigurationException if the configuration cannot be loaded.
     */
    protected static Configuration getTorqueConfiguraton() throws ConfigurationException {
        Configuration configuration = new PropertiesConfiguration(
                System.getProperty(BaseDatabaseTestCase.CONFIG_FILE_SYSTEM_PROPERTY));
        return configuration;
    }

    /**
     * extraxts the default Database out of Torque's configuration.
     * @param torqueConfiguration the Torque configuration
     * @return the default Data Source.
     */
    protected static String getDefaultDatabase(Configuration torqueConfiguration) {
        String defaultDatabase = torqueConfiguration
                .getString(Torque.TORQUE_KEY + "." + Torque.DATABASE_KEY + "." + Torque.DEFAULT_KEY);
        return defaultDatabase;
    }

    /**
     * Prints the contents of the configuration to System.out
     * @param configuration the configuration to be debugged.
     */
    public static void debugConfiguration(Configuration configuration) {
        for (Iterator dsKeyIt = configuration.getKeys(); dsKeyIt.hasNext();) {

            String key = (String) dsKeyIt.next();
            System.out.println(key + " = " + configuration.getString(key));
        }
    }
}