This commit is contained in:
Chang-Yu Huang 2025-10-07 17:00:44 -04:00 committed by GitHub
commit 7e0d5d02a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 34 additions and 11 deletions

View File

@ -76,7 +76,7 @@ public class FeatureCommand {
.newArgumentParser("kafka-features") .newArgumentParser("kafka-features")
.defaultHelp(true) .defaultHelp(true)
.description("This tool manages feature flags in Kafka."); .description("This tool manages feature flags in Kafka.");
MutuallyExclusiveGroup bootstrapGroup = parser.addMutuallyExclusiveGroup().required(true); MutuallyExclusiveGroup bootstrapGroup = parser.addMutuallyExclusiveGroup();
bootstrapGroup.addArgument("--bootstrap-server") bootstrapGroup.addArgument("--bootstrap-server")
.help("A comma-separated list of host:port pairs to use for establishing the connection to the Kafka cluster."); .help("A comma-separated list of host:port pairs to use for establishing the connection to the Kafka cluster.");
bootstrapGroup.addArgument("--bootstrap-controller") bootstrapGroup.addArgument("--bootstrap-controller")
@ -92,14 +92,27 @@ public class FeatureCommand {
addVersionMappingParser(subparsers); addVersionMappingParser(subparsers);
addFeatureDependenciesParser(subparsers); addFeatureDependenciesParser(subparsers);
Namespace namespace = parser.parseArgsOrFail(args); Namespace namespace = parser.parseArgs(args);
String command = namespace.getString("command"); String command = namespace.getString("command");
if (command.equals("version-mapping")) {
handleVersionMapping(namespace, Feature.PRODUCTION_FEATURES);
return;
} else if (command.equals("feature-dependencies")) {
handleFeatureDependencies(namespace, Feature.PRODUCTION_FEATURES);
return;
}
String configPath = namespace.getString("command_config"); String configPath = namespace.getString("command_config");
Properties properties = (configPath == null) ? new Properties() : Utils.loadProps(configPath); Properties properties = (configPath == null) ? new Properties() : Utils.loadProps(configPath);
CommandLineUtils.initializeBootstrapProperties(properties, try {
Optional.ofNullable(namespace.getString("bootstrap_server")), CommandLineUtils.initializeBootstrapProperties(properties,
Optional.ofNullable(namespace.getString("bootstrap_controller"))); Optional.ofNullable(namespace.getString("bootstrap_server")),
Optional.ofNullable(namespace.getString("bootstrap_controller")));
} catch (Exception e) {
// bootstrap_server and bootstrap_controller are in a mutually exclusive group,
// so the exception happens only when both of them are missing
throw new ArgumentParserException(e.getMessage(), parser);
}
try (Admin adminClient = Admin.create(properties)) { try (Admin adminClient = Admin.create(properties)) {
switch (command) { switch (command) {
@ -115,12 +128,6 @@ public class FeatureCommand {
case "disable": case "disable":
handleDisable(namespace, adminClient); handleDisable(namespace, adminClient);
break; break;
case "version-mapping":
handleVersionMapping(namespace, Feature.PRODUCTION_FEATURES);
break;
case "feature-dependencies":
handleFeatureDependencies(namespace, Feature.PRODUCTION_FEATURES);
break;
default: default:
throw new TerseException("Unknown command " + command); throw new TerseException("Unknown command " + command);
} }

View File

@ -459,6 +459,22 @@ public class FeatureCommandTest {
MetadataVersion.MINIMUM_VERSION, MetadataVersion.latestTesting()), exception2.getMessage()); MetadataVersion.MINIMUM_VERSION, MetadataVersion.latestTesting()), exception2.getMessage());
} }
@Test
public void testHandleVersionMappingWithoutBootstrap() {
Map.Entry<String, String> output = ToolsTestUtils.grabConsoleOutputAndError(() -> FeatureCommand.mainNoExit("version-mapping"));
assertEquals("", output.getValue());
MetadataVersion metadataVersion = MetadataVersion.latestProduction();
assertTrue(output.getKey().contains("metadata.version=" + metadataVersion.featureLevel() + " (" + metadataVersion.version() + ")"),
"Output did not contain expected Metadata Version: " + output.getKey());
}
@Test
public void testHandleRemoteCommandWithoutBootstrap() {
String errorMessage = ToolsTestUtils.grabConsoleError(() -> FeatureCommand.mainNoExit("upgrade"));
assertTrue(errorMessage.contains("You must specify either --bootstrap-controller " +
"or --bootstrap-server."));
}
@Test @Test
public void testHandleFeatureDependenciesForFeatureWithDependencies() { public void testHandleFeatureDependenciesForFeatureWithDependencies() {
Map<String, Object> namespace = new HashMap<>(); Map<String, Object> namespace = new HashMap<>();