com.jaspersoft.jasperserver.api.engine.common.virtualdatasourcequery.teiid.impl.HiveTeiidConnectorImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.jaspersoft.jasperserver.api.engine.common.virtualdatasourcequery.teiid.impl.HiveTeiidConnectorImpl.java

Source

/*
 * Copyright (C) 2005 - 2014 TIBCO Software Inc. All rights reserved.
 * http://www.jaspersoft.com.
 *
 * Unless you have purchased  a commercial license agreement from Jaspersoft,
 * the following license terms  apply:
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License  as
 * published by the Free Software Foundation, either version 3 of  the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero  General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public  License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.jaspersoft.jasperserver.api.engine.common.virtualdatasourcequery.teiid.impl;

import com.jaspersoft.jasperserver.api.common.virtualdatasourcequery.teiid.TeiidDataSource;
import com.jaspersoft.jasperserver.api.engine.common.virtualdatasourcequery.VirtualSQLDataSource;
import com.jaspersoft.jasperserver.api.engine.common.virtualdatasourcequery.teiid.TeiidEmbeddedServer;
import com.jaspersoft.jasperserver.api.engine.common.virtualdatasourcequery.teiid.TranslatorConfig;
import com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl.VirtualReportDataSourceServiceFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.teiid.adminapi.Model;
import org.teiid.adminapi.impl.ModelMetaData;
import org.teiid.dqp.internal.datamgr.ConnectorManager;
import org.teiid.translator.ExecutionFactory;
import org.teiid.translator.TranslatorException;

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

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * @author Ivan Chan (ichan@jaspersoft.com)
 * @version $Id: HiveTeiidConnectorImpl.java 48307 2014-08-15 21:38:37Z ichan $
 */
public class HiveTeiidConnectorImpl implements TeiidDataSource,
        com.jaspersoft.jasperserver.api.common.virtualdatasourcequery.ConnectionFactory {

    String jndiName;
    String dataSourceName;
    String databaseName;
    TranslatorConfig translatorConfig;
    private Map<String, String> importPropertyMap = new HashMap<String, String>();
    private static final Log log = LogFactory.getLog(TeiidEmbeddedServer.class);
    Connection connection;
    String userName = null;
    String password = null;
    String jdbcURL = null;
    String driver = null;
    boolean useDatabaseExplicitly = false;

    public String getJndiName() {
        return jndiName;
    }

    public void setJndiName(String jndiName) {
        this.jndiName = jndiName;
    }

    public TranslatorConfig getTranslatorConfig() {
        return translatorConfig;
    }

    public void setTranslatorConfig(TranslatorConfig translatorConfig) {
        this.translatorConfig = translatorConfig;
    }

    /*
    * get teiid import properties through spring injection
    */
    public Map<String, String> getImportPropertyMap() {
        return importPropertyMap;
    }

    /*
    * set teiid import properties through spring injection
    */
    public void setImportPropertyMap(Map<String, String> importPropertyMap) {
        this.importPropertyMap = importPropertyMap;
    }

    /*
    * returns connector name which use for reference in teiid connector manager repository (sub data source id)
    */
    public String getConnectorName() {
        return (jndiName).hashCode() + "";
    }

    /*
     * returns connector manager which contains the connection and translator information
     */
    public ConnectorManager getConnectorManager() throws Exception {
        return null;
    }

    public Object getConnectionFactory() throws Exception {
        if (translatorConfig == null) {
            translatorConfig = new TranslatorConfig();
            translatorConfig.setProductName("hive");
            translatorConfig.setTranslatorName("hive");
            translatorConfig.setTranslatorFactoryClass("org.teiid.translator.hive.HiveExecutionFactory");
        }
        Context ctx = new InitialContext();
        DataSource ds = (DataSource) ctx.lookup("java:comp/env/" + jndiName);
        translatorConfig.setupTranslator();
        return ds;
    }

    public String getTranslatorName() {
        return translatorConfig.getTranslatorName();
    }

    public String getSchemaText(Map map) throws Exception {
        return null;
    }

    public String getSchemaSourceType() throws Exception {
        return "native";
    }

    public boolean isUseDatabaseExplicitly() {
        return useDatabaseExplicitly;
    }

    public void setUseDatabaseExplicitly(boolean useDatabaseExplicitly) {
        this.useDatabaseExplicitly = useDatabaseExplicitly;
    }

    public Object getConnectionFactory(Map map) throws Exception {
        userName = (String) map.get("username");
        password = (String) map.get("password");
        jdbcURL = (String) map.get("jdbcURL");
        // workaround for HIVE 0.11 driver
        // it ignore the database name in the URL, and it is fixed in HIVE 0.13 driver
        // we should turn off/ remove this workaround when we upgrade to HIVE 0.13 driver
        //https://issues.apache.org/jira/browse/HIVE-4256
        if (useDatabaseExplicitly)
            databaseName = getDatabase(jdbcURL);
        driver = null;
        if (jdbcURL.toLowerCase().startsWith("jdbc:hive2://"))
            driver = "org.apache.hive.jdbc.HiveDriver";
        else if (jdbcURL.toLowerCase().startsWith("jdbc:hive://"))
            driver = "org.apache.hadoop.hive.jdbc.HiveDriver";
        return new VirtualSQLDataSource(this);

    }

    public Connection createConnection() throws SQLException {
        try {
            if ((connection == null) || connection.isClosed()) {
                // HIVE DRIVER DOESN'T SUPPORT XAConnection, PooledDataSource
                // JNDI connection is still recommended by HIVE Connection
                Class.forName(driver);
                connection = DriverManager.getConnection(jdbcURL, userName, password);
                if ((databaseName != null) && !databaseName.toLowerCase().equals("default")) {
                    Statement statement = connection.createStatement();
                    log.debug("HIVE USE NON-DEFAULT DATABASE:  EXECUTE UPDATE - [USE " + databaseName + "]");
                    statement.executeUpdate("USE " + databaseName);
                    statement.close();
                }
            }
            return connection;
        } catch (SQLException sqlEx) {
            throw sqlEx;
        } catch (Exception ex) {
            throw new SQLException(ex);
        }
    }

    public TranslatorConfig getTranslator() throws Exception {
        if (translatorConfig == null) {
            translatorConfig = new TranslatorConfig();
            translatorConfig.setProductName("hive");
            translatorConfig.setTranslatorName("hive");
            translatorConfig.setTranslatorFactoryClass("org.teiid.translator.hive.HiveExecutionFactory");
        }
        translatorConfig.setupTranslator();
        return translatorConfig;
    }

    public ExecutionFactory getTranslatorFactory() throws TranslatorException {
        return translatorConfig.getTranslatorFactory();
    }

    /*
     * returns list of modelMetaData (schema) which is going to be available in virtual data source
     */
    public List<ModelMetaData> getModelMetaDataList() {
        ArrayList<ModelMetaData> modelMetaDataList = new ArrayList<ModelMetaData>();
        modelMetaDataList.add(getModel());
        return modelMetaDataList;
    }

    private ModelMetaData getModel() {
        String subDataSourceID = getConnectorName();
        String modelName = dataSourceName;
        ModelMetaData model = new ModelMetaData();
        model.setModelType(Model.Type.PHYSICAL);
        model.setName(modelName);
        Properties importProperties = new Properties() {
            private static final long serialVersionUID = 1L;
            {
                setProperty("importer.trimColumnNames", Boolean.TRUE.toString());
            }
        };
        if (importPropertyMap != null) {
            importProperties.putAll(importPropertyMap);
        }
        model.setProperties(importProperties);

        model.addSourceMapping(subDataSourceID, translatorConfig.getTranslatorName(), subDataSourceID);
        return model;
    }

    public String getDataSourceName() {
        return dataSourceName;
    }

    public void setDataSourceName(String dataSourceName) {
        this.dataSourceName = dataSourceName;
    }

    /***
     * retrieve the database name from JDBC URL
     * for example:
     *      jdbc:hive2://qa-hadoop-master.eng.jaspersoft.com:21050/;auth=noSasl   return default
     *      jdbc:hive2://qa-hadoop-master.eng.jaspersoft.com:10001/default        return default
     *      jdbc:hive2://qa-hadoop-master.eng.jaspersoft.com:21050/non_default;auth=noSasl        return non_default
     * @param jdbcURL
     * @return
     */
    private static String getDatabase(String jdbcURL) {
        int indexForSemiColon = jdbcURL.indexOf(";");
        String databaseName;
        if (indexForSemiColon > 0)
            databaseName = jdbcURL.substring(0, indexForSemiColon);
        else
            databaseName = jdbcURL;
        int lastSeparator = databaseName.lastIndexOf("/");
        if (lastSeparator > 0)
            databaseName = databaseName.substring(lastSeparator + 1);
        if (databaseName.equals("") || databaseName.contains(":"))
            databaseName = "default";
        log.debug("HIVE:  DETECT DATABASE NAME  = " + databaseName);
        return databaseName;
    }

}