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

jmanno pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/main by this push:
     new a8db761  Closes #1929. Add property verification for Sampler Options 
(#1944)
a8db761 is described below

commit a8db76146740770fe86a84ff5428b15f5c8e7e68
Author: Jeffrey Manno <jeffreymann...@gmail.com>
AuthorDate: Thu Feb 25 13:12:40 2021 -0500

    Closes #1929. Add property verification for Sampler Options (#1944)
    
    
    Co-authored-by: Christopher Tubbs <ctubb...@apache.org>
---
 .../core/client/sample/AbstractHashSampler.java    | 29 ++++++++++++++++++----
 .../core/client/sample/RowColumnSampler.java       | 10 ++++++--
 .../accumulo/core/client/sample/Sampler.java       |  8 ++++++
 .../accumulo/core/sample/impl/SamplerFactory.java  | 13 +++++++---
 4 files changed, 49 insertions(+), 11 deletions(-)

diff --git 
a/core/src/main/java/org/apache/accumulo/core/client/sample/AbstractHashSampler.java
 
b/core/src/main/java/org/apache/accumulo/core/client/sample/AbstractHashSampler.java
index df22797..8f5f29c 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/client/sample/AbstractHashSampler.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/client/sample/AbstractHashSampler.java
@@ -23,6 +23,7 @@ import static java.util.Objects.requireNonNull;
 
 import java.io.DataOutput;
 import java.io.IOException;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.accumulo.core.data.Key;
@@ -57,12 +58,34 @@ public abstract class AbstractHashSampler implements 
Sampler {
   private int modulus;
 
   private static final Set<String> VALID_OPTIONS = Set.of("hasher", "modulus");
+  private static final Set<String> VALID_VALUES_HASHER = Set.of("murmur3_32", 
"md5", "sha1");
+
+  /**
+   * Subclasses with options should override this method to validate subclass 
options while also
+   * calling {@code super.validateOptions(config)} to validate base class 
options.
+   */
+  @Override
+  public void validateOptions(Map<String,String> config) {
+    for (Map.Entry<String,String> entry : config.entrySet()) {
+      checkArgument(VALID_OPTIONS.contains(entry.getKey()), "Unknown option: 
%s", entry.getKey());
+
+      if (entry.getKey().equals("hasher"))
+        checkArgument(VALID_VALUES_HASHER.contains(entry.getValue()),
+            "Unknown value for hasher: %s", entry.getValue());
+
+      if (entry.getKey().equals("modulus"))
+        checkArgument(Integer.parseInt(entry.getValue()) > 0,
+            "Improper Integer value for modulus: %s", entry.getValue());
+    }
+  }
 
   /**
    * Subclasses with options should override this method and return true if 
the option is valid for
    * the subclass or if {@code super.isValidOption(opt)} returns true.
+   *
+   * @deprecated since 2.1.0, replaced by {@link #validateOptions(Map)}
    */
-
+  @Deprecated(since = "2.1.0")
   protected boolean isValidOption(String option) {
     return VALID_OPTIONS.contains(option);
   }
@@ -80,10 +103,6 @@ public abstract class AbstractHashSampler implements 
Sampler {
     requireNonNull(hasherOpt, "Hasher not specified");
     requireNonNull(modulusOpt, "Modulus not specified");
 
-    for (String option : config.getOptions().keySet()) {
-      checkArgument(isValidOption(option), "Unknown option : %s", option);
-    }
-
     switch (hasherOpt) {
       case "murmur3_32":
         hashFunction = Hashing.murmur3_32();
diff --git 
a/core/src/main/java/org/apache/accumulo/core/client/sample/RowColumnSampler.java
 
b/core/src/main/java/org/apache/accumulo/core/client/sample/RowColumnSampler.java
index a2785e3..1d71214 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/client/sample/RowColumnSampler.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/client/sample/RowColumnSampler.java
@@ -18,8 +18,11 @@
  */
 package org.apache.accumulo.core.client.sample;
 
+import static com.google.common.base.Preconditions.checkArgument;
+
 import java.io.DataOutput;
 import java.io.IOException;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.accumulo.core.data.ByteSequence;
@@ -80,8 +83,11 @@ public class RowColumnSampler extends AbstractHashSampler {
   }
 
   @Override
-  protected boolean isValidOption(String option) {
-    return super.isValidOption(option) || VALID_OPTIONS.contains(option);
+  public void validateOptions(Map<String,String> config) {
+    super.validateOptions(config);
+    for (String option : config.keySet()) {
+      checkArgument(VALID_OPTIONS.contains(option), "Unknown option : %s", 
option);
+    }
   }
 
   @Override
diff --git 
a/core/src/main/java/org/apache/accumulo/core/client/sample/Sampler.java 
b/core/src/main/java/org/apache/accumulo/core/client/sample/Sampler.java
index d7e07c8..810b8ae 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/sample/Sampler.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/sample/Sampler.java
@@ -18,6 +18,8 @@
  */
 package org.apache.accumulo.core.client.sample;
 
+import java.util.Map;
+
 import org.apache.accumulo.core.data.Key;
 
 /**
@@ -61,4 +63,10 @@ public interface Sampler {
    *         Return false if it should not be included.
    */
   boolean accept(Key k);
+
+  /**
+   * @param config
+   *          Sampler options configuration to validate. Validates option and 
value.
+   */
+  default void validateOptions(Map<String,String> config) {}
 }
diff --git 
a/core/src/main/java/org/apache/accumulo/core/sample/impl/SamplerFactory.java 
b/core/src/main/java/org/apache/accumulo/core/sample/impl/SamplerFactory.java
index f35d005..8f23314 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/sample/impl/SamplerFactory.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/sample/impl/SamplerFactory.java
@@ -23,10 +23,14 @@ import java.io.IOException;
 import org.apache.accumulo.core.classloader.ClassLoaderUtil;
 import org.apache.accumulo.core.client.sample.Sampler;
 import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class SamplerFactory {
+  private static final Logger log = 
LoggerFactory.getLogger(SamplerFactory.class);
+
   public static Sampler newSampler(SamplerConfigurationImpl config, 
AccumuloConfiguration acuconf,
-      boolean useAccumuloStart) throws IOException {
+      boolean useAccumuloStart) {
     String context = ClassLoaderUtil.tableContext(acuconf);
 
     Class<? extends Sampler> clazz;
@@ -38,13 +42,14 @@ public class SamplerFactory {
         clazz = ClassLoaderUtil.loadClass(context, config.getClassName(), 
Sampler.class);
 
       Sampler sampler = clazz.getDeclaredConstructor().newInstance();
-
+      sampler.validateOptions(config.getOptions());
       sampler.init(config.toSamplerConfiguration());
 
       return sampler;
 
-    } catch (ReflectiveOperationException e) {
-      throw new RuntimeException(e);
+    } catch (ReflectiveOperationException | RuntimeException e) {
+      log.error("Cannot initialize sampler {}: {}", config.getClassName(), 
e.getMessage(), e);
+      return null;
     }
   }
 

Reply via email to