SessionManager extends BackoffLimitedRetryHandler implements HttpRequestFilter { @Override public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) { boolean retry = false; try { byte[] data = closeClientButKeepContentStream(response); String message = data != null ? new String(data) : null; if (response.getStatusCode() == 401 || (message != null && message.indexOf(IP_MISMATCH) != -1)) { logger.debug("invalidating session"); sessionCache.invalidateAll(); retry = super.shouldRetryRequest(command, response); } return retry; } finally { releasePayload(response); } } @Inject  SessionManager(@Provider Supplier<Credentials> creds, SessionApi sessionApi);   SessionManager(@Provider Supplier<Credentials> creds, LoadingCache<Credentials, Session> sessionCache,
         SessionApi sessionApi); @Override HttpRequest filter(HttpRequest request); @Override boolean shouldRetryRequest(HttpCommand command, HttpResponse response); @PreDestroy void logoutOnClose();  }
@SuppressWarnings("unchecked") @Test public void testUnauthorizedShouldInvalidateSessionAndRetry() { HttpCommand command = createMock(HttpCommand.class); Supplier<Credentials> creds = createMock(Supplier.class); LoadingCache<Credentials, Session> sessionCache = createMock(LoadingCache.class); SessionApi sessionApi = createMock(SessionApi.class); sessionCache.invalidateAll(); expectLastCall(); expect(command.incrementFailureCount()).andReturn(1); expect(command.isReplayable()).andReturn(true); expect(command.getFailureCount()).andReturn(1).atLeastOnce(); replay(creds, sessionCache, sessionApi, command); HttpResponse response = HttpResponse.builder().statusCode(UNAUTHORIZED.getStatusCode()).build(); SessionManager retry = new SessionManager(creds, sessionCache, sessionApi); assertTrue(retry.shouldRetryRequest(command, response)); verify(creds, sessionCache, sessionApi, command); }
@SuppressWarnings("unchecked") @Test public void testIPMismatchShouldInvalidateSessionAndRetry() throws IOException { HttpCommand command = createMock(HttpCommand.class); Supplier<Credentials> creds = createMock(Supplier.class); LoadingCache<Credentials, Session> sessionCache = createMock(LoadingCache.class); SessionApi sessionApi = createMock(SessionApi.class); sessionCache.invalidateAll(); expectLastCall(); expect(command.incrementFailureCount()).andReturn(1); expect(command.isReplayable()).andReturn(true); expect(command.getFailureCount()).andReturn(1).atLeastOnce(); replay(creds, sessionCache, sessionApi, command); HttpResponse response = HttpResponse.builder() .statusCode(BAD_REQUEST.getStatusCode()) .payload(getResource("ip_mismatch.json").openStream()) .build(); SessionManager retry = new SessionManager(creds, sessionCache, sessionApi); assertTrue(retry.shouldRetryRequest(command, response)); verify(creds, sessionCache, sessionApi, command); }
@SuppressWarnings("unchecked") @Test public void testForbiddenShouldNotInvalidateSessionOrRetry() { HttpCommand command = createMock(HttpCommand.class); Supplier<Credentials> creds = createMock(Supplier.class); LoadingCache<Credentials, Session> sessionCache = createMock(LoadingCache.class); SessionApi sessionApi = createMock(SessionApi.class); replay(creds, sessionCache, sessionApi, command); HttpResponse response = HttpResponse.builder().statusCode(FORBIDDEN.getStatusCode()).build(); SessionManager retry = new SessionManager(creds, sessionCache, sessionApi); assertFalse(retry.shouldRetryRequest(command, response)); verify(creds, sessionCache, sessionApi, command); }