Skip to content

Commit 67720bd

Browse files
committed
HDFS-17606. Do not require implementing CustomizedCallbackHandler.
1 parent b5f8899 commit 67720bd

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocol/datatransfer/sasl/CustomizedCallbackHandler.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import javax.security.auth.callback.Callback;
2121
import javax.security.auth.callback.UnsupportedCallbackException;
2222
import java.io.IOException;
23+
import java.lang.reflect.InvocationTargetException;
24+
import java.lang.reflect.Method;
2325
import java.util.List;
2426

2527
/** For handling customized {@link Callback}. */
@@ -34,6 +36,24 @@ public void handleCallback(List<Callback> callbacks, String username, char[] pas
3436
}
3537
}
3638

39+
static CustomizedCallbackHandler delegate(Object delegated) {
40+
return (callbacks, name, password) -> {
41+
final String methodName = "handleCallback";
42+
final Class<?> clazz = delegated.getClass();
43+
final Method method;
44+
try {
45+
method = clazz.getMethod("handleCallback", List.class, String.class, char[].class);
46+
} catch (NoSuchMethodException e) {
47+
throw new IllegalStateException("Failed to get method " + methodName + " from " + clazz, e);
48+
}
49+
try {
50+
method.invoke(delegated, callbacks, name, password);
51+
} catch (IllegalAccessException | InvocationTargetException e) {
52+
throw new IOException("Failed to invoke " + method, e);
53+
}
54+
};
55+
}
56+
3757
void handleCallback(List<Callback> callbacks, String name, char[] password)
3858
throws UnsupportedCallbackException, IOException;
3959
}

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocol/datatransfer/sasl/SaslDataTransferServer.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,14 +225,20 @@ static final class SaslServerCallbackHandler
225225
SaslServerCallbackHandler(Configuration conf, PasswordFunction passwordFunction) {
226226
this.passwordFunction = passwordFunction;
227227

228-
final Class<? extends CustomizedCallbackHandler> clazz = conf.getClass(
228+
final Class<?> clazz = conf.getClass(
229229
HdfsClientConfigKeys.DFS_DATA_TRANSFER_SASL_CUSTOMIZEDCALLBACKHANDLER_CLASS_KEY,
230-
CustomizedCallbackHandler.DefaultHandler.class, CustomizedCallbackHandler.class);
230+
CustomizedCallbackHandler.DefaultHandler.class);
231+
final Object callbackHandler;
231232
try {
232-
this.customizedCallbackHandler = clazz.newInstance();
233+
callbackHandler = clazz.newInstance();
233234
} catch (Exception e) {
234235
throw new IllegalStateException("Failed to create a new instance of " + clazz, e);
235236
}
237+
if (callbackHandler instanceof CustomizedCallbackHandler) {
238+
customizedCallbackHandler = (CustomizedCallbackHandler) callbackHandler;
239+
} else {
240+
customizedCallbackHandler = CustomizedCallbackHandler.delegate(callbackHandler);
241+
}
236242
}
237243

238244
@Override

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/protocol/datatransfer/sasl/TestCustomizedCallbackHandler.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,30 @@ public void testCustomizedCallbackHandler() throws Exception {
6060
MyCallbackHandler.class, CustomizedCallbackHandler.class);
6161
new SaslServerCallbackHandler(conf, String::toCharArray).handle(callbacks);
6262
}
63+
64+
static class MyCallbackMethod {
65+
public void handleCallback(List<Callback> callbacks, String name, char[] password)
66+
throws UnsupportedCallbackException {
67+
LOG.info("{}: handling {} for {}", getClass().getSimpleName(), callbacks, name);
68+
}
69+
}
70+
71+
@Test
72+
public void testCustomizedCallbackMethod() throws Exception {
73+
final Configuration conf = new Configuration();
74+
final Callback[] callbacks = {new MyCallback()};
75+
76+
// without setting conf, expect UnsupportedCallbackException
77+
try {
78+
new SaslServerCallbackHandler(conf, String::toCharArray).handle(callbacks);
79+
Assert.fail("Expected UnsupportedCallbackException for " + Arrays.asList(callbacks));
80+
} catch (UnsupportedCallbackException e) {
81+
LOG.info("The failure is expected", e);
82+
}
83+
84+
// set conf and expect success
85+
conf.setClass(HdfsClientConfigKeys.DFS_DATA_TRANSFER_SASL_CUSTOMIZEDCALLBACKHANDLER_CLASS_KEY,
86+
MyCallbackMethod.class, Object.class);
87+
new SaslServerCallbackHandler(conf, String::toCharArray).handle(callbacks);
88+
}
6389
}

0 commit comments

Comments
 (0)