2020import org .apache .hadoop .conf .Configuration ;
2121import org .apache .hadoop .hdfs .client .HdfsClientConfigKeys ;
2222import org .apache .hadoop .hdfs .protocol .datatransfer .sasl .SaslDataTransferServer .SaslServerCallbackHandler ;
23+ import org .apache .hadoop .test .LambdaTestUtils ;
2324import org .junit .Assert ;
2425import org .junit .Test ;
2526import org .slf4j .Logger ;
2627import org .slf4j .LoggerFactory ;
2728
2829import javax .security .auth .callback .Callback ;
2930import javax .security .auth .callback .UnsupportedCallbackException ;
30- import java .util . Arrays ;
31+ import java .io . IOException ;
3132import java .util .List ;
33+ import java .util .concurrent .atomic .AtomicReference ;
3234
35+ /** For testing {@link CustomizedCallbackHandler}. */
3336public class TestCustomizedCallbackHandler {
34- public static final Logger LOG = LoggerFactory .getLogger (TestCustomizedCallbackHandler .class );
37+ static final Logger LOG = LoggerFactory .getLogger (TestCustomizedCallbackHandler .class );
38+
39+ static final AtomicReference <List <Callback >> LAST_CALLBACKS = new AtomicReference <>();
40+
41+ static void runHandleCallbacks (Object caller , List <Callback > callbacks , String name ) {
42+ LOG .info ("{}: handling {} for {}" , caller .getClass ().getSimpleName (), callbacks , name );
43+ LAST_CALLBACKS .set (callbacks );
44+ }
45+
46+ /** Assert if the callbacks in {@link #LAST_CALLBACKS} are the same as the expected callbacks. */
47+ static void assertCallbacks (Callback [] expected ) {
48+ final List <Callback > computed = LAST_CALLBACKS .getAndSet (null );
49+ Assert .assertNotNull (computed );
50+ Assert .assertEquals (expected .length , computed .size ());
51+ for (int i = 0 ; i < expected .length ; i ++) {
52+ Assert .assertSame (expected [i ], computed .get (i ));
53+ }
54+ }
3555
3656 static class MyCallback implements Callback { }
3757
3858 static class MyCallbackHandler implements CustomizedCallbackHandler {
3959 @ Override
40- public void handleCallback (List <Callback > callbacks , String name , char [] password ) {
41- LOG . info ( "{}: handling {} for {}" , getClass (). getSimpleName () , callbacks , name );
60+ public void handleCallbacks (List <Callback > callbacks , String name , char [] password ) {
61+ runHandleCallbacks ( this , callbacks , name );
4262 }
4363 }
4464
@@ -48,16 +68,52 @@ public void testCustomizedCallbackHandler() throws Exception {
4868 final Callback [] callbacks = {new MyCallback ()};
4969
5070 // without setting conf, expect UnsupportedCallbackException
51- try {
52- new SaslServerCallbackHandler (conf , String ::toCharArray ).handle (callbacks );
53- Assert .fail ("Expected UnsupportedCallbackException for " + Arrays .asList (callbacks ));
54- } catch (UnsupportedCallbackException e ) {
55- LOG .info ("The failure is expected" , e );
56- }
71+ LambdaTestUtils .intercept (UnsupportedCallbackException .class , () -> runTest (conf , callbacks ));
5772
5873 // set conf and expect success
5974 conf .setClass (HdfsClientConfigKeys .DFS_DATA_TRANSFER_SASL_CUSTOMIZEDCALLBACKHANDLER_CLASS_KEY ,
6075 MyCallbackHandler .class , CustomizedCallbackHandler .class );
6176 new SaslServerCallbackHandler (conf , String ::toCharArray ).handle (callbacks );
77+ assertCallbacks (callbacks );
78+ }
79+
80+ static class MyCallbackMethod {
81+ public void handleCallbacks (List <Callback > callbacks , String name , char [] password )
82+ throws UnsupportedCallbackException {
83+ runHandleCallbacks (this , callbacks , name );
84+ }
85+ }
86+
87+ static class MyExceptionMethod {
88+ public void handleCallbacks (List <Callback > callbacks , String name , char [] password )
89+ throws UnsupportedCallbackException {
90+ runHandleCallbacks (this , callbacks , name );
91+ throw new UnsupportedCallbackException (callbacks .get (0 ));
92+ }
93+ }
94+
95+ @ Test
96+ public void testCustomizedCallbackMethod () throws Exception {
97+ final Configuration conf = new Configuration ();
98+ final Callback [] callbacks = {new MyCallback ()};
99+
100+ // without setting conf, expect UnsupportedCallbackException
101+ LambdaTestUtils .intercept (UnsupportedCallbackException .class , () -> runTest (conf , callbacks ));
102+
103+ // set conf and expect success
104+ conf .setClass (HdfsClientConfigKeys .DFS_DATA_TRANSFER_SASL_CUSTOMIZEDCALLBACKHANDLER_CLASS_KEY ,
105+ MyCallbackMethod .class , Object .class );
106+ new SaslServerCallbackHandler (conf , String ::toCharArray ).handle (callbacks );
107+ assertCallbacks (callbacks );
108+
109+ // set conf and expect exception
110+ conf .setClass (HdfsClientConfigKeys .DFS_DATA_TRANSFER_SASL_CUSTOMIZEDCALLBACKHANDLER_CLASS_KEY ,
111+ MyExceptionMethod .class , Object .class );
112+ LambdaTestUtils .intercept (IOException .class , () -> runTest (conf , callbacks ));
113+ }
114+
115+ static void runTest (Configuration conf , Callback ... callbacks )
116+ throws IOException , UnsupportedCallbackException {
117+ new SaslServerCallbackHandler (conf , String ::toCharArray ).handle (callbacks );
62118 }
63119}
0 commit comments