@@ -131,8 +131,9 @@ private Connection connectInternal(String driverProtocol, HostSpec hostSpec, Pro
131131 port ,
132132 region );
133133 final TokenInfo tokenInfo = tokenCache .get (cacheKey );
134+ final boolean isCachedToken = tokenInfo != null && !tokenInfo .isExpired ();
134135
135- if (tokenInfo != null && ! tokenInfo . isExpired () ) {
136+ if (isCachedToken ) {
136137 LOGGER .finest (
137138 () -> Messages .get (
138139 "IamAuthConnectionPlugin.useCachedIamToken" ,
@@ -154,7 +155,47 @@ private Connection connectInternal(String driverProtocol, HostSpec hostSpec, Pro
154155 cacheKey ,
155156 new TokenInfo (token , Instant .now ().plus (tokenExpirationSec , ChronoUnit .SECONDS )));
156157 }
157- return connectFunc .call ();
158+
159+ try {
160+ return connectFunc .call ();
161+ } catch (final SQLException exception ) {
162+
163+ LOGGER .finest (
164+ () -> Messages .get (
165+ "IamAuthConnectionPlugin.connectException" ,
166+ new Object [] {exception }));
167+
168+ if (!this .pluginService .isLoginException (exception ) || !isCachedToken ) {
169+ throw exception ;
170+ }
171+
172+ // Login unsuccessful with cached token
173+ // Try to generate a new token and try to connect again
174+
175+ final String token = generateAuthenticationToken (
176+ hostSpec ,
177+ props ,
178+ host ,
179+ port ,
180+ region );
181+ LOGGER .finest (
182+ () -> Messages .get (
183+ "IamAuthConnectionPlugin.generatedNewIamToken" ,
184+ new Object [] {token }));
185+ PropertyDefinition .PASSWORD .set (props , token );
186+ tokenCache .put (
187+ cacheKey ,
188+ new TokenInfo (token , Instant .now ().plus (tokenExpirationSec , ChronoUnit .SECONDS )));
189+
190+ return connectFunc .call ();
191+
192+ } catch (final Exception exception ) {
193+ LOGGER .warning (
194+ () -> Messages .get (
195+ "IamAuthConnectionPlugin.unhandledException" ,
196+ new Object [] {exception }));
197+ throw new SQLException (exception );
198+ }
158199 }
159200
160201 @ Override
0 commit comments