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

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


The following commit(s) were added to refs/heads/HDDS-3816-ec by this push:
     new 6b5c01c  HDDS-6184. EC: put command should create EC key if bucket is 
EC (#2990)
6b5c01c is described below

commit 6b5c01c8433a771edfacc61fc958a0518131865c
Author: Uma Maheswara Rao G <[email protected]>
AuthorDate: Fri Jan 28 02:34:49 2022 -0800

    HDDS-6184. EC: put command should create EC key if bucket is EC (#2990)
---
 .../hadoop/ozone/shell/TestOzoneShellHA.java       |  26 +++++
 .../apache/hadoop/ozone/om/OzoneConfigUtil.java    |   8 +-
 .../hadoop/ozone/om/TestOzoneConfigUtil.java       | 105 +++++++++++++++++++++
 .../apache/hadoop/fs/ozone/OzoneClientUtils.java   |  42 +++++++++
 .../hadoop/fs/ozone/TestOzoneClientUtils.java      |  95 +++++++++++++++++++
 .../hadoop/ozone/shell/keys/PutKeyHandler.java     |   7 +-
 6 files changed, 280 insertions(+), 3 deletions(-)

diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java
index aba9954..1a18b26 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java
@@ -34,6 +34,7 @@ import org.apache.hadoop.fs.FileUtil;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hdds.cli.GenericCli;
 import org.apache.hadoop.hdds.cli.OzoneAdmin;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
 import org.apache.hadoop.ozone.OFSPath;
 import org.apache.hadoop.fs.ozone.OzoneFsShell;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
@@ -41,6 +42,7 @@ import org.apache.hadoop.ozone.MiniOzoneCluster;
 import org.apache.hadoop.ozone.MiniOzoneOMHAClusterImpl;
 import org.apache.hadoop.ozone.client.ObjectStore;
 import org.apache.hadoop.ozone.client.OzoneBucket;
+import org.apache.hadoop.ozone.client.OzoneKeyDetails;
 import org.apache.hadoop.ozone.client.OzoneVolume;
 import org.apache.hadoop.ozone.client.io.ECKeyOutputStream;
 import org.apache.hadoop.ozone.client.io.KeyOutputStream;
@@ -911,6 +913,30 @@ public class TestOzoneShellHA {
   }
 
   @Test
+  public void testPutKeyOnBucketWithECReplicationConfig() throws Exception {
+    final String volumeName = UUID.randomUUID().toString();
+    final String bucketName = UUID.randomUUID().toString();
+    final String keyName = UUID.randomUUID().toString();
+    getVolume(volumeName);
+    String bucketPath =
+        Path.SEPARATOR + volumeName + Path.SEPARATOR + bucketName;
+    String[] args =
+        new String[] {"bucket", "create", bucketPath, "-t", "EC", "-r",
+            "rs-3-2-1024k"};
+    execute(ozoneShell, args);
+
+    args = new String[] {"key", "put", bucketPath + Path.SEPARATOR + keyName,
+        testFilePathString};
+    execute(ozoneShell, args);
+
+    OzoneKeyDetails key =
+        cluster.getClient().getObjectStore().getVolume(volumeName)
+            .getBucket(bucketName).getKey(keyName);
+    assertEquals(HddsProtos.ReplicationType.EC,
+        key.getReplicationConfig().getReplicationType());
+  }
+
+  @Test
   public void testCreateBucketWithRatisReplicationConfig() throws Exception {
     final String volumeName = "volume101";
     getVolume(volumeName);
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneConfigUtil.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneConfigUtil.java
index f8a2add..ea559f8 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneConfigUtil.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneConfigUtil.java
@@ -44,12 +44,18 @@ public final class OzoneConfigUtil {
     } else {
       // type is NONE, so, let's look for the bucket defaults.
       if (bucketDefaultReplicationConfig != null) {
+        boolean hasECReplicationConfig = bucketDefaultReplicationConfig
+            .getType() == ReplicationType.EC && bucketDefaultReplicationConfig
+            .getEcReplicationConfig() != null;
         // Since Bucket defaults are available, let's inherit
         replicationConfig = ReplicationConfig.fromProto(
             ReplicationType.toProto(bucketDefaultReplicationConfig.getType()),
             ReplicationFactor
                 .toProto(bucketDefaultReplicationConfig.getFactor()),
-            bucketDefaultReplicationConfig.getEcReplicationConfig().toProto());
+            hasECReplicationConfig ?
+                bucketDefaultReplicationConfig.getEcReplicationConfig()
+                    .toProto() :
+                null);
       } else {
         // if bucket defaults also not available, then use server defaults.
         replicationConfig = omDefaultReplicationConfig;
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOzoneConfigUtil.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOzoneConfigUtil.java
new file mode 100644
index 0000000..7dc07603
--- /dev/null
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOzoneConfigUtil.java
@@ -0,0 +1,105 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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;
+
+import org.apache.hadoop.hdds.client.DefaultReplicationConfig;
+import org.apache.hadoop.hdds.client.ECReplicationConfig;
+import org.apache.hadoop.hdds.client.RatisReplicationConfig;
+import org.apache.hadoop.hdds.client.ReplicationConfig;
+import org.apache.hadoop.hdds.client.ReplicationFactor;
+import org.apache.hadoop.hdds.client.ReplicationType;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests the server side replication config preference logic.
+ */
+public class TestOzoneConfigUtil {
+  private ReplicationConfig ratis3ReplicationConfig =
+      new RatisReplicationConfig(HddsProtos.ReplicationFactor.THREE);
+  private HddsProtos.ReplicationType noneType = 
HddsProtos.ReplicationType.NONE;
+  private HddsProtos.ReplicationFactor zeroFactor =
+      HddsProtos.ReplicationFactor.ZERO;
+  private HddsProtos.ECReplicationConfig clientECReplicationConfig =
+      new ECReplicationConfig("rs-3-2-1024K").toProto();
+  private DefaultReplicationConfig bucketECConfig =
+      new DefaultReplicationConfig(
+          new ECReplicationConfig(clientECReplicationConfig));
+
+  /**
+   * Tests EC bucket defaults.
+   */
+  @Test
+  public void testResolveClientSideRepConfigWhenBucketHasEC() {
+    ReplicationConfig replicationConfig = OzoneConfigUtil
+        .resolveReplicationConfigPreference(noneType, zeroFactor,
+            clientECReplicationConfig, bucketECConfig, 
ratis3ReplicationConfig);
+    // Client has no preference, so we should bucket defaults as we passed.
+    Assert.assertEquals(bucketECConfig.getEcReplicationConfig(),
+        replicationConfig);
+  }
+
+  /**
+   * Tests server defaults.
+   */
+  @Test
+  public void testResolveClientSideRepConfigWithNoClientAndBucketDefaults() {
+    ReplicationConfig replicationConfig = OzoneConfigUtil
+        .resolveReplicationConfigPreference(noneType, zeroFactor,
+            clientECReplicationConfig, null, ratis3ReplicationConfig);
+    // Client has no preference, no bucket defaults, so it should return server
+    // defaults.
+    Assert.assertEquals(ratis3ReplicationConfig, replicationConfig);
+  }
+
+  /**
+   * Tests client preference of EC.
+   */
+  @Test
+  public void testResolveClientSideRepConfigWhenClientPassEC() {
+    ReplicationConfig replicationConfig = OzoneConfigUtil
+        .resolveReplicationConfigPreference(HddsProtos.ReplicationType.EC,
+            zeroFactor, clientECReplicationConfig, null,
+            ratis3ReplicationConfig);
+    // Client has preference of type EC, no bucket defaults, so it should 
return
+    // client preference.
+    Assert.assertEquals(new ECReplicationConfig("rs-3-2-1024K"),
+        replicationConfig);
+  }
+
+  /**
+   * Tests bucket ratis defaults.
+   */
+  @Test
+  public void testResolveClientSideRepConfigWhenBucketHasEC3() {
+    DefaultReplicationConfig ratisBucketDefaults =
+        new DefaultReplicationConfig(ReplicationType.RATIS,
+            ReplicationFactor.THREE);
+    ReplicationConfig replicationConfig = OzoneConfigUtil
+        .resolveReplicationConfigPreference(noneType, zeroFactor,
+            clientECReplicationConfig, ratisBucketDefaults,
+            ratis3ReplicationConfig);
+    // Client has no preference of type and bucket has ratis defaults, so it
+    // should return ratis.
+    Assert.assertEquals(ratisBucketDefaults.getType().name(),
+        replicationConfig.getReplicationType().name());
+    Assert.assertEquals(ratisBucketDefaults.getFactor(),
+        ReplicationFactor.valueOf(replicationConfig.getRequiredNodes()));
+  }
+
+}
diff --git 
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientUtils.java
 
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientUtils.java
index 6e94553..b632aae 100644
--- 
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientUtils.java
+++ 
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientUtils.java
@@ -147,4 +147,46 @@ public final class OzoneClientUtils {
         config.get(OZONE_REPLICATION_TYPE, OZONE_REPLICATION_TYPE_DEFAULT)),
         replication, config);
   }
+
+  /**
+   * Gets the client side replication config by checking user passed values vs
+   * client configured values.
+   * @param userPassedType - User provided replication type.
+   * @param userPassedReplication - User provided replication.
+   * @param clientSideConfig - Client side configuration.
+   * @return ReplicationConfig.
+   */
+  public static ReplicationConfig validateAndGetClientReplicationConfig(
+      ReplicationType userPassedType, String userPassedReplication,
+      OzoneConfiguration clientSideConfig) {
+    // Priority 1: User passed replication config values.
+    // Priority 2: Client side configured replication config values.
+    /* if above two are not available, we should just return null and clients
+     can pass null replication config to server. Now server will take the
+     decision of finding the replication config( either from bucket defaults
+     or server defaults). */
+    ReplicationType clientReplicationType = userPassedType;
+    String clientReplication = userPassedReplication;
+    String clientConfiguredDefaultType =
+        clientSideConfig.get(OZONE_REPLICATION_TYPE);
+    if (userPassedType == null && clientConfiguredDefaultType != null) {
+      clientReplicationType =
+          ReplicationType.valueOf(clientConfiguredDefaultType);
+    }
+
+    String clientConfiguredDefaultReplication =
+        clientSideConfig.get(OZONE_REPLICATION);
+    if (userPassedReplication == null
+        && clientConfiguredDefaultReplication != null) {
+      clientReplication = clientConfiguredDefaultReplication;
+    }
+
+    // if clientReplicationType or clientReplication is null, then we just pass
+    // replication config as null, so that server will take decision.
+    if (clientReplicationType == null || clientReplication == null) {
+      return null;
+    }
+    return ReplicationConfig
+        .parse(clientReplicationType, clientReplication, clientSideConfig);
+  }
 }
diff --git 
a/hadoop-ozone/ozonefs-common/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneClientUtils.java
 
b/hadoop-ozone/ozonefs-common/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneClientUtils.java
index 46ab0bf..f610b75 100644
--- 
a/hadoop-ozone/ozonefs-common/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneClientUtils.java
+++ 
b/hadoop-ozone/ozonefs-common/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneClientUtils.java
@@ -19,8 +19,10 @@ package org.apache.hadoop.fs.ozone;
 import org.apache.hadoop.hdds.client.ECReplicationConfig;
 import org.apache.hadoop.hdds.client.RatisReplicationConfig;
 import org.apache.hadoop.hdds.client.ReplicationConfig;
+import org.apache.hadoop.hdds.client.ReplicationType;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
+import org.apache.hadoop.ozone.OzoneConfigKeys;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -128,4 +130,97 @@ public class TestOzoneClientUtils {
     // Configured value is ratis THREE
     Assert.assertEquals(ratis3ReplicationConfig, replicationConfig);
   }
+
+  /**
+   * Tests validateAndGetClientReplicationConfig with user passed valid config
+   * values.
+   */
+  @Test
+  public void testValidateAndGetRepConfWhenValidUserPassedValues() {
+    ReplicationConfig replicationConfig = OzoneClientUtils
+        .validateAndGetClientReplicationConfig(ReplicationType.RATIS, "1",
+            new OzoneConfiguration());
+    // Configured value is ratis ONE
+    Assert.assertEquals(ratis1ReplicationConfig, replicationConfig);
+  }
+
+  /**
+   * Tests validateAndGetClientReplicationConfig with user passed null values.
+   */
+  @Test
+  public void testValidateAndGetRepConfWhenValidUserPassedNullValues() {
+    ReplicationConfig replicationConfig = OzoneClientUtils
+        .validateAndGetClientReplicationConfig(null, null,
+            new OzoneConfiguration());
+    Assert.assertNull(replicationConfig);
+  }
+
+  /**
+   * Tests validateAndGetClientReplicationConfig with user passed null values
+   * but client config has valid values.
+   */
+  @Test
+  public void testValidateAndGetRepConfWhenValidConfigValues() {
+    OzoneConfiguration clientSideConfig = new OzoneConfiguration();
+    clientSideConfig.set(OzoneConfigKeys.OZONE_REPLICATION_TYPE, "EC");
+    clientSideConfig.set(OzoneConfigKeys.OZONE_REPLICATION, "rs-3-2-1024K");
+    ReplicationConfig replicationConfig = OzoneClientUtils
+        .validateAndGetClientReplicationConfig(null, null, clientSideConfig);
+    Assert.assertEquals(ecReplicationConfig, replicationConfig);
+  }
+
+  /**
+   * Tests validateAndGetClientReplicationConfig with user passed null values
+   * but client config has valid values.
+   */
+  @Test
+  public void testValidateAndGetRepConfWhenNullTypeFromUser() {
+    ReplicationConfig replicationConfig = OzoneClientUtils
+        .validateAndGetClientReplicationConfig(null, "3",
+            new OzoneConfiguration());
+    Assert.assertNull(replicationConfig);
+  }
+
+  /**
+   * Tests validateAndGetClientReplicationConfig with user passed null
+   * replication but valid type.
+   */
+  @Test
+  public void testValidateAndGetRepConfWhenNullReplicationFromUser() {
+    ReplicationConfig replicationConfig = OzoneClientUtils
+        .validateAndGetClientReplicationConfig(ReplicationType.EC, null,
+            new OzoneConfiguration());
+    Assert.assertNull(replicationConfig);
+  }
+
+  /**
+   * Tests validateAndGetClientReplicationConfig with user pass null values but
+   * config has only replication configured.
+   */
+  @Test
+  public void testValidateAndGetRepConfWhenNullTypeConfigValues() {
+    OzoneConfiguration clientSideConfig = new OzoneConfiguration();
+    clientSideConfig.set(OzoneConfigKeys.OZONE_REPLICATION, "rs-3-2-1024K");
+    //By default config values are null. Let's don't set type to keep it as
+    // null.
+    ReplicationConfig replicationConfig = OzoneClientUtils
+        .validateAndGetClientReplicationConfig(null, null, clientSideConfig);
+    Assert.assertNull(replicationConfig);
+  }
+
+  /**
+   * Tests validateAndGetClientReplicationConfig with user pass null values but
+   * config has only type configured.
+   */
+  @Test
+  public void testValidateAndGetRepConfWhenNullReplicationConfigValues() {
+    OzoneConfiguration clientSideConfig = new OzoneConfiguration();
+    clientSideConfig.set(OzoneConfigKeys.OZONE_REPLICATION_TYPE, "EC");
+    //By default config values are null. Let's don't set replication to keep it
+    // as null.
+    ReplicationConfig replicationConfig = OzoneClientUtils
+        .validateAndGetClientReplicationConfig(null, null, clientSideConfig);
+    Assert.assertNull(replicationConfig);
+  }
+
 }
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/keys/PutKeyHandler.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/keys/PutKeyHandler.java
index c32fc45..0c4e33c 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/keys/PutKeyHandler.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/keys/PutKeyHandler.java
@@ -27,6 +27,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.hadoop.conf.StorageUnit;
+import org.apache.hadoop.fs.ozone.OzoneClientUtils;
 import org.apache.hadoop.hdds.client.ReplicationConfig;
 import org.apache.hadoop.hdds.client.ReplicationType;
 import org.apache.hadoop.io.IOUtils;
@@ -40,6 +41,7 @@ import org.apache.hadoop.ozone.shell.OzoneAddress;
 import org.apache.commons.codec.digest.DigestUtils;
 import static 
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_CHUNK_SIZE_DEFAULT;
 import static 
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_CHUNK_SIZE_KEY;
+
 import picocli.CommandLine.Command;
 import picocli.CommandLine.Option;
 import picocli.CommandLine.Parameters;
@@ -83,8 +85,9 @@ public class PutKeyHandler extends KeyHandler {
       }
     }
 
-    ReplicationConfig replicationConfig =
-        ReplicationConfig.parse(replicationType, replication, getConf());
+    ReplicationConfig replicationConfig = OzoneClientUtils
+        .validateAndGetClientReplicationConfig(replicationType, replication,
+            getConf());
 
     OzoneVolume vol = client.getObjectStore().getVolume(volumeName);
     OzoneBucket bucket = vol.getBucket(bucketName);

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

Reply via email to