KNOX-2618 - INFO level logging added about removing expired tokens from the DB (#455)

diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/JDBCTokenStateService.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/JDBCTokenStateService.java
index ecb648d..c1ff7e2 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/JDBCTokenStateService.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/JDBCTokenStateService.java
@@ -19,10 +19,12 @@
 
 import java.sql.SQLException;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.knox.gateway.config.GatewayConfig;
@@ -209,11 +211,17 @@
   @Override
   protected void evictExpiredTokens() {
     try {
-      int numOfExpiredTokens = tokenDatabase.deleteExpiredTokens(TimeUnit.SECONDS.toMillis(tokenEvictionGracePeriod));
-      log.removedTokensFromDatabase(numOfExpiredTokens);
+      final long expirationLimit = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(tokenEvictionGracePeriod);
+      final Set<String> expiredTokenIds = tokenDatabase.getExpiredTokenIds(expirationLimit);
+      if (!expiredTokenIds.isEmpty()) {
+        log.removingExpiredTokensFromDatabase(expiredTokenIds.size(),
+            String.join(", ", expiredTokenIds.stream().map(tokenId -> Tokens.getTokenIDDisplayText(tokenId)).collect(Collectors.toSet())));
+        final int numOfExpiredTokens = tokenDatabase.deleteExpiredTokens(expirationLimit);
+        log.removedTokensFromDatabase(numOfExpiredTokens);
 
-      // remove from in-memory collections
-      super.evictExpiredTokens();
+        // remove from in-memory collections
+        super.evictExpiredTokens();
+      }
     } catch (SQLException e) {
       log.errorRemovingTokensFromDatabase(e.getMessage(), e);
     }
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/TokenStateDatabase.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/TokenStateDatabase.java
index 695e62b..82de1fb 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/TokenStateDatabase.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/TokenStateDatabase.java
@@ -27,8 +27,10 @@
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 
 import javax.sql.DataSource;
 
@@ -43,6 +45,7 @@
   static final String TOKEN_METADATA_TABLE_NAME = "KNOX_TOKEN_METADATA";
   private static final String ADD_TOKEN_SQL = "INSERT INTO " + TOKENS_TABLE_NAME + "(token_id, issue_time, expiration, max_lifetime) VALUES(?, ?, ?, ?)";
   private static final String REMOVE_TOKEN_SQL = "DELETE FROM " + TOKENS_TABLE_NAME + " WHERE token_id = ?";
+  private static final String GET_EXPIRED_TOKENS_SQL = "SELECT token_id FROM " + TOKENS_TABLE_NAME + " WHERE expiration < ?";
   private static final String REMOVE_EXPIRED_TOKENS_SQL = "DELETE FROM " + TOKENS_TABLE_NAME + " WHERE expiration < ?";
   static final String GET_TOKEN_ISSUE_TIME_SQL = "SELECT issue_time FROM " + TOKENS_TABLE_NAME + " WHERE token_id = ?";
   static final String GET_TOKEN_EXPIRATION_SQL = "SELECT expiration FROM " + TOKENS_TABLE_NAME + " WHERE token_id = ?";
@@ -138,9 +141,22 @@
     }
   }
 
-  int deleteExpiredTokens(long tokenEvictionGracePeriod) throws SQLException {
+  Set<String> getExpiredTokenIds(long expirationLimit) throws SQLException {
+    final Set<String> expiredTokenIds = new HashSet<>();
+    try (Connection connection = dataSource.getConnection(); PreparedStatement getExpiredTokenIdsStatement = connection.prepareStatement(GET_EXPIRED_TOKENS_SQL)) {
+      getExpiredTokenIdsStatement.setLong(1, expirationLimit);
+      try (ResultSet rs = getExpiredTokenIdsStatement.executeQuery()) {
+        while(rs.next()) {
+          expiredTokenIds.add(rs.getString(1));
+        }
+        return expiredTokenIds;
+      }
+    }
+  }
+
+  int deleteExpiredTokens(long expirationLimit) throws SQLException {
     try (Connection connection = dataSource.getConnection(); PreparedStatement deleteExpiredTokensStatement = connection.prepareStatement(REMOVE_EXPIRED_TOKENS_SQL)) {
-      deleteExpiredTokensStatement.setLong(1, System.currentTimeMillis() - tokenEvictionGracePeriod);
+      deleteExpiredTokensStatement.setLong(1, expirationLimit);
       return deleteExpiredTokensStatement.executeUpdate();
     }
   }
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/TokenStateServiceMessages.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/TokenStateServiceMessages.java
index e5d0707..16c0251 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/TokenStateServiceMessages.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/TokenStateServiceMessages.java
@@ -193,6 +193,9 @@
   @Message(level = MessageLevel.ERROR, text = "An error occurred while removing token {0} from the database : {1}")
   void errorRemovingTokenFromDatabase(String tokenId, String errorMessage, @StackTrace(level = MessageLevel.DEBUG) Exception e);
 
+  @Message(level = MessageLevel.INFO, text = "Removing {0} expired token(s) from the database: {1}")
+  void removingExpiredTokensFromDatabase(int size, String expiredTokensList);
+
   @Message(level = MessageLevel.DEBUG, text = "{0} expired tokens have been removed from the database")
   void removedTokensFromDatabase(int size);