1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.fail;
23
24 import java.io.IOException;
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 import java.util.List;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.hadoop.conf.Configuration;
32 import org.junit.Test;
33 import org.junit.experimental.categories.Category;
34
35 @Category(SmallTests.class)
36 public class TestHBaseConfiguration {
37
38 private static final Log LOG = LogFactory.getLog(TestHBaseConfiguration.class);
39
40 @Test
41 public void testGetIntDeprecated() {
42 int VAL = 1, VAL2 = 2;
43 String NAME = "foo";
44 String DEPRECATED_NAME = "foo.deprecated";
45
46 Configuration conf = HBaseConfiguration.create();
47 conf.setInt(NAME, VAL);
48 assertEquals(VAL, HBaseConfiguration.getInt(conf, NAME, DEPRECATED_NAME, 0));
49
50 conf = HBaseConfiguration.create();
51 conf.setInt(DEPRECATED_NAME, VAL);
52 assertEquals(VAL, HBaseConfiguration.getInt(conf, NAME, DEPRECATED_NAME, 0));
53
54 conf = HBaseConfiguration.create();
55 conf.setInt(DEPRECATED_NAME, VAL);
56 conf.setInt(NAME, VAL);
57 assertEquals(VAL, HBaseConfiguration.getInt(conf, NAME, DEPRECATED_NAME, 0));
58
59 conf = HBaseConfiguration.create();
60 conf.setInt(DEPRECATED_NAME, VAL);
61 conf.setInt(NAME, VAL2);
62 assertEquals(VAL, HBaseConfiguration.getInt(conf, NAME, DEPRECATED_NAME, 0));
63 }
64
65 @Test
66 public void testGetPassword() throws Exception {
67 Configuration conf = HBaseConfiguration.create();
68 conf.set(ReflectiveCredentialProviderClient.CREDENTIAL_PROVIDER_PATH,
69 "jceks://file/tmp/foo.jks");
70 ReflectiveCredentialProviderClient client =
71 new ReflectiveCredentialProviderClient();
72 if (client.isHadoopCredentialProviderAvailable()) {
73 char[] keyPass = {'k', 'e', 'y', 'p', 'a', 's', 's'};
74 char[] storePass = {'s', 't', 'o', 'r', 'e', 'p', 'a', 's', 's'};
75 client.createEntry(conf, "ssl.keypass.alias", keyPass);
76 client.createEntry(conf, "ssl.storepass.alias", storePass);
77
78 String keypass = HBaseConfiguration.getPassword(
79 conf, "ssl.keypass.alias", null);
80 assertEquals(keypass, new String(keyPass));
81
82 String storepass = HBaseConfiguration.getPassword(
83 conf, "ssl.storepass.alias", null);
84 assertEquals(storepass, new String(storePass));
85 }
86 }
87
88 private static class ReflectiveCredentialProviderClient {
89 public static final String HADOOP_CRED_PROVIDER_FACTORY_CLASS_NAME =
90 "org.apache.hadoop.security.alias.JavaKeyStoreProvider$Factory";
91 public static final String
92 HADOOP_CRED_PROVIDER_FACTORY_GET_PROVIDERS_METHOD_NAME = "getProviders";
93
94 public static final String HADOOP_CRED_PROVIDER_CLASS_NAME =
95 "org.apache.hadoop.security.alias.CredentialProvider";
96 public static final String
97 HADOOP_CRED_PROVIDER_GET_CREDENTIAL_ENTRY_METHOD_NAME =
98 "getCredentialEntry";
99 public static final String
100 HADOOP_CRED_PROVIDER_GET_ALIASES_METHOD_NAME = "getAliases";
101 public static final String
102 HADOOP_CRED_PROVIDER_CREATE_CREDENTIAL_ENTRY_METHOD_NAME =
103 "createCredentialEntry";
104 public static final String HADOOP_CRED_PROVIDER_FLUSH_METHOD_NAME = "flush";
105
106 public static final String HADOOP_CRED_ENTRY_CLASS_NAME =
107 "org.apache.hadoop.security.alias.CredentialProvider$CredentialEntry";
108 public static final String HADOOP_CRED_ENTRY_GET_CREDENTIAL_METHOD_NAME =
109 "getCredential";
110
111 public static final String CREDENTIAL_PROVIDER_PATH =
112 "hadoop.security.credential.provider.path";
113
114 private static Object hadoopCredProviderFactory = null;
115 private static Method getProvidersMethod = null;
116 private static Method getAliasesMethod = null;
117 private static Method getCredentialEntryMethod = null;
118 private static Method getCredentialMethod = null;
119 private static Method createCredentialEntryMethod = null;
120 private static Method flushMethod = null;
121 private static Boolean hadoopClassesAvailable = null;
122
123
124
125
126
127
128
129
130
131 private boolean isHadoopCredentialProviderAvailable() {
132 if (null != hadoopClassesAvailable) {
133
134 if (hadoopClassesAvailable && null != getProvidersMethod
135 && null != hadoopCredProviderFactory
136 && null != getCredentialEntryMethod && null != getCredentialMethod) {
137 return true;
138 } else {
139
140 return false;
141 }
142 }
143
144 hadoopClassesAvailable = false;
145
146
147 Class<?> hadoopCredProviderFactoryClz = null;
148 try {
149 hadoopCredProviderFactoryClz = Class
150 .forName(HADOOP_CRED_PROVIDER_FACTORY_CLASS_NAME);
151 } catch (ClassNotFoundException e) {
152 return false;
153 }
154
155 try {
156 hadoopCredProviderFactory = hadoopCredProviderFactoryClz.newInstance();
157 } catch (InstantiationException e) {
158 return false;
159 } catch (IllegalAccessException e) {
160 return false;
161 }
162
163 try {
164 getProvidersMethod = loadMethod(hadoopCredProviderFactoryClz,
165 HADOOP_CRED_PROVIDER_FACTORY_GET_PROVIDERS_METHOD_NAME,
166 Configuration.class);
167
168
169 Class<?> hadoopCredProviderClz = null;
170 hadoopCredProviderClz = Class.forName(HADOOP_CRED_PROVIDER_CLASS_NAME);
171 getCredentialEntryMethod = loadMethod(hadoopCredProviderClz,
172 HADOOP_CRED_PROVIDER_GET_CREDENTIAL_ENTRY_METHOD_NAME, String.class);
173
174 getAliasesMethod = loadMethod(hadoopCredProviderClz,
175 HADOOP_CRED_PROVIDER_GET_ALIASES_METHOD_NAME);
176
177 createCredentialEntryMethod = loadMethod(hadoopCredProviderClz,
178 HADOOP_CRED_PROVIDER_CREATE_CREDENTIAL_ENTRY_METHOD_NAME,
179 String.class, char[].class);
180
181 flushMethod = loadMethod(hadoopCredProviderClz,
182 HADOOP_CRED_PROVIDER_FLUSH_METHOD_NAME);
183
184
185 Class<?> hadoopCredentialEntryClz = null;
186 try {
187 hadoopCredentialEntryClz = Class
188 .forName(HADOOP_CRED_ENTRY_CLASS_NAME);
189 } catch (ClassNotFoundException e) {
190 LOG.error("Failed to load class:" + e);
191 return false;
192 }
193
194 getCredentialMethod = loadMethod(hadoopCredentialEntryClz,
195 HADOOP_CRED_ENTRY_GET_CREDENTIAL_METHOD_NAME);
196 } catch (Exception e1) {
197 return false;
198 }
199
200 hadoopClassesAvailable = true;
201 LOG.info("Credential provider classes have been" +
202 " loaded and initialized successfully through reflection.");
203 return true;
204
205 }
206
207 private Method loadMethod(Class<?> clz, String name, Class<?>... classes)
208 throws Exception {
209 Method method = null;
210 try {
211 method = clz.getMethod(name, classes);
212 } catch (SecurityException e) {
213 fail("security exception caught for: " + name + " in " +
214 clz.getCanonicalName());
215 throw e;
216 } catch (NoSuchMethodException e) {
217 LOG.error("Failed to load the " + name + ": " + e);
218 fail("no such method: " + name + " in " + clz.getCanonicalName());
219 throw e;
220 }
221 return method;
222 }
223
224
225
226
227
228
229
230
231 @SuppressWarnings("unchecked")
232 protected List<Object> getCredentialProviders(Configuration conf) {
233
234 Object providersObj = null;
235 try {
236 providersObj = getProvidersMethod.invoke(hadoopCredProviderFactory,
237 conf);
238 } catch (IllegalArgumentException e) {
239 LOG.error("Failed to invoke: " + getProvidersMethod.getName() +
240 ": " + e);
241 return null;
242 } catch (IllegalAccessException e) {
243 LOG.error("Failed to invoke: " + getProvidersMethod.getName() +
244 ": " + e);
245 return null;
246 } catch (InvocationTargetException e) {
247 LOG.error("Failed to invoke: " + getProvidersMethod.getName() +
248 ": " + e);
249 return null;
250 }
251
252
253 try {
254 return (List<Object>) providersObj;
255 } catch (ClassCastException e) {
256 return null;
257 }
258 }
259
260
261
262
263
264
265
266
267
268
269
270
271 public void createEntry(Configuration conf, String name, char[] credential)
272 throws Exception {
273
274 if (!isHadoopCredentialProviderAvailable()) {
275 return;
276 }
277
278 List<Object> providers = getCredentialProviders(conf);
279 if (null == providers) {
280 throw new IOException("Could not fetch any CredentialProviders, " +
281 "is the implementation available?");
282 }
283
284 Object provider = providers.get(0);
285 createEntryInProvider(provider, name, credential);
286 }
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301 private void createEntryInProvider(Object credentialProvider,
302 String name, char[] credential) throws Exception {
303
304 if (!isHadoopCredentialProviderAvailable()) {
305 return;
306 }
307
308 try {
309 createCredentialEntryMethod.invoke(credentialProvider, name, credential);
310 } catch (IllegalArgumentException e) {
311 return;
312 } catch (IllegalAccessException e) {
313 return;
314 } catch (InvocationTargetException e) {
315 return;
316 }
317
318 try {
319 flushMethod.invoke(credentialProvider);
320 } catch (IllegalArgumentException e) {
321 throw e;
322 } catch (IllegalAccessException e) {
323 throw e;
324 } catch (InvocationTargetException e) {
325 throw e;
326 }
327 }
328 }
329 }