Skip to content

Commit

Permalink
Keycloak DevService: Improve error messages and documentation for cli…
Browse files Browse the repository at this point in the history
…ent timeouts

We used to experience a lot of flakiness due to the keycloak devservice starting,
but doing so with errors and therefore causing all tests that were running
with keycloak to emit 'IllegalArgument accessToken cannot be null'.
The start-up errors were a bit cryptic and unspecific and looked like this:

    2023-11-06 08:01:14,552 INFO  [tc.doc.xxx.0.1] (build-7) Container ourrepomirror.docker/keycloak/keycloak:22.0.1 started in PT3M46.054007184S
    2023-11-06 08:01:18,712 ERROR [io.qua.oid.dep.dev.key.KeycloakDevServicesProcessor] (build-7) Admin token can not be acquired: null
    2023-11-06 08:01:19,655 ERROR [io.qua.oid.dep.dev.key.KeycloakDevServicesProcessor] (build-7) Realm rdpro can not be created 401 - Unauthorized
    2023-11-06 08:01:27,690 ERROR [io.qua.oid.dep.dev.key.KeycloakDevServicesProcessor] (build-7) Realm rdpro can not be created: Keycloak server is not available: Retries exhausted : 5 attempts against 1699257689687/1699257689656 expiration
    2023-11-06 08:01:27,699 INFO  [io.qua.oid.dep.dev.key.KeycloakDevServicesProcessor] (build-7) Dev Services for Keycloak started.

It took us some time to realize that `Admin token can not be acquired: null` actually meant
'Acquiring the Admin token timed out' and that 'null' was the TimeoutException's message.
Thankfully the property `quarkus.oidc.devui.web-client-timeout` exists to increase this timeout,
though it is somewhat oddly named ("devui"?).

I tried to improve the situation by making errors actually print the exception and stacktrace,
and by improving the user feedback a bit.
  • Loading branch information
Felk committed Nov 6, 2023
1 parent 2776bde commit 77fcb1f
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public String getGrantType() {
* The WebClient timeout.
* Use this property to configure how long an HTTP client used by Dev UI handlers will wait for a response when requesting
* tokens from OpenId Connect Provider and sending them to the service endpoint.
* This timeout is also used by the OIDC dev service admin client.
*/
@ConfigItem(defaultValue = "4S")
public Duration webClientTimeout;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.function.Supplier;
import java.util.stream.Collectors;

import io.smallrye.mutiny.TimeoutException;
import org.eclipse.microprofile.config.ConfigProvider;
import org.jboss.logging.Logger;
import org.keycloak.representations.idm.ClientRepresentation;
Expand Down Expand Up @@ -626,8 +627,11 @@ private String getAdminToken(WebClient client, String keycloakUrl) {
keycloakUrl + "/realms/master/protocol/openid-connect/token",
"admin-cli", null, "admin", "admin", null)
.await().atMost(oidcConfig.devui.webClientTimeout);
} catch (TimeoutException e) {
LOG.error("Admin token can not be acquired due to a client connection timeout. " +
"You may try increasing the `quarkus.oidc.devui.web-client-timeout` property.");
} catch (Throwable t) {
LOG.errorf("Admin token can not be acquired: %s", t.getMessage());
LOG.error("Admin token can not be acquired", t);
}
return null;
}
Expand Down Expand Up @@ -673,7 +677,7 @@ private void createRealm(WebClient client, String token, String keycloakUrl, Rea
} catch (Throwable t) {
errors.add(String.format("Realm %s can not be created: %s", realm.getRealm(), t.getMessage()));

LOG.errorf("Realm %s can not be created: %s", realm.getRealm(), t.getMessage());
LOG.errorf(t, "Realm %s can not be created", realm.getRealm());
}
}

Expand Down

0 comments on commit 77fcb1f

Please sign in to comment.