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

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

commit bd486cbaf216a957263a1b550087164a6ddcb692
Merge: 55868ab304 53e207f20c
Author: Kevin Rathbun <[email protected]>
AuthorDate: Fri Dec 12 12:10:49 2025 -0500

    Merge branch '2.1'

 .../shell/commands/CreateTableCommand.java         | 66 +++++++++-----------
 .../accumulo/test/shell/ShellCreateTableIT.java    | 71 ++++++++++++----------
 .../org/apache/accumulo/test/shell/ShellIT.java    |  4 +-
 3 files changed, 68 insertions(+), 73 deletions(-)

diff --cc 
shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java
index fbc9ac0777,88220ad604..a8c28a139a
--- 
a/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java
+++ 
b/shell/src/main/java/org/apache/accumulo/shell/commands/CreateTableCommand.java
@@@ -56,10 -54,13 +55,7 @@@ import org.apache.hadoop.io.Text
  
  public class CreateTableCommand extends Command {
    private Option createTableOptCopySplits;
--  // copies configuration (property hierarchy: system, namespace, table) into 
table properties
 -  @Deprecated(since = "2.1.4")
--  private Option createTableOptCopyConfig;
--  // copies properties from target table, (omits system and namespace 
properties in configuration)
 -  @Deprecated(since = "2.1.4")
--  private Option createTableOptExcludeParentProps;
+   private Option createTableOptCopyProps;
    private Option createTableOptSplit;
    private Option createTableOptTimeLogical;
    private Option createTableOptTimeMillis;
@@@ -72,7 -75,7 +68,8 @@@
    private Option createTableOptLocalityProps;
    private Option createTableOptIteratorProps;
    private Option createTableOptOffline;
 +  private Option createTableOptInitialTabletAvailability;
+   private OptionGroup copyConfigGroup;
  
    @Override
    public int execute(final String fullCommand, final CommandLine cl, final 
Shell shellState)
@@@ -107,15 -110,28 +104,18 @@@
        }
      }
  
--    // exclude parent properties; only valid with copy config
--    if (cl.hasOption(createTableOptExcludeParentProps.getLongOpt())
--        && !cl.hasOption(createTableOptCopyConfig.getOpt())) {
--      throw new 
IllegalArgumentException(createTableOptExcludeParentProps.getLongOpt()
--          + " only valid when using " + 
createTableOptCopyConfig.getLongOpt());
 -    }
 -
+     for (var copyOpt : copyConfigGroup.getOptions()) {
 -      if (cl.hasOption(copyOpt) && (cl.hasOption(createTableNoDefaultIters)
 -          || cl.hasOption(createTableNoDefaultTableProps) || 
cl.hasOption(createTableOptInitProp)
 -          || cl.hasOption(createTableOptIteratorProps) || 
cl.hasOption(createTableOptFormatter)
 -          || cl.hasOption(createTableOptLocalityProps) || 
cl.hasOption(createTableOptEVC))) {
++      if (cl.hasOption(copyOpt)
++          && (cl.hasOption(createTableNoDefaultTableProps) || 
cl.hasOption(createTableOptInitProp)
++              || cl.hasOption(createTableOptIteratorProps) || 
cl.hasOption(createTableOptFormatter)
++              || cl.hasOption(createTableOptLocalityProps) || 
cl.hasOption(createTableOptEVC))) {
+         throw new IllegalArgumentException(copyOpt.getLongOpt()
+             + " is mutually exclusive with any other option that sets 
per-table properties");
+       }
      }
  
-     if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
-       final String oldTable = 
cl.getOptionValue(createTableOptCopyConfig.getOpt());
 -    if (cl.hasOption(createTableOptCopyConfig) || 
cl.hasOption(createTableOptCopyProps)) {
 -      String oldTable = cl.getOptionValue(createTableOptCopyConfig);
 -      if (oldTable == null) {
 -        oldTable = cl.getOptionValue(createTableOptCopyProps);
 -      }
++    if (cl.hasOption(createTableOptCopyProps)) {
++      String oldTable = cl.getOptionValue(createTableOptCopyProps);
        if (!shellState.getAccumuloClient().tableOperations().exists(oldTable)) 
{
          throw new TableNotFoundException(null, oldTable, null);
        }
@@@ -165,18 -168,32 +165,12 @@@
      }
  
      // Copy configuration options if flag was set
-     Map<String,String> srcTableConfig = null;
-     if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
-       String srcTable = cl.getOptionValue(createTableOptCopyConfig.getOpt());
-       if (cl.hasOption(createTableOptExcludeParentProps.getLongOpt())) {
-         // copy properties, excludes parent properties in configuration
-         srcTableConfig =
-             
shellState.getAccumuloClient().tableOperations().getTableProperties(srcTable);
-       } else {
-         // copy configuration (include parent properties)
-         srcTableConfig =
-             
shellState.getAccumuloClient().tableOperations().getConfiguration(srcTable);
-       }
+     Map<String,String> srcTableConfig;
 -    var hasCopyConfigOpt = cl.hasOption(createTableOptCopyConfig);
 -    var hasCopyPropsOpt = cl.hasOption(createTableOptCopyProps);
 -    if (hasCopyConfigOpt || hasCopyPropsOpt) {
 -      if (hasCopyConfigOpt) {
 -        Shell.log.warn("{} is deprecated and will be removed in a future 
version. Use {} instead.",
 -            createTableOptCopyConfig.getLongOpt(), 
createTableOptCopyProps.getLongOpt());
 -        String srcTable = cl.getOptionValue(createTableOptCopyConfig);
 -        if (cl.hasOption(createTableOptExcludeParentProps)) {
 -          Shell.log.warn(
 -              "{} is deprecated and will be removed in a future version. Use 
{} instead.",
 -              createTableOptExcludeParentProps.getLongOpt(), 
createTableOptCopyProps.getLongOpt());
 -          // copy properties, excludes parent properties in configuration
 -          srcTableConfig =
 -              
shellState.getAccumuloClient().tableOperations().getTableProperties(srcTable);
 -        } else {
 -          // copy configuration (include parent properties)
 -          srcTableConfig =
 -              
shellState.getAccumuloClient().tableOperations().getConfiguration(srcTable);
 -        }
 -      } else {
 -        String srcTable = cl.getOptionValue(createTableOptCopyProps);
 -        // copy properties, excludes parent properties in configuration
 -        srcTableConfig =
 -            
shellState.getAccumuloClient().tableOperations().getTableProperties(srcTable);
 -      }
++    if (cl.hasOption(createTableOptCopyProps)) {
++      String srcTable = cl.getOptionValue(createTableOptCopyProps);
++      // copy properties, excludes parent properties in configuration
++      srcTableConfig =
++          
shellState.getAccumuloClient().tableOperations().getTableProperties(srcTable);
        srcTableConfig.entrySet().stream()
            .filter(entry -> Property.isValidTablePropertyKey(entry.getKey()))
            .forEach(entry -> initProperties.put(entry.getKey(), 
entry.getValue()));
@@@ -185,11 -202,12 +179,7 @@@
        ntc = ntc.withoutDefaults();
      }
  
-     // if no defaults selected, remove, even if copied from configuration or 
properties
-     if (cl.hasOption(createTableNoDefaultTableProps.getOpt())) {
-       // handles if default props were copied over
-       Set<String> initialProps = 
IteratorConfigUtil.getInitialTableProperties().keySet();
-       initialProps.forEach(initProperties::remove);
 -    final boolean noDefaultIters = cl.hasOption(createTableNoDefaultIters);
 -    if (noDefaultIters || cl.hasOption(createTableNoDefaultTableProps)) {
 -      if (noDefaultIters) {
 -        Shell.log.warn("{} is deprecated and will be removed in a future 
version. Use {} instead",
 -            createTableNoDefaultIters.getLongOpt(), 
createTableNoDefaultTableProps.getLongOpt());
 -      }
++    if (cl.hasOption(createTableNoDefaultTableProps)) {
        // prevents default props from being added in create table call
        ntc = ntc.withoutDefaults();
      }
@@@ -339,10 -357,14 +329,8 @@@
    public Options getOptions() {
      final Options o = new Options();
  
--    createTableOptCopyConfig =
--        new Option("cc", "copy-config", true, "table to copy effective 
configuration from");
-     createTableOptExcludeParentProps = new Option(null, 
"exclude-parent-properties", false,
-         "exclude properties from its parent(s) when copying configuration");
+     createTableOptCopyProps = new Option("cp", "copy-properties", true,
+         "table to copy properties from. Excludes properties from its 
parent(s).");
 -    createTableOptExcludeParentProps = new Option(null, 
"exclude-parent-properties", false,
 -        String.format(
 -            "deprecated; use %s instead. Exclude properties from its 
parent(s) when copying configuration.",
 -            createTableOptCopyProps.getLongOpt()));
      createTableOptCopySplits =
          new Option("cs", "copy-splits", true, "table to copy current splits 
from");
      createTableOptSplit = new Option("sf", "splits-file", true,
@@@ -359,9 -385,8 +347,9 @@@
          "comma-separated user-defined initial key=value pairs");
      createTableOptInitPropFile =
          new Option("pf", "propFile", true, "user-defined initial properties 
file");
 -    createTableOptCopyConfig.setArgName("table");
 +    createTableOptInitialTabletAvailability =
 +        new Option("a", "availability", true, "initial tablet availability 
(defaults to ONDEMAND)");
-     createTableOptCopyConfig.setArgName("table");
+     createTableOptCopyProps.setArgName("table");
      createTableOptCopySplits.setArgName("table");
      createTableOptSplit.setArgName("filename");
      createTableOptFormatter.setArgName("className");
@@@ -392,14 -416,20 +380,17 @@@
      timeGroup.addOption(createTableOptTimeLogical);
      timeGroup.addOption(createTableOptTimeMillis);
  
+     // these table config options are mutually exclusive
+     copyConfigGroup = new OptionGroup();
 -    copyConfigGroup.addOption(createTableOptCopyConfig);
+     copyConfigGroup.addOption(createTableOptCopyProps);
+     copyConfigGroup.addOption(createTableOptInitPropFile);
+ 
      base64Opt = new Option("b64", "base64encoded", false, "decode encoded 
split points");
      o.addOption(base64Opt);
  
      o.addOptionGroup(splitOrCopySplit);
      o.addOptionGroup(timeGroup);
-     o.addOption(createTableOptSplit);
-     o.addOption(createTableOptCopyConfig);
-     o.addOption(createTableOptExcludeParentProps);
+     o.addOptionGroup(copyConfigGroup);
 -    o.addOption(createTableOptExcludeParentProps);
 -    o.addOption(createTableNoDefaultIters);
      o.addOption(createTableNoDefaultTableProps);
      o.addOption(createTableOptEVC);
      o.addOption(createTableOptFormatter);
diff --cc 
test/src/main/java/org/apache/accumulo/test/shell/ShellCreateTableIT.java
index 59eb8aa53c,8ea3bf70bd..4c358d69f2
--- a/test/src/main/java/org/apache/accumulo/test/shell/ShellCreateTableIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/shell/ShellCreateTableIT.java
@@@ -826,8 -789,13 +826,7 @@@ public class ShellCreateTableIT extend
      ts.exec("config -s " + nsPropName + "=" + nsPropValue1 + " -ns " + srcNS);
  
      ts.exec("createtable " + srcTable);
-     ts.exec("createtable --exclude-parent-properties --copy-config " + 
srcTable + " " + destTable,
-         true);
 -    // (--exclude-parent-properties and --copy-config) should be equivalent 
to (--copy-properties)
 -    if (copyConfig) {
 -      ts.exec("createtable --exclude-parent-properties --copy-config " + 
srcTable + " " + destTable,
 -          true);
 -    } else {
 -      ts.exec("createtable --copy-properties " + srcTable + " " + destTable, 
true);
 -    }
++    ts.exec("createtable --copy-properties " + srcTable + " " + destTable, 
true);
  
      try (AccumuloClient accumuloClient = 
Accumulo.newClient().from(getClientProps()).build()) {
        Map<String,String> tids = accumuloClient.tableOperations().tableIdMap();
@@@ -940,46 -914,63 +939,54 @@@
  
    @Test
    public void testCreateTableNoDefaults() throws Exception {
-     // tests the no default table props setting
-     final String table1 = getUniqueNames(1)[0];
+     // tests the no defaults settings
 -    final String[] tableNames = getUniqueNames(2);
 -    final String table1 = tableNames[0];
 -    final String table2 = tableNames[1];
++    final String table = getUniqueNames(1)[0];
+ 
 -    // functionality should be identical
 -    ts.exec("createtable -ndi " + table1, true);
 -    ts.exec("createtable -ndtp " + table2, true);
++    ts.exec("createtable -ndtp " + table, true);
  
-     ts.exec("createtable -ndtp " + table1, true);
      // verify no default iterator props
      for (IteratorUtil.IteratorScope iterScope : 
IteratorUtil.IteratorScope.values()) {
 -      for (String table : tableNames) {
 -        var res = ts.exec(
 -            "config -t " + table + " -f " + Property.TABLE_ITERATOR_PREFIX + 
iterScope.name(),
 -            true);
 -        assertFalse(res.contains(Property.TABLE_ITERATOR_PREFIX + 
iterScope.name() + ".vers"));
 -      }
 -    }
 -    // verify no default table props
 -    for (String table : tableNames) {
 -      // note filtering by "table.constraint" but checking output for 
"table.constraint."
 -      // don't want to match command itself
 -      var res = ts.exec("config -t " + table + " -f table.constraint", true);
 -      assertFalse(res.contains(Property.TABLE_CONSTRAINT_PREFIX.getKey()));
 +      var res = ts.exec(
-           "config -t " + table1 + " -f " + Property.TABLE_ITERATOR_PREFIX + 
iterScope.name(), true);
++          "config -t " + table + " -f " + Property.TABLE_ITERATOR_PREFIX + 
iterScope.name(), true);
 +      assertFalse(res.contains(Property.TABLE_ITERATOR_PREFIX + 
iterScope.name() + ".vers"));
      }
 +    // verify no default non-iterator props
-     var res = ts.exec("config -t " + table1 + " -f " + 
Property.TABLE_CONSTRAINT_PREFIX, true);
-     assertFalse(res.contains(Property.TABLE_CONSTRAINT_PREFIX + "1"));
++    // note filtering by "table.constraint" but checking output for 
"table.constraint."
++    // don't want to match command itself
++    var res = ts.exec("config -t " + table + " -f table.constraint", true);
++    assertFalse(res.contains(Property.TABLE_CONSTRAINT_PREFIX.getKey()));
    }
  
    @Test
-   public void testCreateTableNoDefaults2() throws Exception {
-     // tests the no default table props setting
+   public void testCreateTableMutuallyExclusiveCopyOpts() throws Exception {
      final String[] tableNames = getUniqueNames(3);
-     final String table1 = tableNames[0];
-     final String table2 = tableNames[1];
-     final String table3 = tableNames[2];
- 
-     // create table1 with default iterators, create table2 without default 
iterators but copying
-     // table1 config... Expect no default iterators
-     ts.exec("createtable " + table1, true);
-     // make sure order doesn't matter
-     ts.exec("createtable " + table2 + " -ndtp -cc " + table1);
-     ts.exec("createtable " + table3 + " -cc " + table1 + " -ndtp");
-     for (IteratorUtil.IteratorScope iterScope : 
IteratorUtil.IteratorScope.values()) {
-       var res = ts.exec(
-           "config -t " + table1 + " -f " + Property.TABLE_ITERATOR_PREFIX + 
iterScope.name(), true);
-       // verify default iterator props for table1 but not table2 or table3
-       assertTrue(res.contains(Property.TABLE_ITERATOR_PREFIX + 
iterScope.name() + ".vers"));
-       res = ts.exec(
-           "config -t " + table2 + " -f " + Property.TABLE_ITERATOR_PREFIX + 
iterScope.name(), true);
-       assertFalse(res.contains(Property.TABLE_ITERATOR_PREFIX + 
iterScope.name() + ".vers"));
-       res = ts.exec(
-           "config -t " + table3 + " -f " + Property.TABLE_ITERATOR_PREFIX + 
iterScope.name(), true);
-       assertFalse(res.contains(Property.TABLE_ITERATOR_PREFIX + 
iterScope.name() + ".vers"));
+     final String optArg = "foo";
+     final String src = tableNames[0];
+     final String src2 = tableNames[1];
+     final String dest = tableNames[2];
+ 
+     ts.exec("createtable " + src, true);
+     ts.exec("createtable " + src2, true);
+ 
+     var res = ts.exec(String.format("createtable -cc %s -cp %s %s", src, 
src2, dest), false);
+     assertTrue(res.contains("AlreadySelectedException"));
+     res = ts.exec(String.format("createtable -cc %s -pf %s %s", src, optArg, 
dest), false);
+     assertTrue(res.contains("AlreadySelectedException"));
+     res = ts.exec(String.format("createtable -cp %s -pf %s %s", src, optArg, 
dest), false);
+     assertTrue(res.contains("AlreadySelectedException"));
+ 
 -    for (var copyOpt : List.of("-cc", "-cp", "-pf")) {
 -      for (var noArgPropOpt : List.of("-ndi", "-ndtp", "-evc")) {
++    for (var copyOpt : List.of("-cp", "-pf")) {
++      for (var noArgPropOpt : List.of("-ndtp", "-evc")) {
+         res = ts.exec(String.format("createtable %s %s %s %s", noArgPropOpt, 
copyOpt, src, dest),
+             false);
+         assertTrue(res.contains("mutually exclusive with"));
+       }
+       for (var propOpt : List.of("-prop", "-i", "-f", "-l")) {
+         res = ts.exec(
+             String.format("createtable %s %s %s %s %s", propOpt, optArg, 
copyOpt, src, dest),
+             false);
+         assertTrue(res.contains("mutually exclusive with"));
+       }
      }
    }
  

Reply via email to