Java tutorial
/** * 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. */ package org.apache.sqoop.repository; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.ConnectionFactory; import org.apache.commons.dbcp.DriverManagerConnectionFactory; import org.apache.commons.dbcp.PoolableConnectionFactory; import org.apache.commons.dbcp.PoolingDataSource; import org.apache.commons.pool.KeyedObjectPoolFactory; import org.apache.commons.pool.impl.GenericKeyedObjectPoolFactory; import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.log4j.Logger; import org.apache.sqoop.common.SqoopException; import org.apache.sqoop.common.MapContext; import org.apache.sqoop.core.SqoopConfiguration; import org.apache.sqoop.utils.ClassUtils; public class JdbcRepositoryProvider implements RepositoryProvider { private static final Logger LOG = Logger.getLogger(JdbcRepositoryProvider.class); private JdbcRepositoryContext repoContext; private Driver driver; private GenericObjectPool connectionPool; private KeyedObjectPoolFactory statementPool; private DataSource dataSource; private JdbcRepositoryHandler handler; private JdbcRepositoryTransactionFactory txFactory; private JdbcRepository repository; public JdbcRepositoryProvider() { // Default constructor } @Override public synchronized void initialize(MapContext context) { repoContext = new JdbcRepositoryContext(SqoopConfiguration.getInstance().getContext()); initializeRepositoryHandler(); LOG.info("JdbcRepository initialized."); } @Override public synchronized void destroy() { try { connectionPool.close(); } catch (Exception ex) { LOG.error("Failed to shutdown connection pool", ex); } handler.shutdown(); if (driver != null) { try { LOG.info("Deregistering JDBC driver"); DriverManager.deregisterDriver(driver); } catch (SQLException ex) { LOG.error("Failed to deregister driver", ex); } } handler = null; driver = null; dataSource = null; } private void initializeRepositoryHandler() { String jdbcHandlerClassName = repoContext.getHandlerClassName(); Class<?> handlerClass = ClassUtils.loadClass(jdbcHandlerClassName); if (handlerClass == null) { throw new SqoopException(RepositoryError.JDBCREPO_0001, jdbcHandlerClassName); } try { handler = (JdbcRepositoryHandler) handlerClass.newInstance(); } catch (Exception ex) { throw new SqoopException(RepositoryError.JDBCREPO_0001, jdbcHandlerClassName, ex); } String connectUrl = repoContext.getConnectionUrl(); if (connectUrl == null || connectUrl.trim().length() == 0) { throw new SqoopException(RepositoryError.JDBCREPO_0002); } String jdbcDriverClassName = repoContext.getDriverClass(); if (jdbcDriverClassName == null || jdbcDriverClassName.trim().length() == 0) { throw new SqoopException(RepositoryError.JDBCREPO_0003); } // Initialize a datasource Class<?> driverClass = ClassUtils.loadClass(jdbcDriverClassName); if (driverClass == null) { throw new SqoopException(RepositoryError.JDBCREPO_0003, jdbcDriverClassName); } try { driver = (Driver) driverClass.newInstance(); } catch (Exception ex) { throw new SqoopException(RepositoryError.JDBCREPO_0003, jdbcDriverClassName, ex); } Properties jdbcProps = repoContext.getConnectionProperties(); ConnectionFactory connFactory = new DriverManagerConnectionFactory(connectUrl, jdbcProps); connectionPool = new GenericObjectPool(); connectionPool.setMaxActive(repoContext.getMaximumConnections()); statementPool = new GenericKeyedObjectPoolFactory(null); // creating the factor automatically wires the connection pool new PoolableConnectionFactory(connFactory, connectionPool, statementPool, handler.validationQuery(), false, false, repoContext.getTransactionIsolation().getCode()); dataSource = new PoolingDataSource(connectionPool); txFactory = new JdbcRepositoryTransactionFactory(dataSource); repoContext.initialize(dataSource, txFactory); handler.initialize(repoContext); repository = new JdbcRepository(handler, repoContext); LOG.info("JdbcRepositoryProvider initialized"); } @Override public synchronized Repository getRepository() { return repository; } @Override public void configurationChanged() { LOG.info("Begin JdbcRepository reconfiguring."); JdbcRepositoryContext oldRepoContext = repoContext; repoContext = new JdbcRepositoryContext(SqoopConfiguration.getInstance().getContext()); // reconfigure jdbc handler String newJdbcHandlerClassName = repoContext.getHandlerClassName(); if (newJdbcHandlerClassName == null || newJdbcHandlerClassName.trim().length() == 0) { throw new SqoopException(RepositoryError.JDBCREPO_0001, newJdbcHandlerClassName); } String oldJdbcHandlerClassName = oldRepoContext.getHandlerClassName(); if (!newJdbcHandlerClassName.equals(oldJdbcHandlerClassName)) { LOG.warn("Repository JDBC handler cannot be replaced at the runtime. " + "You might need to restart the server."); } // reconfigure jdbc driver String newJdbcDriverClassName = repoContext.getDriverClass(); if (newJdbcDriverClassName == null || newJdbcDriverClassName.trim().length() == 0) { throw new SqoopException(RepositoryError.JDBCREPO_0003, newJdbcDriverClassName); } String oldJdbcDriverClassName = oldRepoContext.getDriverClass(); if (!newJdbcDriverClassName.equals(oldJdbcDriverClassName)) { LOG.warn("Repository JDBC driver cannot be replaced at the runtime. " + "You might need to restart the server."); } // reconfigure max connection connectionPool.setMaxActive(repoContext.getMaximumConnections()); // reconfigure the url of repository String connectUrl = repoContext.getConnectionUrl(); String oldurl = oldRepoContext.getConnectionUrl(); if (connectUrl != null && !connectUrl.equals(oldurl)) { LOG.warn( "Repository URL cannot be replaced at the runtime. " + "You might need to restart the server."); } // if connection properties or transaction isolation option changes boolean connFactoryChanged = false; // compare connection properties if (!connFactoryChanged) { Properties oldProp = oldRepoContext.getConnectionProperties(); Properties newProp = repoContext.getConnectionProperties(); if (newProp.size() != oldProp.size()) { connFactoryChanged = true; } else { for (Object key : newProp.keySet()) { if (!newProp.getProperty((String) key).equals(oldProp.getProperty((String) key))) { connFactoryChanged = true; break; } } } } // compare the transaction isolation option if (!connFactoryChanged) { String oldTxOption = oldRepoContext.getTransactionIsolation().toString(); String newTxOption = repoContext.getTransactionIsolation().toString(); if (!newTxOption.equals(oldTxOption)) { connFactoryChanged = true; } } if (connFactoryChanged) { // try to reconfigure connection factory try { LOG.info("Reconfiguring Connection Factory."); Properties jdbcProps = repoContext.getConnectionProperties(); ConnectionFactory connFactory = new DriverManagerConnectionFactory(connectUrl, jdbcProps); new PoolableConnectionFactory(connFactory, connectionPool, statementPool, handler.validationQuery(), false, false, repoContext.getTransactionIsolation().getCode()); } catch (IllegalStateException ex) { // failed to reconfigure connection factory LOG.warn("Repository connection cannot be reconfigured currently. " + "You might need to restart the server."); } } // ignore the create schema option, because the repo url is not allowed to change LOG.info("JdbcRepository reconfigured."); } }