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

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


The following commit(s) were added to refs/heads/master by this push:
     new 9779b0c  HDDS-426. Add field modificationTime for Volume and Bucket 
(#164)
9779b0c is described below

commit 9779b0c055f0a4c5ef3d34488fbc99f701543bde
Author: Yi-Sheng Lien <[email protected]>
AuthorDate: Sat Jun 27 06:04:11 2020 +0800

    HDDS-426. Add field modificationTime for Volume and Bucket (#164)
---
 .../java/org/apache/hadoop/ozone/OzoneConsts.java  |  1 +
 .../apache/hadoop/ozone/client/OzoneBucket.java    | 55 ++++++++++++++++-
 .../apache/hadoop/ozone/client/OzoneVolume.java    | 69 +++++++++++++++++++---
 .../apache/hadoop/ozone/client/rpc/RpcClient.java  |  5 ++
 .../hadoop/ozone/om/helpers/OmBucketInfo.java      | 33 ++++++++++-
 .../hadoop/ozone/om/helpers/OmVolumeArgs.java      | 33 +++++++++--
 .../src/main/proto/OmClientProtocol.proto          |  3 +
 .../om/request/bucket/OMBucketCreateRequest.java   |  6 +-
 .../om/request/volume/OMVolumeCreateRequest.java   |  8 ++-
 .../om/request/volume/OMVolumeSetOwnerRequest.java | 22 ++++++-
 .../om/request/volume/OMVolumeSetQuotaRequest.java | 17 ++++++
 .../ozone/om/request/TestOMRequestUtils.java       |  4 +-
 .../request/bucket/TestOMBucketCreateRequest.java  |  2 +
 .../request/volume/TestOMVolumeCreateRequest.java  |  7 +++
 .../volume/TestOMVolumeSetOwnerRequest.java        |  7 +++
 .../volume/TestOMVolumeSetQuotaRequest.java        |  7 +++
 .../hadoop/ozone/client/ObjectStoreStub.java       |  6 +-
 .../hadoop/ozone/client/OzoneVolumeStub.java       | 10 ++--
 .../ozone/shell/volume/UpdateVolumeHandler.java    |  4 +-
 19 files changed, 266 insertions(+), 33 deletions(-)

diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java
index e027c82..54e44b1 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java
@@ -280,6 +280,7 @@ public final class OzoneConsts {
   public static final String RESOURCE_TYPE = "resourceType";
   public static final String IS_VERSION_ENABLED = "isVersionEnabled";
   public static final String CREATION_TIME = "creationTime";
+  public static final String MODIFICATION_TIME = "modificationTime";
   public static final String DATA_SIZE = "dataSize";
   public static final String REPLICATION_TYPE = "replicationType";
   public static final String REPLICATION_FACTOR = "replicationFactor";
diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
index f4bfbcd..d22b846 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
@@ -38,6 +38,7 @@ import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
 import org.apache.hadoop.ozone.om.helpers.WithMetadata;
 import org.apache.hadoop.ozone.security.acl.OzoneObj;
 import org.apache.hadoop.ozone.security.acl.OzoneObjInfo;
+import org.apache.hadoop.util.Time;
 
 import java.io.IOException;
 import java.time.Instant;
@@ -97,6 +98,11 @@ public class OzoneBucket extends WithMetadata {
   private Instant creationTime;
 
   /**
+   * Modification time of the bucket.
+   */
+  private Instant modificationTime;
+
+  /**
    * Bucket Encryption key name if bucket encryption is enabled.
    */
   private String encryptionKeyName;
@@ -144,6 +150,21 @@ public class OzoneBucket extends WithMetadata {
     this.creationTime = Instant.ofEpochMilli(creationTime);
     this.metadata = metadata;
     this.encryptionKeyName = encryptionKeyName;
+    modificationTime = Instant.now();
+    if (modificationTime.isBefore(this.creationTime)) {
+      modificationTime = Instant.ofEpochSecond(
+          this.creationTime.getEpochSecond(), this.creationTime.getNano());
+    }
+  }
+
+  @SuppressWarnings("parameternumber")
+  public OzoneBucket(ConfigurationSource conf, ClientProtocol proxy,
+      String volumeName, String bucketName, StorageType storageType,
+      Boolean versioning, long creationTime, long modificationTime,
+      Map<String, String> metadata, String encryptionKeyName) {
+    this(conf, proxy, volumeName, bucketName, storageType, versioning,
+        creationTime, metadata, encryptionKeyName);
+    this.modificationTime = Instant.ofEpochMilli(modificationTime);
   }
 
   /**
@@ -166,6 +187,24 @@ public class OzoneBucket extends WithMetadata {
     this.listCacheSize = HddsClientUtils.getListCacheSize(conf);
     this.creationTime = Instant.ofEpochMilli(creationTime);
     this.metadata = metadata;
+    modificationTime = Instant.now();
+    if (modificationTime.isBefore(this.creationTime)) {
+      modificationTime = Instant.ofEpochSecond(
+          this.creationTime.getEpochSecond(), this.creationTime.getNano());
+    }
+  }
+
+  /**
+   * @param modificationTime modification time of the bucket.
+   */
+  @SuppressWarnings("parameternumber")
+  public OzoneBucket(ConfigurationSource conf, ClientProtocol proxy,
+      String volumeName, String bucketName, StorageType storageType,
+      Boolean versioning, long creationTime, long modificationTime,
+      Map<String, String> metadata) {
+    this(conf, proxy, volumeName, bucketName, storageType, versioning,
+        creationTime, metadata);
+    this.modificationTime = Instant.ofEpochMilli(modificationTime);
   }
 
   @VisibleForTesting
@@ -187,9 +226,14 @@ public class OzoneBucket extends WithMetadata {
         .setVolumeName(volumeName)
         .setResType(OzoneObj.ResourceType.BUCKET)
         .setStoreType(OzoneObj.StoreType.OZONE).build();
+    long modifiedTime = Time.now();
+    if (modifiedTime < creationTime) {
+      this.modificationTime = Instant.ofEpochMilli(creationTime);
+    } else {
+      this.modificationTime = Instant.ofEpochMilli(modifiedTime);
+    }
   }
 
-
   /**
    * Returns Volume Name.
    *
@@ -246,6 +290,15 @@ public class OzoneBucket extends WithMetadata {
   }
 
   /**
+   * Returns modification time of the Bucket.
+   *
+   * @return modification time of the bucket
+   */
+  public Instant getModificationTime() {
+    return modificationTime;
+  }
+
+  /**
    * Return the bucket encryption key name.
    * @return the bucket encryption key name
    */
diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneVolume.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneVolume.java
index 07c1e26..9978cc7 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneVolume.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneVolume.java
@@ -69,6 +69,10 @@ public class OzoneVolume extends WithMetadata {
    */
   private Instant creationTime;
   /**
+   * Modification time of the volume.
+   */
+  private Instant modificationTime;
+  /**
    * Volume ACLs.
    */
   private List<OzoneAcl> acls;
@@ -89,10 +93,8 @@ public class OzoneVolume extends WithMetadata {
    */
   @SuppressWarnings("parameternumber")
   public OzoneVolume(ConfigurationSource conf, ClientProtocol proxy,
-      String name,
-      String admin, String owner, long quotaInBytes,
-      long creationTime, List<OzoneAcl> acls,
-      Map<String, String> metadata) {
+      String name, String admin, String owner, long quotaInBytes,
+      long creationTime, List<OzoneAcl> acls, Map<String, String> metadata) {
     Preconditions.checkNotNull(proxy, "Client proxy is not set.");
     this.proxy = proxy;
     this.name = name;
@@ -103,21 +105,50 @@ public class OzoneVolume extends WithMetadata {
     this.acls = acls;
     this.listCacheSize = HddsClientUtils.getListCacheSize(conf);
     this.metadata = metadata;
+    modificationTime = Instant.now();
+    if (modificationTime.isBefore(this.creationTime)) {
+      modificationTime = Instant.ofEpochSecond(
+          this.creationTime.getEpochSecond(), this.creationTime.getNano());
+    }
+  }
+
+  /**
+   * @param modificationTime modification time of the volume.
+   */
+  @SuppressWarnings("parameternumber")
+  public OzoneVolume(ConfigurationSource conf, ClientProtocol proxy,
+      String name, String admin, String owner, long quotaInBytes,
+      long creationTime, long modificationTime, List<OzoneAcl> acls,
+      Map<String, String> metadata) {
+    this(conf, proxy, name, admin, owner, quotaInBytes,
+        creationTime, acls, metadata);
+    this.modificationTime = Instant.ofEpochMilli(modificationTime);
   }
 
   @SuppressWarnings("parameternumber")
   public OzoneVolume(ConfigurationSource conf, ClientProtocol proxy,
-      String name,
-      String admin, String owner, long quotaInBytes,
+      String name, String admin, String owner, long quotaInBytes,
       long creationTime, List<OzoneAcl> acls) {
     this(conf, proxy, name, admin, owner, quotaInBytes, creationTime, acls,
         new HashMap<>());
+    modificationTime = Instant.now();
+    if (modificationTime.isBefore(this.creationTime)) {
+      modificationTime = Instant.ofEpochSecond(
+          this.creationTime.getEpochSecond(), this.creationTime.getNano());
+    }
+  }
+
+  @SuppressWarnings("parameternumber")
+  public OzoneVolume(ConfigurationSource conf, ClientProtocol proxy,
+      String name, String admin, String owner, long quotaInBytes,
+      long creationTime, long modificationTime, List<OzoneAcl> acls) {
+    this(conf, proxy, name, admin, owner, quotaInBytes, creationTime, acls);
+    this.modificationTime = Instant.ofEpochMilli(modificationTime);
   }
 
   @VisibleForTesting
   protected OzoneVolume(String name, String admin, String owner,
-      long quotaInBytes,
-      long creationTime, List<OzoneAcl> acls) {
+      long quotaInBytes, long creationTime, List<OzoneAcl> acls) {
     this.proxy = null;
     this.name = name;
     this.admin = admin;
@@ -126,6 +157,19 @@ public class OzoneVolume extends WithMetadata {
     this.creationTime = Instant.ofEpochMilli(creationTime);
     this.acls = acls;
     this.metadata = new HashMap<>();
+    modificationTime = Instant.now();
+    if (modificationTime.isBefore(this.creationTime)) {
+      modificationTime = Instant.ofEpochSecond(
+          this.creationTime.getEpochSecond(), this.creationTime.getNano());
+    }
+  }
+
+  @VisibleForTesting
+  protected OzoneVolume(String name, String admin, String owner,
+      long quotaInBytes, long creationTime, long modificationTime,
+      List<OzoneAcl> acls) {
+    this(name, admin, owner, quotaInBytes, creationTime, acls);
+    this.modificationTime = Instant.ofEpochMilli(modificationTime);
   }
 
   /**
@@ -174,6 +218,15 @@ public class OzoneVolume extends WithMetadata {
   }
 
   /**
+   * Returns modification time of the volume.
+   *
+   * @return modification time.
+   */
+  public Instant getModificationTime() {
+    return modificationTime;
+  }
+
+  /**
    * Returns OzoneAcl list associated with the Volume.
    *
    * @return aclMap
diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
index dcdce10..d488343 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
@@ -345,6 +345,7 @@ public class RpcClient implements ClientProtocol {
         volume.getOwnerName(),
         volume.getQuotaInBytes(),
         volume.getCreationTime(),
+        volume.getModificationTime(),
         volume.getAclMap().ozoneAclGetProtobuf().stream().
             map(OzoneAcl::fromProtobuf).collect(Collectors.toList()),
         volume.getMetadata());
@@ -377,6 +378,7 @@ public class RpcClient implements ClientProtocol {
         volume.getOwnerName(),
         volume.getQuotaInBytes(),
         volume.getCreationTime(),
+        volume.getModificationTime(),
         volume.getAclMap().ozoneAclGetProtobuf().stream().
             map(OzoneAcl::fromProtobuf).collect(Collectors.toList())))
         .collect(Collectors.toList());
@@ -397,6 +399,7 @@ public class RpcClient implements ClientProtocol {
         volume.getOwnerName(),
         volume.getQuotaInBytes(),
         volume.getCreationTime(),
+        volume.getModificationTime(),
         volume.getAclMap().ozoneAclGetProtobuf().stream().
             map(OzoneAcl::fromProtobuf).collect(Collectors.toList()),
         volume.getMetadata()))
@@ -604,6 +607,7 @@ public class RpcClient implements ClientProtocol {
         bucketInfo.getStorageType(),
         bucketInfo.getIsVersionEnabled(),
         bucketInfo.getCreationTime(),
+        bucketInfo.getModificationTime(),
         bucketInfo.getMetadata(),
         bucketInfo.getEncryptionKeyInfo() != null ? bucketInfo
             .getEncryptionKeyInfo().getKeyName() : null);
@@ -624,6 +628,7 @@ public class RpcClient implements ClientProtocol {
         bucket.getStorageType(),
         bucket.getIsVersionEnabled(),
         bucket.getCreationTime(),
+        bucket.getModificationTime(),
         bucket.getMetadata(),
         bucket.getEncryptionKeyInfo() != null ? bucket
             .getEncryptionKeyInfo().getKeyName() : null))
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmBucketInfo.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmBucketInfo.java
index f8c4d7a..e9a8cbc 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmBucketInfo.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmBucketInfo.java
@@ -66,6 +66,10 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
    * Creation time of bucket.
    */
   private final long creationTime;
+  /**
+   * modification time of bucket.
+   */
+  private long modificationTime;
 
   /**
    * Bucket encryption key info if encryption is enabled.
@@ -80,6 +84,7 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
    * @param isVersionEnabled - Bucket version flag.
    * @param storageType - Storage type to be used.
    * @param creationTime - Bucket creation time.
+   * @param modificationTime - Bucket modification time.
    * @param metadata - metadata.
    * @param bekInfo - bucket encryption key info.
    */
@@ -90,6 +95,7 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
                        boolean isVersionEnabled,
                        StorageType storageType,
                        long creationTime,
+                       long modificationTime,
                        long objectID,
                        long updateID,
                        Map<String, String> metadata,
@@ -100,6 +106,7 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
     this.isVersionEnabled = isVersionEnabled;
     this.storageType = storageType;
     this.creationTime = creationTime;
+    this.modificationTime = modificationTime;
     this.objectID = objectID;
     this.updateID = updateID;
     this.metadata = metadata;
@@ -185,6 +192,15 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
   }
 
   /**
+   * Returns modification time.
+   * @return long
+   */
+  public long getModificationTime() {
+    return modificationTime;
+  }
+
+
+  /**
    * Returns bucket encryption key info.
    * @return bucket encryption key info
    */
@@ -217,6 +233,8 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
     auditMap.put(OzoneConsts.CREATION_TIME, String.valueOf(this.creationTime));
     auditMap.put(OzoneConsts.BUCKET_ENCRYPTION_KEY,
         (bekInfo != null) ? bekInfo.getKeyName() : null);
+    auditMap.put(OzoneConsts.MODIFICATION_TIME,
+        String.valueOf(this.modificationTime));
     return auditMap;
   }
 
@@ -230,6 +248,7 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
         .setStorageType(storageType)
         .setIsVersionEnabled(isVersionEnabled)
         .setCreationTime(creationTime)
+        .setModificationTime(modificationTime)
         .setObjectID(objectID)
         .setUpdateID(updateID)
         .setBucketEncryptionKey(bekInfo != null ?
@@ -257,6 +276,7 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
     private Boolean isVersionEnabled;
     private StorageType storageType;
     private long creationTime;
+    private long modificationTime;
     private long objectID;
     private long updateID;
     private Map<String, String> metadata;
@@ -309,6 +329,11 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
       return this;
     }
 
+    public Builder setModificationTime(long modifiedOn) {
+      this.modificationTime = modifiedOn;
+      return this;
+    }
+
     public Builder setObjectID(long obId) {
       this.objectID = obId;
       return this;
@@ -349,7 +374,8 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
       Preconditions.checkNotNull(storageType);
 
       return new OmBucketInfo(volumeName, bucketName, acls, isVersionEnabled,
-          storageType, creationTime, objectID, updateID, metadata, bekInfo);
+          storageType, creationTime, modificationTime, objectID, updateID,
+          metadata, bekInfo);
     }
   }
 
@@ -364,6 +390,7 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
         .setIsVersionEnabled(isVersionEnabled)
         .setStorageType(storageType.toProto())
         .setCreationTime(creationTime)
+        .setModificationTime(modificationTime)
         .setObjectID(objectID)
         .setUpdateID(updateID)
         .addAllMetadata(KeyValueUtil.toProtobuf(metadata));
@@ -386,7 +413,8 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
             OzoneAcl::fromProtobuf).collect(Collectors.toList()))
         .setIsVersionEnabled(bucketInfo.getIsVersionEnabled())
         .setStorageType(StorageType.valueOf(bucketInfo.getStorageType()))
-        .setCreationTime(bucketInfo.getCreationTime());
+        .setCreationTime(bucketInfo.getCreationTime())
+        .setModificationTime(bucketInfo.getModificationTime());
     if (bucketInfo.hasObjectID()) {
       obib.setObjectID(bucketInfo.getObjectID());
     }
@@ -424,6 +452,7 @@ public final class OmBucketInfo extends WithObjectID 
implements Auditable {
     }
     OmBucketInfo that = (OmBucketInfo) o;
     return creationTime == that.creationTime &&
+        modificationTime == that.modificationTime &&
         volumeName.equals(that.volumeName) &&
         bucketName.equals(that.bucketName) &&
         Objects.equals(acls, that.acls) &&
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmVolumeArgs.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmVolumeArgs.java
index 26d0b23..b9caf9d 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmVolumeArgs.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmVolumeArgs.java
@@ -42,6 +42,7 @@ public final class OmVolumeArgs extends WithObjectID 
implements Auditable {
   private String ownerName;
   private final String volume;
   private long creationTime;
+  private long modificationTime;
   private long quotaInBytes;
   private final OmOzoneAclMap aclMap;
 
@@ -62,8 +63,8 @@ public final class OmVolumeArgs extends WithObjectID 
implements Auditable {
       "builder."})
   private OmVolumeArgs(String adminName, String ownerName, String volume,
                        long quotaInBytes, Map<String, String> metadata,
-                       OmOzoneAclMap aclMap, long creationTime, long objectID,
-                      long updateID) {
+                       OmOzoneAclMap aclMap, long creationTime,
+                       long modificationTime, long objectID, long updateID) {
     this.adminName = adminName;
     this.ownerName = ownerName;
     this.volume = volume;
@@ -71,6 +72,7 @@ public final class OmVolumeArgs extends WithObjectID 
implements Auditable {
     this.metadata = metadata;
     this.aclMap = aclMap;
     this.creationTime = creationTime;
+    this.modificationTime = modificationTime;
     this.objectID = objectID;
     this.updateID = updateID;
   }
@@ -88,6 +90,10 @@ public final class OmVolumeArgs extends WithObjectID 
implements Auditable {
     this.creationTime = time;
   }
 
+  public void setModificationTime(long time) {
+    this.modificationTime = time;
+  }
+
   public void addAcl(OzoneAcl acl) throws OMException {
     this.aclMap.addAcl(acl);
   }
@@ -133,6 +139,14 @@ public final class OmVolumeArgs extends WithObjectID 
implements Auditable {
   }
 
   /**
+   * Returns modification time.
+   * @return long
+   */
+  public long getModificationTime() {
+    return modificationTime;
+  }
+
+  /**
    * Returns Quota in Bytes.
    * @return long, Quota in bytes.
    */
@@ -159,6 +173,8 @@ public final class OmVolumeArgs extends WithObjectID 
implements Auditable {
     auditMap.put(OzoneConsts.OWNER, this.ownerName);
     auditMap.put(OzoneConsts.VOLUME, this.volume);
     auditMap.put(OzoneConsts.CREATION_TIME, String.valueOf(this.creationTime));
+    auditMap.put(OzoneConsts.MODIFICATION_TIME,
+        String.valueOf(this.modificationTime));
     auditMap.put(OzoneConsts.QUOTA_IN_BYTES, 
String.valueOf(this.quotaInBytes));
     auditMap.put(OzoneConsts.OBJECT_ID, String.valueOf(this.getObjectID()));
     auditMap.put(OzoneConsts.UPDATE_ID, String.valueOf(this.getUpdateID()));
@@ -190,6 +206,7 @@ public final class OmVolumeArgs extends WithObjectID 
implements Auditable {
     private String ownerName;
     private String volume;
     private long creationTime;
+    private long modificationTime;
     private long quotaInBytes;
     private Map<String, String> metadata;
     private OmOzoneAclMap aclMap;
@@ -245,6 +262,11 @@ public final class OmVolumeArgs extends WithObjectID 
implements Auditable {
       return this;
     }
 
+    public Builder setModificationTime(long modifiedOn) {
+      this.modificationTime = modifiedOn;
+      return this;
+    }
+
     public Builder setQuotaInBytes(long quota) {
       this.quotaInBytes = quota;
       return this;
@@ -276,7 +298,7 @@ public final class OmVolumeArgs extends WithObjectID 
implements Auditable {
       Preconditions.checkNotNull(ownerName);
       Preconditions.checkNotNull(volume);
       return new OmVolumeArgs(adminName, ownerName, volume, quotaInBytes,
-          metadata, aclMap, creationTime, objectID, updateID);
+          metadata, aclMap, creationTime, modificationTime, objectID, 
updateID);
     }
 
   }
@@ -292,6 +314,7 @@ public final class OmVolumeArgs extends WithObjectID 
implements Auditable {
         .addAllVolumeAcls(aclList)
         .setCreationTime(
             creationTime == 0 ? System.currentTimeMillis() : creationTime)
+        .setModificationTime(modificationTime)
         .setObjectID(objectID)
         .setUpdateID(updateID)
         .build();
@@ -309,6 +332,7 @@ public final class OmVolumeArgs extends WithObjectID 
implements Auditable {
         KeyValueUtil.getFromProtobuf(volInfo.getMetadataList()),
         aclMap,
         volInfo.getCreationTime(),
+        volInfo.getModificationTime(),
         volInfo.getObjectID(),
         volInfo.getUpdateID());
   }
@@ -336,6 +360,7 @@ public final class OmVolumeArgs extends WithObjectID 
implements Auditable {
     OmOzoneAclMap cloneAclMap = aclMap.copyObject();
 
     return new OmVolumeArgs(adminName, ownerName, volume, quotaInBytes,
-        cloneMetadata, cloneAclMap, creationTime, objectID, updateID);
+        cloneMetadata, cloneAclMap, creationTime, modificationTime,
+        objectID, updateID);
   }
 }
diff --git 
a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto 
b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index 5c47cfa..ba193c7 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -349,6 +349,7 @@ message VolumeInfo {
     optional uint64 creationTime = 7;
     optional uint64 objectID = 8;
     optional uint64 updateID = 9;
+    optional uint64 modificationTime = 10;
 }
 
 /**
@@ -406,6 +407,7 @@ message SetVolumePropertyRequest {
     required string volumeName = 1;
     optional string ownerName = 2;
     optional uint64 quotaInBytes = 3;
+    optional uint64 modificationTime = 4;
 }
 
 message SetVolumePropertyResponse {
@@ -481,6 +483,7 @@ message BucketInfo {
     optional BucketEncryptionInfoProto beinfo = 8;
     optional uint64 objectID = 9;
     optional uint64 updateID = 10;
+    optional uint64 modificationTime = 11;
 }
 
 enum StorageTypeProto {
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/bucket/OMBucketCreateRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/bucket/OMBucketCreateRequest.java
index 12d86ba..8181a64 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/bucket/OMBucketCreateRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/bucket/OMBucketCreateRequest.java
@@ -104,8 +104,10 @@ public class OMBucketCreateRequest extends OMClientRequest 
{
 
     BucketInfo.Builder newBucketInfo = bucketInfo.toBuilder();
 
-    // Set creation time.
-    newBucketInfo.setCreationTime(Time.now());
+    // Set creation time & modification time.
+    long initialTime = Time.now();
+    newBucketInfo.setCreationTime(initialTime)
+        .setModificationTime(initialTime);
 
     if (bucketInfo.hasBeinfo()) {
       newBucketInfo.setBeinfo(getBeinfo(kmsProvider, bucketInfo));
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeCreateRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeCreateRequest.java
index dcd66c7..765a20c 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeCreateRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeCreateRequest.java
@@ -76,9 +76,13 @@ public class OMVolumeCreateRequest extends OMVolumeRequest {
     // Verify resource name
     OmUtils.validateVolumeName(volumeInfo.getVolume());
 
-    // Set creation time
+    // Set creation time & set modification time
+    long initialTime = Time.now();
     VolumeInfo updatedVolumeInfo =
-        volumeInfo.toBuilder().setCreationTime(Time.now()).build();
+        volumeInfo.toBuilder()
+            .setCreationTime(initialTime)
+            .setModificationTime(initialTime)
+            .build();
 
     return getOmRequest().toBuilder().setCreateVolumeRequest(
         CreateVolumeRequest.newBuilder().setVolumeInfo(updatedVolumeInfo))
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeSetOwnerRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeSetOwnerRequest.java
index 898f345..1eea419 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeSetOwnerRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeSetOwnerRequest.java
@@ -23,6 +23,7 @@ import java.util.Map;
 
 import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
 import org.apache.hadoop.ozone.om.request.util.OmResponseUtil;
+import org.apache.hadoop.util.Time;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import com.google.common.base.Optional;
@@ -66,10 +67,23 @@ public class OMVolumeSetOwnerRequest extends 
OMVolumeRequest {
   }
 
   @Override
+  public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
+
+    long modificationTime = Time.now();
+    SetVolumePropertyRequest modifiedRequest = getOmRequest()
+        .getSetVolumePropertyRequest().toBuilder()
+        .setModificationTime(modificationTime).build();
+
+    return getOmRequest().toBuilder()
+        .setSetVolumePropertyRequest(modifiedRequest.toBuilder())
+        .setUserInfo(getUserInfo())
+        .build();
+  }
+
+  @Override
   public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
       long transactionLogIndex,
       OzoneManagerDoubleBufferHelper ozoneManagerDoubleBufferHelper) {
-
     SetVolumePropertyRequest setVolumePropertyRequest =
         getOmRequest().getSetVolumePropertyRequest();
     Preconditions.checkNotNull(setVolumePropertyRequest);
@@ -134,7 +148,6 @@ public class OMVolumeSetOwnerRequest extends 
OMVolumeRequest {
             transactionLogIndex, setVolumePropertyRequest);
         return new 
OMVolumeSetOwnerResponse(createReplayOMResponse(omResponse));
       }
-
       oldOwner = omVolumeArgs.getOwnerName();
 
       // Return OK immediately if newOwner is the same as oldOwner.
@@ -167,6 +180,10 @@ public class OMVolumeSetOwnerRequest extends 
OMVolumeRequest {
       omVolumeArgs.setUpdateID(transactionLogIndex,
           ozoneManager.isRatisEnabled());
 
+      // Update modificationTime.
+      omVolumeArgs.setModificationTime(
+          setVolumePropertyRequest.getModificationTime());
+
       // Update cache.
       omMetadataManager.getUserTable().addCacheEntry(
           new CacheKey<>(omMetadataManager.getUserKey(newOwner)),
@@ -184,7 +201,6 @@ public class OMVolumeSetOwnerRequest extends 
OMVolumeRequest {
           SetVolumePropertyResponse.newBuilder().setResponse(true).build());
       omClientResponse = new OMVolumeSetOwnerResponse(omResponse.build(),
           oldOwner, oldOwnerVolumeList, newOwnerVolumeList, omVolumeArgs);
-
     } catch (IOException ex) {
       exception = ex;
       omClientResponse = new OMVolumeSetOwnerResponse(
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeSetQuotaRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeSetQuotaRequest.java
index 91b02a2..7e0cb72 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeSetQuotaRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeSetQuotaRequest.java
@@ -25,6 +25,7 @@ import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
 import org.apache.hadoop.ozone.om.request.util.OmResponseUtil;
+import org.apache.hadoop.util.Time;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -66,6 +67,20 @@ public class OMVolumeSetQuotaRequest extends OMVolumeRequest 
{
   }
 
   @Override
+  public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
+
+    long modificationTime = Time.now();
+    SetVolumePropertyRequest modifiedRequest = getOmRequest()
+        .getSetVolumePropertyRequest().toBuilder()
+        .setModificationTime(modificationTime).build();
+
+    return getOmRequest().toBuilder()
+        .setSetVolumePropertyRequest(modifiedRequest.toBuilder())
+        .setUserInfo(getUserInfo())
+        .build();
+  }
+
+  @Override
   public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
       long transactionLogIndex,
       OzoneManagerDoubleBufferHelper ozoneManagerDoubleBufferHelper) {
@@ -133,6 +148,8 @@ public class OMVolumeSetQuotaRequest extends 
OMVolumeRequest {
       omVolumeArgs.setQuotaInBytes(setVolumePropertyRequest.getQuotaInBytes());
       omVolumeArgs.setUpdateID(transactionLogIndex,
           ozoneManager.isRatisEnabled());
+      omVolumeArgs.setModificationTime(
+          setVolumePropertyRequest.getModificationTime());
 
       // update cache.
       omMetadataManager.getVolumeTable().addCacheEntry(
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMRequestUtils.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMRequestUtils.java
index c5aa9fe..dadeacb 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMRequestUtils.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMRequestUtils.java
@@ -350,7 +350,7 @@ public final class TestOMRequestUtils {
       String newOwner) {
     SetVolumePropertyRequest setVolumePropertyRequest =
         SetVolumePropertyRequest.newBuilder().setVolumeName(volumeName)
-            .setOwnerName(newOwner).build();
+            .setOwnerName(newOwner).setModificationTime(Time.now()).build();
 
     return OMRequest.newBuilder().setClientId(UUID.randomUUID().toString())
         .setCmdType(OzoneManagerProtocolProtos.Type.SetVolumeProperty)
@@ -368,7 +368,7 @@ public final class TestOMRequestUtils {
       long quota) {
     SetVolumePropertyRequest setVolumePropertyRequest =
         SetVolumePropertyRequest.newBuilder().setVolumeName(volumeName)
-            .setQuotaInBytes(quota).build();
+            .setQuotaInBytes(quota).setModificationTime(Time.now()).build();
 
     return OMRequest.newBuilder().setClientId(UUID.randomUUID().toString())
         .setCmdType(OzoneManagerProtocolProtos.Type.SetVolumeProperty)
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/bucket/TestOMBucketCreateRequest.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/bucket/TestOMBucketCreateRequest.java
index ab5ad6b..7bef6b8 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/bucket/TestOMBucketCreateRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/bucket/TestOMBucketCreateRequest.java
@@ -168,6 +168,8 @@ public class TestOMBucketCreateRequest extends 
TestBucketRequest {
 
     Assert.assertEquals(bucketInfoFromProto.getCreationTime(),
         dbBucketInfo.getCreationTime());
+    Assert.assertEquals(bucketInfoFromProto.getModificationTime(),
+        dbBucketInfo.getModificationTime());
     Assert.assertEquals(bucketInfoFromProto.getAcls(),
         dbBucketInfo.getAcls());
     Assert.assertEquals(bucketInfoFromProto.getIsVersionEnabled(),
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeCreateRequest.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeCreateRequest.java
index 05d0eba..27973ed 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeCreateRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeCreateRequest.java
@@ -139,6 +139,11 @@ public class TestOMVolumeCreateRequest extends 
TestOMVolumeRequest {
     Assert.assertEquals(expectedObjId, omVolumeArgs.getObjectID());
     Assert.assertEquals(txLogIndex, omVolumeArgs.getUpdateID());
 
+    // Initial modificationTime should be equal to creationTime.
+    long creationTime = omVolumeArgs.getCreationTime();
+    long modificationTime = omVolumeArgs.getModificationTime();
+    Assert.assertEquals(creationTime, modificationTime);
+
     // Check data from table and request.
     Assert.assertEquals(volumeInfo.getVolume(), omVolumeArgs.getVolume());
     Assert.assertEquals(volumeInfo.getOwnerName(), 
omVolumeArgs.getOwnerName());
@@ -236,6 +241,8 @@ public class TestOMVolumeCreateRequest extends 
TestOMVolumeRequest {
         updated.getOwnerName());
     Assert.assertNotEquals(original.getCreationTime(),
         updated.getCreationTime());
+    Assert.assertNotEquals(original.getModificationTime(),
+        updated.getModificationTime());
   }
 
   @Test
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeSetOwnerRequest.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeSetOwnerRequest.java
index c71c1a8..0e1ac54 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeSetOwnerRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeSetOwnerRequest.java
@@ -92,6 +92,13 @@ public class TestOMVolumeSetOwnerRequest extends 
TestOMVolumeRequest {
         .getVolumeTable().get(volumeKey).getOwnerName();
     Assert.assertEquals(newOwner, fromDBOwner);
 
+    // modificationTime should be greater than creationTime.
+    long creationTime = omMetadataManager.getVolumeTable()
+        .get(volumeKey).getCreationTime();
+    long modificationTime = omMetadataManager.getVolumeTable()
+        .get(volumeKey).getModificationTime();
+    Assert.assertTrue(modificationTime > creationTime);
+
 
     OzoneManagerProtocolProtos.UserVolumeInfo newOwnerVolumeList =
         omMetadataManager.getUserTable().get(newOwnerKey);
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeSetQuotaRequest.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeSetQuotaRequest.java
index c981c9f..bd90222 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeSetQuotaRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeSetQuotaRequest.java
@@ -92,6 +92,13 @@ public class TestOMVolumeSetQuotaRequest extends 
TestOMVolumeRequest {
         .getVolumeTable().get(volumeKey).getQuotaInBytes();
     Assert.assertEquals(quotaSet, quotaAfterSet);
     Assert.assertNotEquals(quotaBeforeSet, quotaAfterSet);
+
+    // modificationTime should be greater than creationTime.
+    long creationTime = omMetadataManager
+        .getVolumeTable().get(volumeKey).getCreationTime();
+    long modificationTime = omMetadataManager
+        .getVolumeTable().get(volumeKey).getModificationTime();
+    Assert.assertTrue(modificationTime > creationTime);
   }
 
   @Test
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ObjectStoreStub.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ObjectStoreStub.java
index b0b8d43..b83cf6c 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ObjectStoreStub.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ObjectStoreStub.java
@@ -29,6 +29,7 @@ import java.util.stream.Collectors;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.scm.client.HddsClientUtils;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.util.Time;
 
 import static 
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.BUCKET_ALREADY_EXISTS;
 import static 
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.BUCKET_NOT_EMPTY;
@@ -59,14 +60,13 @@ public class ObjectStoreStub extends ObjectStore {
   }
 
   @Override
-  public void createVolume(String volumeName, VolumeArgs volumeArgs)
-      throws IOException {
+  public void createVolume(String volumeName, VolumeArgs volumeArgs) {
     OzoneVolumeStub volume =
         new OzoneVolumeStub(volumeName,
             volumeArgs.getAdmin(),
             volumeArgs.getOwner(),
             Long.parseLong(volumeArgs.getQuota()),
-            System.currentTimeMillis(),
+            Time.now(),
             volumeArgs.getAcls());
     volumes.put(volumeName, volume);
   }
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/OzoneVolumeStub.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/OzoneVolumeStub.java
index 67aa68a..8538bb2 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/OzoneVolumeStub.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/OzoneVolumeStub.java
@@ -29,6 +29,7 @@ import java.util.stream.Collectors;
 import org.apache.hadoop.hdds.protocol.StorageType;
 import org.apache.hadoop.ozone.OzoneAcl;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.util.Time;
 
 /**
  * Ozone volume with in-memory state for testing.
@@ -38,9 +39,9 @@ public class OzoneVolumeStub extends OzoneVolume {
   private Map<String, OzoneBucketStub> buckets = new HashMap<>();
 
   public OzoneVolumeStub(String name, String admin, String owner,
-      long quotaInBytes,
-      long creationTime, List<OzoneAcl> acls) {
-    super(name, admin, owner, quotaInBytes, creationTime, acls);
+      long quotaInBytes, long creationTime, List<OzoneAcl> acls) {
+    super(name, admin, owner, quotaInBytes,
+        creationTime, acls);
   }
 
   @Override
@@ -58,8 +59,7 @@ public class OzoneVolumeStub extends OzoneVolume {
         bucketName,
         bucketArgs.getStorageType(),
         bucketArgs.getVersioning(),
-        System.currentTimeMillis()));
-
+        Time.now()));
   }
 
   @Override
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/volume/UpdateVolumeHandler.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/volume/UpdateVolumeHandler.java
index 52ba5f0..ba55e08 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/volume/UpdateVolumeHandler.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/volume/UpdateVolumeHandler.java
@@ -63,6 +63,8 @@ public class UpdateVolumeHandler extends VolumeHandler {
       }
     }
 
-    printObjectAsJson(volume);
+    // For printing newer modificationTime.
+    OzoneVolume updatedVolume = client.getObjectStore().getVolume(volumeName);
+    printObjectAsJson(updatedVolume);
   }
 }


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

Reply via email to