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")); + } } }
