Author: xedin
Date: Mon Aug 29 12:53:02 2011
New Revision: 1162775

URL: http://svn.apache.org/viewvc?rev=1162775&view=rev
Log:
Improvements of the CLI `describe` command
patch by satishbabu; reviewed by xedin for CASSANDRA-2630

Modified:
    cassandra/trunk/CHANGES.txt
    cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g
    cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java
    cassandra/trunk/src/java/org/apache/cassandra/cli/CliUtils.java
    cassandra/trunk/src/resources/org/apache/cassandra/cli/CliHelp.yaml
    cassandra/trunk/test/unit/org/apache/cassandra/cli/CliTest.java

Modified: cassandra/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/CHANGES.txt?rev=1162775&r1=1162774&r2=1162775&view=diff
==============================================================================
--- cassandra/trunk/CHANGES.txt (original)
+++ cassandra/trunk/CHANGES.txt Mon Aug 29 12:53:02 2011
@@ -45,7 +45,7 @@
  * Add timeouts to client request schedulers (CASSANDRA-3079)
  * Cli to use hashes rather than array of hashes for strategy options 
(CASSANDRA-3081)
  * LeveledCompactionStrategy (CASSANDRA-1608)
-
+ * Improvements of the CLI `describe` command (CASSANDRA-2630)
 
 0.8.5
  * fix NPE when encryption_options is unspecified (CASSANDRA-3007)

Modified: cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g?rev=1162775&r1=1162774&r2=1162775&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g Mon Aug 29 12:53:02 
2011
@@ -35,7 +35,7 @@ tokens {
     // various top-level CLI statements.
     //
     NODE_CONNECT;
-    NODE_DESCRIBE_TABLE;
+    NODE_DESCRIBE;
     NODE_DESCRIBE_CLUSTER;
     NODE_USE_TABLE;
     NODE_EXIT;
@@ -180,8 +180,8 @@ helpStatement
         -> ^(NODE_HELP NODE_CONNECT)
     | HELP USE 
         -> ^(NODE_HELP NODE_USE_TABLE)
-    | HELP DESCRIBE KEYSPACE 
-        -> ^(NODE_HELP NODE_DESCRIBE_TABLE)
+    | HELP DESCRIBE
+        -> ^(NODE_HELP NODE_DESCRIBE)
     | HELP DESCRIBE 'CLUSTER'
         -> ^(NODE_HELP NODE_DESCRIBE_CLUSTER)
     | HELP EXIT 
@@ -366,8 +366,8 @@ showSchema
     ;
 
 describeTable
-    : DESCRIBE KEYSPACE (keyspace)?
-        -> ^(NODE_DESCRIBE_TABLE (keyspace)?)
+    : DESCRIBE (keyspace)?
+        -> ^(NODE_DESCRIBE (keyspace)?)
     ;
     
 describeCluster

Modified: cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java?rev=1162775&r1=1162774&r2=1162775&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java Mon Aug 29 
12:53:02 2011
@@ -250,8 +250,8 @@ public class CliClient
                 case CliParser.NODE_SHOW_SCHEMA:
                     executeShowSchema(tree);
                     break;
-                case CliParser.NODE_DESCRIBE_TABLE:
-                    executeDescribeKeySpace(tree);
+                case CliParser.NODE_DESCRIBE:
+                    executeDescribe(tree);
                     break;
                 case CliParser.NODE_DESCRIBE_CLUSTER:
                     executeDescribeCluster();
@@ -1857,92 +1857,10 @@ public class CliClient
 
             sessionState.out.println("  Column Families:");
 
-            boolean isSuper;
-
             Collections.sort(ks_def.cf_defs, new CfDefNamesComparator());
-            for (CfDef cf_def : ks_def.cf_defs)
-            {
-                // fetching bean for current column family store
-                ColumnFamilyStoreMBean cfMBean = (probe == null) ? null : 
probe.getCfsProxy(ks_def.getName(), cf_def.getName());
 
-                isSuper = cf_def.column_type.equals("Super");
-                sessionState.out.printf("    ColumnFamily: %s%s%n", 
cf_def.name, isSuper ? " (Super)" : "");
-
-                if (cf_def.comment != null && !cf_def.comment.isEmpty())
-                {
-                    sessionState.out.printf("    \"%s\"%n", cf_def.comment);
-                }
-                if (cf_def.key_validation_class != null)
-                    sessionState.out.printf("      Key Validation Class: 
%s%n", cf_def.key_validation_class);
-                if (cf_def.default_validation_class != null)
-                    sessionState.out.printf("      Default column value 
validator: %s%n", cf_def.default_validation_class);
-                sessionState.out.printf("      Columns sorted by: %s%s%n", 
cf_def.comparator_type, cf_def.column_type.equals("Super") ? "/" + 
cf_def.subcomparator_type : "");
-                sessionState.out.printf("      Row cache size / save period in 
seconds / keys to save : %s/%s/%s%n",
-                                        cf_def.row_cache_size, 
cf_def.row_cache_save_period_in_seconds,
-                                        cf_def.row_cache_keys_to_save == 
Integer.MAX_VALUE ? "all" : cf_def.row_cache_keys_to_save);
-                sessionState.out.printf("      Key cache size / save period in 
seconds: %s/%s%n", cf_def.key_cache_size, 
cf_def.key_cache_save_period_in_seconds);
-                sessionState.out.printf("      Memtable thresholds: %s/%s 
(millions of ops/MB)%n",
-                                cf_def.memtable_operations_in_millions, 
cf_def.memtable_throughput_in_mb);
-                sessionState.out.printf("      GC grace seconds: %s%n", 
cf_def.gc_grace_seconds);
-                sessionState.out.printf("      Compaction min/max thresholds: 
%s/%s%n", cf_def.min_compaction_threshold, cf_def.max_compaction_threshold);
-                sessionState.out.printf("      Read repair chance: %s%n", 
cf_def.read_repair_chance);
-                sessionState.out.printf("      Replicate on write: %s%n", 
cf_def.replicate_on_write);
-                sessionState.out.printf("      Compression enabled: %s%n", 
cf_def.compression);
-
-                // if we have connection to the cfMBean established
-                if (cfMBean != null)
-                {
-                    sessionState.out.printf("      Built indexes: %s%n", 
cfMBean.getBuiltIndexes());
-                }
-
-                if (cf_def.getColumn_metadataSize() != 0)
-                {
-                    String leftSpace = "      ";
-                    String columnLeftSpace = leftSpace + "    ";
-
-                    String compareWith = isSuper ? cf_def.subcomparator_type
-                                                                               
       : cf_def.comparator_type;
-                    AbstractType columnNameValidator = 
getFormatType(compareWith);
-
-                    sessionState.out.println(leftSpace + "Column Metadata:");
-                    for (ColumnDef columnDef : cf_def.getColumn_metadata())
-                    {
-                        String columnName = 
columnNameValidator.getString(columnDef.name);
-                        if (columnNameValidator instanceof BytesType)
-                        {
-                            try
-                            {
-                                String columnString = 
UTF8Type.instance.getString(columnDef.name);
-                                columnName = columnString + " (" + columnName 
+ ")";
-                            }
-                            catch (MarshalException e)
-                            {
-                                // guess it wasn't a utf8 column name after all
-                            }
-                        }
-
-                        sessionState.out.println(leftSpace + "  Column Name: " 
+ columnName);
-                        sessionState.out.println(columnLeftSpace + "Validation 
Class: " + columnDef.getValidation_class());
-
-                        if (columnDef.isSetIndex_name())
-                        {
-                            sessionState.out.println(columnLeftSpace + "Index 
Name: " + columnDef.getIndex_name());
-                        }
-
-                        if (columnDef.isSetIndex_type())
-                        {
-                            sessionState.out.println(columnLeftSpace + "Index 
Type: " + columnDef.getIndex_type().name());
-                        }
-                    }
-                }
-                sessionState.out.printf("      Compaction Strategy: %s%n", 
cf_def.compaction_strategy);
-                if (!cf_def.compaction_strategy_options.isEmpty())
-                {
-                    sessionState.out.println("      Compaction Strategy 
Options:");
-                    for (Map.Entry<String, String> e : 
cf_def.compaction_strategy_options.entrySet())
-                        sessionState.out.printf("        %s: %s%n", 
e.getKey(), e.getValue());
-                }
-            }
+            for (CfDef cf_def : ks_def.cf_defs)
+                describeColumnFamily(ks_def, cf_def, probe);
 
             // compaction manager information
             if (compactionManagerMBean != null)
@@ -1977,34 +1895,151 @@ public class CliClient
         }
     }
 
-    // DESCRIBE KEYSPACE (<keyspace_name>)?
-    private void executeDescribeKeySpace(Tree statement) throws TException, 
InvalidRequestException
+    private void describeColumnFamily(KsDef ks_def, CfDef cf_def, NodeProbe 
probe) throws TException
     {
-        if (!CliMain.isConnected())
-            return;
+        // fetching bean for current column family store
+        ColumnFamilyStoreMBean cfMBean = (probe == null) ? null : 
probe.getCfsProxy(ks_def.getName(), cf_def.getName());
 
+        boolean isSuper = cf_def.column_type.equals("Super");
+        sessionState.out.printf("    ColumnFamily: %s%s%n", cf_def.name, 
isSuper ? " (Super)" : "");
 
-        String keySpaceName;
+        if (cf_def.comment != null && !cf_def.comment.isEmpty())
+            sessionState.out.printf("    \"%s\"%n", cf_def.comment);
 
-        // Get keyspace name
-        if (statement.getChildCount() == 0)
+        if (cf_def.key_validation_class != null)
+            sessionState.out.printf("      Key Validation Class: %s%n", 
cf_def.key_validation_class);
+
+        if (cf_def.default_validation_class != null)
+            sessionState.out.printf("      Default column value validator: 
%s%n", cf_def.default_validation_class);
+
+        sessionState.out.printf("      Columns sorted by: %s%s%n", 
cf_def.comparator_type, cf_def.column_type.equals("Super") ? "/" + 
cf_def.subcomparator_type : "");
+        sessionState.out.printf("      Row cache size / save period in seconds 
/ keys to save : %s/%s/%s%n",
+                cf_def.row_cache_size, cf_def.row_cache_save_period_in_seconds,
+                cf_def.row_cache_keys_to_save == Integer.MAX_VALUE ? "all" : 
cf_def.row_cache_keys_to_save);
+        sessionState.out.printf("      Key cache size / save period in 
seconds: %s/%s%n", cf_def.key_cache_size, 
cf_def.key_cache_save_period_in_seconds);
+        sessionState.out.printf("      Memtable thresholds: %s/%s (millions of 
ops/MB)%n",
+                cf_def.memtable_operations_in_millions, 
cf_def.memtable_throughput_in_mb);
+        sessionState.out.printf("      GC grace seconds: %s%n", 
cf_def.gc_grace_seconds);
+        sessionState.out.printf("      Compaction min/max thresholds: 
%s/%s%n", cf_def.min_compaction_threshold, cf_def.max_compaction_threshold);
+        sessionState.out.printf("      Read repair chance: %s%n", 
cf_def.read_repair_chance);
+        sessionState.out.printf("      Replicate on write: %s%n", 
cf_def.replicate_on_write);
+        sessionState.out.printf("      Compression enabled: %s%n", 
cf_def.compression);
+
+        // if we have connection to the cfMBean established
+        if (cfMBean != null)
+            sessionState.out.printf("      Built indexes: %s%n", 
cfMBean.getBuiltIndexes());
+
+        if (cf_def.getColumn_metadataSize() != 0)
         {
-            // trying to use current keyspace if keyspace name was not given
-            keySpaceName = keySpace;
+            String leftSpace = "      ";
+            String columnLeftSpace = leftSpace + "    ";
+
+            String compareWith = isSuper ? cf_def.subcomparator_type
+                    : cf_def.comparator_type;
+            AbstractType columnNameValidator = getFormatType(compareWith);
+
+            sessionState.out.println(leftSpace + "Column Metadata:");
+            for (ColumnDef columnDef : cf_def.getColumn_metadata())
+            {
+                String columnName = 
columnNameValidator.getString(columnDef.name);
+                if (columnNameValidator instanceof BytesType)
+                {
+                    try
+                    {
+                        String columnString = 
UTF8Type.instance.getString(columnDef.name);
+                        columnName = columnString + " (" + columnName + ")";
+                    }
+                    catch (MarshalException e)
+                    {
+                        // guess it wasn't a utf8 column name after all
+                    }
+                }
+
+                sessionState.out.println(leftSpace + "  Column Name: " + 
columnName);
+                sessionState.out.println(columnLeftSpace + "Validation Class: 
" + columnDef.getValidation_class());
+
+                if (columnDef.isSetIndex_name())
+                    sessionState.out.println(columnLeftSpace + "Index Name: " 
+ columnDef.getIndex_name());
+
+                if (columnDef.isSetIndex_type())
+                    sessionState.out.println(columnLeftSpace + "Index Type: " 
+ columnDef.getIndex_type().name());
+            }
         }
-        else
+
+        sessionState.out.printf("      Compaction Strategy: %s%n", 
cf_def.compaction_strategy);
+
+        if (!cf_def.compaction_strategy_options.isEmpty())
         {
-            // we have keyspace name as an argument
-            keySpaceName = CliCompiler.getKeySpace(statement, 
thriftClient.describe_keyspaces());
+            sessionState.out.println("      Compaction Strategy Options:");
+            for (Map.Entry<String, String> e : 
cf_def.compaction_strategy_options.entrySet())
+                sessionState.out.printf("        %s: %s%n", e.getKey(), 
e.getValue());
         }
+    }
 
-        if (keySpaceName == null)
-        {
-            sessionState.out.println("Keyspace argument required if you are 
not authorized in any keyspace.");
+    // DESCRIBE KEYSPACE (<keyspace> | <column_family>)?
+    private void executeDescribe(Tree statement) throws TException, 
InvalidRequestException
+    {
+        if (!CliMain.isConnected())
             return;
+
+        int argCount = statement.getChildCount();
+
+        KsDef currentKeySpace = keyspacesMap.get(keySpace);
+
+        if (argCount > 1) // in case somebody changes Cli grammar
+            throw new RuntimeException("`describe` command take maximum one 
argument. See `help describe;`");
+
+        if (argCount == 0)
+        {
+            if (currentKeySpace != null)
+            {
+                describeKeySpace(currentKeySpace.name, null);
+                return;
+            }
+
+            sessionState.out.println("Authenticate to a Keyspace, before using 
`describe` or `describe <column_family>`");
+        }
+        else if (argCount == 1)
+        {
+            // name of the keyspace or ColumnFamily
+            String entityName = statement.getChild(0).getText();
+
+            KsDef inputKsDef = CliUtils.getKeySpaceDef(entityName, 
thriftClient.describe_keyspaces());
+
+            if (inputKsDef == null && currentKeySpace == null)
+                throw new RuntimeException(String.format("Keyspace with name 
'%s' wasn't found, " +
+                                                         "to lookup 
ColumnFamily with that name, please, authorize to one " +
+                                                         "of the keyspaces 
first.", entityName));
+
+            CfDef inputCfDef = (inputKsDef == null)
+                    ? getCfDef(currentKeySpace, entityName)
+                    : null;  // no need to lookup CfDef if we know that it was 
keyspace
+
+            if (inputKsDef != null)
+            {
+                describeKeySpace(inputKsDef.name, inputKsDef);
+            }
+            else if (inputCfDef != null)
+            {
+                NodeProbe probe = sessionState.getNodeProbe();
+
+                try
+                {
+                    describeColumnFamily(currentKeySpace, inputCfDef, probe);
+
+                    if (probe != null)
+                        probe.close();
+                }
+                catch (IOException e)
+                {
+                    sessionState.out.println("Error while closing JMX 
connection: " + e.getMessage());
+                }
+            }
+            else
+            {
+                sessionState.out.println("Sorry, no Keyspace nor ColumnFamily 
was found with name: " + entityName);
+            }
         }
-        
-        describeKeySpace(keySpaceName, null);
     }
 
     // ^(NODE_DESCRIBE_CLUSTER) or describe: schema_versions, partitioner, 
snitch

Modified: cassandra/trunk/src/java/org/apache/cassandra/cli/CliUtils.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cli/CliUtils.java?rev=1162775&r1=1162774&r2=1162775&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/CliUtils.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/CliUtils.java Mon Aug 29 
12:53:02 2011
@@ -1,6 +1,7 @@
 package org.apache.cassandra.cli;
 
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Set;
 
 import org.apache.cassandra.thrift.CfDef;
@@ -96,4 +97,25 @@ public class CliUtils
 
         return names;
     }
+
+    /**
+     * Parse the statement from cli and return KsDef
+     *
+     * @param keyspaceName - name of the keyspace to lookup
+     * @param keyspaces - List of known keyspaces
+     *
+     * @return metadata about keyspace or null
+     */
+    public static KsDef getKeySpaceDef(String keyspaceName, List<KsDef> 
keyspaces)
+    {
+        keyspaceName = keyspaceName.toUpperCase();
+
+        for (KsDef ksDef : keyspaces)
+        {
+            if (ksDef.name.toUpperCase().equals(keyspaceName))
+                return ksDef;
+        }
+
+        return null;
+    }
 }

Modified: cassandra/trunk/src/resources/org/apache/cassandra/cli/CliHelp.yaml
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/resources/org/apache/cassandra/cli/CliHelp.yaml?rev=1162775&r1=1162774&r2=1162775&view=diff
==============================================================================
--- cassandra/trunk/src/resources/org/apache/cassandra/cli/CliHelp.yaml 
(original)
+++ cassandra/trunk/src/resources/org/apache/cassandra/cli/CliHelp.yaml Mon Aug 
29 12:53:02 2011
@@ -41,7 +41,7 @@ help: |
     del                     Delete a column, super column or row.
     decr                    Decrements a counter column.
     describe cluster        Describe the cluster configuration.
-    describe keyspace       Describe a keyspace and it's column families.
+    describe                Describe a keyspace and it's column families or 
column family in current keyspace.
     drop column family      Remove a column family and it's data.
     drop keyspace           Remove a keyspace and it's data.
     drop index              Remove an existing index from specific column.
@@ -115,21 +115,24 @@ commands:
         Examples:
         use Keyspace1;
         use Keyspace1 user 'badpasswd';
-    - name: NODE_DESCRIBE_TABLE
+    - name: NODE_DESCRIBE
       help: |
-        describe keyspace;
-        describe keyspace <keyspace>;
+        describe;
+        describe <keyspace>;
+        describe <column_family>;
 
-        Describes the settings for the current or named keyspace, and the 
settings
-        for all column families in the keyspace.
+        Describes the settings for the current or named keyspace, or the 
settings
+        of the column family in the current authenticated keyspace.
 
         Optional Parameters:
         - keyspace: Name of the keyspace to describe.
+        - column_family: Name of the column family to describe.
 
         Examples:
-        describe keyspace;
-        describe keyspace Keyspace1;
-    - name: NODE_DESCRIBE_CLUSTER
+        describe; - Describes current authenticated keyspace
+        describe <keyspace>; - Describe this keyspace
+        describe <column_family>; - Describe the colum family in the current 
authenticated keyspace
+    - name:
       help: |
         describe cluster;
 

Modified: cassandra/trunk/test/unit/org/apache/cassandra/cli/CliTest.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/cli/CliTest.java?rev=1162775&r1=1162774&r2=1162775&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/cli/CliTest.java (original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/cli/CliTest.java Mon Aug 29 
12:53:02 2011
@@ -170,7 +170,7 @@ public class CliTest extends CleanupHelp
         "help help",
         "help connect",
         "help use",
-        "help describe KEYSPACE",
+        "help describe",
         "HELP exit",
         "help QUIT",
         "help show cluster name",


Reply via email to