org.apache.hadoop.crypto.key.RangerKMSDB.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.crypto.key.RangerKMSDB.java

Source

/*
 * 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.hadoop.crypto.key;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.log4j.Logger;
import org.apache.ranger.kms.dao.DaoManager;

public class RangerKMSDB {

    static final Logger logger = Logger.getLogger(RangerKMSDB.class);

    private EntityManagerFactory entityManagerFactory;
    private DaoManager daoManager;

    private static Map<String, String> DB_PROPERTIES = null;

    private static final String PROPERTY_PREFIX = "ranger.ks.";
    private static final String DB_DIALECT = "jpa.jdbc.dialect";
    private static final String DB_DRIVER = "jpa.jdbc.driver";
    private static final String DB_URL = "jpa.jdbc.url";
    private static final String DB_USER = "jpa.jdbc.user";
    private static final String DB_PASSWORD = "jpa.jdbc.password";

    private static final String JPA_DB_DIALECT = "javax.persistence.jdbc.dialect";
    private static final String JPA_DB_DRIVER = "javax.persistence.jdbc.driver";
    private static final String JPA_DB_URL = "javax.persistence.jdbc.url";
    private static final String JPA_DB_USER = "javax.persistence.jdbc.user";
    private static final String JPA_DB_PASSWORD = "javax.persistence.jdbc.password";

    private static final String DB_SSL_ENABLED = "db.ssl.enabled";
    private static final String DB_SSL_REQUIRED = "db.ssl.required";
    private static final String DB_SSL_VerifyServerCertificate = "db.ssl.verifyServerCertificate";
    private static final String DB_SSL_KEYSTORE = "keystore.file";
    private static final String DB_SSL_KEYSTORE_PASSWORD = "keystore.password";
    private static final String DB_SSL_TRUSTSTORE = "truststore.file";
    private static final String DB_SSL_TRUSTSTORE_PASSWORD = "truststore.password";

    public static final int DB_FLAVOR_UNKNOWN = 0;
    public static final int DB_FLAVOR_MYSQL = 1;
    public static final int DB_FLAVOR_ORACLE = 2;
    public static final int DB_FLAVOR_POSTGRES = 3;
    public static final int DB_FLAVOR_SQLSERVER = 4;
    public static final int DB_FLAVOR_SQLANYWHERE = 5;

    private final Configuration conf;

    public RangerKMSDB() {
        conf = new Configuration();
        //TODO: need to load kms db config file here ...
    }

    public RangerKMSDB(Configuration conf) {
        this.conf = conf;
        initDBConnectivity();
    }

    public DaoManager getDaoManager() {
        return daoManager;
    }

    private void initDBConnectivity() {
        try {

            DB_PROPERTIES = new HashMap<String, String>();
            DB_PROPERTIES.put(JPA_DB_DIALECT, conf.get(PROPERTY_PREFIX + DB_DIALECT));
            DB_PROPERTIES.put(JPA_DB_DRIVER, conf.get(PROPERTY_PREFIX + DB_DRIVER));
            DB_PROPERTIES.put(JPA_DB_URL, conf.get(PROPERTY_PREFIX + DB_URL));
            DB_PROPERTIES.put(JPA_DB_USER, conf.get(PROPERTY_PREFIX + DB_USER));
            DB_PROPERTIES.put(JPA_DB_PASSWORD, conf.get(PROPERTY_PREFIX + DB_PASSWORD));
            if (getDBFlavor(conf) == DB_FLAVOR_MYSQL) {
                updateDBSSLURL();
            }

            //DB_PROPERTIES.list(System.out);

            /*
            Set keys = DB_PROPERTIES.keySet();
                
               for (Iterator i = keys.iterator(); i.hasNext();) {
               String key = (String) i.next();
               String value = (String) DB_PROPERTIES.get(key);
               System.out.println(key + " = " + value);
               }
            */

            entityManagerFactory = Persistence.createEntityManagerFactory("persistence_ranger_server",
                    DB_PROPERTIES);
            daoManager = new DaoManager();
            daoManager.setEntityManagerFactory(entityManagerFactory);
            daoManager.getEntityManager(); // this forces the connection to be made to DB
            logger.info("Connected to DB : " + isDbConnected());
        } catch (Exception excp) {
            excp.printStackTrace();
        }
    }

    private boolean isDbConnected() {
        EntityManager em = getEntityManager();

        return em != null && em.isOpen();
    }

    private EntityManager getEntityManager() {
        DaoManager daoMgr = daoManager;

        if (daoMgr != null) {
            try {
                return daoMgr.getEntityManager();
            } catch (Exception excp) {
                excp.printStackTrace();
            }
        }

        return null;
    }

    public int getDBFlavor(Configuration newConfig) {
        String[] propertyNames = { PROPERTY_PREFIX + DB_DIALECT, PROPERTY_PREFIX + DB_DRIVER,
                PROPERTY_PREFIX + DB_URL };

        for (String propertyName : propertyNames) {
            String propertyValue = DB_PROPERTIES.get(propertyName);
            if (StringUtils.isBlank(propertyValue)) {
                continue;
            }
            if (StringUtils.containsIgnoreCase(propertyValue, "mysql")) {
                return DB_FLAVOR_MYSQL;
            } else if (StringUtils.containsIgnoreCase(propertyValue, "oracle")) {
                return DB_FLAVOR_ORACLE;
            } else if (StringUtils.containsIgnoreCase(propertyValue, "postgresql")) {
                return DB_FLAVOR_POSTGRES;
            } else if (StringUtils.containsIgnoreCase(propertyValue, "sqlserver")) {
                return DB_FLAVOR_SQLSERVER;
            } else if (StringUtils.containsIgnoreCase(propertyValue, "mssql")) {
                return DB_FLAVOR_SQLSERVER;
            } else if (StringUtils.containsIgnoreCase(propertyValue, "sqlanywhere")) {
                return DB_FLAVOR_SQLANYWHERE;
            } else if (StringUtils.containsIgnoreCase(propertyValue, "sqla")) {
                return DB_FLAVOR_SQLANYWHERE;
            } else {
                if (logger.isDebugEnabled()) {
                    logger.debug("DB Flavor could not be determined from property - " + propertyName + "="
                            + propertyValue);
                }
            }
        }
        logger.error("DB Flavor could not be determined");
        return DB_FLAVOR_UNKNOWN;
    }

    private void updateDBSSLURL() {
        if (conf != null && conf.get(PROPERTY_PREFIX + DB_SSL_ENABLED) != null) {
            String db_ssl_enabled = conf.get(PROPERTY_PREFIX + DB_SSL_ENABLED);
            if (StringUtils.isEmpty(db_ssl_enabled) || !"true".equalsIgnoreCase(db_ssl_enabled)) {
                db_ssl_enabled = "false";
            }
            db_ssl_enabled = db_ssl_enabled.toLowerCase();
            if ("true".equalsIgnoreCase(db_ssl_enabled)) {
                String db_ssl_required = conf.get(PROPERTY_PREFIX + DB_SSL_REQUIRED);
                if (StringUtils.isEmpty(db_ssl_required) || !"true".equalsIgnoreCase(db_ssl_required)) {
                    db_ssl_required = "false";
                }
                db_ssl_required = db_ssl_required.toLowerCase();
                String db_ssl_verifyServerCertificate = conf.get(PROPERTY_PREFIX + DB_SSL_VerifyServerCertificate);
                if (StringUtils.isEmpty(db_ssl_verifyServerCertificate)
                        || !"true".equalsIgnoreCase(db_ssl_verifyServerCertificate)) {
                    db_ssl_verifyServerCertificate = "false";
                }
                db_ssl_verifyServerCertificate = db_ssl_verifyServerCertificate.toLowerCase();
                conf.set(PROPERTY_PREFIX + DB_SSL_ENABLED, db_ssl_enabled);
                conf.set(PROPERTY_PREFIX + DB_SSL_REQUIRED, db_ssl_required);
                conf.set(PROPERTY_PREFIX + DB_SSL_VerifyServerCertificate, db_ssl_verifyServerCertificate);
                String ranger_jpa_jdbc_url = conf.get(PROPERTY_PREFIX + DB_URL);
                if (!StringUtils.isEmpty(ranger_jpa_jdbc_url)) {
                    StringBuffer ranger_jpa_jdbc_url_ssl = new StringBuffer(ranger_jpa_jdbc_url);
                    ranger_jpa_jdbc_url_ssl.append("?useSSL=" + db_ssl_enabled + "&requireSSL=" + db_ssl_required
                            + "&verifyServerCertificate=" + db_ssl_verifyServerCertificate);
                    conf.set(PROPERTY_PREFIX + DB_URL, ranger_jpa_jdbc_url_ssl.toString());
                    DB_PROPERTIES.put(JPA_DB_URL, conf.get(PROPERTY_PREFIX + DB_URL));
                    logger.info(PROPERTY_PREFIX + DB_URL + "=" + ranger_jpa_jdbc_url_ssl.toString());
                }

                if ("true".equalsIgnoreCase(db_ssl_verifyServerCertificate)) {
                    if (conf != null) {
                        // update system key store path with custom key store.
                        String keystore = conf.get(PROPERTY_PREFIX + DB_SSL_KEYSTORE);
                        if (!StringUtils.isEmpty(keystore)) {
                            Path path = Paths.get(keystore);
                            if (Files.exists(path) && Files.isReadable(path)) {
                                System.setProperty("javax.net.ssl.keyStore",
                                        conf.get(PROPERTY_PREFIX + DB_SSL_KEYSTORE));
                                System.setProperty("javax.net.ssl.keyStorePassword",
                                        conf.get(PROPERTY_PREFIX + DB_SSL_KEYSTORE_PASSWORD));
                                System.setProperty("javax.net.ssl.keyStoreType", KeyStore.getDefaultType());
                            } else {
                                logger.debug("Could not find or read keystore file '" + keystore + "'");
                            }
                        } else {
                            logger.debug("keystore property '" + PROPERTY_PREFIX + DB_SSL_KEYSTORE
                                    + "' value not found!");
                        }
                        // update system trust store path with custom trust store.
                        String truststore = conf.get(PROPERTY_PREFIX + DB_SSL_TRUSTSTORE);
                        if (!StringUtils.isEmpty(truststore)) {
                            Path path = Paths.get(truststore);
                            if (Files.exists(path) && Files.isReadable(path)) {
                                System.setProperty("javax.net.ssl.trustStore",
                                        conf.get(PROPERTY_PREFIX + DB_SSL_TRUSTSTORE));
                                System.setProperty("javax.net.ssl.trustStorePassword",
                                        conf.get(PROPERTY_PREFIX + DB_SSL_TRUSTSTORE_PASSWORD));
                                System.setProperty("javax.net.ssl.trustStoreType", KeyStore.getDefaultType());
                            } else {
                                logger.debug("Could not find or read truststore file '" + truststore + "'");
                            }
                        } else {
                            logger.debug("truststore property '" + PROPERTY_PREFIX + DB_SSL_TRUSTSTORE
                                    + "' value not found!");
                        }
                    }
                }
            }
        }
    }
}