@@ -44,19 +44,57 @@ public class DefaultCredentialsRefreshService implements CredentialsRefreshServi
44
44
45
45
private static final Logger LOGGER = LoggerFactory .getLogger (DefaultCredentialsRefreshService .class );
46
46
47
+ /**
48
+ * Scheduler used to schedule credentials refresh.
49
+ * <p>
50
+ * Default is a single-threaded scheduler, which should be enough for most scenarios, assuming
51
+ * that credentials expire after a few minutes or hours. This default scheduler
52
+ * is automatically disposed of when the {@link DefaultCredentialsRefreshService} is closed.
53
+ * <p>
54
+ * If an external scheduler is passed in, it is the developer's responsibility to
55
+ * close it.
56
+ */
47
57
private final ScheduledExecutorService scheduler ;
48
58
49
59
private final ConcurrentMap <CredentialsProvider , CredentialsProviderState > credentialsProviderStates = new ConcurrentHashMap <>();
50
60
51
61
private final boolean privateScheduler ;
52
62
63
+ /**
64
+ * Strategy to schedule credentials refresh after credentials retrieval.
65
+ * <p>
66
+ * Typical strategies schedule refresh after a ratio of the time before expiration
67
+ * (e.g. 80 % of the time before expiration) or after a fixed time before
68
+ * expiration (e.g. 20 seconds before credentials expire).
69
+ *
70
+ * @see #ratioRefreshDelayStrategy(double)
71
+ * @see #fixedDelayBeforeExpirationRefreshDelayStrategy(Duration)
72
+ */
53
73
private final Function <Duration , Duration > refreshDelayStrategy ;
54
74
55
- private final Function <Duration , Boolean > needRefreshStrategy ;
75
+ /**
76
+ * Strategy to provide a hint about whether credentials should be renewed now or not before attempting to connect.
77
+ * <p>
78
+ * This can avoid a connection to use almost expired credentials if this connection
79
+ * is created just before credentials are refreshed in the background, but does not
80
+ * benefit from the refresh.
81
+ * <p>
82
+ * Note setting such a strategy may require knowledge of the credentials validity and must be consistent
83
+ * with the {@link #refreshDelayStrategy} chosen. For example, for a validity of 60 minutes and
84
+ * a {@link #refreshDelayStrategy} that instructs to refresh 10 minutes before credentials expire, this
85
+ * strategy could hint that credentials that expire in 11 minutes or less (1 minute before a refresh is actually
86
+ * scheduled) should be refreshed, which would trigger an early refresh.
87
+ * <p>
88
+ * The default strategy always return false.
89
+ */
90
+ private final Function <Duration , Boolean > approachingExpirationStrategy ;
56
91
57
- public DefaultCredentialsRefreshService (ScheduledExecutorService scheduler , Function <Duration , Duration > refreshDelayStrategy , Function <Duration , Boolean > needRefreshStrategy ) {
92
+ public DefaultCredentialsRefreshService (ScheduledExecutorService scheduler , Function <Duration , Duration > refreshDelayStrategy , Function <Duration , Boolean > approachingExpirationStrategy ) {
93
+ if (refreshDelayStrategy == null ) {
94
+ throw new IllegalArgumentException ("Refresh delay strategy can not be null" );
95
+ }
58
96
this .refreshDelayStrategy = refreshDelayStrategy ;
59
- this .needRefreshStrategy = needRefreshStrategy ;
97
+ this .approachingExpirationStrategy = approachingExpirationStrategy == null ? duration -> false : approachingExpirationStrategy ;
60
98
if (scheduler == null ) {
61
99
this .scheduler = Executors .newScheduledThreadPool (1 );
62
100
privateScheduler = true ;
@@ -69,8 +107,8 @@ public DefaultCredentialsRefreshService(ScheduledExecutorService scheduler, Func
69
107
/**
70
108
* Delay before refresh is a ratio of the time before expiration.
71
109
* <p>
72
- * E.g. if time before expiration is 60 seconds and specified ratio is 0.8, refresh will
73
- * be scheduled in 60 x 0.8 = 48 seconds .
110
+ * E.g. if time before expiration is 60 minutes and specified ratio is 0.8, refresh will
111
+ * be scheduled in 60 x 0.8 = 48 minutes .
74
112
*
75
113
* @param ratio
76
114
* @return the delay before refreshing
@@ -82,8 +120,8 @@ public static Function<Duration, Duration> ratioRefreshDelayStrategy(double rati
82
120
/**
83
121
* Delay before refresh is <code>time before expiration - specified duration</code>.
84
122
* <p>
85
- * E.g. if time before expiration is 60 seconds and specified duration is 20 seconds , refresh will
86
- * be scheduled in 60 - 20 = 40 seconds .
123
+ * E.g. if time before expiration is 60 minutes and specified duration is 10 minutes , refresh will
124
+ * be scheduled in 60 - 10 = 50 minutes .
87
125
*
88
126
* @param duration
89
127
* @return the delay before refreshing
@@ -98,8 +136,8 @@ public static Function<Duration, Duration> fixedDelayBeforeExpirationRefreshDela
98
136
* @param limitBeforeExpiration
99
137
* @return true if credentials should be refreshed, false otherwise
100
138
*/
101
- public static Function <Duration , Boolean > fixedTimeNeedRefreshStrategy (Duration limitBeforeExpiration ) {
102
- return new FixedTimeNeedRefreshStrategy (limitBeforeExpiration .toMillis ());
139
+ public static Function <Duration , Boolean > fixedTimeApproachingExpirationStrategy (Duration limitBeforeExpiration ) {
140
+ return new FixedTimeApproachingExpirationStrategy (limitBeforeExpiration .toMillis ());
103
141
}
104
142
105
143
private static Runnable refresh (ScheduledExecutorService scheduler , CredentialsProviderState credentialsProviderState ,
@@ -157,8 +195,8 @@ public void unregister(CredentialsProvider credentialsProvider, String registrat
157
195
}
158
196
159
197
@ Override
160
- public boolean needRefresh (Duration timeBeforeExpiration ) {
161
- return this .needRefreshStrategy .apply (timeBeforeExpiration );
198
+ public boolean isApproachingExpiration (Duration timeBeforeExpiration ) {
199
+ return this .approachingExpirationStrategy .apply (timeBeforeExpiration );
162
200
}
163
201
164
202
public void close () {
@@ -167,11 +205,11 @@ public void close() {
167
205
}
168
206
}
169
207
170
- private static class FixedTimeNeedRefreshStrategy implements Function <Duration , Boolean > {
208
+ private static class FixedTimeApproachingExpirationStrategy implements Function <Duration , Boolean > {
171
209
172
210
private final long limitBeforeExpiration ;
173
211
174
- private FixedTimeNeedRefreshStrategy (long limitBeforeExpiration ) {
212
+ private FixedTimeApproachingExpirationStrategy (long limitBeforeExpiration ) {
175
213
this .limitBeforeExpiration = limitBeforeExpiration ;
176
214
}
177
215
@@ -340,7 +378,7 @@ public static class DefaultCredentialsRefreshServiceBuilder {
340
378
341
379
private Function <Duration , Duration > refreshDelayStrategy = ratioRefreshDelayStrategy (0.8 );
342
380
343
- private Function <Duration , Boolean > needRefreshStrategy = ttl -> false ;
381
+ private Function <Duration , Boolean > approachingExpirationStrategy = ttl -> false ;
344
382
345
383
public DefaultCredentialsRefreshServiceBuilder scheduler (ScheduledThreadPoolExecutor scheduler ) {
346
384
this .scheduler = scheduler ;
@@ -352,13 +390,13 @@ public DefaultCredentialsRefreshServiceBuilder refreshDelayStrategy(Function<Dur
352
390
return this ;
353
391
}
354
392
355
- public DefaultCredentialsRefreshServiceBuilder needRefreshStrategy (Function <Duration , Boolean > needRefreshStrategy ) {
356
- this .needRefreshStrategy = needRefreshStrategy ;
393
+ public DefaultCredentialsRefreshServiceBuilder approachingExpirationStrategy (Function <Duration , Boolean > approachingExpirationStrategy ) {
394
+ this .approachingExpirationStrategy = approachingExpirationStrategy ;
357
395
return this ;
358
396
}
359
397
360
398
public DefaultCredentialsRefreshService build () {
361
- return new DefaultCredentialsRefreshService (scheduler , refreshDelayStrategy , needRefreshStrategy );
399
+ return new DefaultCredentialsRefreshService (scheduler , refreshDelayStrategy , approachingExpirationStrategy );
362
400
}
363
401
364
402
}
0 commit comments