You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kafka.apache.org by ew...@apache.org on 2016/10/11 03:02:08 UTC

kafka git commit: KAFKA-4010: add ConfigDef toEnrichedRst() for additional fields in output

Repository: kafka
Updated Branches:
  refs/heads/trunk 2e82bc0a1 -> 72d5675a7


KAFKA-4010: add ConfigDef toEnrichedRst() for additional fields in output

followup on https://github.com/apache/kafka/pull/1696

cc rekhajoshm

Author: Shikhar Bhushan <sh...@confluent.io>
Author: Joshi <re...@gmail.com>

Reviewers: Shikhar Bhushan <sh...@confluent.io>, Ewen Cheslack-Postava <ew...@confluent.io>

Closes #1964 from shikhar/kafka-4010


Project: http://git-wip-us.apache.org/repos/asf/kafka/repo
Commit: http://git-wip-us.apache.org/repos/asf/kafka/commit/72d5675a
Tree: http://git-wip-us.apache.org/repos/asf/kafka/tree/72d5675a
Diff: http://git-wip-us.apache.org/repos/asf/kafka/diff/72d5675a

Branch: refs/heads/trunk
Commit: 72d5675a7cfc64a5547b921672856ea4afc4f4c2
Parents: 2e82bc0
Author: Joshi <re...@gmail.com>
Authored: Mon Oct 10 20:02:04 2016 -0700
Committer: Ewen Cheslack-Postava <me...@ewencp.org>
Committed: Mon Oct 10 20:02:04 2016 -0700

----------------------------------------------------------------------
 .../apache/kafka/common/config/ConfigDef.java   | 122 ++++++++++++++-----
 .../kafka/common/config/ConfigDefTest.java      |  97 ++++++++++++++-
 2 files changed, 189 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kafka/blob/72d5675a/clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java
----------------------------------------------------------------------
diff --git a/clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java b/clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java
index 7174736..08c3617 100644
--- a/clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java
+++ b/clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java
@@ -913,10 +913,11 @@ public class ConfigDef {
                 if (key.hasDefault()) {
                     if (key.defaultValue == null)
                         return "null";
-                    else if (key.type == Type.STRING && key.defaultValue.toString().isEmpty())
+                    String defaultValueStr = convertToString(key.defaultValue, key.type);
+                    if (defaultValueStr.isEmpty())
                         return "\"\"";
                     else
-                        return key.defaultValue.toString();
+                        return defaultValueStr;
                 } else
                     return "";
             case "Valid Values":
@@ -927,7 +928,7 @@ public class ConfigDef {
                 throw new RuntimeException("Can't find value for header '" + headerName + "' in " + key.name);
         }
     }
-    
+
     public String toHtmlTable() {
         List<ConfigKey> configs = sortedConfigs();
         StringBuilder b = new StringBuilder();
@@ -959,43 +960,76 @@ public class ConfigDef {
      * documentation.
      */
     public String toRst() {
-        List<ConfigKey> configs = sortedConfigs();
         StringBuilder b = new StringBuilder();
+        for (ConfigKey def : sortedConfigs()) {
+            getConfigKeyRst(def, b);
+            b.append("\n");
+        }
+        return b.toString();
+    }
 
-        for (ConfigKey def : configs) {
-            b.append("``");
-            b.append(def.name);
-            b.append("``\n");
-            for (String docLine : def.documentation.split("\n")) {
-                if (docLine.length() == 0) {
-                    continue;
+    /**
+     * Configs with new metadata (group, orderInGroup, dependents) formatted with reStructuredText, suitable for embedding in Sphinx
+     * documentation.
+     */
+    public String toEnrichedRst() {
+        StringBuilder b = new StringBuilder();
+
+        String lastKeyGroupName = "";
+        for (ConfigKey def : sortedConfigsByGroup()) {
+            if (def.group != null) {
+                if (!lastKeyGroupName.equalsIgnoreCase(def.group)) {
+                    b.append(def.group).append("\n");
+
+                    char[] underLine = new char[def.group.length()];
+                    Arrays.fill(underLine, '^');
+                    b.append(new String(underLine)).append("\n\n");
                 }
-                b.append("  ");
-                b.append(docLine);
-                b.append("\n\n");
+                lastKeyGroupName = def.group;
             }
-            b.append("  * Type: ");
-            b.append(def.type.toString().toLowerCase(Locale.ROOT));
-            b.append("\n");
-            if (def.defaultValue != null) {
-                b.append("  * Default: ");
-                if (def.type == Type.STRING) {
-                    b.append("\"");
-                    b.append(def.defaultValue);
-                    b.append("\"");
-                } else {
-                    b.append(def.defaultValue);
+
+            getConfigKeyRst(def, b);
+
+            if (def.dependents != null && def.dependents.size() > 0) {
+                int j = 0;
+                b.append("  * Dependents: ");
+                for (String dependent : def.dependents) {
+                    b.append("``");
+                    b.append(dependent);
+                    if (++j == def.dependents.size())
+                        b.append("``");
+                    else
+                        b.append("``, ");
                 }
                 b.append("\n");
             }
-            b.append("  * Importance: ");
-            b.append(def.importance.toString().toLowerCase(Locale.ROOT));
-            b.append("\n\n");
+            b.append("\n");
         }
         return b.toString();
     }
 
     /**
+     * Shared content on Rst and Enriched Rst.
+     */
+    private void getConfigKeyRst(ConfigKey def, StringBuilder b) {
+        b.append("``").append(def.name).append("``").append("\n");
+        for (String docLine : def.documentation.split("\n")) {
+            if (docLine.length() == 0) {
+                continue;
+            }
+            b.append("  ").append(docLine).append("\n\n");
+        }
+        b.append("  * Type: ").append(getConfigValue(def, "Type")).append("\n");
+        if (def.hasDefault()) {
+            b.append("  * Default: ").append(getConfigValue(def, "Default")).append("\n");
+        }
+        if (def.validator != null) {
+            b.append("  * Valid Values: ").append(getConfigValue(def, "Valid Values")).append("\n");
+        }
+        b.append("  * Importance: ").append(getConfigValue(def, "Importance")).append("\n");
+    }
+
+    /**
      * Get a list of configs sorted into "natural" order: listing required fields first, then
      * ordering by importance, and finally by name.
      */
@@ -1023,4 +1057,34 @@ public class ConfigDef {
         });
         return configs;
     }
-}
+
+    /**
+     * Get a list of configs sorted taking the 'group' and 'orderInGroup' into account.
+     */
+    protected List<ConfigKey> sortedConfigsByGroup() {
+        final Map<String, Integer> groupOrd = new HashMap<>(groups.size());
+        int ord = 0;
+        for (String group: groups) {
+            groupOrd.put(group, ord++);
+        }
+
+        List<ConfigKey> configs = new ArrayList<>(configKeys.values());
+        Collections.sort(configs, new Comparator<ConfigKey>() {
+            @Override
+            public int compare(ConfigKey k1, ConfigKey k2) {
+                int cmp = k1.group == null
+                        ? (k2.group == null ? 0 : -1)
+                        : (k2.group == null ? 1 : Integer.compare(groupOrd.get(k1.group), groupOrd.get(k2.group)));
+                if (cmp == 0) {
+                    cmp = Integer.compare(k1.orderInGroup, k2.orderInGroup);
+                }
+                if (cmp == 0) {
+                    cmp = k1.name.compareTo(k2.name);
+                }
+                return cmp;
+            }
+        });
+        return configs;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/kafka/blob/72d5675a/clients/src/test/java/org/apache/kafka/common/config/ConfigDefTest.java
----------------------------------------------------------------------
diff --git a/clients/src/test/java/org/apache/kafka/common/config/ConfigDefTest.java b/clients/src/test/java/org/apache/kafka/common/config/ConfigDefTest.java
index 0b781fd..5a6339e 100644
--- a/clients/src/test/java/org/apache/kafka/common/config/ConfigDefTest.java
+++ b/clients/src/test/java/org/apache/kafka/common/config/ConfigDefTest.java
@@ -222,7 +222,7 @@ public class ConfigDefTest {
 
         Map<String, ConfigValue> configValues = new HashMap<>();
 
-        for (String name: def.configKeys().keySet()) {
+        for (String name : def.configKeys().keySet()) {
             configValues.put(name, new ConfigValue(name));
         }
 
@@ -364,4 +364,99 @@ public class ConfigDefTest {
             }
         }
     }
+
+    @Test
+    public void toRst() {
+        final ConfigDef def = new ConfigDef()
+                .define("opt1", Type.STRING, "a", ValidString.in("a", "b", "c"), Importance.HIGH, "docs1")
+                .define("opt2", Type.INT, Importance.MEDIUM, "docs2")
+                .define("opt3", Type.LIST, Arrays.asList("a", "b"), Importance.LOW, "docs3");
+
+        final String expectedRst = "" +
+                "``opt2``\n" +
+                "  docs2\n" +
+                "\n" +
+                "  * Type: int\n" +
+                "  * Importance: medium\n" +
+                "\n" +
+                "``opt1``\n" +
+                "  docs1\n" +
+                "\n" +
+                "  * Type: string\n" +
+                "  * Default: a\n" +
+                "  * Valid Values: [a, b, c]\n" +
+                "  * Importance: high\n" +
+                "\n" +
+                "``opt3``\n" +
+                "  docs3\n" +
+                "\n" +
+                "  * Type: list\n" +
+                "  * Default: a,b\n" +
+                "  * Importance: low\n" +
+                "\n";
+
+        assertEquals(expectedRst, def.toRst());
+    }
+
+    @Test
+    public void toEnrichedRst() {
+        final ConfigDef def = new ConfigDef()
+                .define("opt1.of.group1", Type.STRING, "a", ValidString.in("a", "b", "c"), Importance.HIGH, "Doc doc.",
+                        "Group One", 0, Width.NONE, "..", Collections.<String>emptyList())
+                .define("opt2.of.group1", Type.INT, ConfigDef.NO_DEFAULT_VALUE, Importance.MEDIUM, "Doc doc doc.",
+                        "Group One", 1, Width.NONE, "..", Arrays.asList("some.option1", "some.option2"))
+                .define("opt2.of.group2", Type.BOOLEAN, false, Importance.HIGH, "Doc doc doc doc.",
+                        "Group Two", 1, Width.NONE, "..", Collections.<String>emptyList())
+                .define("opt1.of.group2", Type.BOOLEAN, false, Importance.HIGH, "Doc doc doc doc doc.",
+                        "Group Two", 0, Width.NONE, "..", Collections.singletonList("some.option"))
+                .define("poor.opt", Type.STRING, "foo", Importance.HIGH, "Doc doc doc doc.");
+
+        final String expectedRst = "" +
+                "``poor.opt``\n" +
+                "  Doc doc doc doc.\n" +
+                "\n" +
+                "  * Type: string\n" +
+                "  * Default: foo\n" +
+                "  * Importance: high\n" +
+                "\n" +
+                "Group One\n" +
+                "^^^^^^^^^\n" +
+                "\n" +
+                "``opt1.of.group1``\n" +
+                "  Doc doc.\n" +
+                "\n" +
+                "  * Type: string\n" +
+                "  * Default: a\n" +
+                "  * Valid Values: [a, b, c]\n" +
+                "  * Importance: high\n" +
+                "\n" +
+                "``opt2.of.group1``\n" +
+                "  Doc doc doc.\n" +
+                "\n" +
+                "  * Type: int\n" +
+                "  * Importance: medium\n" +
+                "  * Dependents: ``some.option1``, ``some.option2``\n" +
+                "\n" +
+                "Group Two\n" +
+                "^^^^^^^^^\n" +
+                "\n" +
+                "``opt1.of.group2``\n" +
+                "  Doc doc doc doc doc.\n" +
+                "\n" +
+                "  * Type: boolean\n" +
+                "  * Default: false\n" +
+                "  * Importance: high\n" +
+                "  * Dependents: ``some.option``\n" +
+                "\n" +
+                "``opt2.of.group2``\n" +
+                "  Doc doc doc doc.\n" +
+                "\n" +
+                "  * Type: boolean\n" +
+                "  * Default: false\n" +
+                "  * Importance: high\n" +
+                "\n";
+
+        assertEquals(expectedRst, def.toEnrichedRst());
+    }
+
 }