Package org.geoserver.jdbcconfig

Source Code of org.geoserver.jdbcconfig.JDBCConfigTestSupport$Config

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.jdbcconfig;

import static org.easymock.classextension.EasyMock.*;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;

import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.geoserver.catalog.impl.CatalogImpl;
import org.geoserver.config.util.XStreamPersisterFactory;
import org.geoserver.jdbcconfig.internal.ConfigDatabase;
import org.geoserver.jdbcconfig.internal.DbMappings;
import org.geoserver.jdbcconfig.internal.Dialect;
import org.geoserver.jdbcconfig.internal.Util;
import org.geoserver.jdbcconfig.internal.XStreamInfoSerialBinding;
import org.geoserver.platform.GeoServerExtensionsHelper;
import org.geoserver.platform.GeoServerResourceLoader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.context.WebApplicationContext;

@SuppressWarnings("unused")
public class JDBCConfigTestSupport {

    public static File createTempDir() throws IOException {
        File f = File.createTempFile("jdbcconfig", "data", new File("target"));
        f.delete();
        f.mkdirs();
        return f;
    }

    public static class DBConfig {
        String name;
        String driver;
        String connectionUrl;
        String dbUser;
        String dbPasswd;
        BasicDataSource dataSource;
        boolean initialized = false;

        public DBConfig(String name, String driver, String connectionUrl, String dbUser, String dbPasswd) {
            this.name = name;
            this.driver = driver;
            this.connectionUrl = connectionUrl;
            this.dbUser = dbUser;
            this.dbPasswd = dbPasswd;
        }

        DBConfig() {
        }

        BasicDataSource dataSource() throws Exception {
            if (dataSource != null) return dataSource;

            dataSource = new BasicDataSource() {

                @Override
                public synchronized void close() throws SQLException {
                    // do nothing
                }

            };
            dataSource.setDriverClassName(driver);
            dataSource.setUrl(connectionUrl.replace("${DATA_DIR}", createTempDir().getAbsolutePath()));
            dataSource.setUsername(dbUser);
            dataSource.setPassword(dbPasswd);

            dataSource.setMinIdle(3);
            dataSource.setMaxActive(10);
            Connection connection = dataSource.getConnection();
            connection.close();
            return dataSource;
        }

        public String getInitScript() {
            return "initdb." + name + ".sql";

        }

        public String getDropScript() {
            return "dropdb." + name + ".sql";
        }

        public String getResetScript() {
            return "resetdb." + name + ".sql";
        }

        @Override
        public String toString() {
            return name;
        }

        public String detailString() {
            return "DBConfig{" + "name=" + name + ", driver=" + driver + ", connectionUrl=" + connectionUrl + ", dbUser=" + dbUser + ", dbPasswd=" + dbPasswd + '}';
        }

    }

    private static List<Object[]> parameterizedDBConfigs;
    public static final List<Object[]> parameterizedDBConfigs() {
        if (parameterizedDBConfigs == null) {
            parameterizedDBConfigs = new ArrayList<Object[]>();
            for (DBConfig conf: getDBConfigurations()) {
                parameterizedDBConfigs.add(new Object[] {conf});
            }
        }
        return parameterizedDBConfigs;
    }

    static List<DBConfig> getDBConfigurations() {
        ArrayList<DBConfig> configs = new ArrayList<DBConfig>();

        dbConfig(configs, "h2", "org.h2.Driver", "jdbc:h2:file:${DATA_DIR}/geoserver");
        dbConfig(configs, "postgres", "org.postgresql.Driver", "jdbc:postgresql://localhost:5432/geoserver");
        dbConfig(configs, "oracle", "oracle.jdbc.OracleDriver", "jdbc:oracle:thin:@//localhost:49161/xe");

        return configs;
    }

    static String getProperty(String dbName, String property) {
        return System.getProperty("jdbcconfig." + dbName + "." + property);
    }

    public static void dbConfig(List<DBConfig> configs, String name, String driver, String connectionUrl) {
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException cnfe) {
            System.err.println("skipping " + name + " tests, enable via maven profile");
            return;
        }
        if ("true".equals(System.getProperty("jdbcconfig." + name + ".skip"))) {
            System.err.println("skipping " + name + " tests, enable via maven profile");
            return;
        }
        DBConfig conf = new DBConfig();
        conf.name = name;
        conf.driver = driver;
        conf.connectionUrl = connectionUrl;
        conf.dbUser = System.getProperty("user.name");
        conf.dbPasswd = "";

        connectionUrl = getProperty(name, "connectionUrl");
        if (connectionUrl != null) {
            conf.connectionUrl = connectionUrl;
        }
        String dbUser = getProperty(name, "dbUser");
        if (dbUser != null) {
            conf.dbUser = dbUser;
        }
        String dbPass = getProperty(name, "dbPasswd");
        if (dbPass != null) {
            conf.dbPasswd = dbPass;
        }
        try {
            conf.dataSource();
        } catch (Exception ex) {
            System.err.println("Unable to connect to datastore, either disable test or specify correct configuration:");
            System.out.println(ex.getMessage());
            System.out.println("Current configuration : " + conf.detailString());
            return;
        }
        configs.add(conf);
    }

    private final DBConfig dbConfig;

    private WebApplicationContext appContext;

    private GeoServerResourceLoader resourceLoader;

    private CatalogImpl catalog;

    private BasicDataSource dataSource;

    private ConfigDatabase configDb;

    public JDBCConfigTestSupport(DBConfig dbConfig) {
        this.dbConfig = dbConfig;
    }

    public void setUp() throws Exception {
        ConfigDatabase.LOGGER.setLevel(Level.FINER);

        resourceLoader = new GeoServerResourceLoader(createTempDir());

        // just to avoid hundreds of warnings in the logs about extension lookups with no app
        // context set
        appContext = createNiceMock(WebApplicationContext.class);
        GeoServerExtensionsHelper.init(appContext);

        configureAppContext(appContext);
        replay(appContext);

//        final File testDbDir = new File("target", "jdbcconfig");
//        FileUtils.deleteDirectory(testDbDir);
//        testDbDir.mkdirs();

        dataSource = dbConfig.dataSource();

        dropDb();
        initDb();

        // use a context to initialize the ConfigDatabase as this will enable
        // transaction management making the tests much faster (and correcter)
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        // use the dataSource we just created
        context.getBean(Config.class).real = dataSource;
        configDb = context.getBean(ConfigDatabase.class);

        catalog = new CatalogImpl();
        configDb.setCatalog(catalog);
        configDb.initDb(null);
    }

    protected void configureAppContext(WebApplicationContext appContext) {
        expect(appContext.getBeansOfType((Class) anyObject()))
            .andReturn(Collections.EMPTY_MAP).anyTimes();
        expect(appContext.getBeanNamesForType((Class) anyObject()))
            .andReturn(new String[] {}).anyTimes();

        ServletContext servletContext = createNiceMock(ServletContext.class);
        replay(servletContext);

        expect(appContext.getServletContext()).andReturn(servletContext);
    }

    public void tearDown() throws Exception {
        try {
            if (configDb != null) {
                configDb.dispose();
            }
        } finally {
            if (dataSource != null) {
                dataSource.close();
            }
        }
    }

    public GeoServerResourceLoader getResourceLoader() {
        return resourceLoader;
    }

    public WebApplicationContext getApplicationContext() {
        return appContext;
    }

    public ConfigDatabase getDatabase() {
        return configDb;
    }

    private void initDb() throws Exception {
        if (!dbConfig.initialized) {
            runScript(dbConfig.getInitScript(), null, true);
            dbConfig.initialized = true;
        }
    }

    private void dropDb() throws Exception {
        URL url = JDBCGeoServerLoader.class.getResource(dbConfig.getResetScript());
        if (url != null && dbConfig.initialized) {
            runScript(dbConfig.getResetScript(), null, true);
        } else {
            // drop script cannot be run in a transaction - if a statement fails
            // the whole thing aborts
            runScript(dbConfig.getDropScript(), null, false);
            dbConfig.initialized = false;
        }
    }

    public void runScript(String dbScriptName, Logger logger, boolean tx) throws IOException {
        final URL url = JDBCGeoServerLoader.class.getResource(dbScriptName);
        if (url == null) {
            throw new IllegalArgumentException("Script not found: " + getClass().getName() + "/"
                    + dbScriptName);
        }

        if (!tx) {
            NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(dataSource);
            Util.runScript(url, template.getJdbcOperations(), null);
        } else {
            DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
            NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(transactionManager.getDataSource());
            TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
            final JdbcOperations jdbcOperations = template.getJdbcOperations();
            transactionTemplate.execute(new TransactionCallback<Object>() {

                @Override
                public Object doInTransaction(TransactionStatus ts) {
                    try {
                        Util.runScript(url, jdbcOperations, null);
                    } catch (IOException ex) {
                        throw new RuntimeException(ex);
                    }
                    return null;
                }
            });
        }
    }

    public DataSource getDataSource() {
        return this.dataSource;
    }

    public DbMappings getDbMappings() {
        return this.configDb.getDbMappings();
    }

    public CatalogImpl getCatalog() {
        return catalog;
    }

    @Configuration
    @EnableTransactionManagement
    public static class Config {
        DataSource real;
        // we need a datasource immediately, but don't have one so use this as
        // a delegate that uses the 'real' DataSource
        DataSource lazy = new BasicDataSource() {

            @Override
            protected synchronized DataSource createDataSource() throws SQLException {
                return real;
            }

        };

        @Bean
        public PlatformTransactionManager transactionManager() {
            return new DataSourceTransactionManager(dataSource());
        }

        @Bean
        public ConfigDatabase configDatabase() {
            return new ConfigDatabase(dataSource(), new XStreamInfoSerialBinding(
                new XStreamPersisterFactory()));
        }

        @Bean
        public DataSource dataSource() {
            return lazy;
        }
    }
}
TOP

Related Classes of org.geoserver.jdbcconfig.JDBCConfigTestSupport$Config

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.