|
13 | 13 | import com.gooddata.sdk.model.gdc.UriResponse; |
14 | 14 | import com.gooddata.sdk.service.AbstractService; |
15 | 15 | import com.gooddata.sdk.service.GoodDataSettings; |
| 16 | +import org.slf4j.Logger; |
| 17 | +import org.slf4j.LoggerFactory; |
16 | 18 | import org.springframework.http.HttpStatus; |
17 | 19 | import org.springframework.http.converter.json.MappingJacksonValue; |
18 | 20 | import org.springframework.web.client.RestClientException; |
|
28 | 30 | */ |
29 | 31 | public class AccountService extends AbstractService { |
30 | 32 |
|
| 33 | + private static final Logger logger = LoggerFactory.getLogger(AccountService.class); |
| 34 | + |
31 | 35 | public static final UriTemplate ACCOUNT_TEMPLATE = new UriTemplate(Account.URI); |
32 | 36 | public static final UriTemplate ACCOUNTS_TEMPLATE = new UriTemplate(Account.ACCOUNTS_URI); |
33 | 37 | public static final UriTemplate ACCOUNT_BY_LOGIN_TEMPLATE = new UriTemplate(Account.ACCOUNT_BY_EMAIL_URI); |
@@ -63,11 +67,47 @@ public void logout() { |
63 | 67 | try { |
64 | 68 | final String id = getCurrent().getId(); |
65 | 69 | restTemplate.delete(Account.LOGIN_URI, id); |
| 70 | + } catch (GoodDataRestException e) { |
| 71 | + if (isAlreadyLoggedOutError(e)) { |
| 72 | + logger.debug("User already logged out (status={}, errorCode={}, message={})", |
| 73 | + e.getStatusCode(), e.getErrorCode(), e.getMessage()); |
| 74 | + return; |
| 75 | + } |
| 76 | + throw new GoodDataException("Unable to logout", e); |
66 | 77 | } catch (GoodDataException | RestClientException e) { |
67 | 78 | throw new GoodDataException("Unable to logout", e); |
68 | 79 | } |
69 | 80 | } |
70 | 81 |
|
| 82 | + /** |
| 83 | + * Checks if the exception indicates the user is already logged out. |
| 84 | + * This is not an error condition - it means the logout goal is already achieved. |
| 85 | + */ |
| 86 | + private static boolean isAlreadyLoggedOutError(final GoodDataRestException e) { |
| 87 | + // HTTP 400 indicates a client error, which includes "not logged in" |
| 88 | + if (e.getStatusCode() != HttpStatus.BAD_REQUEST.value()) { |
| 89 | + return false; |
| 90 | + } |
| 91 | + |
| 92 | + // Prefer error code matching (API contract) over message content (locale-sensitive) |
| 93 | + final String errorCode = e.getErrorCode(); |
| 94 | + if (errorCode != null && !errorCode.isEmpty()) { |
| 95 | + // Match known error codes for "not logged in" state |
| 96 | + // Common patterns: gdc.login.not_logged_in, NOT_LOGGED_IN, etc. |
| 97 | + final String lowerErrorCode = errorCode.toLowerCase(); |
| 98 | + return lowerErrorCode.contains("not_logged") || lowerErrorCode.contains("notlogged"); |
| 99 | + } |
| 100 | + |
| 101 | + // Fallback to message matching if error code is not available |
| 102 | + final String message = e.getMessage(); |
| 103 | + if (message != null) { |
| 104 | + final String lowerMessage = message.toLowerCase(); |
| 105 | + return lowerMessage.contains("not logged in") || lowerMessage.contains("not logged-in"); |
| 106 | + } |
| 107 | + |
| 108 | + return false; |
| 109 | + } |
| 110 | + |
71 | 111 | /** |
72 | 112 | * Creates new account in given organization (domain). |
73 | 113 | * Only domain admin is allowed create new accounts! This means rest request has to authorized as domain admin. |
|
0 commit comments