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",