Repository: apache/kafka
File: tools/src/main/java/org/apache/kafka/tools/ClientMetricsCommand.java (Java)

Code before:
            System.out.println("Altered client metrics config for " + entityName + ".");
        }

        public void deleteClientMetrics(ClientMetricsCommandOptions opts) throws Exception {
            String entityName = opts.name().get();
            Collection<ConfigEntry> oldConfigs = getClientMetricsConfig(entityName);

            ConfigResource configResource = new ConfigResource(ConfigResource.Type.CLIENT_METRICS, entityName);
            AlterConfigsOptions alterOptions = new AlterConfigsOptions().timeoutMs(30000).validateOnly(false);
            Collection<AlterConfigOp> alterEntries = oldConfigs.stream()
                    .map(entry -> new AlterConfigOp(entry, AlterConfigOp.OpType.DELETE)).collect(Collectors.toList());
            adminClient.incrementalAlterConfigs(Collections.singletonMap(configResource, alterEntries), alterOptions)
                    .all().get(30, TimeUnit.SECONDS);

            System.out.println("Deleted client metrics config for " + entityName + ".");
        }

        public void describeClientMetrics(ClientMetricsCommandOptions opts) throws Exception {
            Optional<String> entityNameOpt = opts.name();

            List<String> entities;
            if (entityNameOpt.isPresent()) {
                if (adminClient.listConfigResources(Set.of(ConfigResource.Type.CLIENT_METRICS), new ListConfigResourcesOptions())
                        .all().get(30, TimeUnit.SECONDS).stream()
                        .noneMatch(resource -> resource.name().equals(entityNameOpt.get()))) {
                    System.out.println("The client-metric " + entityNameOpt.get() + " doesn't exist and doesn't have dynamic config.");
                    return;
                }
                entities = Collections.singletonList(entityNameOpt.get());
            } else {
                Collection<ConfigResource> resources = adminClient
                    .listConfigResources(Set.of(ConfigResource.Type.CLIENT_METRICS), new ListConfigResourcesOptions())
                    .all()
                    .get(30, TimeUnit.SECONDS);
                entities = resources.stream().map(ConfigResource::name).toList();
            }

            for (String entity : entities) {
                System.out.println("Client metrics configs for " + entity + " are:");
                getClientMetricsConfig(entity)
                        .forEach(entry -> System.out.println("  " + entry.name() + "=" + entry.value()));
            }
        }

        public void listClientMetrics() throws Exception {
            Collection<ConfigResource> resources = adminClient
                .listConfigResources(Set.of(ConfigResource.Type.CLIENT_METRICS), new ListConfigResourcesOptions())
                .all()
                .get(30, TimeUnit.SECONDS);
            String results = resources.stream().map(ConfigResource::name).collect(Collectors.joining("\n"));
            System.out.println(results);

Review comment (suggestion):
I think I'd use `client metrics resource`. This is the terminology in the usage message for this tool. It's a bit of a mouthful, but `client-metric` sounds like a metric from a client, not something uses to configure them.

Code after:
            System.out.println("Altered client metrics config for " + entityName + ".");
        }

        public void deleteClientMetrics(ClientMetricsCommandOptions opts) throws Exception {
            String entityName = opts.name().get();
            Collection<ConfigEntry> oldConfigs = getClientMetricsConfig(entityName);

            ConfigResource configResource = new ConfigResource(ConfigResource.Type.CLIENT_METRICS, entityName);
            AlterConfigsOptions alterOptions = new AlterConfigsOptions().timeoutMs(30000).validateOnly(false);
            Collection<AlterConfigOp> alterEntries = oldConfigs.stream()
                    .map(entry -> new AlterConfigOp(entry, AlterConfigOp.OpType.DELETE)).collect(Collectors.toList());
            adminClient.incrementalAlterConfigs(Collections.singletonMap(configResource, alterEntries), alterOptions)
                    .all().get(30, TimeUnit.SECONDS);

            System.out.println("Deleted client metrics config for " + entityName + ".");
        }

        public void describeClientMetrics(ClientMetricsCommandOptions opts) throws Exception {
            Optional<String> entityNameOpt = opts.name();

            List<String> entities;
            if (entityNameOpt.isPresent()) {
                if (adminClient.listConfigResources(Set.of(ConfigResource.Type.CLIENT_METRICS), new ListConfigResourcesOptions())
                        .all().get(30, TimeUnit.SECONDS).stream()
                        .noneMatch(resource -> resource.name().equals(entityNameOpt.get()))) {
                    System.out.println("The client metric resource " + entityNameOpt.get() + " doesn't exist and doesn't have dynamic config.");
                    return;
                }
                entities = Collections.singletonList(entityNameOpt.get());
            } else {
                Collection<ConfigResource> resources = adminClient
                    .listConfigResources(Set.of(ConfigResource.Type.CLIENT_METRICS), new ListConfigResourcesOptions())
                    .all()
                    .get(30, TimeUnit.SECONDS);
                entities = resources.stream().map(ConfigResource::name).toList();
            }

            for (String entity : entities) {
                System.out.println("Client metrics configs for " + entity + " are:");
                getClientMetricsConfig(entity)
                        .forEach(entry -> System.out.println("  " + entry.name() + "=" + entry.value()));
            }
        }

        public void listClientMetrics() throws Exception {
            Collection<ConfigResource> resources = adminClient
                .listConfigResources(Set.of(ConfigResource.Type.CLIENT_METRICS), new ListConfigResourcesOptions())
                .all()
                .get(30, TimeUnit.SECONDS);
            String results = resources.stream().map(ConfigResource::name).collect(Collectors.joining("\n"));
            System.out.println(results);