139
139
import org .apache .hadoop .thirdparty .protobuf .Message ;
140
140
import org .slf4j .Logger ;
141
141
import org .slf4j .LoggerFactory ;
142
+ import org .apache .hadoop .security .AuthorizationContext ;
142
143
143
144
/** An abstract IPC service. IPC calls take a single {@link Writable} as a
144
145
* parameter, and return a {@link Writable} as their value. A service runs on
@@ -1004,6 +1005,7 @@ public static class Call implements Schedulable,
1004
1005
final byte [] clientId ;
1005
1006
private final Span span ; // the trace span on the server side
1006
1007
private final CallerContext callerContext ; // the call context
1008
+ private final byte [] authHeader ; // the auth header
1007
1009
private boolean deferredResponse = false ;
1008
1010
private int priorityLevel ;
1009
1011
// the priority level assigned by scheduler, 0 by default
@@ -1035,6 +1037,11 @@ public Call(int id, int retryCount, Void ignore1, Void ignore2,
1035
1037
1036
1038
Call (int id , int retryCount , RPC .RpcKind kind , byte [] clientId ,
1037
1039
Span span , CallerContext callerContext ) {
1040
+ this (id , retryCount , kind , clientId , span , callerContext , null );
1041
+ }
1042
+
1043
+ Call (int id , int retryCount , RPC .RpcKind kind , byte [] clientId ,
1044
+ Span span , CallerContext callerContext , byte [] authHeader ) {
1038
1045
this .callId = id ;
1039
1046
this .retryCount = retryCount ;
1040
1047
this .timestampNanos = Time .monotonicNowNanos ();
@@ -1043,6 +1050,7 @@ public Call(int id, int retryCount, Void ignore1, Void ignore2,
1043
1050
this .clientId = clientId ;
1044
1051
this .span = span ;
1045
1052
this .callerContext = callerContext ;
1053
+ this .authHeader = authHeader ;
1046
1054
this .clientStateId = Long .MIN_VALUE ;
1047
1055
this .isCallCoordinated = false ;
1048
1056
}
@@ -1243,7 +1251,14 @@ private class RpcCall extends Call {
1243
1251
RpcCall (Connection connection , int id , int retryCount ,
1244
1252
Writable param , RPC .RpcKind kind , byte [] clientId ,
1245
1253
Span span , CallerContext context ) {
1246
- super (id , retryCount , kind , clientId , span , context );
1254
+ this (connection , id , retryCount , param , kind , clientId ,
1255
+ span , context , new byte [0 ]);
1256
+ }
1257
+
1258
+ RpcCall (Connection connection , int id , int retryCount ,
1259
+ Writable param , RPC .RpcKind kind , byte [] clientId ,
1260
+ Span span , CallerContext context , byte [] authHeader ) {
1261
+ super (id , retryCount , kind , clientId , span , context , authHeader );
1247
1262
this .connection = connection ;
1248
1263
this .rpcRequest = param ;
1249
1264
}
@@ -2975,51 +2990,61 @@ private void processRpcRequest(RpcRequestHeaderProto header,
2975
2990
.build ();
2976
2991
}
2977
2992
2978
- RpcCall call = new RpcCall (this , header .getCallId (),
2979
- header .getRetryCount (), rpcRequest ,
2980
- ProtoUtil .convert (header .getRpcKind ()),
2981
- header .getClientId ().toByteArray (), span , callerContext );
2982
-
2983
- // Save the priority level assignment by the scheduler
2984
- call .setPriorityLevel (callQueue .getPriorityLevel (call ));
2985
- call .markCallCoordinated (false );
2986
- if (alignmentContext != null && call .rpcRequest != null &&
2987
- (call .rpcRequest instanceof ProtobufRpcEngine2 .RpcProtobufRequest )) {
2988
- // if call.rpcRequest is not RpcProtobufRequest, will skip the following
2989
- // step and treat the call as uncoordinated. As currently only certain
2990
- // ClientProtocol methods request made through RPC protobuf needs to be
2991
- // coordinated.
2992
- String methodName ;
2993
- String protoName ;
2994
- ProtobufRpcEngine2 .RpcProtobufRequest req =
2995
- (ProtobufRpcEngine2 .RpcProtobufRequest ) call .rpcRequest ;
2996
- try {
2997
- methodName = req .getRequestHeader ().getMethodName ();
2998
- protoName = req .getRequestHeader ().getDeclaringClassProtocolName ();
2999
- if (alignmentContext .isCoordinatedCall (protoName , methodName )) {
3000
- call .markCallCoordinated (true );
3001
- long stateId ;
3002
- stateId = alignmentContext .receiveRequestState (
3003
- header , getMaxIdleTime ());
3004
- call .setClientStateId (stateId );
3005
- if (header .hasRouterFederatedState ()) {
3006
- call .setFederatedNamespaceState (header .getRouterFederatedState ());
2993
+ // Set AuthorizationContext for this thread if present
2994
+ byte [] authHeader = null ;
2995
+ try {
2996
+ if (header .hasAuthorizationHeader ()) {
2997
+ authHeader = header .getAuthorizationHeader ().toByteArray ();
2998
+ }
2999
+
3000
+ RpcCall call = new RpcCall (this , header .getCallId (),
3001
+ header .getRetryCount (), rpcRequest ,
3002
+ ProtoUtil .convert (header .getRpcKind ()),
3003
+ header .getClientId ().toByteArray (), span , callerContext , authHeader );
3004
+
3005
+ // Save the priority level assignment by the scheduler
3006
+ call .setPriorityLevel (callQueue .getPriorityLevel (call ));
3007
+ call .markCallCoordinated (false );
3008
+ if (alignmentContext != null && call .rpcRequest != null &&
3009
+ (call .rpcRequest instanceof ProtobufRpcEngine2 .RpcProtobufRequest )) {
3010
+ // if call.rpcRequest is not RpcProtobufRequest, will skip the following
3011
+ // step and treat the call as uncoordinated. As currently only certain
3012
+ // ClientProtocol methods request made through RPC protobuf needs to be
3013
+ // coordinated.
3014
+ String methodName ;
3015
+ String protoName ;
3016
+ ProtobufRpcEngine2 .RpcProtobufRequest req =
3017
+ (ProtobufRpcEngine2 .RpcProtobufRequest ) call .rpcRequest ;
3018
+ try {
3019
+ methodName = req .getRequestHeader ().getMethodName ();
3020
+ protoName = req .getRequestHeader ().getDeclaringClassProtocolName ();
3021
+ if (alignmentContext .isCoordinatedCall (protoName , methodName )) {
3022
+ call .markCallCoordinated (true );
3023
+ long stateId ;
3024
+ stateId = alignmentContext .receiveRequestState (
3025
+ header , getMaxIdleTime ());
3026
+ call .setClientStateId (stateId );
3027
+ if (header .hasRouterFederatedState ()) {
3028
+ call .setFederatedNamespaceState (header .getRouterFederatedState ());
3029
+ }
3007
3030
}
3031
+ } catch (IOException ioe ) {
3032
+ throw new RpcServerException ("Processing RPC request caught " , ioe );
3008
3033
}
3009
- } catch (IOException ioe ) {
3010
- throw new RpcServerException ("Processing RPC request caught " , ioe );
3011
3034
}
3012
- }
3013
3035
3014
- try {
3015
- internalQueueCall (call );
3016
- } catch (RpcServerException rse ) {
3017
- throw rse ;
3018
- } catch (IOException ioe ) {
3019
- throw new FatalRpcServerException (
3020
- RpcErrorCodeProto .ERROR_RPC_SERVER , ioe );
3036
+ try {
3037
+ internalQueueCall (call );
3038
+ } catch (RpcServerException rse ) {
3039
+ throw rse ;
3040
+ } catch (IOException ioe ) {
3041
+ throw new FatalRpcServerException (
3042
+ RpcErrorCodeProto .ERROR_RPC_SERVER , ioe );
3043
+ }
3044
+ incRpcCount (); // Increment the rpc count
3045
+ } finally {
3046
+ AuthorizationContext .clear ();
3021
3047
}
3022
- incRpcCount (); // Increment the rpc count
3023
3048
}
3024
3049
3025
3050
/**
@@ -3245,6 +3270,7 @@ public void run() {
3245
3270
}
3246
3271
// always update the current call context
3247
3272
CallerContext .setCurrent (call .callerContext );
3273
+ AuthorizationContext .setCurrentAuthorizationHeader (call .authHeader );
3248
3274
UserGroupInformation remoteUser = call .getRemoteUser ();
3249
3275
connDropped = !call .isOpen ();
3250
3276
if (remoteUser != null ) {
0 commit comments