001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.oozie.action.hadoop; 020 021import java.io.IOException; 022import java.util.HashMap; 023import java.util.Map; 024 025import com.google.common.annotations.VisibleForTesting; 026import org.apache.hadoop.io.Text; 027import org.apache.hadoop.security.UserGroupInformation; 028import org.apache.hadoop.security.token.Token; 029import org.apache.oozie.service.ConfigurationService; 030import org.apache.oozie.util.XLog; 031 032public class CredentialsProviderFactory { 033 public static final String CRED_KEY = "oozie.credentials.credentialclasses"; 034 private static final XLog LOG = XLog.getLog(CredentialsProviderFactory.class); 035 public static final String HDFS = "hdfs"; 036 public static final String YARN = "yarnRM"; 037 public static final String JHS = "jhs"; 038 private static CredentialsProviderFactory instance; 039 private final Map<String, Class<? extends CredentialsProvider>> providerCache; 040 041 @VisibleForTesting 042 static void destroy() { 043 instance = null; 044 } 045 046 public static CredentialsProviderFactory getInstance() throws Exception { 047 if(instance == null) { 048 instance = new CredentialsProviderFactory(); 049 } 050 return instance; 051 } 052 053 private CredentialsProviderFactory() throws Exception { 054 providerCache = new HashMap<>(); 055 for (String function : ConfigurationService.getStrings(CRED_KEY)) { 056 function = trim(function); 057 LOG.debug("Creating Credential class for : " + function); 058 String[] str = function.split("="); 059 if (str.length > 0) { 060 String type = str[0]; 061 String classname = str[1]; 062 if (classname != null) { 063 LOG.debug("Creating Credential type : '{0}', class Name : '{1}'", type, classname); 064 Class<?> klass = null; 065 try { 066 klass = Thread.currentThread().getContextClassLoader().loadClass(classname); 067 } 068 catch (ClassNotFoundException ex) { 069 LOG.warn("Exception while loading the class '{0}'", classname, ex); 070 throw ex; 071 } 072 providerCache.put(type, (Class<CredentialsProvider>) klass); 073 } else { 074 LOG.warn("Credential provider class is null for '{0}', skipping", type); 075 } 076 } 077 } 078 providerCache.put(HDFS, HDFSCredentials.class); 079 providerCache.put(YARN, YarnRMCredentials.class); 080 providerCache.put(JHS, JHSCredentials.class); 081 } 082 083 static Text getUniqueAlias(Token<?> token) { 084 return new Text(String.format("%s_%s_%d", token.getKind().toString(), 085 token.getService().toString(), System.currentTimeMillis())); 086 } 087 088 /** 089 * Create Credential object 090 * 091 * @param type 092 * @return Credential object 093 * @throws Exception 094 */ 095 public CredentialsProvider createCredentialsProvider(String type) throws Exception { 096 Class<? extends CredentialsProvider> providerClass = providerCache.get(type); 097 if(providerClass == null){ 098 return null; 099 } 100 return providerClass.newInstance(); 101 } 102 103 /** 104 * Relogs into Kerberos using the Keytab for the Oozie server user. This should be called before attempting to get delegation 105 * tokens via {@link CredentialsProvider} implementations to ensure that the Kerberos credentials are current and won't expire 106 * too soon. 107 * 108 * @throws IOException 109 */ 110 public static void ensureKerberosLogin() throws IOException { 111 LOG.debug("About to relogin from keytab"); 112 UserGroupInformation.getLoginUser().checkTGTAndReloginFromKeytab(); 113 LOG.debug("Relogin from keytab successful"); 114 } 115 116 /** 117 * To trim string 118 * 119 * @param str 120 * @return trim string 121 */ 122 public String trim(String str) { 123 if (str != null) { 124 str = str.replaceAll("\\n", ""); 125 str = str.replaceAll("\\t", ""); 126 str = str.trim(); 127 } 128 return str; 129 } 130}