diff --git a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/AbstractHTTPFunction.java b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/AbstractHTTPFunction.java index b8830058..1b6678f4 100644 --- a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/AbstractHTTPFunction.java +++ b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/AbstractHTTPFunction.java @@ -82,6 +82,15 @@ public AbstractHTTPFunction() { allowedDomains = ConfigProvider.getInstance().getAllowedDomainsForHttpFunctions(); } + public enum RetryDecision { + RETRY, + NO_RETRY; + + public boolean shouldRetry() { + return this == RETRY; + } + } + protected void executeHttpMethod(HttpUriRequest clientRequest, Map eventHandlers, AuthConfigModel authConfigModel) { @@ -107,9 +116,9 @@ protected void executeHttpMethod(HttpUriRequest clientRequest, Map> result = executeRequest(request, endpointURL); - if (Boolean.TRUE.equals(result.getLeft())) { - LOG.error("Error while calling endpoint. Url: " + endpointURL); + Pair> result = executeRequest(request, endpointURL); + if (result.getLeft().shouldRetry()) { + LOG.info("Failed to invoke the endpoint. Url: " + endpointURL + ". Retrying the request."); result = executeRequestWithRetries(request, endpointURL, requestRetryCount); } outcome = result.getRight().getLeft(); @@ -132,13 +141,13 @@ protected void executeHttpMethod(HttpUriRequest clientRequest, Map> executeRequestWithRetries + private Pair> executeRequestWithRetries (HttpUriRequest request, String endpointURL, int maxRetries) { - Pair> result; + Pair> result; String outcome = Constants.OUTCOME_FAIL; int attempts = 0; - boolean isRetry = false; + RetryDecision isRetry = RetryDecision.NO_RETRY; while (attempts < maxRetries) { attempts++; @@ -156,7 +165,7 @@ protected void executeHttpMethod(HttpUriRequest clientRequest, Map> executeRequest(HttpUriRequest request, String endpointURL) { + private Pair> executeRequest(HttpUriRequest request, String endpointURL) { JSONObject json = null; String outcome; - boolean isRetry = false; + RetryDecision isRetry = RetryDecision.NO_RETRY; try (CloseableHttpResponse response = client.execute(request)) { int responseCode = response.getStatusLine().getStatusCode(); @@ -203,7 +212,7 @@ private Pair> executeRequest(HttpUriRequest re LOG.info("Successfully called the external api. Status code: " + responseCode + ". Url: " + endpointURL); outcome = Constants.OUTCOME_SUCCESS; - return Pair.of(false, Pair.of(outcome, json)); // Success, return immediately + return Pair.of(RetryDecision.NO_RETRY, Pair.of(outcome, json)); // Success, return immediately } else if (responseCode >= 300 && responseCode < 400) { if (LoggerUtils.isDiagnosticLogsEnabled()) { DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new @@ -219,7 +228,7 @@ private Pair> executeRequest(HttpUriRequest re LOG.warn("External api invocation returned a redirection. Status code: " + responseCode + ". Url: " + endpointURL); outcome = Constants.OUTCOME_FAIL; - return Pair.of(false, Pair.of(outcome, null)); // Unauthorized, no retry + return Pair.of(RetryDecision.NO_RETRY, Pair.of(outcome, null)); // Unauthorized, no retry } else if (responseCode >= 400 && responseCode < 500) { if (LoggerUtils.isDiagnosticLogsEnabled()) { DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new @@ -235,7 +244,7 @@ private Pair> executeRequest(HttpUriRequest re LOG.warn("External api invocation returned a client error. Status code: " + responseCode + ". Url: " + endpointURL); outcome = Constants.OUTCOME_FAIL; - return Pair.of(false, Pair.of(outcome, null)); // Unauthorized, no retry + return Pair.of(RetryDecision.NO_RETRY, Pair.of(outcome, null)); // Unauthorized, no retry } else { if (LoggerUtils.isDiagnosticLogsEnabled()) { DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new @@ -251,7 +260,7 @@ private Pair> executeRequest(HttpUriRequest re LOG.error("Received unknown response from external API call. Status code: " + responseCode + ". Url: " + endpointURL); outcome = Constants.OUTCOME_FAIL; - return Pair.of(true, Pair.of(outcome, null)); // Server error, retry if attempts left + return Pair.of(RetryDecision.RETRY, Pair.of(outcome, null)); // Server error, retry if attempts left } } catch (Exception e) { // Log the error based on its type @@ -279,12 +288,11 @@ private Pair> executeRequest(HttpUriRequest re .resultStatus(DiagnosticLog.ResultStatus.FAILED); LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); } - isRetry = true; // Timeout, retry if attempts left + isRetry = RetryDecision.RETRY; // Timeout, retry if attempts left outcome = Constants.OUTCOME_TIMEOUT; LOG.error("Error while waiting to connect to " + endpointURL, e); } else if (e instanceof IOException) { - isRetry = true; // Timeout, retry if attempts left - outcome = Constants.OUTCOME_TIMEOUT; + outcome = Constants.OUTCOME_FAIL; LOG.error("Error while calling endpoint. ", e); } else if (e instanceof ParseException) { if (LoggerUtils.isDiagnosticLogsEnabled()) { @@ -297,7 +305,6 @@ private Pair> executeRequest(HttpUriRequest re .resultStatus(DiagnosticLog.ResultStatus.FAILED); LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); } - isRetry = true; // Timeout, retry if attempts left outcome = Constants.OUTCOME_FAIL; LOG.error("Error while parsing response. ", e); } else { @@ -311,7 +318,6 @@ private Pair> executeRequest(HttpUriRequest re .resultStatus(DiagnosticLog.ResultStatus.FAILED); LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); } - isRetry = true; // Timeout, retry if attempts left outcome = Constants.OUTCOME_FAIL; LOG.error("Error while calling endpoint. ", e); } diff --git a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPGetFunctionImpl.java b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPGetFunctionImpl.java index 0b3bf478..f8aa1fb9 100644 --- a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPGetFunctionImpl.java +++ b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPGetFunctionImpl.java @@ -69,13 +69,13 @@ public void httpGet(String endpointURL, Object... params) { authConfig = getAuthConfigModel((Map) params[1]); eventHandlers = (Map) params[2]; } else { - throw new IllegalArgumentException("Invalid argument type. Expected payloadData " + - "(Map), headers (Map), and eventHandlers " + - "(Map) respectively."); + throw new IllegalArgumentException("Invalid argument type. Expected " + + "headers (Map), authConfig (Map)," + + " and eventHandlers (Map) respectively."); } break; default: - throw new IllegalArgumentException("Invalid number of arguments. Expected 1 or 2, but got: " + + throw new IllegalArgumentException("Invalid number of arguments. Expected 1, 2 or 3, but got: " + params.length + "."); } diff --git a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPPostFunctionImpl.java b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPPostFunctionImpl.java index faf961f5..e5f7ab9a 100644 --- a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPPostFunctionImpl.java +++ b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPPostFunctionImpl.java @@ -95,12 +95,12 @@ public void httpPost(String endpointURL, Object... params) { eventHandlers = (Map) params[3]; } else { throw new IllegalArgumentException("Invalid argument type. Expected payloadData " + - "(Map), headers (Map), and eventHandlers " + - "(Map) respectively."); + "(Map), headers (Map), authConfig (Map)," + + " and eventHandlers (Map) respectively."); } break; default: - throw new IllegalArgumentException("Invalid number of arguments. Expected 1, 2, or 3. Found: " + throw new IllegalArgumentException("Invalid number of arguments. Expected 1, 2, 3, or 4. Found: " + params.length + "."); } diff --git a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/util/ClientCredentialAuthConfig.java b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/util/ClientCredentialAuthConfig.java index 758bd1f6..e8732aa4 100644 --- a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/util/ClientCredentialAuthConfig.java +++ b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/util/ClientCredentialAuthConfig.java @@ -20,10 +20,11 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; +import com.nimbusds.jwt.SignedJWT; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.nimbusds.jwt.SignedJWT; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; @@ -50,12 +51,15 @@ import java.text.ParseException; import java.time.LocalDateTime; import java.time.ZoneId; -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; import static org.apache.http.HttpHeaders.ACCEPT; import static org.apache.http.HttpHeaders.CONTENT_TYPE; -import static org.wso2.carbon.identity.conditional.auth.functions.common.utils.CommonUtils.*; import static org.wso2.carbon.identity.conditional.auth.functions.common.utils.Constants.OUTCOME_FAIL; /** @@ -129,6 +133,15 @@ public String getScopes() { return scopes; } + public enum RetryDecision { + RETRY, + NO_RETRY; + + public boolean shouldRetry() { + return this == RETRY; + } + } + @Override public HttpUriRequest applyAuth(HttpUriRequest request, AuthConfigModel authConfigModel) throws FrameworkException { @@ -216,35 +229,29 @@ private String getAccessToken() throws FrameworkException { // Attempt the first request for an access token LOG.info("Attempting initial access token request for session data key: " + authenticationContext.getContextIdentifier()); - accessToken = requestAccessToken(); // Attempt to request a new token - if (accessToken != null) { - return accessToken; - } - if (LoggerUtils.isDiagnosticLogsEnabled()) { - DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new - DiagnosticLog.DiagnosticLogBuilder(Constants.LogConstants.ADAPTIVE_AUTH_SERVICE, - Constants.LogConstants.ActionIDs.RECEIVE_TOKEN); - diagnosticLogBuilder.inputParam(Constants.LogConstants.InputKeys.TOKEN_ENDPOINT, getTokenEndpoint()) - .configParam(Constants.LogConstants.ConfigKeys.SUPPORTED_GRANT_TYPES, - GRANT_TYPE_CLIENT_CREDENTIALS) - .resultMessage("Initial request failed, proceeding with retry attempts.") - .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) - .resultStatus(DiagnosticLog.ResultStatus.FAILED); - LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); + Pair retryDecision = requestAccessToken(); + if (retryDecision.getLeft().shouldRetry()) { + return attemptAccessTokenRequest(maxRequestAttemptsForAPIEndpointTimeout); + } else { + return retryDecision.getRight(); } - // If the initial request fails, proceed with retry logic - LOG.info("Initial request failed, proceeding with retry attempts."); - return attemptAccessTokenRequest(maxRequestAttemptsForAPIEndpointTimeout); } } catch (ParseException e) { + LOG.error("Error parsing token expiry.", e); + if (LoggerUtils.isDiagnosticLogsEnabled()) { + DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new + DiagnosticLog.DiagnosticLogBuilder(Constants.LogConstants.ADAPTIVE_AUTH_SERVICE, + Constants.LogConstants.ActionIDs.RECEIVE_API_RESPONSE); + diagnosticLogBuilder.inputParam(Constants.LogConstants.InputKeys.TOKEN_ENDPOINT, getTokenEndpoint()) + .resultMessage("Failed to parse token expiry.") + .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) + .resultStatus(DiagnosticLog.ResultStatus.FAILED); + LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); + } LOG.error("Error parsing token expiry.", e); asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL); - } catch (IllegalArgumentException e) { - LOG.error("Invalid endpoint URL: " + getTokenEndpoint(), e); - asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL); - } catch (Exception e) { - LOG.error("Unexpected error during token acquisition.", e); - asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL); + } catch (IOException e) { + LOG.error("Error while calling token endpoint. ", e); } return null; } @@ -259,7 +266,8 @@ private String attemptAccessTokenRequest(int maxAttempts) { int attemptCount = 0; - while (++attemptCount < maxAttempts) { + while (attemptCount < maxAttempts) { + try { if (LoggerUtils.isDiagnosticLogsEnabled()) { DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new @@ -268,22 +276,22 @@ private String attemptAccessTokenRequest(int maxAttempts) { diagnosticLogBuilder.inputParam(Constants.LogConstants.InputKeys.TOKEN_ENDPOINT, getTokenEndpoint()) .configParam(Constants.LogConstants.ConfigKeys.SUPPORTED_GRANT_TYPES, GRANT_TYPE_CLIENT_CREDENTIALS) - .resultMessage("Retrying token request for the provided token endpoint.") + .resultMessage("Retrying token request for the provided token endpoint. Attempt: " + + attemptCount + ".") .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) .resultStatus(DiagnosticLog.ResultStatus.FAILED); - LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); + attemptCount++; LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); } LOG.info("Retrying token request for session data key: " + - this.authenticationContext.getContextIdentifier()); - String accessToken = requestAccessToken(); - if (accessToken != null) { - return accessToken; + this.authenticationContext.getContextIdentifier() + ". Attempt: " + attemptCount); + Pair retryDecision = requestAccessToken(); + if (!retryDecision.getLeft().shouldRetry()) { + return retryDecision.getRight(); } } catch (IOException e) { - LOG.error("Attempt " + attemptCount + " failed.", e); + LOG.error("Error while calling token endpoint. ", e); } - - LOG.info("Retrying token request. Attempt: " + attemptCount); + attemptCount++; } LOG.warn("Maximum token request attempts reached."); @@ -296,8 +304,9 @@ private String attemptAccessTokenRequest(int maxAttempts) { * @return Access token * @throws IOException {@link IOException} */ - private String requestAccessToken() throws IOException { + private Pair requestAccessToken() throws IOException { + RetryDecision isRetry = RetryDecision.NO_RETRY; HttpPost request = new HttpPost(tokenEndpoint); request.setHeader(ACCEPT, TYPE_APPLICATION_JSON); request.setHeader(CONTENT_TYPE, TYPE_FORM_DATA); @@ -327,44 +336,94 @@ private String requestAccessToken() throws IOException { int responseCode = response.getStatusLine().getStatusCode(); if (responseCode >= 200 && responseCode < 300) { return processSuccessfulResponse(response); + } else if (responseCode >= 300 && responseCode < 400) { + if (LoggerUtils.isDiagnosticLogsEnabled()) { + DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new + DiagnosticLog.DiagnosticLogBuilder(Constants.LogConstants.ADAPTIVE_AUTH_SERVICE, + Constants.LogConstants.ActionIDs.RECEIVE_API_RESPONSE); + diagnosticLogBuilder.inputParam(Constants.LogConstants.InputKeys.TOKEN_ENDPOINT, getTokenEndpoint()) + .resultMessage("Token endpoint returned a redirection. Status code: " + responseCode) + .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) + .resultStatus(DiagnosticLog.ResultStatus.FAILED); + LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); + } + LOG.warn("Token endpoint returned a redirection. Status code: " + responseCode + ". Url: " + + tokenEndpoint); + return Pair.of(RetryDecision.NO_RETRY, null); + } else if (responseCode >= 400 && responseCode < 500) { + if (LoggerUtils.isDiagnosticLogsEnabled()) { + DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new + DiagnosticLog.DiagnosticLogBuilder(Constants.LogConstants.ADAPTIVE_AUTH_SERVICE, + Constants.LogConstants.ActionIDs.RECEIVE_API_RESPONSE); + diagnosticLogBuilder.inputParam(Constants.LogConstants.InputKeys.TOKEN_ENDPOINT, getTokenEndpoint()) + .resultMessage("Token endpoint returned a client error. Status code: " + responseCode) + .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) + .resultStatus(DiagnosticLog.ResultStatus.FAILED); + LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); + } + LOG.warn("Token endpoint returned a client error. Status code: " + responseCode + ". Url: " + + tokenEndpoint); + return Pair.of(RetryDecision.NO_RETRY, null); } else { - LOG.error("Failed to retrieve access token. Response Code: " + responseCode + ". Session data key: " + - authenticationContext.getContextIdentifier()); - } - } catch (ConnectTimeoutException e) { - if (LoggerUtils.isDiagnosticLogsEnabled()) { - DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new - DiagnosticLog.DiagnosticLogBuilder(Constants.LogConstants.ADAPTIVE_AUTH_SERVICE, - Constants.LogConstants.ActionIDs.RECEIVE_TOKEN); - diagnosticLogBuilder.inputParam(Constants.LogConstants.InputKeys.TOKEN_ENDPOINT, getTokenEndpoint()) - .configParam(Constants.LogConstants.ConfigKeys.SUPPORTED_GRANT_TYPES, - GRANT_TYPE_CLIENT_CREDENTIALS) - .resultMessage("Connection timed out while requesting access token.") - .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) - .resultStatus(DiagnosticLog.ResultStatus.FAILED); - LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); - } - LOG.error("Connection timed out while requesting access token: " + tokenEndpoint, e); - } catch (SocketTimeoutException e) { - if (LoggerUtils.isDiagnosticLogsEnabled()) { - DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new - DiagnosticLog.DiagnosticLogBuilder(Constants.LogConstants.ADAPTIVE_AUTH_SERVICE, - Constants.LogConstants.ActionIDs.RECEIVE_TOKEN); - diagnosticLogBuilder.inputParam(Constants.LogConstants.InputKeys.TOKEN_ENDPOINT, getTokenEndpoint()) - .configParam(Constants.LogConstants.ConfigKeys.SUPPORTED_GRANT_TYPES, - GRANT_TYPE_CLIENT_CREDENTIALS) - .resultMessage("Socket timed out while requesting access token.") - .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) - .resultStatus(DiagnosticLog.ResultStatus.FAILED); - LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); + if (LoggerUtils.isDiagnosticLogsEnabled()) { + DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new + DiagnosticLog.DiagnosticLogBuilder(Constants.LogConstants.ADAPTIVE_AUTH_SERVICE, + Constants.LogConstants.ActionIDs.RECEIVE_API_RESPONSE); + diagnosticLogBuilder.inputParam(Constants.LogConstants.InputKeys.TOKEN_ENDPOINT, getTokenEndpoint()) + .resultMessage("Received unknown response from token endpoint. Status code: " + + responseCode) + .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) + .resultStatus(DiagnosticLog.ResultStatus.FAILED); + LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); + } + LOG.error("Received unknown response from token endpoint. Status code: " + responseCode + ". Url: " + + tokenEndpoint); + return Pair.of(RetryDecision.RETRY, null); // Server error, retry if attempts left } - LOG.error("Socket timed out while requesting access token: " + tokenEndpoint, e); - } catch (IOException e) { - LOG.error("IO Exception while requesting access token: ", e); } catch (Exception e) { - LOG.error("Unexpected error during token request: ", e); + // Log the error based on its type + if (e instanceof IllegalArgumentException) { + if (LoggerUtils.isDiagnosticLogsEnabled()) { + DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new + DiagnosticLog.DiagnosticLogBuilder(Constants.LogConstants.ADAPTIVE_AUTH_SERVICE, + Constants.LogConstants.ActionIDs.RECEIVE_API_RESPONSE); + diagnosticLogBuilder.inputParam(Constants.LogConstants.InputKeys.TOKEN_ENDPOINT, getTokenEndpoint()) + .resultMessage("Invalid Url for token endpoint.") + .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) + .resultStatus(DiagnosticLog.ResultStatus.FAILED); + LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); + } + LOG.error("Invalid Url: " + tokenEndpoint, e); + } else if (e instanceof SocketTimeoutException || e instanceof ConnectTimeoutException) { + if (LoggerUtils.isDiagnosticLogsEnabled()) { + DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new + DiagnosticLog.DiagnosticLogBuilder(Constants.LogConstants.ADAPTIVE_AUTH_SERVICE, + Constants.LogConstants.ActionIDs.RECEIVE_API_RESPONSE); + diagnosticLogBuilder.inputParam(Constants.LogConstants.InputKeys.TOKEN_ENDPOINT, getTokenEndpoint()) + .resultMessage("Request for the token endpoint timed out.") + .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) + .resultStatus(DiagnosticLog.ResultStatus.FAILED); + LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); + } + isRetry = RetryDecision.RETRY; // Timeout, retry if attempts left + LOG.error("Error while waiting to connect to " + tokenEndpoint, e); + } else if (e instanceof IOException) { + LOG.error("Error while calling token endpoint. ", e); + } else { + if (LoggerUtils.isDiagnosticLogsEnabled()) { + DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new + DiagnosticLog.DiagnosticLogBuilder(Constants.LogConstants.ADAPTIVE_AUTH_SERVICE, + Constants.LogConstants.ActionIDs.RECEIVE_API_RESPONSE); + diagnosticLogBuilder.inputParam(Constants.LogConstants.InputKeys.TOKEN_ENDPOINT, getTokenEndpoint()) + .resultMessage("Received an error while invoking the token endpoint.") + .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) + .resultStatus(DiagnosticLog.ResultStatus.FAILED); + LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); + } + LOG.error("Error while calling token endpoint. ", e); + } } - return null; + return Pair.of(isRetry, null); } /** @@ -374,19 +433,32 @@ private String requestAccessToken() throws IOException { * @return Access token * @throws IOException {@link IOException} */ - private String processSuccessfulResponse(CloseableHttpResponse response) throws IOException { + private Pair processSuccessfulResponse(CloseableHttpResponse response) throws IOException { Type responseBodyType = new TypeToken>(){}.getType(); Map responseBody = GSON.fromJson(EntityUtils.toString(response.getEntity()), responseBodyType); String accessToken = responseBody.get(ACCESS_TOKEN_KEY); if (accessToken != null) { + + if (LoggerUtils.isDiagnosticLogsEnabled()) { + DiagnosticLog.DiagnosticLogBuilder diagnosticLogBuilder = new + DiagnosticLog.DiagnosticLogBuilder(Constants.LogConstants.ADAPTIVE_AUTH_SERVICE, + Constants.LogConstants.ActionIDs.RECEIVE_API_RESPONSE); + diagnosticLogBuilder.inputParam(Constants.LogConstants.InputKeys.TOKEN_ENDPOINT, getTokenEndpoint()) + .resultMessage("Received access token from the token endpoint.") + .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) + .resultStatus(DiagnosticLog.ResultStatus.SUCCESS); + LoggerUtils.triggerDiagnosticLogEvent(diagnosticLogBuilder); + } + LOG.info("Received access token from the token endpoint. Session data key: " + + authenticationContext.getContextIdentifier()); apiAccessTokenCache.addToCache(getConsumerKey(), accessToken, this.authenticationContext.getTenantDomain()); - return accessToken; + return Pair.of(RetryDecision.NO_RETRY, accessToken); } LOG.error("Token response does not contain an access token. Session data key: " + authenticationContext.getContextIdentifier()); - return null; + return Pair.of(RetryDecision.NO_RETRY, null); } }