co.cask.cdap.explore.service.ExploreServiceUtilsTest.java Source code

Java tutorial

Introduction

Here is the source code for co.cask.cdap.explore.service.ExploreServiceUtilsTest.java

Source

/*
 * Copyright  2014-2015 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.cdap.explore.service;

import com.google.common.base.Joiner;
import com.google.common.io.ByteStreams;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.MRJobConfig;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hive.service.auth.HiveAuthFactory;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 *
 */
public class ExploreServiceUtilsTest {

    @ClassRule
    public static TemporaryFolder tmpFolder = new TemporaryFolder();

    @Test
    public void testHiveVersion() throws Exception {
        // This would throw an exception if it didn't pass
        ExploreServiceUtils.checkHiveSupport(getClass().getClassLoader());
    }

    @Test
    public void hijackConfFileTest() throws Exception {
        Configuration conf = new Configuration(false);
        conf.set("foo", "bar");
        Assert.assertEquals(1, conf.size());

        File tempDir = tmpFolder.newFolder();

        File confFile = tmpFolder.newFile("hive-site.xml");

        try (FileOutputStream os = new FileOutputStream(confFile)) {
            conf.writeXml(os);
        }

        File newConfFile = ExploreServiceUtils.updateConfFileForExplore(confFile, tempDir);

        conf = new Configuration(false);
        conf.addResource(newConfFile.toURI().toURL());

        Assert.assertEquals(3, conf.size());
        Assert.assertEquals("false", conf.get(Job.MAPREDUCE_JOB_USER_CLASSPATH_FIRST));
        Assert.assertEquals("false", conf.get(Job.MAPREDUCE_JOB_CLASSLOADER));
        Assert.assertEquals("bar", conf.get("foo"));

        // check yarn-site changes
        confFile = tmpFolder.newFile("yarn-site.xml");
        conf = new YarnConfiguration();

        try (FileOutputStream os = new FileOutputStream(confFile)) {
            conf.writeXml(os);
        }

        String yarnApplicationClassPath = "$PWD/*," + conf.get(YarnConfiguration.YARN_APPLICATION_CLASSPATH,
                Joiner.on(",").join(YarnConfiguration.DEFAULT_YARN_APPLICATION_CLASSPATH));

        newConfFile = ExploreServiceUtils.updateConfFileForExplore(confFile, tempDir);

        conf = new Configuration(false);
        conf.addResource(newConfFile.toURI().toURL());

        Assert.assertEquals(yarnApplicationClassPath, conf.get(YarnConfiguration.YARN_APPLICATION_CLASSPATH));

        // check mapred-site changes
        confFile = tmpFolder.newFile("mapred-site.xml");
        conf = new YarnConfiguration();

        try (FileOutputStream os = new FileOutputStream(confFile)) {
            conf.writeXml(os);
        }

        String mapredApplicationClassPath = "$PWD/*," + conf.get(MRJobConfig.MAPREDUCE_APPLICATION_CLASSPATH,
                MRJobConfig.DEFAULT_MAPREDUCE_APPLICATION_CLASSPATH);

        newConfFile = ExploreServiceUtils.updateConfFileForExplore(confFile, tempDir);

        conf = new Configuration(false);
        conf.addResource(newConfFile.toURI().toURL());

        Assert.assertEquals(mapredApplicationClassPath, conf.get(MRJobConfig.MAPREDUCE_APPLICATION_CLASSPATH));

        // Ensure conf files that are not hive-site.xml/mapred-site.xml/yarn-site.xml are unchanged
        confFile = tmpFolder.newFile("core-site.xml");
        Assert.assertEquals(confFile, ExploreServiceUtils.updateConfFileForExplore(confFile, tempDir));
    }

    @Test
    public void testRewriteHiveAuthFactory() throws Exception {
        URL hiveAuthURL = getClass().getClassLoader()
                .getResource(HiveAuthFactory.class.getName().replace('.', '/') + ".class");

        String hiveJarFilePath = hiveAuthURL.getPath();
        File hiveJarFile = new File(URI.create(hiveJarFilePath.substring(0, hiveJarFilePath.indexOf("!/"))));

        File targetJar = ExploreServiceUtils.rewriteHiveAuthFactory(hiveJarFile,
                new File(tmpFolder.newFolder(), "hive.jar"));

        try (TestHiveAuthFactoryClassLoader cl = new TestHiveAuthFactoryClassLoader(targetJar,
                getClass().getClassLoader())) {
            Class<?> hiveAuthFactoryClass = cl.loadClass(HiveAuthFactory.class.getName());
            Method loginFromKeytab = hiveAuthFactoryClass.getMethod("loginFromKeytab", HiveConf.class);

            // If the write is not successful, this will throw exception
            loginFromKeytab.invoke(null, new Object[] { null });
        }
    }

    /**
     * A class loader which tries to load from the given jarFile first rather than the parent.
     */
    private static final class TestHiveAuthFactoryClassLoader extends ClassLoader implements Closeable {

        private final JarFile jarFile;

        public TestHiveAuthFactoryClassLoader(File jarFile, ClassLoader parent) throws IOException {
            super(parent);
            this.jarFile = new JarFile(jarFile);
        }

        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            return loadClass(name, true);
        }

        @Override
        protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
            // Try to load from itself first
            String fileName = name.replace('.', '/') + ".class";
            JarEntry jarEntry = jarFile.getJarEntry(fileName);
            if (jarEntry == null) {
                return super.loadClass(name, resolve);
            }

            try (InputStream input = jarFile.getInputStream(jarEntry)) {
                byte[] bytes = ByteStreams.toByteArray(input);
                Class<?> cls = defineClass(name, bytes, 0, bytes.length);

                if (resolve) {
                    resolveClass(cls);
                }
                return cls;

            } catch (IOException e) {
                throw new ClassNotFoundException("Class " + name + " not found.", e);
            }
        }

        @Override
        public void close() throws IOException {
            jarFile.close();
        }
    }
}