@@ -73,10 +73,18 @@ public class GrpcClient {
7373 private static final Logger logger = LoggerFactory .getLogger (GrpcClient .class );
7474
7575 private final long defaultTimeoutMs ;
76+
77+ public interface AuthProvider {
78+ CallCredentials refreshCredentials ();
79+ boolean requiresReauth (Throwable t );
80+ }
81+
82+ private static final AuthProvider NO_AUTH = new AuthProvider () {
83+ @ Override public boolean requiresReauth (Throwable t ) { return false ; }
84+ @ Override public CallCredentials refreshCredentials () { throw new IllegalStateException (); }
85+ };
7686
77- //TODO maybe combine these into an auth provider intface
78- private final Supplier <CallCredentials > refreshCreds ;
79- private final Predicate <Throwable > reauthRequired ;
87+ private final AuthProvider authProvider ;
8088
8189 private final ManagedChannel channel ;
8290
@@ -98,18 +106,37 @@ public class GrpcClient {
98106 // modified only by reauthenticate() method
99107 private CallOptions callOptions = CallOptions .DEFAULT ; // volatile tbd - lazy probably ok
100108
101-
102- //TODO whether some/all of the channel construction is moved in here
109+ /**
110+ * @deprecated use other constructor
111+ */
112+ @ Deprecated
103113 public GrpcClient (ManagedChannel channel ,
104114 Predicate <Throwable > reauthRequired ,
105115 Supplier <CallCredentials > credsSupplier ,
106116 ScheduledExecutorService executor , Condition isEventThread ,
107117 Executor userExecutor , boolean sendViaEventLoop , long defaultTimeoutMs ) {
108- Preconditions .checkArgument ((reauthRequired == null ) == (credsSupplier == null ),
109- "must supply both or neither reauth and creds" );
118+ this (channel , reauthRequired == null ? null : new AuthProvider () {
119+ {
120+ Preconditions .checkArgument ((reauthRequired == null ) == (credsSupplier == null ),
121+ "must supply both or neither reauth and creds" );
122+ }
123+ @ Override
124+ public boolean requiresReauth (Throwable t ) {
125+ return reauthRequired .apply (t );
126+ }
127+ @ Override
128+ public CallCredentials refreshCredentials () {
129+ return credsSupplier .get ();
130+ }
131+ }, executor , isEventThread , userExecutor , sendViaEventLoop , defaultTimeoutMs );
132+ }
133+
134+ //TODO whether some/all of the channel construction is moved in here
135+ public GrpcClient (ManagedChannel channel , AuthProvider authProvider ,
136+ ScheduledExecutorService executor , Condition isEventThread ,
137+ Executor userExecutor , boolean sendViaEventLoop , long defaultTimeoutMs ) {
110138 this .channel = channel ;
111- this .refreshCreds = credsSupplier ;
112- this .reauthRequired = reauthRequired ;
139+ this .authProvider = authProvider != null ? authProvider : NO_AUTH ;
113140 this .ses = MoreExecutors .listeningDecorator (executor );
114141 this .isEventThread = isEventThread ;
115142 this .userExecutor = userExecutor ;
@@ -138,9 +165,8 @@ public Executor getResponseExecutor() {
138165 }
139166
140167 public void authenticateNow () {
141- if (refreshCreds != null ) {
142- reauthenticate (getCallOptions ());
143- }
168+ assert authProvider != NO_AUTH ;
169+ reauthenticate (getCallOptions ());
144170 }
145171
146172 protected CallOptions getCallOptions () {
@@ -298,11 +324,11 @@ protected static boolean causedByJavaError(Throwable t) {
298324 * @return true if reauthentication was required and attempted
299325 */
300326 protected boolean reauthIfRequired (Throwable error , CallOptions callOpts ) {
301- if (reauthRequired == null || !reauthRequired .apply (error )) {
302- return false ;
327+ if (authProvider .requiresReauth (error )) {
328+ reauthenticate (callOpts );
329+ return true ;
303330 }
304- reauthenticate (callOpts );
305- return true ;
331+ return false ;
306332 }
307333
308334 public static boolean isConnectException (Throwable t ) {
@@ -321,7 +347,7 @@ private void reauthenticate(CallOptions failedOpts) {
321347 synchronized (this ) {
322348 CallOptions callOpts = getCallOptions ();
323349 if (callOpts == failedOpts ) {
324- callOptions = callOpts .withCallCredentials (refreshCreds . get ());
350+ callOptions = callOpts .withCallCredentials (authProvider . refreshCredentials ());
325351 }
326352 }
327353 }
@@ -335,7 +361,7 @@ public <ReqT,RespT> StreamObserver<ReqT> callStream(MethodDescriptor<ReqT,RespT>
335361 public <ReqT ,RespT > StreamObserver <ReqT > callStream (MethodDescriptor <ReqT ,RespT > method ,
336362 ResilientResponseObserver <ReqT ,RespT > respStream , Executor responseExecutor ) {
337363 // must explicitly auth in stream case to ensure unauthenticated version isn't used
338- if (refreshCreds != null && getCallOptions () == CallOptions .DEFAULT ) {
364+ if (authProvider != NO_AUTH && getCallOptions () == CallOptions .DEFAULT ) {
339365 // This will update callOptions with new CallCredentials prior to opening the stream
340366 authenticateNow ();
341367 }
@@ -551,8 +577,7 @@ private void onFinish(Throwable err) {
551577 // is required - instead just cancel the "current"
552578 // stream which will cause the top-level stream
553579 // to be refreshed after a reauth is done
554- if (err == null || reauthRequired == null
555- || !reauthRequired .apply (err )) {
580+ if (err == null || !authProvider .requiresReauth (err )) {
556581 error = err ;
557582 finished = true ;
558583 }
0 commit comments