All Downloads are FREE. Search and download functionalities are using the official Maven repository.

co.cask.hydrator.plugin.DBManager Maven / Gradle / Ivy

There is a newer version: 2.1.2
Show newest version
/*
 * Copyright © 2015-2016 Cask Data, Inc.
 *
 * Licensed 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 co.cask.hydrator.plugin;

import co.cask.cdap.api.plugin.PluginProperties;
import co.cask.cdap.etl.api.Destroyable;
import co.cask.cdap.etl.api.PipelineConfigurer;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Class to manage common database operations for Database source and sink plugins.
 */
public class DBManager implements Destroyable {
  private static final Logger LOG = LoggerFactory.getLogger(DBManager.class);
  private final ConnectionConfig config;
  private DriverCleanup driverCleanup;

  public DBManager(ConnectionConfig config) {
    this.config = config;
  }

  public void validateJDBCPluginPipeline(PipelineConfigurer pipelineConfigurer, String jdbcPluginId) {
    Preconditions.checkArgument(!(config.user == null && config.password != null),
                                "user is null. Please provide both user name and password if database requires " +
                                  "authentication. If not, please remove password and retry.");
    Class jdbcDriverClass = pipelineConfigurer.usePluginClass(config.jdbcPluginType,
                                                                                config.jdbcPluginName,
                                                                                jdbcPluginId,
                                                                                PluginProperties.builder().build());
    Preconditions.checkArgument(
      jdbcDriverClass != null, "Unable to load JDBC Driver class for plugin name '%s'. Please make sure that the " +
        "plugin '%s' of type '%s' containing the driver has been installed correctly.", config.jdbcPluginName,
      config.jdbcPluginName, config.jdbcPluginType);
  }

  public boolean tableExists(Class jdbcDriverClass, String tableName) {
    try {
      ensureJDBCDriverIsAvailable(jdbcDriverClass);
    } catch (IllegalAccessException | InstantiationException | SQLException e) {
      LOG.error("Unable to load or register JDBC driver {} while checking for the existence of the database table {}.",
                jdbcDriverClass, tableName, e);
      throw Throwables.propagate(e);
    }

    Connection connection;
    try {
      if (config.user == null) {
        connection = DriverManager.getConnection(config.connectionString);
      } else {
        connection = DriverManager.getConnection(config.connectionString, config.user, config.password);
      }

      try {
        DatabaseMetaData metadata = connection.getMetaData();
        try (ResultSet rs = metadata.getTables(null, null, tableName, null)) {
          return rs.next();
        }
      } finally {
        connection.close();
      }
    } catch (SQLException e) {
      LOG.error("Exception while trying to check the existence of database table {} for connection {}.",
                tableName, config.connectionString, e);
      throw Throwables.propagate(e);
    }
  }

  /**
   * Ensures that the JDBC Driver specified in configuration is available and can be loaded. Also registers it with
   * {@link DriverManager} if it is not already registered.
   */
  public void ensureJDBCDriverIsAvailable(Class jdbcDriverClass)
    throws IllegalAccessException, InstantiationException, SQLException {
    driverCleanup = DBUtils.ensureJDBCDriverIsAvailable(jdbcDriverClass, config.connectionString,
                                                        config.jdbcPluginType, config.jdbcPluginName);
  }

  @Override
  public void destroy() {
    if (driverCleanup != null) {
      driverCleanup.destroy();
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy