1
- // Copyright (c) 2017, 2023 , Oracle and/or its affiliates.
1
+ // Copyright (c) 2017, 2025 , Oracle and/or its affiliates.
2
2
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
3
3
4
4
package com .oracle .wls .exporter ;
5
5
6
6
import java .io .IOException ;
7
7
import java .io .PrintStream ;
8
+ import java .time .Duration ;
8
9
import java .time .OffsetDateTime ;
9
10
import java .util .ArrayList ;
11
+ import java .util .Collection ;
10
12
import java .util .Collections ;
11
13
import java .util .HashMap ;
12
14
import java .util .List ;
13
15
import java .util .Map ;
14
16
import java .util .Optional ;
17
+ import java .util .Set ;
15
18
import java .util .stream .Collectors ;
16
19
17
20
import com .oracle .wls .exporter .domain .MBeanSelector ;
@@ -38,11 +41,12 @@ public abstract class AuthenticatedCall {
38
41
* A map of authentication credentials to lists of cookies. The cookies will be sent on any request with
39
42
* the specified credentials.
40
43
*/
41
- private static final Map <String ,List < Cookie >> COOKIES = new HashMap <>();
44
+ private static final Map <String ,Map < String , Cookie >> COOKIES = new HashMap <>();
42
45
43
46
private final WebClientFactory webClientFactory ;
44
47
private final InvocationContext context ;
45
48
private final UrlBuilder urlBuilder ;
49
+ private static final List <Retry > callRetries = new ArrayList <>();
46
50
47
51
// For unit testing only
48
52
static void clearCookies () {
@@ -55,6 +59,10 @@ protected AuthenticatedCall(WebClientFactory webClientFactory, InvocationContext
55
59
this .urlBuilder = context .createUrlBuilder ();
56
60
}
57
61
62
+ public static int getRecentRetries () {
63
+ return callRetries .size ();
64
+ }
65
+
58
66
public String getAuthenticationUrl () {
59
67
return urlBuilder .createUrl (QueryType .RUNTIME_URL_PATTERN );
60
68
}
@@ -86,23 +94,25 @@ private void manageCookies(WebClient webClient) {
86
94
87
95
public List <String > getCookies (String credentials ) {
88
96
final OffsetDateTime now = SystemClock .now ();
89
- final List <Cookie > cookieList = getCookieList (credentials );
97
+ final Collection <Cookie > cookieList = getCookieList (credentials );
90
98
cookieList .removeIf (c -> c .isExpiredAt (now ));
91
99
92
100
return cookieList .stream ().map (Cookie ::getValue ).collect (Collectors .toList ());
93
101
}
94
102
95
- private List <Cookie > getCookieList (String credentials ) {
96
- return Optional .ofNullable (COOKIES .get (credentials )).orElse (Collections .emptyList ());
103
+ private Collection <Cookie > getCookieList (String credentials ) {
104
+ return Optional .ofNullable (COOKIES .get (credentials ))
105
+ .map (Map ::values )
106
+ .orElse (Collections .emptySet ());
97
107
}
98
108
99
109
void handleNewCookie (String cookieHeader ) {
100
110
if (context .getAuthenticationHeader () == null ) return ;
101
111
102
112
final Cookie cookie = new Cookie (cookieHeader );
103
113
COOKIES
104
- .computeIfAbsent (context .getAuthenticationHeader (), h -> new ArrayList <>())
105
- .add ( cookie );
114
+ .computeIfAbsent (context .getAuthenticationHeader (), h -> new HashMap <>())
115
+ .put ( cookie . getCookieName (), cookie );
106
116
}
107
117
108
118
private static class Cookie {
@@ -117,6 +127,13 @@ String getValue() {
117
127
return value ;
118
128
}
119
129
130
+ String getCookieName () {
131
+ if (!value .contains ("=" ))
132
+ return value ;
133
+ else
134
+ return value .substring (0 , value .indexOf ('=' ));
135
+ }
136
+
120
137
boolean isExpiredAt (OffsetDateTime now ) {
121
138
return now .isAfter (expirationTime );
122
139
}
@@ -184,9 +201,12 @@ public String getRequestContentType() {
184
201
185
202
186
203
private void performRequest (WebClient webClient ) throws IOException {
204
+ boolean retryNeeded ;
187
205
do {
188
206
invoke (webClient , context );
189
- } while (webClient .isRetryNeeded ());
207
+ retryNeeded = webClient .isRetryNeeded ();
208
+ if (retryNeeded ) addRetry ();
209
+ } while (retryNeeded );
190
210
}
191
211
192
212
private void reportUnableToContactRestApiPort (String uri ) throws IOException {
@@ -211,4 +231,20 @@ private void reportUnableToContactRestApiPort(String uri) throws IOException {
211
231
*/
212
232
protected abstract void invoke (WebClient webClient , InvocationContext context ) throws IOException ;
213
233
234
+ private void addRetry () {
235
+ callRetries .removeIf (Retry ::isObsolete );
236
+ callRetries .add (new Retry ());
237
+ }
238
+
239
+ private static class Retry {
240
+ private final OffsetDateTime time ;
241
+
242
+ Retry () {
243
+ this .time = SystemClock .now ();
244
+ }
245
+
246
+ private boolean isObsolete () {
247
+ return Duration .between (time , SystemClock .now ()).toMinutes () > 10 ;
248
+ }
249
+ }
214
250
}
0 commit comments