This is an automated email from the ASF dual-hosted git repository.

sammichen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 4445662c29 HDDS-9444. S3SecretManager fails to revoke secret due to 
inconsistency between S3Cache and S3SecretTable. (#5445)
4445662c29 is described below

commit 4445662c29e72d0e48652dfe6d4a4043bcacaa6b
Author: Arafat2198 <[email protected]>
AuthorDate: Wed Nov 22 06:55:00 2023 +0530

    HDDS-9444. S3SecretManager fails to revoke secret due to inconsistency 
between S3Cache and S3SecretTable. (#5445)
---
 .../apache/hadoop/ozone/om/S3InMemoryCache.java    |  73 +++++++------
 .../org/apache/hadoop/ozone/om/S3SecretCache.java  |   8 ++
 .../hadoop/ozone/om/S3SecretLockedManager.java     |  11 ++
 .../apache/hadoop/ozone/om/S3SecretManager.java    |  15 +++
 .../hadoop/ozone/om/helpers/S3SecretValue.java     |  34 +++++-
 .../hadoop/ozone/TestSecureOzoneCluster.java       |   2 +-
 .../hadoop/ozone/om/S3SecretManagerImpl.java       |  16 +++
 .../ozone/om/ratis/OzoneManagerDoubleBuffer.java   |  20 +++-
 .../ozone/om/ratis/OzoneManagerStateMachine.java   |   1 +
 .../metrics/OzoneManagerDoubleBufferMetrics.java   |   4 +
 .../om/request/s3/security/OMSetSecretRequest.java |   3 +-
 .../om/request/s3/security/S3GetSecretRequest.java |   2 +
 .../request/s3/security/S3RevokeSecretRequest.java |   5 +
 .../tenant/OMTenantAssignUserAccessIdRequest.java  |   2 +
 .../hadoop/ozone/om/s3/S3SecretCacheProvider.java  |  15 +--
 .../om/ratis/TestOzoneManagerDoubleBuffer.java     | 120 ++++++++++++++++++++-
 .../s3/security/TestS3GetSecretRequest.java        | 103 +++++++++++++++++-
 17 files changed, 375 insertions(+), 59 deletions(-)

diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3InMemoryCache.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3InMemoryCache.java
index 0194e813d8..4f1f66facc 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3InMemoryCache.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3InMemoryCache.java
@@ -21,8 +21,10 @@ import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
 
-import java.time.Duration;
-import java.time.temporal.TemporalUnit;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * S3 secret cache implementation based on in-memory cache.
@@ -30,17 +32,11 @@ import java.time.temporal.TemporalUnit;
 public class S3InMemoryCache implements S3SecretCache {
   private final Cache<String, S3SecretValue> cache;
 
-  public S3InMemoryCache(Duration expireTime, long maxSize) {
+  public S3InMemoryCache() {
     cache = CacheBuilder.newBuilder()
-        .expireAfterWrite(expireTime)
-        .maximumSize(maxSize)
         .build();
   }
 
-  public static S3InMemoryCacheBuilder builder() {
-    return new S3InMemoryCacheBuilder();
-  }
-
   @Override
   public void put(String id, S3SecretValue secretValue) {
     cache.put(id, secretValue);
@@ -48,35 +44,52 @@ public class S3InMemoryCache implements S3SecretCache {
 
   @Override
   public void invalidate(String id) {
-    cache.invalidate(id);
-  }
-
-  @Override
-  public S3SecretValue get(String id) {
-    return cache.getIfPresent(id);
+    S3SecretValue secret = cache.getIfPresent(id);
+    if (secret == null) {
+      return;
+    }
+    secret.setDeleted(true);
+    secret.setAwsSecret(null);
+    cache.put(id, secret);
   }
 
   /**
-   * Builder for {@link S3InMemoryCache}.
+   * Clears the cache by removing entries that correspond to transactions
+   * flushed by the doubleBuffer.
+   *
+   * @param flushedTransactionIds A list of transaction IDs that have been
+   *                              flushed and should be used to identify and
+   *                              remove corresponding cache entries.
    */
-  public static class S3InMemoryCacheBuilder {
-    private Duration expireTime;
-    private long maxSize;
+  @Override
+  public void clearCache(List<Long> flushedTransactionIds) {
+    // Create a map to store transactionLogIndex-to-cacheKey mappings
+    Map<Long, String> transactionIdToCacheKeys = new HashMap<>();
 
-    @SuppressWarnings("checkstyle:HiddenField")
-    public S3InMemoryCacheBuilder setExpireTime(long expireTime,
-                                                TemporalUnit unit) {
-      this.expireTime = Duration.of(expireTime, unit);
-      return this;
+    // Populate the mapping based on transactionLogIndex to kerberosId.
+    // So that we do not have to do nested iteration for every transactionId.
+    Set<String> cacheKeys = cache.asMap().keySet();
+    for (String cacheKey : cacheKeys) {
+      S3SecretValue secretValue = cache.getIfPresent(cacheKey);
+      if (secretValue != null) {
+        transactionIdToCacheKeys.put(secretValue.getTransactionLogIndex(),
+            cacheKey);
+      }
     }
 
-    public S3InMemoryCacheBuilder setMaxSize(long maxSize) {
-      this.maxSize = maxSize;
-      return this;
+    // Iterate over the provided transactionIds
+    for (Long transactionId : flushedTransactionIds) {
+      // Get the cache key associated with this transactionId
+      String cacheKey = transactionIdToCacheKeys.get(transactionId);
+      if (cacheKey != null) {
+        // Remove the cache entry for this cacheKey.
+        cache.invalidate(cacheKey);
+      }
     }
+  }
 
-    public S3InMemoryCache build() {
-      return new S3InMemoryCache(expireTime, maxSize);
-    }
+  @Override
+  public S3SecretValue get(String id) {
+    return cache.getIfPresent(id);
   }
 }
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3SecretCache.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3SecretCache.java
index a3456f1858..e8d9b508c1 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3SecretCache.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3SecretCache.java
@@ -18,6 +18,8 @@ package org.apache.hadoop.ozone.om;
 
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
 
+import java.util.List;
+
 /**
  * Cache layer of S3 secrets.
  */
@@ -35,6 +37,12 @@ public interface S3SecretCache {
    */
   void invalidate(String id);
 
+  /**
+   * Clears the cache, removing all entries, this is called when the
+   * doubleBuffer is flushed to the DB.
+   */
+  void clearCache(List<Long> transactionIds);
+
   /**
    * Get value from cache.
    * @param id cache secrect identifier.
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3SecretLockedManager.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3SecretLockedManager.java
index d5349a00bc..4cc7ff1bc4 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3SecretLockedManager.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3SecretLockedManager.java
@@ -20,6 +20,7 @@ import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
 import org.apache.hadoop.ozone.om.lock.IOzoneManagerLock;
 
 import java.io.IOException;
+import java.util.List;
 
 import static 
org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.S3_SECRET_LOCK;
 
@@ -77,6 +78,16 @@ public class S3SecretLockedManager implements 
S3SecretManager {
     }
   }
 
+  @Override
+  public void clearS3Cache(List<Long> epochs) {
+    lock.acquireWriteLock(S3_SECRET_LOCK, "cache");
+    try {
+      secretManager.clearS3Cache(epochs);
+    } finally {
+      lock.releaseWriteLock(S3_SECRET_LOCK, "cache");
+    }
+  }
+
   @Override
   public <T> T doUnderLock(String lockId, S3SecretFunction<T> action)
       throws IOException {
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3SecretManager.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3SecretManager.java
index 2213e33ac1..ae238f1b45 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3SecretManager.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/S3SecretManager.java
@@ -23,6 +23,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
+import java.util.List;
 
 /**
  * Interface to manager s3 secret.
@@ -60,6 +61,11 @@ public interface S3SecretManager {
    */
   void revokeSecret(String kerberosId) throws IOException;
 
+  /**
+   * Clear s3 secret cache when double buffer is flushed to the DB.
+   */
+  void clearS3Cache(List<Long> epochs);
+
   /**
    * Apply provided action under write lock.
    * @param lockId lock identifier.
@@ -96,6 +102,7 @@ public interface S3SecretManager {
   default void updateCache(String accessId, S3SecretValue secret) {
     S3SecretCache cache = cache();
     if (cache != null) {
+      LOG.info("Updating cache for accessId/user: {}.", accessId);
       cache.put(accessId, secret);
     }
   }
@@ -106,4 +113,12 @@ public interface S3SecretManager {
       cache.invalidate(id);
     }
   }
+
+  default void clearCache(List<Long> flushedTransactionIds) {
+    S3SecretCache cache = cache();
+    if (cache != null) {
+      cache.clearCache(flushedTransactionIds);
+    }
+  }
+
 }
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3SecretValue.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3SecretValue.java
index c8f2ac8e2e..959f83a14f 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3SecretValue.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3SecretValue.java
@@ -40,10 +40,19 @@ public class S3SecretValue {
   // TODO: This field should be renamed to accessId for generalization.
   private String kerberosID;
   private String awsSecret;
+  private boolean isDeleted;
+  private long transactionLogIndex;
 
   public S3SecretValue(String kerberosID, String awsSecret) {
+    this(kerberosID, awsSecret, false, 0L);
+  }
+
+  public S3SecretValue(String kerberosID, String awsSecret, boolean isDeleted,
+                       long transactionLogIndex) {
     this.kerberosID = kerberosID;
     this.awsSecret = awsSecret;
+    this.isDeleted = isDeleted;
+    this.transactionLogIndex = transactionLogIndex;
   }
 
   public String getKerberosID() {
@@ -62,10 +71,26 @@ public class S3SecretValue {
     this.awsSecret = awsSecret;
   }
 
+  public boolean isDeleted() {
+    return isDeleted;
+  }
+
+  public void setDeleted(boolean status) {
+    this.isDeleted = status;
+  }
+
   public String getAwsAccessKey() {
     return kerberosID;
   }
 
+  public long getTransactionLogIndex() {
+    return transactionLogIndex;
+  }
+
+  public void setTransactionLogIndex(long transactionLogIndex) {
+    this.transactionLogIndex = transactionLogIndex;
+  }
+
   public static S3SecretValue fromProtobuf(
       OzoneManagerProtocolProtos.S3Secret s3Secret) {
     return new S3SecretValue(s3Secret.getKerberosID(), 
s3Secret.getAwsSecret());
@@ -80,7 +105,9 @@ public class S3SecretValue {
 
   @Override
   public String toString() {
-    return "awsAccessKey=" + kerberosID + "\nawsSecret=" + awsSecret;
+    return "awsAccessKey=" + kerberosID + "\nawsSecret=" + awsSecret +
+        "\nisDeleted=" + isDeleted + "\ntransactionLogIndex=" +
+        transactionLogIndex;
   }
 
   @Override
@@ -93,11 +120,12 @@ public class S3SecretValue {
     }
     S3SecretValue that = (S3SecretValue) o;
     return kerberosID.equals(that.kerberosID) &&
-        awsSecret.equals(that.awsSecret);
+        awsSecret.equals(that.awsSecret) && isDeleted == that.isDeleted &&
+        transactionLogIndex == that.transactionLogIndex;
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(kerberosID, awsSecret);
+    return Objects.hash(kerberosID, awsSecret, isDeleted, transactionLogIndex);
   }
 }
diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java
index 939161ee84..cfc3fdf437 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java
@@ -1444,7 +1444,7 @@ final class TestSecureOzoneCluster {
         .setSubject(subject)
         .setDigitalSignature(true)
         .setDigitalEncryption(true);
-    
+
     addIpAndDnsDataToBuilder(csrBuilder);
     LocalDateTime start = LocalDateTime.now();
     Duration certDuration = conf.getDefaultCertDuration();
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/S3SecretManagerImpl.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/S3SecretManagerImpl.java
index 9e15c42bd4..4e46adc66b 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/S3SecretManagerImpl.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/S3SecretManagerImpl.java
@@ -26,6 +26,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
+import java.util.List;
 
 import static 
org.apache.hadoop.hdds.security.exception.OzoneSecurityException.ResultCodes.S3_SECRET_NOT_FOUND;
 
@@ -56,6 +57,11 @@ public class S3SecretManagerImpl implements S3SecretManager {
         "kerberosID cannot be null or empty.");
     S3SecretValue cacheValue = s3SecretCache.get(kerberosID);
     if (cacheValue != null) {
+      if (cacheValue.isDeleted()) {
+        // The cache entry is marked as deleted which means the user has
+        // purposely deleted the secret. Hence, we do not have to check the DB.
+        return null;
+      }
       return new S3SecretValue(cacheValue.getKerberosID(),
           cacheValue.getAwsSecret());
     }
@@ -102,6 +108,11 @@ public class S3SecretManagerImpl implements 
S3SecretManager {
     invalidateCacheEntry(kerberosId);
   }
 
+  @Override
+  public void clearS3Cache(List<Long> flushedTransactionIds) {
+    clearCache(flushedTransactionIds);
+  }
+
   @Override
   public <T> T doUnderLock(String lockId, S3SecretFunction<T> action)
       throws IOException {
@@ -118,4 +129,9 @@ public class S3SecretManagerImpl implements S3SecretManager 
{
   public S3Batcher batcher() {
     return s3SecretStore.batcher();
   }
+
+  @Override
+  public void updateCache(String kerberosID, S3SecretValue secret) {
+    S3SecretManager.super.updateCache(kerberosID, secret);
+  }
 }
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerDoubleBuffer.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerDoubleBuffer.java
index 1ab3634907..3e59a52bda 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerDoubleBuffer.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerDoubleBuffer.java
@@ -45,6 +45,7 @@ import org.apache.hadoop.hdds.utils.TransactionInfo;
 import org.apache.hadoop.hdds.utils.db.BatchOperation;
 import org.apache.hadoop.hdds.utils.db.DBColumnFamilyDefinition;
 import org.apache.hadoop.ozone.om.OMMetadataManager;
+import org.apache.hadoop.ozone.om.S3SecretManager;
 import org.apache.hadoop.ozone.om.codec.OMDBDefinition;
 import org.apache.hadoop.ozone.om.ratis.helpers.DoubleBufferEntry;
 import 
org.apache.hadoop.ozone.om.ratis.metrics.OzoneManagerDoubleBufferMetrics;
@@ -59,6 +60,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static org.apache.hadoop.ozone.OzoneConsts.TRANSACTION_INFO_KEY;
+import static org.apache.hadoop.ozone.om.codec.OMDBDefinition.S3_SECRET_TABLE;
 
 /**
  * This class implements DoubleBuffer implementation of OMClientResponse's. In
@@ -109,6 +111,8 @@ public final class OzoneManagerDoubleBuffer {
   private final Semaphore unFlushedTransactions;
   private final FlushNotifier flushNotifier;
   private final String threadPrefix;
+  private final S3SecretManager s3SecretManager;
+
   /**
    * function which will get term associated with the transaction index.
    */
@@ -125,6 +129,7 @@ public final class OzoneManagerDoubleBuffer {
     private Function<Long, Long> indexToTerm = null;
     private int maxUnFlushedTransactionCount = 0;
     private FlushNotifier flushNotifier;
+    private S3SecretManager s3SecretManager;
     private String threadPrefix = "";
 
 
@@ -169,6 +174,11 @@ public final class OzoneManagerDoubleBuffer {
       return this;
     }
 
+    public Builder setS3SecretManager(S3SecretManager s3SecretManager) {
+      this.s3SecretManager = s3SecretManager;
+      return this;
+    }
+
     public OzoneManagerDoubleBuffer build() {
       if (isRatisEnabled) {
         Preconditions.checkNotNull(rs, "When ratis is enabled, " +
@@ -185,7 +195,7 @@ public final class OzoneManagerDoubleBuffer {
 
       return new OzoneManagerDoubleBuffer(mm, rs, isRatisEnabled,
           isTracingEnabled, indexToTerm, maxUnFlushedTransactionCount,
-          flushNotifier, threadPrefix);
+          flushNotifier, s3SecretManager, threadPrefix);
     }
   }
 
@@ -194,7 +204,8 @@ public final class OzoneManagerDoubleBuffer {
       OzoneManagerRatisSnapshot ozoneManagerRatisSnapShot,
       boolean isRatisEnabled, boolean isTracingEnabled,
       Function<Long, Long> indexToTerm, int maxUnFlushedTransactions,
-      FlushNotifier flushNotifier, String threadPrefix) {
+      FlushNotifier flushNotifier, S3SecretManager s3SecretManager,
+      String threadPrefix) {
     this.currentBuffer = new ConcurrentLinkedQueue<>();
     this.readyBuffer = new ConcurrentLinkedQueue<>();
     this.isRatisEnabled = isRatisEnabled;
@@ -216,6 +227,7 @@ public final class OzoneManagerDoubleBuffer {
     daemon = new Daemon(this::flushTransactions);
     daemon.setName(threadPrefix + "OMDoubleBufferFlushThread");
     daemon.start();
+    this.s3SecretManager = s3SecretManager;
   }
 
   /**
@@ -516,6 +528,10 @@ public final class OzoneManagerDoubleBuffer {
     cleanupEpochs.forEach((tableName, epochs) -> {
       Collections.sort(epochs);
       omMetadataManager.getTable(tableName).cleanupCache(epochs);
+      // Check if the table is S3SecretTable, if yes, then clear the cache.
+      if (tableName.equals(S3_SECRET_TABLE.getName())) {
+        s3SecretManager.clearS3Cache(epochs);
+      }
     });
   }
 
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerStateMachine.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerStateMachine.java
index c8688c7256..f94a7b189c 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerStateMachine.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerStateMachine.java
@@ -473,6 +473,7 @@ public class OzoneManagerStateMachine extends 
BaseStateMachine {
         .setOzoneManagerRatisSnapShot(this::updateLastAppliedIndex)
         .setmaxUnFlushedTransactionCount(maxUnflushedTransactionSize)
         .setIndexToTerm(this::getTermForIndex).setThreadPrefix(threadPrefix)
+        .setS3SecretManager(ozoneManager.getS3SecretManager())
         .enableRatis(true)
         .enableTracing(isTracingEnabled)
         .build();
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/metrics/OzoneManagerDoubleBufferMetrics.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/metrics/OzoneManagerDoubleBufferMetrics.java
index ca74a936a9..f77eda081a 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/metrics/OzoneManagerDoubleBufferMetrics.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/metrics/OzoneManagerDoubleBufferMetrics.java
@@ -80,6 +80,10 @@ public class OzoneManagerDoubleBufferMetrics {
     this.totalNumOfFlushOperations.incr();
   }
 
+  public void incrTotalNumOfFlushOperations(long flushedOperations) {
+    this.totalNumOfFlushOperations.incr(flushedOperations);
+  }
+
   public void incrTotalSizeOfFlushedTransactions(
       long flushedTransactions) {
     this.totalNumOfFlushedTransactions.incr(flushedTransactions);
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/OMSetSecretRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/OMSetSecretRequest.java
index 129cef8093..bf89ae432c 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/OMSetSecretRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/OMSetSecretRequest.java
@@ -124,7 +124,8 @@ public class OMSetSecretRequest extends OMClientRequest {
               LOG.debug("Updating S3SecretTable cache entry");
               // Update S3SecretTable cache entry in this case
               newS3SecretValue = new S3SecretValue(accessId, secretKey);
-
+              // Set the transactionLogIndex to be used for updating.
+              newS3SecretValue.setTransactionLogIndex(transactionLogIndex);
               s3SecretManager
                   .updateCache(accessId, newS3SecretValue);
             } else {
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3GetSecretRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3GetSecretRequest.java
index 978e8f7791..308bed0d80 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3GetSecretRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3GetSecretRequest.java
@@ -162,6 +162,8 @@ public class S3GetSecretRequest extends OMClientRequest {
                 // Add new entry in this case
                 assignS3SecretValue =
                     new S3SecretValue(accessId, awsSecret.get());
+                // Set the transactionLogIndex to be used for updating.
+                
assignS3SecretValue.setTransactionLogIndex(transactionLogIndex);
                 // Add cache entry first.
                 s3SecretManager.updateCache(accessId,
                     assignS3SecretValue);
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSecretRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSecretRequest.java
index 563d76601f..dc051239f1 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSecretRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSecretRequest.java
@@ -95,12 +95,17 @@ public class S3RevokeSecretRequest extends OMClientRequest {
           .doUnderLock(kerberosID, s3SecretManager -> {
             // Remove if entry exists in table
             if (s3SecretManager.hasS3Secret(kerberosID)) {
+              LOG.info("Secret for {} exists in table, removing it.",
+                  kerberosID);
               // Invalid entry in table cache immediately
               s3SecretManager.invalidateCacheEntry(kerberosID);
               return new S3RevokeSecretResponse(kerberosID,
                   s3SecretManager,
                   omResponse.setStatus(Status.OK).build());
             } else {
+              LOG.info(
+                  "Secret for {} doesn't exist in table hence cannot" +
+                      " invalidate it", kerberosID);
               return new S3RevokeSecretResponse(null,
                   s3SecretManager,
                   omResponse.setStatus(Status.S3_SECRET_NOT_FOUND).build());
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantAssignUserAccessIdRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantAssignUserAccessIdRequest.java
index 27898140e7..d284a3e628 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantAssignUserAccessIdRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantAssignUserAccessIdRequest.java
@@ -275,6 +275,8 @@ public class OMTenantAssignUserAccessIdRequest extends 
OMClientRequest {
 
       final S3SecretValue s3SecretValue =
           new S3SecretValue(accessId, awsSecret);
+      // Set the transactionLogIndex to be used for updating.
+      s3SecretValue.setTransactionLogIndex(transactionLogIndex);
 
       // Add to tenantAccessIdTable
       final OmDBAccessIdInfo omDBAccessIdInfo = new OmDBAccessIdInfo.Builder()
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/s3/S3SecretCacheProvider.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/s3/S3SecretCacheProvider.java
index 213ba909cc..b3f2c3d656 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/s3/S3SecretCacheProvider.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/s3/S3SecretCacheProvider.java
@@ -22,13 +22,6 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.ozone.om.S3InMemoryCache;
 import org.apache.hadoop.ozone.om.S3SecretCache;
 
-import java.time.temporal.ChronoUnit;
-
-import static 
org.apache.hadoop.ozone.om.s3.S3SecretStoreConfigurationKeys.CACHE_LIFETIME;
-import static 
org.apache.hadoop.ozone.om.s3.S3SecretStoreConfigurationKeys.CACHE_MAX_SIZE;
-import static 
org.apache.hadoop.ozone.om.s3.S3SecretStoreConfigurationKeys.DEFAULT_CACHE_LIFETIME;
-import static 
org.apache.hadoop.ozone.om.s3.S3SecretStoreConfigurationKeys.DEFAULT_CACHE_MAX_SIZE;
-
 /**
  * Provider of {@link S3SecretCache}.
  */
@@ -46,12 +39,6 @@ public interface S3SecretCacheProvider {
    * In-memory cache implementation.
    */
   S3SecretCacheProvider IN_MEMORY = conf -> {
-    long expireTime = conf
-        .getLong(CACHE_LIFETIME, DEFAULT_CACHE_LIFETIME);
-    return S3InMemoryCache.builder()
-        .setExpireTime(expireTime, ChronoUnit.SECONDS)
-        .setMaxSize(conf
-            .getLong(CACHE_MAX_SIZE, DEFAULT_CACHE_MAX_SIZE))
-        .build();
+    return new S3InMemoryCache();
   };
 }
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/ratis/TestOzoneManagerDoubleBuffer.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/ratis/TestOzoneManagerDoubleBuffer.java
index 5ef4909623..8d408cb505 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/ratis/TestOzoneManagerDoubleBuffer.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/ratis/TestOzoneManagerDoubleBuffer.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.UUID;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -31,17 +32,26 @@ import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.ozone.audit.AuditLogger;
 import org.apache.hadoop.ozone.audit.AuditMessage;
 import org.apache.hadoop.ozone.om.OMConfigKeys;
-import org.apache.hadoop.ozone.om.OMMetadataManager;
 import org.apache.hadoop.ozone.om.OMMetrics;
 import org.apache.hadoop.ozone.om.OmMetadataManagerImpl;
 import org.apache.hadoop.ozone.om.OzoneManager;
+import org.apache.hadoop.ozone.om.S3SecretManagerImpl;
+import org.apache.hadoop.ozone.om.S3SecretCache;
+import org.apache.hadoop.ozone.om.S3SecretLockedManager;
 import 
org.apache.hadoop.ozone.om.ratis.metrics.OzoneManagerDoubleBufferMetrics;
+import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
+import org.apache.hadoop.ozone.om.request.s3.security.S3GetSecretRequest;
 import org.apache.hadoop.ozone.om.response.OMClientResponse;
 import org.apache.hadoop.ozone.om.response.bucket.OMBucketCreateResponse;
 import org.apache.hadoop.ozone.om.response.key.OMKeyCreateResponse;
 import org.apache.hadoop.ozone.om.response.snapshot.OMSnapshotCreateResponse;
+import org.apache.hadoop.ozone.om.s3.S3SecretCacheProvider;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateSnapshotResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authentication.util.KerberosName;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -51,6 +61,7 @@ import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.Mockito;
 
+import static 
org.apache.hadoop.security.authentication.util.KerberosName.DEFAULT_MECHANISM;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -68,6 +79,12 @@ import static org.mockito.Mockito.when;
 class TestOzoneManagerDoubleBuffer {
 
   private OzoneManagerDoubleBuffer doubleBuffer;
+  private OzoneManager ozoneManager;
+  private OmMetadataManagerImpl omMetadataManager;
+  private S3SecretLockedManager secretManager;
+  // Set ozoneManagerDoubleBuffer to do nothing.
+  private final OzoneManagerDoubleBufferHelper ozoneManagerDoubleBufferHelper =
+      ((response, transactionIndex) -> null);
   private CreateSnapshotResponse snapshotResponse1 =
       mock(CreateSnapshotResponse.class);
   private CreateSnapshotResponse snapshotResponse2 =
@@ -89,20 +106,36 @@ class TestOzoneManagerDoubleBuffer {
   private OzoneManagerDoubleBuffer.FlushNotifier flushNotifier;
   private OzoneManagerDoubleBuffer.FlushNotifier spyFlushNotifier;
 
+  private static String userPrincipalId1 = "[email protected]";
+  private static String userPrincipalId2 = "[email protected]";
+  private static String userPrincipalId3 = "[email protected]";
+
   @BeforeEach
   public void setup() throws IOException {
     OMMetrics omMetrics = OMMetrics.create();
     OzoneConfiguration ozoneConfiguration = new OzoneConfiguration();
     ozoneConfiguration.set(OMConfigKeys.OZONE_OM_DB_DIRS,
         tempDir.getAbsolutePath());
-    OMMetadataManager omMetadataManager =
-        new OmMetadataManagerImpl(ozoneConfiguration, null);
-    OzoneManager ozoneManager = mock(OzoneManager.class);
+
+    ozoneManager = mock(OzoneManager.class);
     when(ozoneManager.getMetrics()).thenReturn(omMetrics);
+    omMetadataManager =
+        new OmMetadataManagerImpl(ozoneConfiguration, ozoneManager);
     when(ozoneManager.getMetadataManager()).thenReturn(omMetadataManager);
     when(ozoneManager.getMaxUserVolumeCount()).thenReturn(10L);
     AuditLogger auditLogger = mock(AuditLogger.class);
     when(ozoneManager.getAuditLogger()).thenReturn(auditLogger);
+
+    secretManager = new S3SecretLockedManager(
+        new S3SecretManagerImpl(
+            omMetadataManager,
+            S3SecretCacheProvider.IN_MEMORY.get(ozoneConfiguration)
+        ),
+        omMetadataManager.getLock()
+    );
+    when(ozoneManager.getS3SecretManager()).thenReturn(secretManager);
+    when(ozoneManager.getAuditLogger()).thenReturn(auditLogger);
+    doNothing().when(auditLogger).logWrite(any(AuditMessage.class));
     Mockito.doNothing().when(auditLogger).logWrite(any(AuditMessage.class));
     OzoneManagerRatisSnapshot ozoneManagerRatisSnapshot = index -> {
     };
@@ -111,6 +144,7 @@ class TestOzoneManagerDoubleBuffer {
     spyFlushNotifier = spy(flushNotifier);
     doubleBuffer = new OzoneManagerDoubleBuffer.Builder()
         .setOmMetadataManager(omMetadataManager)
+        .setS3SecretManager(secretManager)
         .setOzoneManagerRatisSnapShot(ozoneManagerRatisSnapshot)
         .setmaxUnFlushedTransactionCount(1000)
         .enableRatis(true)
@@ -290,6 +324,84 @@ class TestOzoneManagerDoubleBuffer {
         flusher::get);
   }
 
+  @Test
+  public void testS3SecretCacheSizePostDoubleBufferFlush() throws IOException {
+    // Create a secret for "alice".
+    // This effectively makes alice an S3 admin.
+    KerberosName.setRuleMechanism(DEFAULT_MECHANISM);
+    KerberosName.setRules(
+        "RULE:[2:$1@$0](.*@EXAMPLE.COM)s/@.*//\n" +
+            "RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\n" +
+            "DEFAULT");
+    UserGroupInformation ugiAlice;
+    ugiAlice = UserGroupInformation.createRemoteUser(userPrincipalId1);
+    UserGroupInformation.createRemoteUser(userPrincipalId2);
+    UserGroupInformation.createRemoteUser(userPrincipalId3);
+    Assertions.assertEquals("alice", ugiAlice.getShortUserName());
+    when(ozoneManager.isS3Admin(ugiAlice)).thenReturn(true);
+
+    // Create 3 secrets and store them in the cache and double buffer.
+    processSuccessSecretRequest(userPrincipalId1, 1, true);
+    processSuccessSecretRequest(userPrincipalId2, 2, true);
+    processSuccessSecretRequest(userPrincipalId3, 3, true);
+
+    S3SecretCache cache = secretManager.cache();
+    // Check if all the three secrets are cached.
+    Assertions.assertTrue(cache.get(userPrincipalId1) != null);
+    Assertions.assertTrue(cache.get(userPrincipalId2) != null);
+    Assertions.assertTrue(cache.get(userPrincipalId3) != null);
+
+    // Flush the current buffer.
+    doubleBuffer.flushCurrentBuffer();
+
+    // Check if all the three secrets are cleared from the cache.
+    Assertions.assertTrue(cache.get(userPrincipalId3) == null);
+    Assertions.assertTrue(cache.get(userPrincipalId2) == null);
+    Assertions.assertTrue(cache.get(userPrincipalId1) == null);
+
+    // cleanup metrics
+    doubleBuffer.stopDaemon();
+    OzoneManagerDoubleBufferMetrics metrics =
+        doubleBuffer.getOzoneManagerDoubleBufferMetrics();
+    metrics.setMaxNumberOfTransactionsFlushedInOneIteration(0);
+    metrics.setAvgFlushTransactionsInOneIteration(0);
+    metrics.incrTotalSizeOfFlushedTransactions(
+        -metrics.getTotalNumOfFlushedTransactions());
+    metrics.incrTotalNumOfFlushOperations(
+        -metrics.getTotalNumOfFlushOperations());
+  }
+
+  private void processSuccessSecretRequest(
+      String userPrincipalId,
+      int txLogIndex,
+      boolean shouldHaveResponse) throws IOException {
+    S3GetSecretRequest s3GetSecretRequest =
+        new S3GetSecretRequest(
+            new S3GetSecretRequest(
+                s3GetSecretRequest(userPrincipalId)
+            ).preExecute(ozoneManager)
+        );
+
+    // Run validateAndUpdateCache
+    OMClientResponse omClientResponse =
+        s3GetSecretRequest.validateAndUpdateCache(ozoneManager,
+            txLogIndex, ozoneManagerDoubleBufferHelper);
+    doubleBuffer.add(omClientResponse, txLogIndex);
+  }
+
+  private OzoneManagerProtocolProtos.OMRequest s3GetSecretRequest(
+      String userPrincipalId) {
+
+    return OzoneManagerProtocolProtos.OMRequest.newBuilder()
+        .setClientId(UUID.randomUUID().toString())
+        .setCmdType(OzoneManagerProtocolProtos.Type.GetS3Secret)
+        .setGetS3SecretRequest(
+            OzoneManagerProtocolProtos.GetS3SecretRequest.newBuilder()
+                .setKerberosID(userPrincipalId)
+                .setCreateIfNotExist(true)
+                .build()
+        ).build();
+  }
 
   // Return a future that waits for the flush.
   private Future<Boolean> awaitFlush(ExecutorService executorService) {
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3GetSecretRequest.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3GetSecretRequest.java
index 8d1e443af5..a634473a3d 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3GetSecretRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3GetSecretRequest.java
@@ -25,13 +25,14 @@ import org.apache.hadoop.ipc.Server.Call;
 import org.apache.hadoop.ozone.audit.AuditLogger;
 import org.apache.hadoop.ozone.audit.AuditMessage;
 import org.apache.hadoop.ozone.om.OMConfigKeys;
-import org.apache.hadoop.ozone.om.OMMetrics;
-import org.apache.hadoop.ozone.om.OMMultiTenantManager;
 import org.apache.hadoop.ozone.om.OmMetadataManagerImpl;
 import org.apache.hadoop.ozone.om.OzoneManager;
 import org.apache.hadoop.ozone.om.S3SecretLockedManager;
+import org.apache.hadoop.ozone.om.OMMetrics;
+import org.apache.hadoop.ozone.om.OMMultiTenantManager;
 import org.apache.hadoop.ozone.om.S3SecretManagerImpl;
 import org.apache.hadoop.ozone.om.TenantOp;
+import org.apache.hadoop.ozone.om.S3SecretCache;
 import org.apache.hadoop.ozone.om.multitenant.AuthorizerLockImpl;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes;
@@ -39,14 +40,17 @@ import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
 import org.apache.hadoop.ozone.om.multitenant.Tenant;
 import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
+import org.apache.hadoop.ozone.om.request.OMClientRequest;
 import 
org.apache.hadoop.ozone.om.request.s3.tenant.OMTenantAssignUserAccessIdRequest;
 import org.apache.hadoop.ozone.om.request.s3.tenant.OMTenantCreateRequest;
 import org.apache.hadoop.ozone.om.response.OMClientResponse;
 import org.apache.hadoop.ozone.om.response.s3.security.S3GetSecretResponse;
+import org.apache.hadoop.ozone.om.response.s3.security.S3RevokeSecretResponse;
 import 
org.apache.hadoop.ozone.om.response.s3.tenant.OMTenantAssignUserAccessIdResponse;
 import org.apache.hadoop.ozone.om.response.s3.tenant.OMTenantCreateResponse;
 import org.apache.hadoop.ozone.om.s3.S3SecretCacheProvider;
 import org.apache.hadoop.ozone.om.upgrade.OMLayoutVersionManager;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateTenantRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3SecretRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3SecretResponse;
@@ -56,8 +60,8 @@ import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantA
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Type;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.authentication.util.KerberosName;
-import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.io.TempDir;
@@ -88,6 +92,7 @@ public class TestS3GetSecretRequest {
   private OzoneManager ozoneManager;
   private OMMetrics omMetrics;
   private AuditLogger auditLogger;
+  private OmMetadataManagerImpl omMetadataManager;
   // Set ozoneManagerDoubleBuffer to do nothing.
   private final OzoneManagerDoubleBufferHelper ozoneManagerDoubleBufferHelper =
       ((response, transactionIndex) -> null);
@@ -133,7 +138,7 @@ public class TestS3GetSecretRequest {
         folder.toAbsolutePath().toString());
     // No need to conf.set(OzoneConfigKeys.OZONE_ADMINISTRATORS, ...) here
     //  as we did the trick earlier with mockito.
-    OmMetadataManagerImpl omMetadataManager = new OmMetadataManagerImpl(conf,
+    omMetadataManager = new OmMetadataManagerImpl(conf,
         ozoneManager);
     when(ozoneManager.getMetrics()).thenReturn(omMetrics);
     when(ozoneManager.getMetadataManager()).thenReturn(omMetadataManager);
@@ -214,10 +219,100 @@ public class TestS3GetSecretRequest {
         .setGetS3SecretRequest(
             GetS3SecretRequest.newBuilder()
                 .setKerberosID(userPrincipalStr)
+                .setCreateIfNotExist(true)
                 .build()
         ).build();
   }
 
+
+  @Test
+  public void testS3CacheRecordsTransactionIndex() throws IOException {
+    // Create secrets for "alice" and "carol".
+    when(ozoneManager.isS3Admin(ugiAlice)).thenReturn(true);
+    when(ozoneManager.isS3Admin(ugiCarol)).thenReturn(true);
+
+    String userPrincipalIdAlice = USER_ALICE;
+    String userPrincipalIdBob = USER_CAROL;
+
+    // Request the creation of secrets for "alice" and "bob".
+    processSuccessSecretRequest(userPrincipalIdAlice, 1, true);
+    processSuccessSecretRequest(userPrincipalIdBob, 2, true);
+
+    // Verify that the transaction index is added to the cache for "alice".
+    S3SecretCache cache = ozoneManager.getS3SecretManager().cache();
+    Assertions.assertNotNull(cache.get(userPrincipalIdAlice));
+    Assertions.assertEquals(1,
+        cache.get(userPrincipalIdAlice).getTransactionLogIndex());
+
+    // Verify that the transaction index is added to the cache for "bob".
+    Assertions.assertNotNull(cache.get(userPrincipalIdBob));
+    Assertions.assertEquals(2,
+        cache.get(userPrincipalIdBob).getTransactionLogIndex());
+  }
+
+  @Test
+  public void testFetchSecretForRevokedUser() throws IOException {
+    // Create a secret for "alice".
+    // This effectively makes alice an S3 admin.
+    when(ozoneManager.isS3Admin(ugiAlice)).thenReturn(true);
+
+    String userPrincipalId = USER_ALICE;
+
+    // Request the creation of a secret.
+    S3Secret originalS3Secret =
+        processSuccessSecretRequest(userPrincipalId, 1, true);
+
+    // Revoke the secret.
+    String kerberosID = originalS3Secret.getKerberosID();
+    OzoneManagerProtocolProtos.RevokeS3SecretRequest revokeS3SecretRequest =
+        OzoneManagerProtocolProtos.RevokeS3SecretRequest.newBuilder()
+            .setKerberosID(kerberosID)
+            .build();
+    OMRequest revokeRequest = OMRequest.newBuilder()
+        .setRevokeS3SecretRequest(revokeS3SecretRequest)
+        .setClientId(UUID.randomUUID().toString())
+        .setCmdType(Type.RevokeS3Secret)
+        .build();
+    OMClientRequest omRevokeRequest = new S3RevokeSecretRequest(revokeRequest);
+
+    // Pre-execute the revoke request.
+    omRevokeRequest.preExecute(ozoneManager);
+
+    // Validate and update cache to revoke the secret.
+    OMClientResponse omRevokeResponse = omRevokeRequest.validateAndUpdateCache(
+        ozoneManager, 2, ozoneManagerDoubleBufferHelper);
+
+    // Verify that the revoke operation was successful.
+    Assertions.assertTrue(omRevokeResponse instanceof S3RevokeSecretResponse);
+    S3RevokeSecretResponse s3RevokeSecretResponse =
+        (S3RevokeSecretResponse) omRevokeResponse;
+    Assertions.assertEquals(OzoneManagerProtocolProtos.Status.OK.getNumber(),
+        s3RevokeSecretResponse.getOMResponse().getStatus().getNumber());
+
+    // Fetch the revoked secret and verify its value is null.
+    S3GetSecretRequest s3GetSecretRequest = new S3GetSecretRequest(
+        new S3GetSecretRequest(s3GetSecretRequest(userPrincipalId)).preExecute(
+            ozoneManager)
+    );
+    S3SecretValue s3SecretValue = omMetadataManager.getSecret(kerberosID);
+    Assertions.assertNull(s3SecretValue);
+
+    // Verify that the secret for revoked user will be set to a new one upon
+    // calling getSecret request.
+    OMClientResponse omClientResponse =
+        s3GetSecretRequest.validateAndUpdateCache(
+            ozoneManager, 3, ozoneManagerDoubleBufferHelper);
+
+    Assertions.assertTrue(omClientResponse instanceof S3GetSecretResponse);
+    S3GetSecretResponse s3GetSecretResponse =
+        (S3GetSecretResponse) omClientResponse;
+
+    // Compare the old secret value and new secret value after revoking;
+    // they should not be the same.
+    Assertions.assertNotEquals(originalS3Secret,
+        s3GetSecretResponse.getS3SecretValue().getAwsSecret());
+  }
+
   @Test
   public void testGetSecretOfAnotherUserAsAdmin() throws IOException {
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to