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

siyao pushed a commit to branch HDDS-4944
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/HDDS-4944 by this push:
     new 2e6754f  HDDS-6214. [Multi-Tenant] Fix KMS Encryption/Decryption 
(#3010)
2e6754f is described below

commit 2e6754f6cc0f077ee6738ca76820ac7c6db391ef
Author: Siyao Meng <[email protected]>
AuthorDate: Tue Feb 15 10:01:13 2022 -0800

    HDDS-6214. [Multi-Tenant] Fix KMS Encryption/Decryption (#3010)
---
 .../apache/hadoop/ozone/client/ObjectStore.java    | 37 ++++++++-
 .../ozone/client/protocol/ClientProtocol.java      | 15 ++--
 .../apache/hadoop/ozone/client/rpc/RpcClient.java  | 16 ++--
 .../main/java/org/apache/hadoop/ozone/OmUtils.java |  2 +-
 .../hadoop/ozone/om/helpers/DeleteTenantInfo.java  | 91 +++++++++++++++++++++
 .../hadoop/ozone/om/helpers/S3VolumeContext.java   | 94 ++++++++++++++++++++++
 .../ozone/om/protocol/OzoneManagerProtocol.java    |  7 +-
 .../apache/hadoop/ozone/om/protocol/S3Auth.java    | 18 ++++-
 ...OzoneManagerProtocolClientSideTranslatorPB.java | 25 +++---
 .../om/multitenant/TestMultiTenantVolume.java      |  4 +-
 .../src/main/proto/OmClientProtocol.proto          | 12 +--
 .../org/apache/hadoop/ozone/om/OzoneAclUtils.java  |  3 +-
 .../org/apache/hadoop/ozone/om/OzoneManager.java   | 24 ++++--
 .../hadoop/ozone/om/request/OMClientRequest.java   |  2 +-
 .../protocolPB/OzoneManagerRequestHandler.java     | 16 ++--
 .../hadoop/ozone/s3/OzoneClientProducer.java       |  4 +-
 .../shell/tenant/TenantAssignAdminHandler.java     |  6 +-
 .../ozone/shell/tenant/TenantDeleteHandler.java    |  4 +-
 18 files changed, 317 insertions(+), 63 deletions(-)

diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
index 6819718..12398dd 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
@@ -33,11 +33,14 @@ import org.apache.hadoop.io.Text;
 import org.apache.hadoop.ozone.OzoneAcl;
 import org.apache.hadoop.ozone.client.protocol.ClientProtocol;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
+import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
 import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
 import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
-import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
+import org.apache.hadoop.ozone.om.protocol.S3Auth;
 import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
 import org.apache.hadoop.ozone.security.acl.OzoneObj;
 import org.apache.hadoop.security.UserGroupInformation;
@@ -45,6 +48,8 @@ import org.apache.hadoop.security.UserGroupInformation;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Strings;
 import org.apache.hadoop.security.token.Token;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * ObjectStore class is responsible for the client operations that can be
@@ -52,6 +57,10 @@ import org.apache.hadoop.security.token.Token;
  */
 public class ObjectStore {
 
+  private static final Logger LOG =
+      LoggerFactory.getLogger(ObjectStore.class);
+
+  private final ConfigurationSource conf;
   /**
    * The proxy used for connecting to the cluster and perform
    * client operations.
@@ -71,6 +80,7 @@ public class ObjectStore {
    * @param proxy ClientProtocol proxy.
    */
   public ObjectStore(ConfigurationSource conf, ClientProtocol proxy) {
+    this.conf = conf;
     this.proxy = TracingUtil.createProxy(proxy, ClientProtocol.class, conf);
     this.listCacheSize = HddsClientUtils.getListCacheSize(conf);
     defaultS3Volume = HddsClientUtils.getDefaultS3VolumeName(conf);
@@ -79,7 +89,7 @@ public class ObjectStore {
   @VisibleForTesting
   protected ObjectStore() {
     // For the unit test
-    OzoneConfiguration conf = new OzoneConfiguration();
+    this.conf = new OzoneConfiguration();
     proxy = null;
     defaultS3Volume = HddsClientUtils.getDefaultS3VolumeName(conf);
   }
@@ -154,7 +164,25 @@ public class ObjectStore {
   }
 
   public OzoneVolume getS3Volume() throws IOException {
-    return proxy.getS3VolumeDetails();
+    final S3VolumeContext resp = proxy.getS3VolumeContext();
+
+    S3Auth s3Auth = proxy.getThreadLocalS3Auth();
+    // Update user principal if needed to be used for KMS client
+    if (s3Auth != null) {
+      // Update userPrincipal field with the value returned from OM. So that
+      //  in multi-tenancy, KMS client can use the correct identity
+      //  (instead of using accessId) to communicate with KMS.
+      LOG.debug("Updating S3Auth.userPrincipal to {}", 
resp.getUserPrincipal());
+      s3Auth.setUserPrincipal(resp.getUserPrincipal());
+      proxy.setTheadLocalS3Auth(s3Auth);
+    }
+
+    OmVolumeArgs volume = resp.getOmVolumeArgs();
+    return proxy.buildOzoneVolume(volume);
+  }
+
+  public S3VolumeContext getS3VolumeContext() throws IOException {
+    return proxy.getS3VolumeContext();
   }
 
   public S3SecretValue getS3Secret(String kerberosID) throws IOException {
@@ -207,8 +235,9 @@ public class ObjectStore {
    * Delete a tenant.
    * @param tenantId tenant name.
    * @throws IOException
+   * @return DeleteTenantInfo
    */
-  public DeleteTenantResponse deleteTenant(String tenantId) throws IOException 
{
+  public DeleteTenantInfo deleteTenant(String tenantId) throws IOException {
     return proxy.deleteTenant(tenantId);
   }
 
diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
index 639a340..2602fd6 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
@@ -43,17 +43,19 @@ import org.apache.hadoop.ozone.client.io.OzoneInputStream;
 import org.apache.hadoop.ozone.client.io.OzoneOutputStream;
 import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
 import org.apache.hadoop.ozone.om.helpers.OmMultipartInfo;
 import org.apache.hadoop.ozone.om.helpers.OmMultipartUploadCompleteInfo;
+import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
 import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
+import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
 import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
 import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
 import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol;
 import org.apache.hadoop.ozone.om.protocol.S3Auth;
-import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRoleInfo;
 import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
 import org.apache.hadoop.ozone.security.acl.OzoneObj;
@@ -124,11 +126,13 @@ public interface ClientProtocol {
       throws IOException;
 
   /**
-   * @return The {@link OzoneVolume} that should be used to for this S3
-   * request based on its access ID.
+   * @return Raw GetS3VolumeContextResponse.
+   * S3Auth won't be updated with actual userPrincipal by this call.
    * @throws IOException
    */
-  OzoneVolume getS3VolumeDetails() throws IOException;
+  S3VolumeContext getS3VolumeContext() throws IOException;
+
+  OzoneVolume buildOzoneVolume(OmVolumeArgs volume);
 
   /**
    * Checks if a Volume exists and the user with a role specified has access
@@ -609,8 +613,9 @@ public interface ClientProtocol {
    * Delete a tenant.
    * @param tenantId tenant name.
    * @throws IOException
+   * @return DeleteTenantInfo
    */
-  DeleteTenantResponse deleteTenant(String tenantId) throws IOException;
+  DeleteTenantInfo deleteTenant(String tenantId) throws IOException;
 
   /**
    * Assign a user to a tenant.
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 831fbd9..5d5e576 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
@@ -84,6 +84,7 @@ import org.apache.hadoop.ozone.client.protocol.ClientProtocol;
 import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.BucketEncryptionKeyInfo;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
 import org.apache.hadoop.ozone.om.helpers.OmBucketArgs;
 import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
 import org.apache.hadoop.ozone.om.helpers.OmDeleteKeys;
@@ -104,6 +105,7 @@ import org.apache.hadoop.ozone.om.helpers.OzoneAclUtil;
 import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
+import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
 import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
@@ -115,7 +117,6 @@ import org.apache.hadoop.ozone.om.protocolPB.OmTransport;
 import org.apache.hadoop.ozone.om.protocolPB.OmTransportFactory;
 import org.apache.hadoop.ozone.om.protocolPB.OzoneManagerClientProtocol;
 import 
org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolClientSideTranslatorPB;
-import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRoleInfo;
 import org.apache.hadoop.ozone.security.GDPRSymmetricKey;
 import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
@@ -437,12 +438,11 @@ public class RpcClient implements ClientProtocol {
   }
 
   @Override
-  public OzoneVolume getS3VolumeDetails() throws IOException {
-    OmVolumeArgs volume = ozoneManagerClient.getS3Volume();
-    return buildOzoneVolume(volume);
+  public S3VolumeContext getS3VolumeContext() throws IOException {
+    return ozoneManagerClient.getS3VolumeContext();
   }
 
-  private OzoneVolume buildOzoneVolume(OmVolumeArgs volume) {
+  public OzoneVolume buildOzoneVolume(OmVolumeArgs volume) {
     return new OzoneVolume(
         conf,
         this,
@@ -770,7 +770,7 @@ public class RpcClient implements ClientProtocol {
    * {@inheritDoc}
    */
   @Override
-  public DeleteTenantResponse deleteTenant(String tenantId) throws IOException 
{
+  public DeleteTenantInfo deleteTenant(String tenantId) throws IOException {
     Preconditions.checkArgument(Strings.isNotBlank(tenantId),
         "tenantId cannot be null or empty.");
     return ozoneManagerClient.deleteTenant(tenantId);
@@ -1062,8 +1062,10 @@ public class RpcClient implements ClientProtocol {
       UserGroupInformation loginUser = UserGroupInformation.getLoginUser();
       UserGroupInformation proxyUser;
       if (getThreadLocalS3Auth() != null) {
+        String userPrincipal = getThreadLocalS3Auth().getUserPrincipal();
+        Preconditions.checkNotNull(userPrincipal);
         UserGroupInformation s3gUGI = UserGroupInformation.createRemoteUser(
-            getThreadLocalS3Auth().getAccessID());
+            userPrincipal);
         proxyUser = UserGroupInformation.createProxyUser(
             s3gUGI.getShortUserName(), loginUser);
         decrypted = proxyUser.doAs(
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
index 19fb44c..be81b0a 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
@@ -263,7 +263,7 @@ public final class OmUtils {
     case ListMultipartUploads:
     case FinalizeUpgradeProgress:
     case PrepareStatus:
-    case GetS3Volume:
+    case GetS3VolumeContext:
     case ListTenant:
     case TenantGetUserInfo:
     case TenantListUser:
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/DeleteTenantInfo.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/DeleteTenantInfo.java
new file mode 100644
index 0000000..b38c3cd
--- /dev/null
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/DeleteTenantInfo.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.hadoop.ozone.om.helpers;
+
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
+
+/**
+ * A class that encapsulates DeleteTenantResponse protobuf message.
+ */
+public class DeleteTenantInfo {
+
+  /**
+   * Volume name associated to the deleted tenant.
+   */
+  private final String volumeName;
+
+  /**
+   * Reference count remaining of the volume associated to the deleted tenant.
+   */
+  private final long volRefCount;
+
+  public DeleteTenantInfo(String volumeName, long volRefCount) {
+    this.volumeName = volumeName;
+    this.volRefCount = volRefCount;
+  }
+
+  public String getVolumeName() {
+    return volumeName;
+  }
+
+  public long getVolRefCount() {
+    return volRefCount;
+  }
+
+  public static DeleteTenantInfo fromProtobuf(DeleteTenantResponse resp) {
+    return new DeleteTenantInfo(resp.getVolumeName(), resp.getVolRefCount());
+  }
+
+  public DeleteTenantResponse getProtobuf() {
+    return DeleteTenantResponse.newBuilder()
+        .setVolumeName(volumeName)
+        .setVolRefCount(volRefCount)
+        .build();
+  }
+
+  public static DeleteTenantInfo.Builder newBuilder() {
+    return new DeleteTenantInfo.Builder();
+  }
+
+  /**
+   * Builder for TenantDeleted.
+   */
+  @SuppressWarnings("checkstyle:hiddenfield")
+  public static final class Builder {
+    private String volumeName;
+    private long volRefCount;
+
+    private Builder() {
+    }
+
+    public Builder setVolumeName(String volumeName) {
+      this.volumeName = volumeName;
+      return this;
+    }
+
+    public Builder setVolRefCount(long volRefCount) {
+      this.volRefCount = volRefCount;
+      return this;
+    }
+
+    public DeleteTenantInfo build() {
+      return new DeleteTenantInfo(volumeName, volRefCount);
+    }
+  }
+}
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3VolumeContext.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3VolumeContext.java
new file mode 100644
index 0000000..dbbc354
--- /dev/null
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3VolumeContext.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.hadoop.ozone.om.helpers;
+
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3VolumeContextResponse;
+
+/**
+ * A class that encapsulates GetS3VolumeContextResponse protobuf message.
+ */
+public class S3VolumeContext {
+
+  /**
+   * Various volume arguments.
+   */
+  private final OmVolumeArgs omVolumeArgs;
+
+  /**
+   * Piggybacked username (principal) response.
+   * To be used for client-side operations involving KMS like getDEK().
+   */
+  private final String userPrincipal;
+
+  public S3VolumeContext(OmVolumeArgs omVolumeArgs, String userPrincipal) {
+    this.omVolumeArgs = omVolumeArgs;
+    this.userPrincipal = userPrincipal;
+  }
+
+  public OmVolumeArgs getOmVolumeArgs() {
+    return omVolumeArgs;
+  }
+
+  public String getUserPrincipal() {
+    return userPrincipal;
+  }
+
+  public static S3VolumeContext fromProtobuf(GetS3VolumeContextResponse resp) {
+    return new S3VolumeContext(
+        OmVolumeArgs.getFromProtobuf(resp.getVolumeInfo()),
+        resp.getUserPrincipal());
+  }
+
+  public GetS3VolumeContextResponse getProtobuf() {
+    return GetS3VolumeContextResponse.newBuilder()
+        .setVolumeInfo(omVolumeArgs.getProtobuf())
+        .setUserPrincipal(userPrincipal)
+        .build();
+  }
+
+  public static S3VolumeContext.Builder newBuilder() {
+    return new S3VolumeContext.Builder();
+  }
+
+  /**
+   * Builder for S3VolumeContext.
+   */
+  @SuppressWarnings("checkstyle:hiddenfield")
+  public static final class Builder {
+    private OmVolumeArgs omVolumeArgs;
+    private String userPrincipal;
+
+    private Builder() {
+    }
+
+    public Builder setOmVolumeArgs(OmVolumeArgs omVolumeArgs) {
+      this.omVolumeArgs = omVolumeArgs;
+      return this;
+    }
+
+    public Builder setUserPrincipal(String userPrincipal) {
+      this.userPrincipal = userPrincipal;
+      return this;
+    }
+
+    public S3VolumeContext build() {
+      return new S3VolumeContext(omVolumeArgs, userPrincipal);
+    }
+  }
+}
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
index b0c35e6..f144d62 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
@@ -27,6 +27,7 @@ import org.apache.hadoop.ozone.OzoneAcl;
 import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.DBUpdates;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
 import org.apache.hadoop.ozone.om.helpers.OmBucketArgs;
 import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
 import org.apache.hadoop.ozone.om.helpers.OmDeleteKeys;
@@ -46,13 +47,13 @@ import org.apache.hadoop.ozone.om.helpers.OpenKeySession;
 import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
+import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
 import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
 import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
 import org.apache.hadoop.ozone.om.helpers.TenantUserList;
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
-import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OzoneAclInfo;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PrepareStatusResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PrepareStatusResponse.PrepareStatus;
@@ -595,7 +596,7 @@ public interface OzoneManagerProtocol
    * @return DeleteTenantResponse
    * @throws IOException
    */
-  default DeleteTenantResponse deleteTenant(String tenantId)
+  default DeleteTenantInfo deleteTenant(String tenantId)
       throws IOException {
     throw new UnsupportedOperationException("OzoneManager does not require " +
         "this to be implemented, as write requests use a new approach");
@@ -617,7 +618,7 @@ public interface OzoneManagerProtocol
         "this to be implemented, as write requests use a new approach");
   }
 
-  OmVolumeArgs getS3Volume() throws IOException;
+  S3VolumeContext getS3VolumeContext() throws IOException;
 
   /**
    * Revoke user accessId to a tenant.
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/S3Auth.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/S3Auth.java
index aae81ad..932ff49 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/S3Auth.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/S3Auth.java
@@ -25,13 +25,19 @@ public class S3Auth {
   private String signature;
   private String accessID;
   public static final String S3_AUTH_CHECK = "ozone.s3.auth.check";
+  // User principal to be used for KMS encryption and decryption
+  private String userPrincipal;
 
   public S3Auth(final String stringToSign,
-                final String signature, final String accessID) {
-    this.accessID = accessID;
+                final String signature,
+                final String accessID,
+                final String userPrincipal) {
     this.stringToSign = stringToSign;
     this.signature = signature;
+    this.accessID = accessID;
+    this.userPrincipal = userPrincipal;
   }
+
   public String getStringTosSign() {
     return stringToSign;
   }
@@ -43,4 +49,12 @@ public class S3Auth {
   public String getAccessID() {
     return accessID;
   }
+
+  public String getUserPrincipal() {
+    return userPrincipal;
+  }
+
+  public void setUserPrincipal(String userPrincipal) {
+    this.userPrincipal = userPrincipal;
+  }
 }
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
index 40dccb6..3b161d7 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
@@ -34,6 +34,7 @@ import org.apache.hadoop.io.Text;
 import org.apache.hadoop.ozone.OzoneAcl;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.DBUpdates;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
 import org.apache.hadoop.ozone.om.helpers.KeyValueUtil;
 import org.apache.hadoop.ozone.om.helpers.OmBucketArgs;
 import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
@@ -55,6 +56,7 @@ import org.apache.hadoop.ozone.om.helpers.OpenKeySession;
 import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
+import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
 import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
@@ -986,7 +988,7 @@ public final class 
OzoneManagerProtocolClientSideTranslatorPB
   }
 
   @Override
-  public DeleteTenantResponse deleteTenant(String tenantId) throws IOException 
{
+  public DeleteTenantInfo deleteTenant(String tenantId) throws IOException {
     final DeleteTenantRequest request = DeleteTenantRequest.newBuilder()
         .setTenantId(tenantId)
         .build();
@@ -994,8 +996,9 @@ public final class 
OzoneManagerProtocolClientSideTranslatorPB
         .setDeleteTenantRequest(request)
         .build();
     final OMResponse omResponse = submitRequest(omRequest);
-
-    return handleError(omResponse).getDeleteTenantResponse();
+    final DeleteTenantResponse resp =
+        handleError(omResponse).getDeleteTenantResponse();
+    return DeleteTenantInfo.fromProtobuf(resp);
   }
 
   /**
@@ -1124,17 +1127,17 @@ public final class 
OzoneManagerProtocolClientSideTranslatorPB
   }
 
   @Override
-  public OmVolumeArgs getS3Volume() throws IOException {
-    final GetS3VolumeRequest request = GetS3VolumeRequest.newBuilder()
+  public S3VolumeContext getS3VolumeContext() throws IOException {
+    final GetS3VolumeContextRequest request = GetS3VolumeContextRequest
+        .newBuilder()
         .build();
-    final OMRequest omRequest = createOMRequest(Type.GetS3Volume)
-        .setGetS3VolumeRequest(request)
+    final OMRequest omRequest = createOMRequest(Type.GetS3VolumeContext)
+        .setGetS3VolumeContextRequest(request)
         .build();
     final OMResponse omResponse = submitRequest(omRequest);
-    final GetS3VolumeResponse resp = handleError(omResponse)
-        .getGetS3VolumeResponse();
-
-    return OmVolumeArgs.getFromProtobuf(resp.getVolumeInfo());
+    final GetS3VolumeContextResponse resp =
+        handleError(omResponse).getGetS3VolumeContextResponse();
+    return S3VolumeContext.fromProtobuf(resp);
   }
 
   /**
diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/multitenant/TestMultiTenantVolume.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/multitenant/TestMultiTenantVolume.java
index 0bb1d58..1975154 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/multitenant/TestMultiTenantVolume.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/multitenant/TestMultiTenantVolume.java
@@ -236,7 +236,9 @@ public class TestMultiTenantVolume {
     // Manually construct an object store instead of using the cluster
     // provided one so we can specify the access ID.
     RpcClient client = new RpcClient(conf, null);
-    client.setTheadLocalS3Auth(new S3Auth("unused1", "unused2", accessID));
+    // userPrincipal is set to be the same as accessId for the test
+    client.setTheadLocalS3Auth(
+        new S3Auth("unused1", "unused2", accessID, accessID));
     return new ObjectStore(conf, client);
   }
 }
diff --git 
a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto 
b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index 7573b99..77c5376 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -114,7 +114,7 @@ enum Type {
   TenantAssignAdmin = 102;
   TenantRevokeAdmin = 103;
 
-  GetS3Volume = 104;
+  GetS3VolumeContext = 104;
   TenantListUser = 105;
 
   SetS3Secret = 106;
@@ -214,7 +214,7 @@ message OMRequest {
   optional TenantAssignAdminRequest         TenantAssignAdminRequest       = 
102;
   optional TenantRevokeAdminRequest         TenantRevokeAdminRequest       = 
103;
 
-  optional GetS3VolumeRequest               getS3VolumeRequest             = 
104;
+  optional GetS3VolumeContextRequest        getS3VolumeContextRequest      = 
104;
   optional TenantListUserRequest            tenantListUserRequest          = 
105;
 
   optional SetS3SecretRequest               SetS3SecretRequest             = 
106;
@@ -307,7 +307,7 @@ message OMResponse {
   optional TenantAssignAdminResponse         TenantAssignAdminResponse     = 
102;
   optional TenantRevokeAdminResponse         TenantRevokeAdminResponse     = 
103;
 
-  optional GetS3VolumeResponse               getS3VolumeResponse           = 
104;
+  optional GetS3VolumeContextResponse        getS3VolumeContextResponse    = 
104;
   optional TenantListUserResponse            tenantListUserResponse        = 
105;
 
   optional SetS3SecretResponse               SetS3SecretResponse           = 
106;
@@ -1504,7 +1504,7 @@ message TenantRevokeAdminRequest {
     optional string tenantName = 2;
 }
 
-message GetS3VolumeRequest {
+message GetS3VolumeContextRequest {
 
 }
 
@@ -1541,8 +1541,10 @@ message OmDBAccessInfo {
   optional bool isDelegatedAdmin = 4;
 }
 
-message GetS3VolumeResponse {
+message GetS3VolumeContextResponse {
   optional VolumeInfo volumeInfo = 1;
+  // Piggybacked username (principal) response to be used for KMS client 
operations
+  optional string userPrincipal = 2;
 }
 
 /**
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneAclUtils.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneAclUtils.java
index 91eeaeb..5257279 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneAclUtils.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneAclUtils.java
@@ -47,7 +47,8 @@ public final class OzoneAclUtils {
    * If the access ID does not belong to a tenant, the access ID is returned
    * as is to be used as the principal.
    */
-  public static String principalToAccessID(String accessID) throws IOException 
{
+  public static String accessIdToUserPrincipal(String accessID)
+      throws IOException {
     String principal = multiTenantManager.getUserNameGivenAccessId(accessID);
     if (principal == null) {
       principal = accessID;
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
index 409212a..7d120e1 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
@@ -126,6 +126,7 @@ import 
org.apache.hadoop.ozone.om.helpers.OmMultipartUploadListParts;
 import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
 import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
+import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
 import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
@@ -2233,7 +2234,7 @@ public final class OzoneManager extends 
ServiceRuntimeInfoImpl
     UserGroupInformation user;
     if (getS3Auth() != null) {
       String principal =
-          OzoneAclUtils.principalToAccessID(getS3Auth().getAccessId());
+          OzoneAclUtils.accessIdToUserPrincipal(getS3Auth().getAccessId());
       user = UserGroupInformation.createRemoteUser(principal);
     } else {
       user = ProtobufRpcEngine.Server.getRemoteUser();
@@ -3077,12 +3078,13 @@ public final class OzoneManager extends 
ServiceRuntimeInfoImpl
   }
 
   @Override
-  public OmVolumeArgs getS3Volume() throws IOException {
+  public S3VolumeContext getS3VolumeContext() throws IOException {
     // Unless the OM request contains S3 authentication info with an access
     // ID that corresponds to a tenant volume, the request will be directed
     // to the default S3 volume.
     String s3Volume = HddsClientUtils.getDefaultS3VolumeName(configuration);
     S3Authentication s3Auth = getS3Auth();
+    String userPrincipal = Server.getRemoteUser().getShortUserName();
 
     if (s3Auth != null) {
       String accessID = s3Auth.getAccessId();
@@ -3110,6 +3112,9 @@ public final class OzoneManager extends 
ServiceRuntimeInfoImpl
                   "tenant {} is directed to the volume {}.", accessID, 
tenantId,
               s3Volume);
         }
+
+        // Inject user name to the response to be used for KMS on the client
+        userPrincipal = OzoneAclUtils.accessIdToUserPrincipal(accessID);
       } else if (LOG.isDebugEnabled()) {
         LOG.debug("No tenant found for access ID {}. Directing " +
             "requests to default s3 volume {}.", accessID, s3Volume);
@@ -3123,8 +3128,12 @@ public final class OzoneManager extends 
ServiceRuntimeInfoImpl
           s3Volume);
     }
 
-    // This call performs acl checks and checks volume existence.
-    return getVolumeInfo(s3Volume);
+    // getVolumeInfo() performs acl checks and checks volume existence.
+    final S3VolumeContext.Builder s3VolumeContext = 
S3VolumeContext.newBuilder()
+        .setOmVolumeArgs(getVolumeInfo(s3Volume))
+        .setUserPrincipal(userPrincipal);
+
+    return s3VolumeContext.build();
   }
 
   @Override
@@ -3862,7 +3871,8 @@ public final class OzoneManager extends 
ServiceRuntimeInfoImpl
       if (getS3Auth() != null) {
         ugi = UserGroupInformation
             .createRemoteUser(
-                OzoneAclUtils.principalToAccessID(getS3Auth().getAccessId()));
+                OzoneAclUtils.accessIdToUserPrincipal(
+                    getS3Auth().getAccessId()));
       }
       InetAddress remoteIp = Server.getRemoteIp();
       resolved = resolveBucketLink(requested, new HashSet<>(),
@@ -3960,7 +3970,7 @@ public final class OzoneManager extends 
ServiceRuntimeInfoImpl
 
       // Add volume and user info to DB and cache.
 
-      OmVolumeArgs omVolumeArgs = createS3VolumeInfo(s3VolumeName, objectID);
+      OmVolumeArgs omVolumeArgs = createS3VolumeContext(s3VolumeName, 
objectID);
 
       String dbUserKey = metadataManager.getUserKey(userName);
       PersistedUserVolumeInfo userVolumeInfo =
@@ -3994,7 +4004,7 @@ public final class OzoneManager extends 
ServiceRuntimeInfoImpl
     }
   }
 
-  private OmVolumeArgs createS3VolumeInfo(String s3Volume,
+  private OmVolumeArgs createS3VolumeContext(String s3Volume,
       long objectID) throws IOException {
     String userName = UserGroupInformation.getCurrentUser().getShortUserName();
     long time = Time.now();
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/OMClientRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/OMClientRequest.java
index e430665..8d1a8f1 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/OMClientRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/OMClientRequest.java
@@ -141,7 +141,7 @@ public abstract class OMClientRequest implements 
RequestAuditor {
 
     // If S3 Authentication is set, determine user based on access ID.
     if (omRequest.hasS3Authentication()) {
-      String principal = OzoneAclUtils.principalToAccessID(
+      String principal = OzoneAclUtils.accessIdToUserPrincipal(
           omRequest.getS3Authentication().getAccessId());
       userInfo.setUserName(principal);
     } else if (user != null) {
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
index b6e5137..d98cbae 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
@@ -81,7 +81,7 @@ import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRespo
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PrepareStatusResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListResponse;
-import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3VolumeResponse;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3VolumeContextResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantGetUserInfoRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantGetUserInfoResponse;
@@ -229,9 +229,10 @@ public class OzoneManagerRequestHandler implements 
RequestHandler {
         PrepareStatusResponse prepareStatusResponse = getPrepareStatus();
         responseBuilder.setPrepareStatusResponse(prepareStatusResponse);
         break;
-      case GetS3Volume:
-        GetS3VolumeResponse s3VolumeResponse = getS3Volume();
-        responseBuilder.setGetS3VolumeResponse(s3VolumeResponse);
+      case GetS3VolumeContext:
+        GetS3VolumeContextResponse s3VolumeContextResponse =
+            getS3VolumeContext();
+        responseBuilder.setGetS3VolumeContextResponse(s3VolumeContextResponse);
         break;
       case TenantGetUserInfo:
         TenantGetUserInfoResponse getUserInfoResponse = tenantGetUserInfo(
@@ -713,12 +714,9 @@ public class OzoneManagerRequestHandler implements 
RequestHandler {
         .setCurrentTxnIndex(prepareState.getIndex()).build();
   }
 
-  private GetS3VolumeResponse getS3Volume()
+  private GetS3VolumeContextResponse getS3VolumeContext()
       throws IOException {
-    OmVolumeArgs s3VolArgs = impl.getS3Volume();
-    return GetS3VolumeResponse.newBuilder()
-        .setVolumeInfo(s3VolArgs.getProtobuf())
-        .build();
+    return impl.getS3VolumeContext().getProtobuf();
   }
 
   public OzoneManager getOzoneManager() {
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/OzoneClientProducer.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/OzoneClientProducer.java
index b81b0aa..a6897fd 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/OzoneClientProducer.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/OzoneClientProducer.java
@@ -91,9 +91,11 @@ public class OzoneClientProducer {
 
       String awsAccessId = signatureInfo.getAwsAccessId();
       validateAccessId(awsAccessId);
+      // Note: userPrincipal is initialized to be the same value as accessId,
+      //  could be updated later in RpcClient#getS3Volume
       return new S3Auth(stringToSign,
           signatureInfo.getSignature(),
-          awsAccessId);
+          awsAccessId, awsAccessId);
     } catch (OS3Exception ex) {
       LOG.debug("Error during Client Creation: ", ex);
       throw wrapOS3Exception(ex);
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantAssignAdminHandler.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantAssignAdminHandler.java
index 2029dec..1de3ec1 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantAssignAdminHandler.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantAssignAdminHandler.java
@@ -59,11 +59,11 @@ public class TenantAssignAdminHandler extends TenantHandler 
{
         objStore.tenantAssignAdmin(accessId, tenantId, delegated);
         // TODO: Make tenantAssignAdmin return accessId, tenantName, user 
later.
         err().println("Assigned admin to '" + accessId +
-            (tenantId != null ? "' in tenant '" + tenantId + "'" : ""));
+            (tenantId != null ? "' in tenant '" + tenantId : "") + "'");
       } catch (IOException e) {
         err().println("Failed to assign admin to '" + accessId +
-            (tenantId != null ? "' in tenant '" + tenantId + "'" : "") +
-            ": " + e.getMessage());
+            (tenantId != null ? "' in tenant '" + tenantId : "") + "': " +
+            e.getMessage());
         if (e instanceof OMException) {
           final OMException omEx = (OMException) e;
           // Don't bother continuing the loop if current user isn't Ozone admin
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java
index 1f8067d..1a88105 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java
@@ -18,7 +18,7 @@
 package org.apache.hadoop.ozone.shell.tenant;
 
 import org.apache.hadoop.ozone.client.OzoneClient;
-import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
 import org.apache.hadoop.ozone.shell.OzoneAddress;
 import picocli.CommandLine;
 
@@ -39,7 +39,7 @@ public class TenantDeleteHandler extends TenantHandler {
   protected void execute(OzoneClient client, OzoneAddress address)
       throws IOException {
     try {
-      final DeleteTenantResponse resp =
+      final DeleteTenantInfo resp =
           client.getObjectStore().deleteTenant(tenantId);
       out().println("Deleted tenant '" + tenantId + "'.");
       long volumeRefCount = resp.getVolRefCount();

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

Reply via email to