blob: b6214049a0c79a3cfc729636c12cd9f75703cf8f [file] [log] [blame]
/**
* 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.oozie.action.hadoop;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import org.apache.commons.io.FileUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.security.Credentials;
import org.apache.oozie.service.HCatAccessorService;
import org.apache.oozie.service.ServiceException;
import org.apache.oozie.service.Services;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ HCatCredentialHelper.class, HCatCredentials.class })
@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.dom.*"})
public class TestHCatCredentials {
private Services services;
private static File OOZIE_HOME_DIR = null;
private static final String TEST_HIVE_METASTORE_PRINCIPAL = "hcat/test-hcat1.com@OOZIE.EXAMPLE.COM";
private static final String TEST_HIVE_METASTORE_URI = "thrift://test-hcat1.com:9898";
private static final String TEST_HIVE_METASTORE_PRINCIPAL2 = "hcat/test-hcat2.com@OOZIE.EXAMPLE.COM";
private static final String TEST_HIVE_METASTORE_URI2 = "thrift://test-hcat2.com:9898";
final String HIVE_METASTORE_PRINCIPAL = "hive.principal";
final String HIVE_METASTORE_URI = "hive.uri";
final String HCAT_METASTORE_PRINCIPAL = "hcat.principal";
final String HCAT_METASTORE_URI = "hcat.uri";
private static File hiveSiteXml = null;
private static ClassLoader prevClassloader = null;
@BeforeClass
public static void initialize() throws Exception {
OOZIE_HOME_DIR = new File(new File("").getAbsolutePath(), "test-oozie-home");
if (!OOZIE_HOME_DIR.exists()) {
OOZIE_HOME_DIR.mkdirs();
}
System.setProperty(Services.OOZIE_HOME_DIR, OOZIE_HOME_DIR.getAbsolutePath());
Services.setOozieHome();
File oozieConfDir = new File(OOZIE_HOME_DIR.getAbsolutePath(), "conf");
oozieConfDir.mkdir();
File hadoopConfDir = new File(oozieConfDir, "hadoop-conf");
hadoopConfDir.mkdir();
File actionConfDir = new File(oozieConfDir, "action-conf");
actionConfDir.mkdir();
hiveSiteXml = new File(OOZIE_HOME_DIR, "hive-site.xml");
Writer fw = new OutputStreamWriter(new FileOutputStream(hiveSiteXml),
StandardCharsets.UTF_8);
fw.write(getHiveConfig(TEST_HIVE_METASTORE_PRINCIPAL, TEST_HIVE_METASTORE_URI));
fw.flush();
fw.close();
prevClassloader = Thread.currentThread().getContextClassLoader();
}
@Before
public void setUp() throws ServiceException, MalformedURLException {
services = new Services();
@SuppressWarnings("deprecation")
Configuration conf = services.getConf();
conf.set(Services.CONF_SERVICE_EXT_CLASSES, HCatAccessorService.class.getName());
conf.set(Services.CONF_SERVICE_CLASSES, "");
ContextClassLoader contextClassLoader = new ContextClassLoader(HCatCredentials.class.getClassLoader());
contextClassLoader.addURL(hiveSiteXml.toURI().toURL());
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
@After
public void tearDown(){
if (services != null) {
services.destroy();
}
}
@AfterClass
public static void terminate() throws IOException {
FileUtils.deleteDirectory(OOZIE_HOME_DIR);
Thread.currentThread().setContextClassLoader(prevClassloader);
}
@Test
public void testAddToJobConfFromHCat() throws Exception {
File hcatConfig = new File(OOZIE_HOME_DIR, "hcatConf.xml");
Writer fw = new OutputStreamWriter(new FileOutputStream(hcatConfig),
StandardCharsets.UTF_8);
fw.write(getHiveConfig(TEST_HIVE_METASTORE_PRINCIPAL2, TEST_HIVE_METASTORE_URI2));
fw.flush();
fw.close();
@SuppressWarnings("deprecation")
Configuration conf = services.getConf();
conf.set(HCatAccessorService.HCAT_CONFIGURATION, OOZIE_HOME_DIR + "/hcatConf.xml");
services.init();
HCatCredentialHelper hcatCredHelper = Mockito.mock(HCatCredentialHelper.class);
PowerMockito.whenNew(HCatCredentialHelper.class).withNoArguments().thenReturn(hcatCredHelper);
CredentialsProperties credProps = new CredentialsProperties("", "");
credProps.setProperties(new HashMap<String, String>());
HCatCredentials hcatCred = new HCatCredentials();
final JobConf jobConf = new JobConf(false);
Credentials credentials = new Credentials();
PowerMockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
Configuration jConf = (Configuration) args[1];
jConf.set(HCAT_METASTORE_PRINCIPAL, (String) args[2]);
jConf.set(HCAT_METASTORE_URI, (String) args[3]);
return null;
}
}).when(hcatCredHelper).set(credentials, jobConf, TEST_HIVE_METASTORE_PRINCIPAL2, TEST_HIVE_METASTORE_URI2);
hcatCred.updateCredentials(credentials, jobConf, credProps, null);
assertEquals(TEST_HIVE_METASTORE_PRINCIPAL2, jobConf.get(HCAT_METASTORE_PRINCIPAL));
assertEquals(TEST_HIVE_METASTORE_URI2, jobConf.get(HCAT_METASTORE_URI));
assertNull(jobConf.get(HIVE_METASTORE_PRINCIPAL));
assertNull(jobConf.get(HIVE_METASTORE_URI));
hcatConfig.delete();
}
@Test
public void testAddToJobConfFromHiveConf() throws Exception {
services.init();
CredentialsProperties credProps = new CredentialsProperties("", "");
credProps.setProperties(new HashMap<String, String>());
HCatCredentials hcatCred = new HCatCredentials();
final JobConf jobConf = new JobConf(false);
Credentials credentials = new Credentials();
HCatCredentialHelper hcatCredHelper = Mockito.mock(HCatCredentialHelper.class);
PowerMockito.whenNew(HCatCredentialHelper.class).withNoArguments().thenReturn(hcatCredHelper);
PowerMockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
Configuration jConf = (Configuration) args[1];
jConf.set(HIVE_METASTORE_PRINCIPAL, (String) args[2]);
jConf.set(HIVE_METASTORE_URI, (String) args[3]);
return null;
}
}).when(hcatCredHelper).set(credentials, jobConf, TEST_HIVE_METASTORE_PRINCIPAL, TEST_HIVE_METASTORE_URI);
hcatCred.updateCredentials(credentials, jobConf, credProps, null);
assertEquals(TEST_HIVE_METASTORE_PRINCIPAL, jobConf.get(HIVE_METASTORE_PRINCIPAL));
assertEquals(TEST_HIVE_METASTORE_URI, jobConf.get(HIVE_METASTORE_URI));
assertNull(jobConf.get(HCAT_METASTORE_PRINCIPAL));
assertNull(jobConf.get(HCAT_METASTORE_URI));
}
@Test
public void testAddToJobConfFromOozieConfig() throws Exception {
services.init();
HCatCredentialHelper hcatCredHelper = Mockito.mock(HCatCredentialHelper.class);
PowerMockito.whenNew(HCatCredentialHelper.class).withNoArguments().thenReturn(hcatCredHelper);
CredentialsProperties credProps = new CredentialsProperties("", "");
HashMap<String, String> prop = new HashMap<String, String>();
prop.put("hcat.metastore.principal", TEST_HIVE_METASTORE_PRINCIPAL2);
prop.put("hcat.metastore.uri", TEST_HIVE_METASTORE_URI2);
credProps.setProperties(prop);
HCatCredentials hcatCred = new HCatCredentials();
final JobConf jobConf = new JobConf(false);
Credentials credentials = new Credentials();
PowerMockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
JobConf jConf = (JobConf) args[1];
jConf.set(HCAT_METASTORE_PRINCIPAL, (String) args[2]);
jConf.set(HCAT_METASTORE_URI, (String) args[3]);
return null;
}
}).when(hcatCredHelper).set(credentials, jobConf, TEST_HIVE_METASTORE_PRINCIPAL2, TEST_HIVE_METASTORE_URI2);
hcatCred.updateCredentials(credentials, jobConf, credProps, null);
assertEquals(TEST_HIVE_METASTORE_PRINCIPAL2, jobConf.get(HCAT_METASTORE_PRINCIPAL));
assertEquals(TEST_HIVE_METASTORE_URI2, jobConf.get(HCAT_METASTORE_URI));
assertNull(jobConf.get(HIVE_METASTORE_PRINCIPAL));
assertNull(jobConf.get(HIVE_METASTORE_URI));
}
private static String getHiveConfig(String hivePrincipal, String hiveUri) {
return "<configuration>"
+ "<property>"
+ "<name>hive.metastore.kerberos.principal</name>"
+ "<value>"+ hivePrincipal + "</value>"
+ "</property>"
+ "<property>"
+ "<name>hive.metastore.uris</name>"
+ "<value>" + hiveUri + "</value>"
+ "</property>"
+ "</configuration>";
}
private static class ContextClassLoader extends URLClassLoader {
// Map the resource name to its url
private HashMap<String, URL> resources = new HashMap<String, URL>();
@Override
public URL findResource(String name) {
if (resources.containsKey(name)) {
return resources.get(name);
}
return super.findResource(name);
}
@Override
public URL getResource(String name) {
if (resources.containsKey(name)) {
return resources.get(name);
}
return super.getResource(name);
}
public ContextClassLoader(ClassLoader classLoader) {
this(new URL[0], classLoader);
}
public ContextClassLoader(URL[] urls, ClassLoader classLoader) {
super(urls, classLoader);
}
@Override
public void addURL(URL url) {
super.addURL(url);
try {
resources.put(new Path(url.toURI()).getName(), url);
}
catch (URISyntaxException e) {
e.printStackTrace(System.out);
}
}
};
}