Skip to content

Commit

Permalink
Issue #35: UnknownhostException should be retried (#36)
Browse files Browse the repository at this point in the history
This PR fixes #35

As described in the proposed solution in issue35, this adds UnkownhostException the predicate that decides what is a retryable exception.
  • Loading branch information
sarlaccpit authored Feb 25, 2021
1 parent ea0c29a commit 11e9386
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import java.io.IOException;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -138,7 +139,7 @@ private static Predicate<Throwable> isRetryable() {
LOG.warn("Retryable HttpResponseException with HTTP code: {}", statusCode);
return true;
}
} else if (rootCause instanceof ConnectException) {
} else if (rootCause instanceof ConnectException || rootCause instanceof UnknownHostException) {
LOG.warn("Retryable connection exception", rootCause);
return true;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
Expand All @@ -45,7 +46,6 @@
public class KeycloakAuthzClientTest {
private static final String SVC_ACCOUNT_JSON_FILE = getResourceFile("service-account.json");
private static final String SVC_ACCOUNT_JSON_STRING = getResourceString(getResourceFile("service-account.json"));
private static final AccessTokenIssuer ISSUER = new AccessTokenIssuer();

@Test
public void getRPTCacheHits() {
Expand Down Expand Up @@ -106,49 +106,22 @@ public void getRPTCannotExchangeAccessTokenForRPT() {

@Test
public void getRPTWithHttp500Exception() {
AuthzClient client = mock(AuthzClient.class, Mockito.RETURNS_DEEP_STUBS);
TokenCache tokenCache = spy(new TokenCache(0));

when(client.obtainAccessToken()).thenThrow(new HttpResponseException("", 500, "", null));
KeycloakAuthzClient authzClient = new KeycloakAuthzClient(client, tokenCache, 3, 1);
try {
authzClient.getRPT();
Assert.fail();
} catch (RetriesExhaustedException e) {
}
verify(client, times(3)).obtainAccessToken();
assertRetried(new HttpResponseException("", 500, "", null), 3);
}

@Test
public void getRPTWithRuntimeConnectException() {
AuthzClient client = mock(AuthzClient.class, Mockito.RETURNS_DEEP_STUBS);
TokenCache tokenCache = spy(new TokenCache(0));
assertRetried(new RuntimeException(new ConnectException()), 3);
}

when(client.obtainAccessToken()).thenThrow(new RuntimeException(new ConnectException()));
KeycloakAuthzClient authzClient = new KeycloakAuthzClient(client, tokenCache, 3, 1);
try {
authzClient.getRPT();
Assert.fail();
} catch (RetriesExhaustedException e) {
}
verify(client, times(3)).obtainAccessToken();
@Test
public void getRPTWithRuntimeUnknownHostException() {
assertRetried(new RuntimeException(new UnknownHostException()), 3);
}

@Test
public void getRPTWithRandomRuntimeException() {
AuthzClient client = mock(AuthzClient.class, Mockito.RETURNS_DEEP_STUBS);
TokenCache tokenCache = spy(new TokenCache(0));

when(client.obtainAccessToken()).thenThrow(new RuntimeException("bogus"));
KeycloakAuthzClient authzClient = new KeycloakAuthzClient(client, tokenCache, 3, 1);
try {
authzClient.getRPT();
Assert.fail();
} catch (RetriesExhaustedException e) {
Assert.fail();
} catch (RuntimeException e) {
}
verify(client, times(1)).obtainAccessToken();
assertRetried(new RuntimeException("bogus"), 1);
}

@Test
Expand Down Expand Up @@ -242,6 +215,21 @@ public void checkDeserializeToken() {
assertEquals(token.getPreferredUsername(), "user-1");
}

private void assertRetried(Exception ex, int retries) {
AuthzClient client = mock(AuthzClient.class, Mockito.RETURNS_DEEP_STUBS);
TokenCache tokenCache = spy(new TokenCache(0));

when(client.obtainAccessToken()).thenThrow(ex);
KeycloakAuthzClient authzClient = new KeycloakAuthzClient(client, tokenCache, 3, 1);
try {
authzClient.getRPT();
Assert.fail();
} catch (RetriesExhaustedException e) {
} catch (RuntimeException e) {
}
verify(client, times(retries)).obtainAccessToken();
}

private AccessTokenResponse accessTokenResponse() {
AccessTokenResponse acr = new AccessTokenResponse();
acr.setToken("TOKEN");
Expand Down

0 comments on commit 11e9386

Please sign in to comment.