Remove cassandra-cli

patch by Aleksey Yeschenko; reviewed by Brandon Williams and Jason Brown
for CASSANDRA-7920
This commit is contained in:
Aleksey Yeschenko 2014-09-24 18:00:43 -07:00
parent 24b18a9e5d
commit 380273826d
32 changed files with 337 additions and 7633 deletions

View File

@ -1,4 +1,5 @@
3.0
* Remove cassandra-cli (CASSANDRA-7920)
* Optimize java source-based UDF invocation (CASSANDRA-7924)
* Accept dollar quoted strings in CQL (CASSANDRA-7769)
* Make assassinate a first class command (CASSANDRA-7935)

View File

@ -21,10 +21,11 @@ New features
- SSTable file name is changed. Now you don't have Keyspace/CF name
in file name. Also, secondary index has its own directory under parent's
directory.
Upgrading
---------
- cassandra-cli has been removed. Please use cqlsh instead.
- YamlFileNetworkTopologySnitch has been removed; switch to
GossipingPropertyFileSnitch instead.
- CQL2 has been removed entirely in this release (previously deprecated

View File

@ -1,51 +0,0 @@
#!/bin/sh
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
if [ "x$CASSANDRA_INCLUDE" = "x" ]; then
for include in "`dirname "$0"`/cassandra.in.sh" \
"$HOME/.cassandra.in.sh" \
/usr/share/cassandra/cassandra.in.sh \
/usr/local/share/cassandra/cassandra.in.sh \
/opt/cassandra/cassandra.in.sh; do
if [ -r "$include" ]; then
. "$include"
break
fi
done
elif [ -r "$CASSANDRA_INCLUDE" ]; then
. "$CASSANDRA_INCLUDE"
fi
# Use JAVA_HOME if set, otherwise look for java in PATH
if [ -x "$JAVA_HOME/bin/java" ]; then
JAVA="$JAVA_HOME/bin/java"
else
JAVA="`which java`"
fi
if [ -z "$CLASSPATH" ]; then
echo "You must set the CLASSPATH var" >&2
exit 1
fi
"$JAVA" -ea -cp "$CLASSPATH" -Xmx256M \
-Dcassandra.storagedir="$cassandra_storagedir" \
-Dlogback.configurationFile=logback-tools.xml \
org.apache.cassandra.cli.CliMain "$@"
# vi:ai sw=4 ts=4 tw=0 et

View File

@ -1,36 +0,0 @@
@REM
@REM Licensed to the Apache Software Foundation (ASF) under one or more
@REM contributor license agreements. See the NOTICE file distributed with
@REM this work for additional information regarding copyright ownership.
@REM The ASF licenses this file to You under the Apache License, Version 2.0
@REM (the "License"); you may not use this file except in compliance with
@REM the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing, software
@REM distributed under the License is distributed on an "AS IS" BASIS,
@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@REM See the License for the specific language governing permissions and
@REM limitations under the License.
@echo off
if "%OS%" == "Windows_NT" setlocal
pushd "%~dp0"
call cassandra.in.bat
if NOT DEFINED CASSANDRA_HOME set CASSANDRA_HOME=%~dp0..
if NOT DEFINED JAVA_HOME goto :err
echo Starting Cassandra Client
"%JAVA_HOME%\bin\java" -cp %CASSANDRA_CLASSPATH% org.apache.cassandra.cli.CliMain %*
goto finally
:err
echo The JAVA_HOME environment variable must be set to run this program!
pause
:finally
ENDLOCAL

View File

@ -189,28 +189,6 @@
<delete dir="${build.dir}" />
</target>
<!--
This generates the CLI grammar files from Cli.g
-->
<target name="check-gen-cli-grammar">
<uptodate property="cliUpToDate"
srcfile="${build.src.java}/org/apache/cassandra/cli/Cli.g"
targetfile="${build.src.gen-java}/org/apache/cassandra/cli/Cli.tokens"/>
</target>
<target name="gen-cli-grammar" depends="check-gen-cli-grammar" unless="cliUpToDate">
<echo>Building Grammar ${build.src.java}/org/apache/cassandra/cli/Cli.g ....</echo>
<java classname="org.antlr.Tool"
classpath="${build.dir.lib}/jars/antlr-3.5.2.jar;${build.lib}/antlr-runtime-3.5.2.jar;${build.lib}/stringtemplate-4.0.2.jar"
fork="true"
failonerror="true">
<jvmarg value="-Xmx512M" />
<arg value="${build.src.java}/org/apache/cassandra/cli/Cli.g" />
<arg value="-fo" />
<arg value="${build.src.gen-java}/org/apache/cassandra/cli/" />
</java>
</target>
<!--
This generates the CQL grammar files from Cql.g
-->
@ -351,9 +329,6 @@
<dependency groupId="ch.qos.logback" artifactId="logback-classic" version="1.1.2"/>
<dependency groupId="org.codehaus.jackson" artifactId="jackson-core-asl" version="1.9.2"/>
<dependency groupId="org.codehaus.jackson" artifactId="jackson-mapper-asl" version="1.9.2"/>
<dependency groupId="jline" artifactId="jline" version="1.0">
<exclusion groupId="junit" artifactId="junit"/>
</dependency>
<dependency groupId="com.googlecode.json-simple" artifactId="json-simple" version="1.1"/>
<dependency groupId="com.boundary" artifactId="high-scale-lib" version="1.0.6"/>
<dependency groupId="com.github.jbellis" artifactId="jamm" version="0.2.6"/>
@ -486,7 +461,6 @@
<dependency groupId="org.slf4j" artifactId="slf4j-api"/>
<dependency groupId="org.codehaus.jackson" artifactId="jackson-core-asl"/>
<dependency groupId="org.codehaus.jackson" artifactId="jackson-mapper-asl"/>
<dependency groupId="jline" artifactId="jline"/>
<dependency groupId="com.googlecode.json-simple" artifactId="json-simple"/>
<dependency groupId="com.boundary" artifactId="high-scale-lib"/>
<dependency groupId="org.yaml" artifactId="snakeyaml"/>
@ -706,7 +680,7 @@
depends="maven-ant-tasks-retrieve-build,build-project" description="Compile Cassandra classes"/>
<target name="codecoverage" depends="jacoco-run,jacoco-report" description="Create code coverage report"/>
<target depends="init,gen-cli-grammar,gen-cql3-grammar"
<target depends="init,gen-cql3-grammar"
name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<!-- Order matters! -->

View File

@ -11,7 +11,6 @@ debian/cassandra.in.sh usr/share/cassandra
debian/cassandra.conf etc/security/limits.d
debian/cassandra-sysctl.conf etc/sysctl.d
bin/cassandra usr/sbin
bin/cassandra-cli usr/bin
bin/nodetool usr/bin
bin/sstablekeys usr/bin
bin/sstableloader usr/bin

View File

@ -19,7 +19,7 @@ contrib/word_count$ bin/word_count_setup
contrib/word_count$ bin/word_count
contrib/word_count$ bin/word_count_counters
In order to view the results in Cassandra, one can use bin/cassandra-cli and
In order to view the results in Cassandra, one can use bin/cqlsh and
perform the following operations:
$ bin/cqlsh localhost
> use cql3_worldcount;

View File

@ -19,12 +19,11 @@ contrib/word_count$ bin/word_count_setup
contrib/word_count$ bin/word_count
contrib/word_count$ bin/word_count_counters
In order to view the results in Cassandra, one can use bin/cassandra-cli and
In order to view the results in Cassandra, one can use bin/cqlsh and
perform the following operations:
$ bin/cassandra-cli
> connect localhost/9160;
$ bin/cqlsh localhost
> use wordcount;
> list output_words;
> select * from output_words;
The output of the word count can now be configured. In the bin/word_count
file, you can specify the OUTPUT_REDUCER. The two options are 'filesystem'

Binary file not shown.

View File

@ -1,33 +0,0 @@
Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu>
All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following
conditions are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with
the distribution.
Neither the name of JLine nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,728 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// ANTLR Grammar for the Cassandra Command Line Interface (CLI).
grammar Cli;
options {
output=AST;
ASTLabelType=CommonTree;
backtrack=true;
}
//
// Nodes in the AST
//
tokens {
//
// Top-level nodes. These typically correspond to
// various top-level CLI statements.
//
NODE_CONNECT;
NODE_DESCRIBE;
NODE_DESCRIBE_CLUSTER;
NODE_USE_TABLE;
NODE_TRACE_NEXT_QUERY;
NODE_SET_TRACE_PROBABILITY;
NODE_EXIT;
NODE_HELP;
NODE_NO_OP;
NODE_SHOW_CLUSTER_NAME;
NODE_SHOW_VERSION;
NODE_SHOW_KEYSPACES;
NODE_SHOW_SCHEMA;
NODE_THRIFT_GET;
NODE_THRIFT_GET_WITH_CONDITIONS;
NODE_THRIFT_SET;
NODE_THRIFT_COUNT;
NODE_THRIFT_DEL;
NODE_THRIFT_INCR;
NODE_THRIFT_DECR;
NODE_ADD_COLUMN_FAMILY;
NODE_ADD_KEYSPACE;
NODE_DEL_KEYSPACE;
NODE_DEL_COLUMN_FAMILY;
NODE_UPDATE_KEYSPACE;
NODE_UPDATE_COLUMN_FAMILY;
NODE_LIST;
NODE_TRUNCATE;
NODE_ASSUME;
NODE_CONSISTENCY_LEVEL;
NODE_DROP_INDEX;
// Internal Nodes.
NODE_COLUMN_ACCESS;
NODE_ID_LIST;
NODE_NEW_CF_ACCESS;
NODE_NEW_KEYSPACE_ACCESS;
CONVERT_TO_TYPE;
FUNCTION_CALL;
CONDITION;
CONDITIONS;
ARRAY;
HASH;
PAIR;
NODE_LIMIT;
NODE_COLUMNS;
NODE_REVERSED;
NODE_KEY_RANGE;
}
@parser::header {
package org.apache.cassandra.cli;
}
@lexer::header {
package org.apache.cassandra.cli;
}
@lexer::members
{
public void reportError(RecognitionException e)
{
StringBuilder errorMessage = new StringBuilder("Syntax error at position ").append(e.charPositionInLine).append(": ");
if (e instanceof NoViableAltException)
{
int index = e.charPositionInLine;
String error = this.input.substring(index, index);
String statement = this.input.substring(0, this.input.size() - 1);
errorMessage.append("unexpected \"").append(error).append("\" for `").append(statement).append("`.");
}
else
{
errorMessage.append(this.getErrorMessage(e, this.getTokenNames()));
}
throw new RuntimeException(errorMessage.toString());
}
}
@parser::members
{
public void reportError(RecognitionException e)
{
String errorMessage = "Syntax error at position " + e.charPositionInLine + ": " + this.getErrorMessage(e, this.getTokenNames());
throw new RuntimeException(errorMessage);
}
}
//
// Parser Section
//
// the root node
root: statement SEMICOLON? EOF -> statement;
statement
: connectStatement
| exitStatement
| countStatement
| describeTable
| describeCluster
| addKeyspace
| addColumnFamily
| updateKeyspace
| updateColumnFamily
| delColumnFamily
| delKeyspace
| useKeyspace
| traceNextQuery
| setTraceProbability
| delStatement
| getStatement
| helpStatement
| setStatement
| incrStatement
| showStatement
| listStatement
| truncateStatement
| assumeStatement
| consistencyLevelStatement
| dropIndex
| -> ^(NODE_NO_OP)
;
connectStatement
: CONNECT host '/' port (username password)?
-> ^(NODE_CONNECT host port (username password)?)
| CONNECT ip_address '/' port (username password)?
-> ^(NODE_CONNECT ip_address port (username password)?)
;
helpStatement
: HELP HELP
-> ^(NODE_HELP NODE_HELP)
| HELP CONNECT
-> ^(NODE_HELP NODE_CONNECT)
| HELP USE
-> ^(NODE_HELP NODE_USE_TABLE)
| HELP TRACE NEXT QUERY
-> ^(NODE_HELP NODE_TRACE_NEXT_QUERY)
| HELP SET TRACE PROBABILITY
-> ^(NODE_HELP NODE_SET_TRACE_PROBABILITY)
| HELP DESCRIBE
-> ^(NODE_HELP NODE_DESCRIBE)
| HELP DESCRIBE 'CLUSTER'
-> ^(NODE_HELP NODE_DESCRIBE_CLUSTER)
| HELP EXIT
-> ^(NODE_HELP NODE_EXIT)
| HELP QUIT
-> ^(NODE_HELP NODE_EXIT)
| HELP SHOW 'CLUSTER NAME'
-> ^(NODE_HELP NODE_SHOW_CLUSTER_NAME)
| HELP SHOW KEYSPACES
-> ^(NODE_HELP NODE_SHOW_KEYSPACES)
| HELP SHOW SCHEMA
-> ^(NODE_HELP NODE_SHOW_SCHEMA)
| HELP SHOW API_VERSION
-> ^(NODE_HELP NODE_SHOW_VERSION)
| HELP CREATE KEYSPACE
-> ^(NODE_HELP NODE_ADD_KEYSPACE)
| HELP UPDATE KEYSPACE
-> ^(NODE_HELP NODE_UPDATE_KEYSPACE)
| HELP CREATE COLUMN FAMILY
-> ^(NODE_HELP NODE_ADD_COLUMN_FAMILY)
| HELP UPDATE COLUMN FAMILY
-> ^(NODE_HELP NODE_UPDATE_COLUMN_FAMILY)
| HELP DROP KEYSPACE
-> ^(NODE_HELP NODE_DEL_KEYSPACE)
| HELP DROP COLUMN FAMILY
-> ^(NODE_HELP NODE_DEL_COLUMN_FAMILY)
| HELP DROP INDEX
-> ^(NODE_HELP NODE_DROP_INDEX)
| HELP GET
-> ^(NODE_HELP NODE_THRIFT_GET)
| HELP SET
-> ^(NODE_HELP NODE_THRIFT_SET)
| HELP INCR
-> ^(NODE_HELP NODE_THRIFT_INCR)
| HELP DECR
-> ^(NODE_HELP NODE_THRIFT_DECR)
| HELP DEL
-> ^(NODE_HELP NODE_THRIFT_DEL)
| HELP COUNT
-> ^(NODE_HELP NODE_THRIFT_COUNT)
| HELP LIST
-> ^(NODE_HELP NODE_LIST)
| HELP TRUNCATE
-> ^(NODE_HELP NODE_TRUNCATE)
| HELP ASSUME
-> ^(NODE_HELP NODE_ASSUME)
| HELP CONSISTENCYLEVEL
-> ^(NODE_HELP NODE_CONSISTENCY_LEVEL)
| HELP
-> ^(NODE_HELP)
| '?'
-> ^(NODE_HELP)
;
exitStatement
: QUIT -> ^(NODE_EXIT)
| EXIT -> ^(NODE_EXIT)
;
getStatement
: GET columnFamilyExpr ('AS' typeIdentifier)? ('LIMIT' limit=IntegerPositiveLiteral)?
-> ^(NODE_THRIFT_GET columnFamilyExpr ( ^(CONVERT_TO_TYPE typeIdentifier) )? ^(NODE_LIMIT $limit)?)
| GET columnFamily 'WHERE' getCondition ('AND' getCondition)* ('LIMIT' limit=IntegerPositiveLiteral)?
-> ^(NODE_THRIFT_GET_WITH_CONDITIONS columnFamily ^(CONDITIONS getCondition+) ^(NODE_LIMIT $limit)?)
;
getCondition
: columnOrSuperColumn operator value
-> ^(CONDITION operator columnOrSuperColumn value)
;
operator
: '=' | '>' | '<' | '>=' | '<='
;
typeIdentifier
: Identifier | StringLiteral | IntegerPositiveLiteral
;
setStatement
: SET columnFamilyExpr '=' objectValue=value (WITH TTL '=' ttlValue=IntegerPositiveLiteral)?
-> ^(NODE_THRIFT_SET columnFamilyExpr $objectValue ( $ttlValue )?)
;
incrStatement
: INCR columnFamilyExpr (BY byValue=incrementValue)?
-> ^(NODE_THRIFT_INCR columnFamilyExpr ( $byValue )?)
| DECR columnFamilyExpr (BY byValue=incrementValue)?
-> ^(NODE_THRIFT_DECR columnFamilyExpr ( $byValue )?)
;
countStatement
: COUNT columnFamilyExpr
-> ^(NODE_THRIFT_COUNT columnFamilyExpr)
;
delStatement
: DEL columnFamilyExpr
-> ^(NODE_THRIFT_DEL columnFamilyExpr)
;
showStatement
: showClusterName
| showVersion
| showKeyspaces
| showSchema
;
listStatement
: LIST columnFamily keyRangeExpr? rowLimitExpr? columnLimitExpr?
-> ^(NODE_LIST columnFamily keyRangeExpr? rowLimitExpr? columnLimitExpr?)
;
truncateStatement
: TRUNCATE columnFamily
-> ^(NODE_TRUNCATE columnFamily)
;
assumeStatement
: ASSUME columnFamily assumptionElement=Identifier 'AS' entityName
-> ^(NODE_ASSUME columnFamily $assumptionElement entityName)
;
consistencyLevelStatement
: CONSISTENCYLEVEL 'AS' defaultType=Identifier
-> ^(NODE_CONSISTENCY_LEVEL $defaultType)
;
showClusterName
: SHOW 'CLUSTER NAME'
-> ^(NODE_SHOW_CLUSTER_NAME)
;
addKeyspace
: CREATE KEYSPACE keyValuePairExpr
-> ^(NODE_ADD_KEYSPACE keyValuePairExpr)
;
addColumnFamily
: CREATE COLUMN FAMILY keyValuePairExpr
-> ^(NODE_ADD_COLUMN_FAMILY keyValuePairExpr)
;
updateKeyspace
: UPDATE KEYSPACE keyValuePairExpr
-> ^(NODE_UPDATE_KEYSPACE keyValuePairExpr)
;
updateColumnFamily
: UPDATE COLUMN FAMILY keyValuePairExpr
-> ^(NODE_UPDATE_COLUMN_FAMILY keyValuePairExpr)
;
delKeyspace
: DROP KEYSPACE keyspace
-> ^(NODE_DEL_KEYSPACE keyspace)
;
delColumnFamily
: DROP COLUMN FAMILY columnFamily
-> ^(NODE_DEL_COLUMN_FAMILY columnFamily)
;
dropIndex
: DROP INDEX ON columnFamily '.' columnName
-> ^(NODE_DROP_INDEX columnFamily columnName)
;
showVersion
: SHOW API_VERSION
-> ^(NODE_SHOW_VERSION)
;
showKeyspaces
: SHOW KEYSPACES
-> ^(NODE_SHOW_KEYSPACES)
;
showSchema
: SHOW SCHEMA (keyspace)?
-> ^(NODE_SHOW_SCHEMA (keyspace)?)
;
describeTable
: DESCRIBE (keyspace)?
-> ^(NODE_DESCRIBE (keyspace)?)
;
describeCluster
: DESCRIBE 'CLUSTER'
-> ^(NODE_DESCRIBE_CLUSTER)
;
useKeyspace
: USE keyspace ( username )? ( password )?
-> ^(NODE_USE_TABLE keyspace ( username )? ( password )?)
;
traceNextQuery
: TRACE NEXT QUERY
-> ^(NODE_TRACE_NEXT_QUERY)
;
setTraceProbability
: SET TRACE PROBABILITY tracingProbability
-> ^(NODE_SET_TRACE_PROBABILITY tracingProbability)
;
keyValuePairExpr
: entityName ( (AND | WITH) keyValuePair )*
-> ^(NODE_NEW_KEYSPACE_ACCESS entityName ( keyValuePair )* )
;
keyValuePair
: attr_name '=' attrValue
-> attr_name attrValue
;
attrValue
: arrayConstruct
| hashConstruct
| attrValueString
| attrValueInt
| attrValueDouble
;
arrayConstruct
: '[' (hashConstruct ','?)* ']'
-> ^(ARRAY (hashConstruct)*)
;
hashConstruct
: '{' hashElementPair (',' hashElementPair)* '}'
-> ^(HASH (hashElementPair)+)
;
hashElementPair
: rowKey ':' rowValue
-> ^(PAIR rowKey rowValue)
;
columnFamilyExpr
: columnFamily '[' rowKey ']'
( '[' column=columnOrSuperColumn ']'
('[' super_column=columnOrSuperColumn ']')?
)?
-> ^(NODE_COLUMN_ACCESS columnFamily rowKey ($column ($super_column)? )?)
;
keyRangeExpr
: '[' ( startKey=entityName? ':' endKey=entityName? )? ']'
-> ^(NODE_KEY_RANGE $startKey? $endKey?)
;
rowLimitExpr
: 'LIMIT' limit=IntegerPositiveLiteral
-> ^(NODE_LIMIT $limit)
;
columnLimitExpr
: 'COLUMNS' columns=IntegerPositiveLiteral reversedExpr?
-> ^(NODE_COLUMNS $columns reversedExpr?)
;
reversedExpr
: 'REVERSED'
-> ^(NODE_REVERSED)
;
columnName
: entityName
;
attr_name
: Identifier
;
attrValueString
: (Identifier | StringLiteral)
;
attrValueInt
: IntegerPositiveLiteral
| IntegerNegativeLiteral
;
attrValueDouble
: DoubleLiteral
;
keyspace
: entityName
;
replica_placement_strategy
: StringLiteral
;
keyspaceNewName
: entityName
;
comparator
: StringLiteral
;
command : Identifier
;
newColumnFamily
: entityName
;
username: Identifier
;
password: StringLiteral
;
columnFamily
: entityName
;
entityName
: (Identifier | StringLiteral | IntegerPositiveLiteral | IntegerNegativeLiteral)
;
rowKey
: (Identifier | StringLiteral | IntegerPositiveLiteral | IntegerNegativeLiteral | functionCall)
;
rowValue
: (Identifier | StringLiteral | IntegerPositiveLiteral | IntegerNegativeLiteral | functionCall | hashConstruct)
;
value
: (Identifier | IntegerPositiveLiteral | IntegerNegativeLiteral | StringLiteral | functionCall)
;
functionCall
: functionName=Identifier '(' functionArgument? ')'
-> ^(FUNCTION_CALL $functionName functionArgument?)
;
functionArgument
: Identifier | StringLiteral | IntegerPositiveLiteral | IntegerNegativeLiteral
;
columnOrSuperColumn
: (Identifier | IntegerPositiveLiteral | IntegerNegativeLiteral | StringLiteral | functionCall)
;
host
: host_name
-> ^(NODE_ID_LIST host_name)
;
host_name
: Identifier ('.' Identifier)*
;
ip_address
: IP_ADDRESS
-> ^(NODE_ID_LIST IP_ADDRESS)
;
port
: IntegerPositiveLiteral
;
incrementValue
: IntegerPositiveLiteral
| IntegerNegativeLiteral
;
traceSessionId
: Identifier
;
tracingProbability
: DoubleLiteral
;
//
// Lexer Section
//
//
// Keywords (in alphabetical order for convenience)
//
// CLI is case-insensitive with respect to these keywords.
// However, they MUST be listed in upper case here.
//
CONFIG: 'CONFIG';
CONNECT: 'CONNECT';
COUNT: 'COUNT';
DEL: 'DEL';
DESCRIBE: 'DESCRIBE';
USE: 'USE';
TRACE: 'TRACE';
PROBABILITY: 'PROBABILITY';
NEXT: 'NEXT';
QUERY: 'QUERY';
GET: 'GET';
HELP: 'HELP';
EXIT: 'EXIT';
FILE: 'FILE';
QUIT: 'QUIT';
SET: 'SET';
INCR: 'INCR';
DECR: 'DECR';
SHOW: 'SHOW';
KEYSPACE: 'KEYSPACE';
KEYSPACES: 'KEYSPACES';
API_VERSION: 'API VERSION';
CREATE: 'CREATE';
DROP: 'DROP';
COLUMN: 'COLUMN';
FAMILY: 'FAMILY';
WITH: 'WITH';
BY: 'BY';
AND: 'AND';
UPDATE: 'UPDATE';
LIST: 'LIST';
LIMIT: 'LIMIT';
TRUNCATE: 'TRUNCATE';
ASSUME: 'ASSUME';
TTL: 'TTL';
CONSISTENCYLEVEL: 'CONSISTENCYLEVEL';
INDEX: 'INDEX';
ON: 'ON';
SCHEMA: 'SCHEMA';
IP_ADDRESS
: IntegerPositiveLiteral '.' IntegerPositiveLiteral '.' IntegerPositiveLiteral '.' IntegerPositiveLiteral
;
// private syntactic rules
fragment
Letter
: 'a'..'z'
| 'A'..'Z'
;
fragment
Digit
: '0'..'9'
;
fragment
Alnum
: Letter
| Digit
;
// syntactic Elements
IntegerPositiveLiteral
: Digit+
;
IntegerNegativeLiteral
: '-' Digit+
;
DoubleLiteral
: Digit+ ('.' Digit+)?
| ' ' '.' Digit+
;
Identifier
: (Letter | Alnum) (Alnum | '_' | '-' )*
;
// literals
StringLiteral
: '\'' SingleStringCharacter* '\''
;
fragment SingleStringCharacter
: ~('\'' | '\\')
| '\\' EscapeSequence
;
fragment EscapeSequence
: CharacterEscapeSequence
| '0'
| HexEscapeSequence
| UnicodeEscapeSequence
;
fragment CharacterEscapeSequence
: SingleEscapeCharacter
| NonEscapeCharacter
;
fragment NonEscapeCharacter
: ~(EscapeCharacter)
;
fragment SingleEscapeCharacter
: '\'' | '"' | '\\' | 'b' | 'f' | 'n' | 'r' | 't' | 'v'
;
fragment EscapeCharacter
: SingleEscapeCharacter
| DecimalDigit
| 'x'
| 'u'
;
fragment HexEscapeSequence
: 'x' HexDigit HexDigit
;
fragment UnicodeEscapeSequence
: 'u' HexDigit HexDigit HexDigit HexDigit
;
fragment HexDigit
: DecimalDigit | ('a'..'f') | ('A'..'F')
;
fragment DecimalDigit
: ('0'..'9')
;
//
// syntactic elements
//
SEMICOLON
: ';'
;
WS
: (' '|'\r'|'\t'|'\n') {$channel=HIDDEN;} // whitepace
;
COMMENT
: '--' (~('\n'|'\r'))* { $channel=HIDDEN; }
| '/*' (options {greedy=false;} : .)* '*/' { $channel=HIDDEN; }
;

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cli;
public class CliCommandHelp
{
public String name;
public String help;
}

View File

@ -1,172 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cli;
import java.util.List;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.tree.Tree;
import org.apache.cassandra.thrift.CfDef;
import org.apache.cassandra.thrift.KsDef;
public class CliCompiler
{
// ANTLR does not provide case-insensitive tokenization support
// out of the box. So we override the LA (lookahead) function
// of the ANTLRStringStream class. Note: This doesn't change the
// token text-- but just relaxes the matching rules to match
// in upper case. [Logic borrowed from Hive code.]
//
// Also see discussion on this topic in:
// http://www.antlr.org/wiki/pages/viewpage.action?pageId=1782.
public static class ANTLRNoCaseStringStream extends ANTLRStringStream
{
public ANTLRNoCaseStringStream(String input)
{
super(input);
}
public int LA(int i)
{
int returnChar = super.LA(i);
if (returnChar == CharStream.EOF)
{
return returnChar;
}
else if (returnChar == 0)
{
return returnChar;
}
return Character.toUpperCase((char)returnChar);
}
}
public static Tree compileQuery(String query)
{
Tree queryTree;
try
{
ANTLRStringStream input = new ANTLRNoCaseStringStream(query);
CliLexer lexer = new CliLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
CliParser parser = new CliParser(tokens);
// start parsing...
queryTree = (Tree)(parser.root().getTree());
// semantic analysis if any...
// [tbd]
}
catch(Exception e)
{
// if there was an exception we don't want to process request any further
throw new RuntimeException(e.getMessage(), e);
}
return queryTree;
}
/*
* NODE_COLUMN_ACCESS related functions.
*/
public static String getColumnFamily(Tree astNode, Iterable<CfDef> cfDefs)
{
return getColumnFamily(CliUtils.unescapeSQLString(astNode.getChild(0).getText()), cfDefs);
}
public static String getColumnFamily(String cfName, Iterable<CfDef> cfDefs)
{
int matches = 0;
String lastMatchedName = "";
for (CfDef cfDef : cfDefs)
{
if (cfDef.name.equals(cfName))
{
return cfName;
}
else if (cfDef.name.toUpperCase().equals(cfName.toUpperCase()))
{
lastMatchedName = cfDef.name;
matches++;
}
}
if (matches > 1 || matches == 0)
throw new RuntimeException(cfName + " not found in current keyspace.");
return lastMatchedName;
}
public static String getKeySpace(Tree statement, List<KsDef> keyspaces)
{
return getKeySpace(CliUtils.unescapeSQLString(statement.getChild(0).getText()), keyspaces);
}
public static String getKeySpace(String ksName, List<KsDef> keyspaces)
{
int matches = 0;
String lastMatchedName = "";
for (KsDef ksDef : keyspaces)
{
if (ksDef.name.equals(ksName))
{
return ksName;
}
else if (ksDef.name.toUpperCase().equals(ksName.toUpperCase()))
{
lastMatchedName = ksDef.name;
matches++;
}
}
if (matches > 1 || matches == 0)
throw new RuntimeException("Keyspace '" + ksName + "' not found.");
return lastMatchedName;
}
public static String getKey(Tree astNode)
{
return CliUtils.unescapeSQLString(astNode.getChild(1).getText());
}
public static int numColumnSpecifiers(Tree astNode)
{
// Skip over keyspace, column family and rowKey
return astNode.getChildCount() - 2;
}
// Returns the pos'th (0-based index) column specifier in the astNode
public static String getColumn(Tree astNode, int pos)
{
// Skip over keyspace, column family and rowKey
return CliUtils.unescapeSQLString(astNode.getChild(pos + 2).getText());
}
}

View File

@ -1,85 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cli;
import jline.SimpleCompletor;
public class CliCompleter extends SimpleCompletor
{
private static final String[] commands = {
"connect",
"describe keyspace",
"exit",
"help",
"quit",
"show cluster name",
"show keyspaces",
"show schema",
"show api version",
"create keyspace",
"create column family",
"drop keyspace",
"drop column family",
"rename keyspace",
"rename column family",
"consistencylevel",
"help connect",
"help describe keyspace",
"help exit",
"help help",
"help quit",
"help show cluster name",
"help show keyspaces",
"help show schema",
"help show api version",
"help create keyspace",
"help create column family",
"help drop keyspace",
"help drop column family",
"help rename keyspace",
"help rename column family",
"help get",
"help set",
"help del",
"help count",
"help list",
"help truncate",
"help consistencylevel"
};
private static final String[] keyspaceCommands = {
"get",
"set",
"count",
"del",
"list",
"truncate",
"incr",
"decr"
};
public CliCompleter()
{
super(commands);
}
String[] getKeyspaceCommands()
{
return keyspaceCommands;
}
}

View File

@ -1,405 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cli;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.CharacterCodingException;
import java.util.*;
import org.apache.cassandra.auth.IAuthenticator;
import org.apache.cassandra.io.util.FileUtils;
import org.apache.cassandra.thrift.*;
import org.apache.cassandra.utils.FBUtilities;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.transport.TTransport;
import jline.ConsoleReader;
import jline.History;
/**
* Cassandra Command Line Interface (CLI) Main
*/
public class CliMain
{
public final static String OLD_HISTORYFILE = ".cassandra.history";
public final static String HISTORYFILE = "cli.history";
private static TTransport transport = null;
private static Cassandra.Client thriftClient = null;
public static final CliSessionState sessionState = new CliSessionState();
private static CliClient cliClient;
private static final CliCompleter completer = new CliCompleter();
private static int lineNumber = 1;
/**
* Establish a thrift connection to cassandra instance
*
* @param server - hostname or IP of the server
* @param port - Thrift port number
*/
public static void connect(String server, int port)
{
if (transport != null)
transport.close();
try
{
transport = sessionState.transportFactory.openTransport(server, port);
}
catch (Exception e)
{
e.printStackTrace(sessionState.err);
String error = (e.getCause() == null) ? e.getMessage() : e.getCause().getMessage();
throw new RuntimeException("Exception connecting to " + server + "/" + port + ". Reason: " + error + ".");
}
TBinaryProtocol binaryProtocol = new TBinaryProtocol(transport, true, true);
thriftClient = new Cassandra.Client(binaryProtocol);
cliClient = new CliClient(sessionState, thriftClient);
if ((sessionState.username != null) && (sessionState.password != null))
{
// Authenticate
Map<String, String> credentials = new HashMap<String, String>();
credentials.put(IAuthenticator.USERNAME_KEY, sessionState.username);
credentials.put(IAuthenticator.PASSWORD_KEY, sessionState.password);
AuthenticationRequest authRequest = new AuthenticationRequest(credentials);
try
{
thriftClient.login(authRequest);
cliClient.setUsername(sessionState.username);
}
catch (AuthenticationException e)
{
thriftClient = null;
sessionState.err.println("Exception during authentication to the cassandra node, " +
"Verify the keyspace exists, and that you are using the correct credentials.");
return;
}
catch (AuthorizationException e)
{
thriftClient = null;
sessionState.err.println("You are not authorized to use keyspace: " + sessionState.keyspace);
return;
}
catch (TException e)
{
thriftClient = null;
sessionState.err.println("Login failure. Did you specify 'keyspace', 'username' and 'password'?");
return;
}
}
if (sessionState.keyspace != null)
{
try
{
sessionState.keyspace = CliCompiler.getKeySpace(sessionState.keyspace, thriftClient.describe_keyspaces());;
thriftClient.set_keyspace(sessionState.keyspace);
cliClient.setKeySpace(sessionState.keyspace);
updateCompletor(CliUtils.getCfNamesByKeySpace(cliClient.getKSMetaData(sessionState.keyspace)));
}
catch (InvalidRequestException | NotFoundException e)
{
sessionState.err.println("Keyspace " + sessionState.keyspace + " not found");
return;
}
catch (TException e)
{
sessionState.err.println("Did you specify 'keyspace'?");
return;
}
}
// Lookup the cluster name, this is to make it clear which cluster the user is connected to
String clusterName;
try
{
clusterName = thriftClient.describe_cluster_name();
}
catch (Exception e)
{
sessionState.err.println("Exception retrieving information about the cassandra node, check you have connected to the thrift port.");
e.printStackTrace(sessionState.err);
return;
}
sessionState.out.printf("Connected to: \"%s\" on %s/%d%n", clusterName, server, port);
}
/**
* Disconnect thrift connection to cassandra instance
*/
public static void disconnect()
{
if (transport != null)
{
transport.close();
transport = null;
}
}
/**
* Checks whether the thrift client is connected.
* @return boolean - true when connected, false otherwise
*/
public static boolean isConnected()
{
if (thriftClient == null)
{
sessionState.out.println("Not connected to a cassandra instance.");
return false;
}
return true;
}
public static void updateCompletor(Set<String> candidates)
{
Set<String> actions = new HashSet<String>();
for (String cf : candidates)
{
for (String cmd : completer.getKeyspaceCommands())
actions.add(String.format("%s %s", cmd, cf));
}
String[] strs = Arrays.copyOf(actions.toArray(), actions.toArray().length, String[].class);
completer.setCandidateStrings(strs);
}
public static void processStatement(String query) throws CharacterCodingException, TException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException
{
cliClient.executeCLIStatement(query);
}
public static void processStatementInteractive(String query)
{
try
{
cliClient.executeCLIStatement(query);
}
catch (Exception e)
{
String errorTemplate = sessionState.inFileMode() ? "Line " + lineNumber + " => " : "";
Throwable exception = (e.getCause() == null) ? e : e.getCause();
String message = (exception instanceof InvalidRequestException) ? ((InvalidRequestException) exception).getWhy() : e.getMessage();
sessionState.err.println(errorTemplate + message);
if (sessionState.debug || !(e instanceof RuntimeException))
e.printStackTrace(sessionState.err);
if (sessionState.batch || sessionState.inFileMode())
{
System.exit(4);
}
}
finally
{
lineNumber++;
}
}
public static void main(String args[]) throws IOException
{
// process command line arguments
CliOptions cliOptions = new CliOptions();
cliOptions.processArgs(sessionState, args);
// connect to cassandra server if host argument specified.
if (sessionState.hostName != null)
{
try
{
connect(sessionState.hostName, sessionState.thriftPort);
}
catch (RuntimeException e)
{
sessionState.err.println(e.getMessage());
}
}
if ( cliClient == null )
{
// Connection parameter was either invalid or not present.
// User must connect explicitly using the "connect" CLI statement.
cliClient = new CliClient(sessionState, null);
}
// load statements from file and process them
if (sessionState.inFileMode())
{
BufferedReader reader = null;
try
{
reader = new BufferedReader(new FileReader(sessionState.filename));
evaluateFileStatements(reader);
}
catch (IOException e)
{
sessionState.err.println(e.getMessage());
System.exit(1);
}
finally
{
FileUtils.closeQuietly(reader);
}
return;
}
ConsoleReader reader = new ConsoleReader();
if (!sessionState.batch)
{
reader.addCompletor(completer);
reader.setBellEnabled(false);
File historyFile = handleHistoryFiles();
try
{
History history = new History(historyFile);
reader.setHistory(history);
}
catch (IOException exp)
{
sessionState.err.printf("Unable to open %s for writing", historyFile.getAbsolutePath());
}
}
else if (!sessionState.verbose) // if in batch mode but no verbose flag
{
sessionState.out.close();
}
cliClient.printBanner();
String prompt;
String line = "";
String currentStatement = "";
boolean inCompoundStatement = false;
while (line != null)
{
prompt = (inCompoundStatement) ? "...\t" : getPrompt(cliClient);
try
{
line = reader.readLine(prompt);
}
catch (IOException e)
{
// retry on I/O Exception
}
if (line == null)
return;
line = line.trim();
// skipping empty and comment lines
if (line.isEmpty() || line.startsWith("--"))
continue;
currentStatement += line;
if (line.endsWith(";") || line.equals("?"))
{
processStatementInteractive(currentStatement);
currentStatement = "";
inCompoundStatement = false;
}
else
{
currentStatement += " "; // ready for new line
inCompoundStatement = true;
}
}
}
private static File handleHistoryFiles()
{
File outputDir = FBUtilities.getToolsOutputDirectory();
File historyFile = new File(outputDir, HISTORYFILE);
File oldHistoryFile = new File(System.getProperty("user.home"), OLD_HISTORYFILE);
if(oldHistoryFile.exists())
FileUtils.renameWithConfirm(oldHistoryFile, historyFile);
return historyFile;
}
private static void evaluateFileStatements(BufferedReader reader) throws IOException
{
String line;
String currentStatement = "";
boolean commentedBlock = false;
while ((line = reader.readLine()) != null)
{
line = line.trim();
// skipping empty and comment lines
if (line.isEmpty() || line.startsWith("--"))
continue;
if (line.startsWith("/*"))
commentedBlock = true;
if (line.startsWith("*/") || line.endsWith("*/"))
{
commentedBlock = false;
continue;
}
if (commentedBlock) // skip commented lines
continue;
currentStatement += line;
if (line.endsWith(";"))
{
processStatementInteractive(currentStatement);
currentStatement = "";
}
else
{
currentStatement += " "; // ready for new line
}
}
}
/**
* Returns prompt for current connection
* @param client - currently connected client
* @return String - prompt with username and keyspace (if any)
*/
private static String getPrompt(CliClient client)
{
return "[" + client.getUsername() + "@" + client.getKeySpace() + "] ";
}
}

View File

@ -1,319 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cli;
import java.util.HashMap;
import java.util.Map;
import com.google.common.base.Joiner;
import org.apache.commons.cli.*;
import org.apache.cassandra.config.EncryptionOptions;
import org.apache.cassandra.thrift.ITransportFactory;
import org.apache.cassandra.thrift.SSLTransportFactory;
/**
*
* Used to process, and act upon the arguments passed to the CLI.
*
*/
public class CliOptions
{
private static final CLIOptions options; // Info about command line options
// Name of the command line tool (used for error messages)
private static final String TOOL_NAME = "cassandra-cli";
// Command line options
private static final String HOST_OPTION = "host";
private static final String PORT_OPTION = "port";
private static final String TRANSPORT_FACTORY = "transport-factory";
private static final String DEBUG_OPTION = "debug";
private static final String USERNAME_OPTION = "username";
private static final String PASSWORD_OPTION = "password";
private static final String KEYSPACE_OPTION = "keyspace";
private static final String BATCH_OPTION = "batch";
private static final String HELP_OPTION = "help";
private static final String FILE_OPTION = "file";
private static final String JMX_PORT_OPTION = "jmxport";
private static final String JMX_USERNAME_OPTION = "jmxusername";
private static final String JMX_PASSWORD_OPTION = "jmxpassword";
private static final String VERBOSE_OPTION = "verbose";
private static final String SSL_TRUSTSTORE = "truststore";
private static final String SSL_TRUSTSTORE_PW = "truststore-password";
private static final String SSL_PROTOCOL = "ssl-protocol";
private static final String SSL_ALGORITHM = "ssl-alg";
private static final String SSL_STORE_TYPE = "store-type";
private static final String SSL_CIPHER_SUITES = "ssl-ciphers";
// Default values for optional command line arguments
private static final String DEFAULT_HOST = "127.0.0.1";
private static final int DEFAULT_THRIFT_PORT = 9160;
// Register the command line options and their properties (such as
// whether they take an extra argument, etc.
static
{
options = new CLIOptions();
options.addOption("h", HOST_OPTION, "HOSTNAME", "cassandra server's host name");
options.addOption("p", PORT_OPTION, "PORT", "cassandra server's thrift port");
options.addOption("u", USERNAME_OPTION, "USERNAME", "user name for cassandra authentication");
options.addOption("pw", PASSWORD_OPTION, "PASSWORD", "password for cassandra authentication");
options.addOption("k", KEYSPACE_OPTION, "KEYSPACE", "cassandra keyspace user is authenticated against");
options.addOption("f", FILE_OPTION, "FILENAME", "load statements from the specific file");
options.addOption(null, JMX_PORT_OPTION, "JMX-PORT", "JMX service port");
options.addOption(null, JMX_USERNAME_OPTION, "JMX-USERNAME", "JMX service username");
options.addOption(null, JMX_PASSWORD_OPTION, "JMX-PASSWORD", "JMX service password");
options.addOption("tf", TRANSPORT_FACTORY, "TRANSPORT-FACTORY", "Fully-qualified ITransportFactory class name for creating a connection to cassandra");
// ssl connection-related options
options.addOption("ts", SSL_TRUSTSTORE, "TRUSTSTORE", "SSL: full path to truststore");
options.addOption("tspw", SSL_TRUSTSTORE_PW, "TRUSTSTORE-PASSWORD", "SSL: password of the truststore");
options.addOption("prtcl", SSL_PROTOCOL, "PROTOCOL", "SSL: connections protocol to use (default: TLS)");
options.addOption("alg", SSL_ALGORITHM, "ALGORITHM", "SSL: algorithm (default: SunX509)");
options.addOption("st", SSL_STORE_TYPE, "STORE-TYPE", "SSL: type of store");
options.addOption("ciphers", SSL_CIPHER_SUITES, "CIPHER-SUITES", "SSL: comma-separated list of encryption suites to use");
// options without argument
options.addOption("B", BATCH_OPTION, "enabled batch mode (suppress output; errors are fatal)");
options.addOption(null, DEBUG_OPTION, "display stack-traces (NOTE: We print strack-traces in the places where it makes sense even without --debug)");
options.addOption("?", HELP_OPTION, "usage help");
options.addOption("v", VERBOSE_OPTION, "verbose output when using batch mode");
}
private static void printUsage()
{
new HelpFormatter().printHelp(TOOL_NAME, options);
}
public void processArgs(CliSessionState css, String[] args)
{
CommandLineParser parser = new GnuParser();
try
{
CommandLine cmd = parser.parse(options, args, false);
if (cmd.hasOption(HOST_OPTION))
{
css.hostName = cmd.getOptionValue(HOST_OPTION);
}
else
{
css.hostName = DEFAULT_HOST;
}
if (cmd.hasOption(DEBUG_OPTION))
{
css.debug = true;
}
// Look for optional args.
if (cmd.hasOption(PORT_OPTION))
{
css.thriftPort = Integer.parseInt(cmd.getOptionValue(PORT_OPTION));
}
else
{
css.thriftPort = DEFAULT_THRIFT_PORT;
}
// Look for authentication credentials (username and password)
if (cmd.hasOption(USERNAME_OPTION))
{
css.username = cmd.getOptionValue(USERNAME_OPTION);
}
if (cmd.hasOption(PASSWORD_OPTION))
{
css.password = cmd.getOptionValue(PASSWORD_OPTION);
}
// Look for keyspace
if (cmd.hasOption(KEYSPACE_OPTION))
{
css.keyspace = cmd.getOptionValue(KEYSPACE_OPTION);
}
if (cmd.hasOption(BATCH_OPTION))
{
css.batch = true;
}
if (cmd.hasOption(FILE_OPTION))
{
css.filename = cmd.getOptionValue(FILE_OPTION);
}
if (cmd.hasOption(JMX_PORT_OPTION))
{
css.jmxPort = Integer.parseInt(cmd.getOptionValue(JMX_PORT_OPTION));
}
if (cmd.hasOption(JMX_USERNAME_OPTION))
{
css.jmxUsername = cmd.getOptionValue(JMX_USERNAME_OPTION);
}
if (cmd.hasOption(JMX_PASSWORD_OPTION))
{
css.jmxPassword = cmd.getOptionValue(JMX_PASSWORD_OPTION);
}
if (cmd.hasOption(HELP_OPTION))
{
printUsage();
System.exit(1);
}
if (cmd.hasOption(VERBOSE_OPTION))
{
css.verbose = true;
}
if(cmd.hasOption(SSL_TRUSTSTORE))
{
css.encOptions.truststore = cmd.getOptionValue(SSL_TRUSTSTORE);
}
if(cmd.hasOption(SSL_TRUSTSTORE_PW))
{
css.encOptions.truststore_password = cmd.getOptionValue(SSL_TRUSTSTORE_PW);
}
if(cmd.hasOption(SSL_PROTOCOL))
{
css.encOptions.protocol = cmd.getOptionValue(SSL_PROTOCOL);
}
if(cmd.hasOption(SSL_ALGORITHM))
{
css.encOptions.algorithm = cmd.getOptionValue(SSL_ALGORITHM);
}
if(cmd.hasOption(SSL_STORE_TYPE))
{
css.encOptions.store_type = cmd.getOptionValue(SSL_STORE_TYPE);
}
if(cmd.hasOption(SSL_CIPHER_SUITES))
{
css.encOptions.cipher_suites = cmd.getOptionValue(SSL_CIPHER_SUITES).split(",");
}
if (cmd.hasOption(TRANSPORT_FACTORY))
{
css.transportFactory = validateAndSetTransportFactory(cmd.getOptionValue(TRANSPORT_FACTORY));
configureTransportFactory(css.transportFactory, css.encOptions);
}
// Abort if there are any unrecognized arguments left
if (cmd.getArgs().length > 0)
{
System.err.printf("Unknown argument: %s%n", cmd.getArgs()[0]);
System.err.println();
printUsage();
System.exit(1);
}
}
catch (ParseException e)
{
System.err.println(e.getMessage());
System.err.println();
printUsage();
System.exit(1);
}
}
private static class CLIOptions extends Options
{
/**
* Add option with argument and argument name
* @param opt shortcut for option name
* @param longOpt complete option name
* @param argName argument name
* @param description description of the option
* @return updated Options object
*/
public Options addOption(String opt, String longOpt, String argName, String description)
{
Option option = new Option(opt, longOpt, true, description);
option.setArgName(argName);
return addOption(option);
}
/**
* Add option without argument
* @param opt shortcut for option name
* @param longOpt complete option name
* @param description description of the option
* @return updated Options object
*/
public Options addOption(String opt, String longOpt, String description)
{
return addOption(new Option(opt, longOpt, false, description));
}
}
private static ITransportFactory validateAndSetTransportFactory(String transportFactory)
{
try
{
Class<?> factory = Class.forName(transportFactory);
if (!ITransportFactory.class.isAssignableFrom(factory))
throw new IllegalArgumentException(String.format("transport factory '%s' " +
"not derived from ITransportFactory", transportFactory));
return (ITransportFactory) factory.newInstance();
}
catch (Exception e)
{
throw new IllegalArgumentException(String.format("Cannot create a transport factory '%s'.", transportFactory), e);
}
}
private static void configureTransportFactory(ITransportFactory transportFactory, EncryptionOptions encOptions)
{
Map<String, String> options = new HashMap<>();
// If the supplied factory supports the same set of options as our SSL impl, set those
if (transportFactory.supportedOptions().contains(SSLTransportFactory.TRUSTSTORE))
options.put(SSLTransportFactory.TRUSTSTORE, encOptions.truststore);
if (transportFactory.supportedOptions().contains(SSLTransportFactory.TRUSTSTORE_PASSWORD))
options.put(SSLTransportFactory.TRUSTSTORE_PASSWORD, encOptions.truststore_password);
if (transportFactory.supportedOptions().contains(SSLTransportFactory.PROTOCOL))
options.put(SSLTransportFactory.PROTOCOL, encOptions.protocol);
if (transportFactory.supportedOptions().contains(SSLTransportFactory.CIPHER_SUITES))
options.put(SSLTransportFactory.CIPHER_SUITES, Joiner.on(',').join(encOptions.cipher_suites));
if (transportFactory.supportedOptions().contains(SSLTransportFactory.KEYSTORE)
&& encOptions.require_client_auth)
options.put(SSLTransportFactory.KEYSTORE, encOptions.keystore);
if (transportFactory.supportedOptions().contains(SSLTransportFactory.KEYSTORE_PASSWORD)
&& encOptions.require_client_auth)
options.put(SSLTransportFactory.KEYSTORE_PASSWORD, encOptions.keystore_password);
// Now check if any of the factory's supported options are set as system properties
for (String optionKey : transportFactory.supportedOptions())
if (System.getProperty(optionKey) != null)
options.put(optionKey, System.getProperty(optionKey));
transportFactory.setOptions(options);
}
}

View File

@ -1,94 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cli;
import java.io.InputStream;
import java.io.PrintStream;
import org.apache.cassandra.config.EncryptionOptions;
import org.apache.cassandra.config.EncryptionOptions.ClientEncryptionOptions;
import org.apache.cassandra.thrift.ITransportFactory;
import org.apache.cassandra.thrift.TFramedTransportFactory;
import org.apache.cassandra.tools.NodeProbe;
/**
* Used to hold the state for the CLI.
*/
public class CliSessionState
{
public String hostName; // cassandra server name
public int thriftPort; // cassandra server's thrift port
public boolean debug = false; // print stack traces when errors occur in the CLI
public String username; // cassandra login name (if password-based authenticator is used)
public String password; // cassandra login password (if password-based authenticator is used)
public String keyspace; // cassandra keyspace user is authenticating
public boolean batch = false; // enable/disable batch processing mode
public String filename = ""; // file to read commands from
public int jmxPort = 7199;// JMX service port
public String jmxUsername; // JMX service username
public String jmxPassword; // JMX service password
public boolean verbose = false; // verbose output
public ITransportFactory transportFactory = new TFramedTransportFactory();
public EncryptionOptions encOptions = new ClientEncryptionOptions();
/*
* Streams to read/write from
*/
public InputStream in;
public PrintStream out;
public PrintStream err;
public CliSessionState()
{
in = System.in;
out = System.out;
err = System.err;
}
public void setOut(PrintStream newOut)
{
this.out = newOut;
}
public void setErr(PrintStream newErr)
{
this.err = newErr;
}
public boolean inFileMode()
{
return !this.filename.isEmpty();
}
public NodeProbe getNodeProbe()
{
try
{
return jmxUsername != null && jmxPassword != null
? new NodeProbe(hostName, jmxPort, jmxUsername, jmxPassword)
: new NodeProbe(hostName, jmxPort);
}
catch (Exception e)
{
err.printf("WARNING: Could not connect to the JMX on %s:%d - some information won't be shown.%n%n", hostName, jmxPort);
}
return null;
}
}

View File

@ -1,29 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cli;
import java.util.List;
public class CliUserHelp
{
public String banner;
public String help;
public List<CliCommandHelp> commands;
}

View File

@ -1,128 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cli;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.apache.cassandra.thrift.CfDef;
import org.apache.cassandra.thrift.IndexOperator;
import org.apache.cassandra.thrift.KsDef;
import org.apache.commons.lang3.StringEscapeUtils;
public class CliUtils
{
/**
* Strips leading and trailing "'" characters, and handles
* and escaped characters such as \n, \r, etc.
* @param b - string to unescape
* @return String - unexspaced string
*/
public static String unescapeSQLString(String b)
{
if (b.charAt(0) == '\'' && b.charAt(b.length()-1) == '\'')
b = b.substring(1, b.length()-1);
return StringEscapeUtils.unescapeJava(b);
}
public static String escapeSQLString(String b)
{
// single quotes are not escaped in java, need to be for cli
return StringEscapeUtils.escapeJava(b).replace("\'", "\\'");
}
public static String maybeEscapeName(String name)
{
return Character.isLetter(name.charAt(0)) ? name : "\'" + name + "\'";
}
/**
* Returns IndexOperator from string representation
* @param operator - string representing IndexOperator (=, >=, >, <, <=)
* @return IndexOperator - enum value of IndexOperator or null if not found
*/
public static IndexOperator getIndexOperator(String operator)
{
if (operator.equals("="))
{
return IndexOperator.EQ;
}
else if (operator.equals(">="))
{
return IndexOperator.GTE;
}
else if (operator.equals(">"))
{
return IndexOperator.GT;
}
else if (operator.equals("<"))
{
return IndexOperator.LT;
}
else if (operator.equals("<="))
{
return IndexOperator.LTE;
}
return null;
}
/**
* Returns set of column family names in specified keySpace.
* @param keySpace - keyspace definition to get column family names from.
* @return Set - column family names
*/
public static Set<String> getCfNamesByKeySpace(KsDef keySpace)
{
Set<String> names = new LinkedHashSet<String>();
for (CfDef cfDef : keySpace.getCf_defs())
{
names.add(cfDef.getName());
}
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;
}
public static String quote(String str)
{
return String.format("'%s'", str);
}
}

View File

@ -1,32 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cli.transport;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportFactory;
public class FramedTransportFactory extends TTransportFactory
{
public static final int DEFAULT_MAX_FRAME_SIZE = 15 * 1024 * 1024; // 15 MiB
public TTransport getTransport(TTransport base)
{
return new TFramedTransport(base, DEFAULT_MAX_FRAME_SIZE);
}
}

View File

@ -1,47 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cli.transport;
import org.apache.cassandra.cli.CliMain;
import org.apache.cassandra.cli.CliSessionState;
import org.apache.thrift.transport.TSSLTransportFactory;
import org.apache.thrift.transport.TSSLTransportFactory.TSSLTransportParameters;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import org.apache.thrift.transport.TTransportFactory;
public class SSLTransportFactory extends TTransportFactory
{
private static final int SOCKET_TIMEOUT = 0;
public TTransport getTransport(TTransport trans)
{
final CliSessionState sessionState = CliMain.sessionState;
try
{
TSSLTransportParameters params = new TSSLTransportParameters(sessionState.encOptions.protocol, sessionState.encOptions.cipher_suites);
params.setTrustStore(sessionState.encOptions.truststore, sessionState.encOptions.truststore_password);
trans = TSSLTransportFactory.getClientSocket(sessionState.hostName, sessionState.thriftPort, SOCKET_TIMEOUT, params);
return new FramedTransportFactory().getTransport(trans);
}
catch (TTransportException e)
{
throw new RuntimeException("Failed to create a client SSL connection.", e);
}
}
}

View File

@ -48,68 +48,6 @@ import org.apache.cassandra.utils.ByteBufferUtil;
* SCHEMA_{KEYSPACES, COLUMNFAMILIES, COLUMNS}_CF are used to store Keyspace/ColumnFamily attributes to make schema
* load/distribution easy, it replaces old mechanism when local migrations where serialized, stored in system.Migrations
* and used for schema distribution.
*
* SCHEMA_KEYSPACES_CF layout:
*
* <key (AsciiType)>
* ascii => json_serialized_value
* ...
* </key>
*
* Where <key> is a name of keyspace e.g. "ks".
*
* SCHEMA_COLUMNFAMILIES_CF layout:
*
* <key (AsciiType)>
* composite(ascii, ascii) => json_serialized_value
* </key>
*
* Where <key> is a name of keyspace e.g. "ks"., first component of the column name is name of the ColumnFamily, last
* component is the name of the ColumnFamily attribute.
*
* SCHEMA_COLUMNS_CF layout:
*
* <key (AsciiType)>
* composite(ascii, ascii, ascii) => json_serialized value
* </key>
*
* Where <key> is a name of keyspace e.g. "ks".
*
* Cell names where made composite to support 3-level nesting which represents following structure:
* "ColumnFamily name":"column name":"column attribute" => "value"
*
* Example of schema (using CLI):
*
* schema_keyspaces
* ----------------
* RowKey: ks
* => (column=durable_writes, value=true, timestamp=1327061028312185000)
* => (column=name, value="ks", timestamp=1327061028312185000)
* => (column=replication_factor, value=0, timestamp=1327061028312185000)
* => (column=strategy_class, value="org.apache.cassandra.locator.NetworkTopologyStrategy", timestamp=1327061028312185000)
* => (column=strategy_options, value={"datacenter1":"1"}, timestamp=1327061028312185000)
*
* schema_columnfamilies
* ---------------------
* RowKey: ks
* => (column=cf:bloom_filter_fp_chance, value=0.0, timestamp=1327061105833119000)
* => (column=cf:caching, value="NONE", timestamp=1327061105833119000)
* => (column=cf:column_type, value="Standard", timestamp=1327061105833119000)
* => (column=cf:comment, value="ColumnFamily", timestamp=1327061105833119000)
* => (column=cf:default_validation_class, value="org.apache.cassandra.db.marshal.BytesType", timestamp=1327061105833119000)
* => (column=cf:gc_grace_seconds, value=864000, timestamp=1327061105833119000)
* => (column=cf:id, value=1000, timestamp=1327061105833119000)
* => (column=cf:key_alias, value="S0VZ", timestamp=1327061105833119000)
* ... part of the output omitted.
*
* schema_columns
* --------------
* RowKey: ks
* => (column=cf:c:index_name, value=null, timestamp=1327061105833119000)
* => (column=cf:c:index_options, value=null, timestamp=1327061105833119000)
* => (column=cf:c:index_type, value=null, timestamp=1327061105833119000)
* => (column=cf:c:name, value="aGVsbG8=", timestamp=1327061105833119000)
* => (column=cf:c:validation_class, value="org.apache.cassandra.db.marshal.AsciiType", timestamp=1327061105833119000)
*/
public class DefsTables
{

View File

@ -18,7 +18,8 @@
package org.apache.cassandra.thrift;
import com.google.common.collect.Sets;
import org.apache.cassandra.cli.transport.FramedTransportFactory;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSSLTransportFactory;
import org.apache.thrift.transport.TTransport;
@ -27,6 +28,8 @@ import java.util.Set;
public class SSLTransportFactory implements ITransportFactory
{
public static final int DEFAULT_MAX_FRAME_SIZE = 15 * 1024 * 1024; // 15 MiB
public static final String TRUSTSTORE = "enc.truststore";
public static final String TRUSTSTORE_PASSWORD = "enc.truststore.password";
public static final String KEYSTORE = "enc.keystore";
@ -57,7 +60,7 @@ public class SSLTransportFactory implements ITransportFactory
if (null != keystore)
params.setKeyStore(keystore, keystorePassword);
TTransport trans = TSSLTransportFactory.getClientSocket(host, port, SOCKET_TIMEOUT, params);
return new FramedTransportFactory().getTransport(trans);
return new TFramedTransport(trans, DEFAULT_MAX_FRAME_SIZE);
}
@Override

File diff suppressed because it is too large Load Diff

View File

@ -18,32 +18,20 @@
package org.apache.cassandra.pig;
import java.io.IOException;
import java.nio.charset.CharacterCodingException;
import java.util.Iterator;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.apache.cassandra.db.marshal.TimeUUIDType;
import org.apache.cassandra.db.marshal.UUIDType;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.thrift.AuthenticationException;
import org.apache.cassandra.thrift.AuthorizationException;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.cassandra.thrift.NotFoundException;
import org.apache.cassandra.thrift.TimedOutException;
import org.apache.cassandra.thrift.UnavailableException;
import org.apache.cassandra.utils.Hex;
import org.apache.pig.data.DataByteArray;
import org.apache.pig.data.Tuple;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
public class CqlRecordReaderTest extends PigTestBase
{
private static String[] statements = {
"DROP KEYSPACE IF EXISTS cql3ks",
"CREATE KEYSPACE cql3ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};",
"USE cql3ks;",
@ -69,11 +57,11 @@ public class CqlRecordReaderTest extends PigTestBase
};
@BeforeClass
public static void setup() throws TTransportException, IOException, InterruptedException, ConfigurationException,
AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, CharacterCodingException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException
public static void setup() throws IOException, InterruptedException, ConfigurationException,
TException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException
{
startCassandra();
setupDataByCql(statements);
executeCQLStatements(statements);
startHadoopCluster();
}

View File

@ -19,24 +19,16 @@
package org.apache.cassandra.pig;
import java.io.IOException;
import java.nio.charset.CharacterCodingException;
import java.util.Iterator;
import org.apache.cassandra.db.marshal.TimeUUIDType;
import org.apache.cassandra.db.marshal.UUIDType;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.thrift.AuthenticationException;
import org.apache.cassandra.thrift.AuthorizationException;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.cassandra.thrift.NotFoundException;
import org.apache.cassandra.thrift.SchemaDisagreementException;
import org.apache.cassandra.thrift.TimedOutException;
import org.apache.cassandra.thrift.UnavailableException;
import org.apache.cassandra.utils.Hex;
import org.apache.pig.data.DataByteArray;
import org.apache.pig.data.Tuple;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
@ -64,6 +56,7 @@ public class CqlTableDataTypeTest extends PigTestBase
//MAP
//Create table to test the above data types
private static String[] statements = {
"DROP KEYSPACE IF EXISTS cql3ks",
"CREATE KEYSPACE cql3ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1}",
"USE cql3ks;",
@ -208,17 +201,16 @@ public class CqlTableDataTypeTest extends PigTestBase
};
@BeforeClass
public static void setup() throws TTransportException, IOException, InterruptedException, ConfigurationException,
AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, CharacterCodingException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException
public static void setup() throws IOException, InterruptedException, ConfigurationException, TException,
ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException
{
startCassandra();
setupDataByCql(statements);
executeCQLStatements(statements);
startHadoopCluster();
}
@Test
public void testCqlNativeStorageRegularType()
throws AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, SchemaDisagreementException, IOException
public void testCqlNativeStorageRegularType() throws TException, IOException
{
//input_cql=select * from cqltable where token(key) > ? and token(key) <= ?
cqlTableTest("rows = LOAD 'cql://cql3ks/cqltable?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20cqltable%20where%20token(key)%20%3E%20%3F%20and%20token(key)%20%3C%3D%20%3F' USING CqlNativeStorage();");
@ -288,8 +280,7 @@ public class CqlTableDataTypeTest extends PigTestBase
}
@Test
public void testCqlNativeStorageSetType()
throws AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, SchemaDisagreementException, IOException
public void testCqlNativeStorageSetType() throws TException, IOException
{
//input_cql=select * from settable where token(key) > ? and token(key) <= ?
settableTest("set_rows = LOAD 'cql://cql3ks/settable?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20settable%20where%20token(key)%20%3E%20%3F%20and%20token(key)%20%3C%3D%20%3F' USING CqlNativeStorage();");
@ -355,8 +346,7 @@ public class CqlTableDataTypeTest extends PigTestBase
}
@Test
public void testCqlNativeStorageListType()
throws AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, SchemaDisagreementException, IOException
public void testCqlNativeStorageListType() throws TException, IOException
{
//input_cql=select * from listtable where token(key) > ? and token(key) <= ?
listtableTest("list_rows = LOAD 'cql://cql3ks/listtable?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20listtable%20where%20token(key)%20%3E%20%3F%20and%20token(key)%20%3C%3D%20%3F' USING CqlNativeStorage();");
@ -422,8 +412,7 @@ public class CqlTableDataTypeTest extends PigTestBase
}
@Test
public void testCqlNativeStorageMapType()
throws AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, SchemaDisagreementException, IOException
public void testCqlNativeStorageMapType() throws TException, IOException
{
//input_cql=select * from maptable where token(key) > ? and token(key) <= ?
maptableTest("map_rows = LOAD 'cql://cql3ks/maptable?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20maptable%20where%20token(key)%20%3E%20%3F%20and%20token(key)%20%3C%3D%20%3F' USING CqlNativeStorage();");

View File

@ -19,21 +19,12 @@
package org.apache.cassandra.pig;
import java.io.IOException;
import java.nio.charset.CharacterCodingException;
import java.util.Iterator;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.thrift.AuthenticationException;
import org.apache.cassandra.thrift.AuthorizationException;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.cassandra.thrift.NotFoundException;
import org.apache.cassandra.thrift.SchemaDisagreementException;
import org.apache.cassandra.thrift.TimedOutException;
import org.apache.cassandra.thrift.UnavailableException;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.Tuple;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
@ -41,6 +32,7 @@ import org.junit.Test;
public class CqlTableTest extends PigTestBase
{
private static String[] statements = {
"DROP KEYSPACE IF EXISTS cql3ks",
"CREATE KEYSPACE cql3ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1}",
"USE cql3ks;",
@ -81,17 +73,16 @@ public class CqlTableTest extends PigTestBase
};
@BeforeClass
public static void setup() throws TTransportException, IOException, InterruptedException, ConfigurationException,
AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, CharacterCodingException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException
public static void setup() throws IOException, InterruptedException, ConfigurationException, TException, ClassNotFoundException,
NoSuchFieldException, IllegalAccessException, InstantiationException
{
startCassandra();
setupDataByCql(statements);
executeCQLStatements(statements);
startHadoopCluster();
}
@Test
public void testCqlNativeStorageSchema()
throws AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, SchemaDisagreementException, IOException
public void testCqlNativeStorageSchema() throws TException, IOException
{
//input_cql=select * from cqltable where token(key1) > ? and token(key1) <= ?
cqlTableSchemaTest("rows = LOAD 'cql://cql3ks/cqltable?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20cqltable%20where%20token(key1)%20%3E%20%3F%20and%20token(key1)%20%3C%3D%20%3F' USING CqlNativeStorage();");
@ -136,15 +127,13 @@ public class CqlTableTest extends PigTestBase
}
@Test
public void testCqlNativeStorageSingleKeyTable()
throws AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, SchemaDisagreementException, IOException
public void testCqlNativeStorageSingleKeyTable() throws TException, IOException
{
//input_cql=select * from moredata where token(x) > ? and token(x) <= ?
SingleKeyTableTest("moretestvalues= LOAD 'cql://cql3ks/moredata?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20moredata%20where%20token(x)%20%3E%20%3F%20and%20token(x)%20%3C%3D%20%3F' USING CqlNativeStorage();");
}
private void SingleKeyTableTest(String initialQuery)
throws AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, SchemaDisagreementException, IOException
private void SingleKeyTableTest(String initialQuery) throws TException, IOException
{
pig.setBatchOn();
pig.registerQuery(initialQuery);
@ -167,15 +156,13 @@ public class CqlTableTest extends PigTestBase
}
@Test
public void testCqlNativeStorageCompositeKeyTable()
throws AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, SchemaDisagreementException, IOException
public void testCqlNativeStorageCompositeKeyTable() throws TException, IOException
{
//input_cql=select * from compmore where token(id) > ? and token(id) <= ?
CompositeKeyTableTest("moredata= LOAD 'cql://cql3ks/compmore?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20compmore%20where%20token(id)%20%3E%20%3F%20and%20token(id)%20%3C%3D%20%3F' USING CqlNativeStorage();");
}
private void CompositeKeyTableTest(String initialQuery)
throws AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, SchemaDisagreementException, IOException
private void CompositeKeyTableTest(String initialQuery) throws TException, IOException
{
pig.setBatchOn();
pig.registerQuery(initialQuery);
@ -204,15 +191,13 @@ public class CqlTableTest extends PigTestBase
}
@Test
public void testCqlNativeStorageCollectionColumnTable()
throws AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, SchemaDisagreementException, IOException
public void testCqlNativeStorageCollectionColumnTable() throws TException, IOException
{
//input_cql=select * from collectiontable where token(m) > ? and token(m) <= ?
CollectionColumnTableTest("collectiontable= LOAD 'cql://cql3ks/collectiontable?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20collectiontable%20where%20token(m)%20%3E%20%3F%20and%20token(m)%20%3C%3D%20%3F' USING CqlNativeStorage();");
}
private void CollectionColumnTableTest(String initialQuery)
throws AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, SchemaDisagreementException, IOException
private void CollectionColumnTableTest(String initialQuery) throws TException, IOException
{
pig.setBatchOn();
pig.registerQuery(initialQuery);
@ -245,7 +230,8 @@ public class CqlTableTest extends PigTestBase
}
@Test
public void testCassandraStorageSchema() throws IOException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException
public void testCassandraStorageSchema() throws IOException, ClassNotFoundException, TException, NoSuchFieldException,
IllegalAccessException, InstantiationException
{
//results: (key1,{((111,),),((111,column1),100),((111,column2),10.1)})
pig.registerQuery("rows = LOAD 'cassandra://cql3ks/cqltable?" + defaultParameters + "' USING CassandraStorage();");
@ -259,10 +245,10 @@ public class CqlTableTest extends PigTestBase
DataBag columns = (DataBag) t.get(1);
Iterator<Tuple> iter = columns.iterator();
int i = 0;
while(iter.hasNext())
while (iter.hasNext())
{
i++;
Tuple column = (Tuple) iter.next();
Tuple column = iter.next();
if (i==1)
{
Assert.assertEquals(((Tuple) column.get(0)).get(0), 111);

View File

@ -18,14 +18,9 @@
*/
package org.apache.cassandra.pig;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.CharacterCodingException;
import org.apache.cassandra.SchemaLoader;
import org.apache.cassandra.cli.CliMain;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.Schema;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.db.marshal.TypeParser;
@ -35,11 +30,6 @@ import org.apache.cassandra.service.EmbeddedCassandraService;
import org.apache.cassandra.thrift.Cassandra;
import org.apache.cassandra.thrift.Compression;
import org.apache.cassandra.thrift.ConsistencyLevel;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.cassandra.thrift.NotFoundException;
import org.apache.cassandra.thrift.SchemaDisagreementException;
import org.apache.cassandra.thrift.TimedOutException;
import org.apache.cassandra.thrift.UnavailableException;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.hadoop.conf.Configuration;
import org.apache.pig.ExecType;
@ -56,7 +46,6 @@ import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
public class PigTestBase extends SchemaLoader
@ -119,75 +108,20 @@ public class PigTestBase extends SchemaLoader
{
return TypeParser.parse(type);
}
catch (ConfigurationException e)
{
throw new IOException(e);
}
catch (SyntaxException e)
catch (ConfigurationException | SyntaxException e)
{
throw new IOException(e);
}
}
protected static void setupDataByCli(String[] statements) throws CharacterCodingException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException
{
// new error/output streams for CliSessionState
ByteArrayOutputStream errStream = new ByteArrayOutputStream();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
// checking if we can connect to the running cassandra node on localhost
CliMain.connect("127.0.0.1", 9170);
// setting new output stream
CliMain.sessionState.setOut(new PrintStream(outStream));
CliMain.sessionState.setErr(new PrintStream(errStream));
// re-creating keyspace for tests
try
{
// dropping in case it exists e.g. could be left from previous run
CliMain.processStatement("drop keyspace thriftKs;");
}
catch (Exception e)
{
}
for (String statement : statements)
{
errStream.reset();
System.out.println("Executing statement: " + statement);
CliMain.processStatement(statement);
String result = outStream.toString();
System.out.println("result: " + result);
outStream.reset(); // reset stream so we have only output from next statement all the time
errStream.reset(); // no errors to the end user.
}
}
protected static void setupDataByCql(String[] statements) throws InvalidRequestException, UnavailableException, TimedOutException, TException
protected static void executeCQLStatements(String[] statements) throws TException
{
Cassandra.Client client = getClient();
// re-creating keyspace for tests
try
{
// dropping in case it exists e.g. could be left from previous run
client.execute_cql3_query(ByteBufferUtil.bytes("DROP KEYSPACE cql3ks"), Compression.NONE, ConsistencyLevel.ONE);
}
catch (Exception e)
{
}
for (String statement : statements)
{
try
{
System.out.println("Executing statement: " + statement);
client.execute_cql3_query(ByteBufferUtil.bytes(statement), Compression.NONE, ConsistencyLevel.ONE);
}
catch (SchemaDisagreementException e)
{
Assert.fail();
}
System.out.println("Executing statement: " + statement);
client.execute_cql3_query(ByteBufferUtil.bytes(statement), Compression.NONE, ConsistencyLevel.ONE);
}
}
}

View File

@ -19,181 +19,138 @@
package org.apache.cassandra.pig;
import java.io.IOException;
import java.nio.charset.CharacterCodingException;
import java.util.Iterator;
import org.apache.cassandra.db.marshal.TimeUUIDType;
import org.apache.cassandra.db.marshal.UUIDType;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.thrift.AuthenticationException;
import org.apache.cassandra.thrift.AuthorizationException;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.cassandra.thrift.NotFoundException;
import org.apache.cassandra.thrift.TimedOutException;
import org.apache.cassandra.thrift.UnavailableException;
import org.apache.cassandra.utils.Hex;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.DataByteArray;
import org.apache.pig.data.Tuple;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static junit.framework.Assert.assertEquals;
public class ThriftColumnFamilyDataTypeTest extends PigTestBase
{
//AsciiType
//LongType
//BytesType
//BooleanType
//CounterColumnType
//DecimalType
//DoubleType
//FloatType
//InetAddressType
//Int32Type
//UTF8Type
//DateType
//UUIDType
//IntegerType
//TimeUUIDType
//IntegerType
//LexicalUUIDType
private static String[] statements = {
"create keyspace thriftKs with placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy' and" +
" strategy_options={replication_factor:1};",
"use thriftKs;",
"DROP KEYSPACE IF EXISTS thrift_ks",
"CREATE KEYSPACE thrift_ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};",
"USE thrift_ks;",
"create column family SomeApp " +
" with comparator = UTF8Type " +
" and default_validation_class = UTF8Type " +
" and key_validation_class = UTF8Type " +
" and column_metadata = [" +
"{column_name: col_ascii, validation_class: AsciiType}, " +
"{column_name: col_long, validation_class: LongType}, " +
"{column_name: col_bytes, validation_class: BytesType}, " +
"{column_name: col_boolean, validation_class: BooleanType}, " +
"{column_name: col_decimal, validation_class: DecimalType}, " +
"{column_name: col_double, validation_class: DoubleType}, " +
"{column_name: col_float, validation_class: FloatType}," +
"{column_name: col_inetaddress, validation_class: InetAddressType}, " +
"{column_name: col_int32, validation_class: Int32Type}, " +
"{column_name: col_uft8, validation_class: UTF8Type}, " +
"{column_name: col_date, validation_class: DateType}, " +
"{column_name: col_uuid, validation_class: UUIDType}, " +
"{column_name: col_integer, validation_class: IntegerType}, " +
"{column_name: col_timeuuid, validation_class: TimeUUIDType}, " +
"{column_name: col_lexical_uuid, validation_class: LexicalUUIDType}, " +
"]; ",
"CREATE TABLE some_app (" +
"key text PRIMARY KEY," +
"col_ascii ascii," +
"col_bigint bigint," +
"col_blob blob," +
"col_boolean boolean," +
"col_decimal decimal," +
"col_double double," +
"col_float float," +
"col_inet inet," +
"col_int int," +
"col_text text," +
"col_timestamp timestamp," +
"col_timeuuid timeuuid," +
"col_uuid uuid," +
"col_varint varint)" +
" WITH COMPACT STORAGE;",
"set SomeApp['foo']['col_ascii'] = 'ascii';",
"set SomeApp['foo']['col_boolean'] = false;",
"set SomeApp['foo']['col_bytes'] = 'DEADBEEF';",
"set SomeApp['foo']['col_date'] = '2011-02-03T04:05:00+0000';",
"set SomeApp['foo']['col_decimal'] = '23.345';",
"set SomeApp['foo']['col_double'] = '2.7182818284590451';",
"set SomeApp['foo']['col_float'] = '23.45';",
"set SomeApp['foo']['col_inetaddress'] = '127.0.0.1';",
"set SomeApp['foo']['col_int32'] = 23;",
"set SomeApp['foo']['col_integer'] = 12345;",
"set SomeApp['foo']['col_long'] = 12345678;",
"set SomeApp['foo']['col_lexical_uuid'] = 'e23f450f-53a6-11e2-7f7f-7f7f7f7f7f77';",
"set SomeApp['foo']['col_timeuuid'] = 'e23f450f-53a6-11e2-7f7f-7f7f7f7f7f7f';",
"set SomeApp['foo']['col_uft8'] = 'hello';",
"set SomeApp['foo']['col_uuid'] = '550e8400-e29b-41d4-a716-446655440000';",
"INSERT INTO some_app (key, col_ascii, col_bigint, col_blob, col_boolean, col_decimal, col_double, col_float," +
"col_inet, col_int, col_text, col_timestamp, col_uuid, col_varint, col_timeuuid) " +
"VALUES ('foo', 'ascii', 12345678, 0xDEADBEEF, false, 23.345, 2.7182818284590451, 23.45, '127.0.0.1', 23, 'hello', " +
"'2011-02-03T04:05:00+0000', 550e8400-e29b-41d4-a716-446655440000, 12345, e23f450f-53a6-11e2-7f7f-7f7f7f7f7f7f);",
"create column family CC with " +
"key_validation_class = UTF8Type and " +
"default_validation_class=CounterColumnType " +
"and comparator=UTF8Type;",
"CREATE TABLE cc (key text, name text, value counter, PRIMARY KEY (key, name)) WITH COMPACT STORAGE",
"incr CC['chuck']['kick'];",
"incr CC['chuck']['kick'];",
"incr CC['chuck']['kick'];"
"UPDATE cc SET value = value + 3 WHERE key = 'chuck' AND name = 'kick'",
};
@BeforeClass
public static void setup() throws TTransportException, IOException, InterruptedException, ConfigurationException,
AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, CharacterCodingException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException
public static void setup() throws IOException, InterruptedException, ConfigurationException, TException,
ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException
{
startCassandra();
setupDataByCli(statements);
executeCQLStatements(statements);
startHadoopCluster();
}
@Test
public void testCassandraStorageDataType() throws IOException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException
public void testCassandraStorageDataType() throws IOException, ClassNotFoundException, TException,
NoSuchFieldException, IllegalAccessException, InstantiationException
{
pig.registerQuery("rows = LOAD 'cassandra://thriftKs/SomeApp?" + defaultParameters + "' USING CassandraStorage();");
pig.registerQuery("rows = LOAD 'cassandra://thrift_ks/some_app?" + defaultParameters + "' USING CassandraStorage();");
Tuple t = pig.openIterator("rows").next();
//{key: chararray, col_ascii: (name: chararray,value: chararray),
//col_boolean: (name: chararray,value: bytearray),
//col_bytes: (name: chararray,value: bytearray),
//col_date: (name: chararray,value: long),
//col_decimal: (name: chararray,value: chararray),
//col_double: (name: chararray,value: double),
//col_float: (name: chararray,value: float),
//col_inetaddress: (name: chararray,value: chararray),
//col_int32: (name: chararray,value: int),
//col_integer: (name: chararray,value: int),
//col_lexical_uuid: (name: chararray,value: chararray),
//col_long: (name: chararray,value: long),
//col_timeuuid: (name: chararray,value: bytearray),
//col_uft8: (name: chararray,value: chararray),
//col_uuid: (name: chararray,value: chararray),
//columns: {(name: chararray,value: chararray)}}
Iterator<Tuple> it = pig.openIterator("rows");
if (it.hasNext()) {
Tuple t = it.next();
Assert.assertEquals(t.get(0), "foo");
Tuple column = (Tuple) t.get(1);
Assert.assertEquals(column.get(1), "ascii");
column = (Tuple) t.get(2);
Assert.assertEquals(column.get(1), false);
column = (Tuple) t.get(3);
Assert.assertEquals(column.get(1), new DataByteArray(Hex.hexToBytes("DEADBEEF")));
column = (Tuple) t.get(4);
Assert.assertEquals(column.get(1), 1296705900000L);
column = (Tuple) t.get(5);
Assert.assertEquals(column.get(1), "23.345");
column = (Tuple) t.get(6);
Assert.assertEquals(column.get(1), 2.7182818284590451d);
column = (Tuple) t.get(7);
Assert.assertEquals(column.get(1), 23.45f);
column = (Tuple) t.get(8);
Assert.assertEquals(column.get(1), "127.0.0.1");
column = (Tuple) t.get(9);
Assert.assertEquals(column.get(1), 23);
column = (Tuple) t.get(10);
Assert.assertEquals(column.get(1), 12345);
column = (Tuple) t.get(11);
Assert.assertEquals(column.get(1), new DataByteArray((TimeUUIDType.instance.fromString("e23f450f-53a6-11e2-7f7f-7f7f7f7f7f77").array())));
column = (Tuple) t.get(12);
Assert.assertEquals(column.get(1), 12345678L);
column = (Tuple) t.get(13);
Assert.assertEquals(column.get(1), new DataByteArray((TimeUUIDType.instance.fromString("e23f450f-53a6-11e2-7f7f-7f7f7f7f7f7f").array())));
column = (Tuple) t.get(14);
Assert.assertEquals(column.get(1), "hello");
column = (Tuple) t.get(15);
Assert.assertEquals(column.get(1), new DataByteArray((UUIDType.instance.fromString("550e8400-e29b-41d4-a716-446655440000").array())));
}
// key
assertEquals("foo", t.get(0));
pig.registerQuery("cc_rows = LOAD 'cassandra://thriftKs/CC?" + defaultParameters + "' USING CassandraStorage();");
// col_ascii
Tuple column = (Tuple) t.get(1);
assertEquals("ascii", column.get(1));
//(chuck,{(kick,3)})
it = pig.openIterator("cc_rows");
if (it.hasNext()) {
Tuple t = it.next();
Assert.assertEquals(t.get(0), "chuck");
DataBag columns = (DataBag) t.get(1);
Iterator<Tuple> iter = columns.iterator();
if(iter.hasNext())
{
Tuple column = iter.next();
Assert.assertEquals(column.get(0), "kick");
Assert.assertEquals(column.get(1), 3L);
}
}
// col_bigint
column = (Tuple) t.get(2);
assertEquals(12345678L, column.get(1));
// col_blob
column = (Tuple) t.get(3);
assertEquals(new DataByteArray(Hex.hexToBytes("DEADBEEF")), column.get(1));
// col_boolean
column = (Tuple) t.get(4);
assertEquals(false, column.get(1));
// col_decimal
column = (Tuple) t.get(5);
assertEquals("23.345", column.get(1));
// col_double
column = (Tuple) t.get(6);
assertEquals(2.7182818284590451d, column.get(1));
// col_float
column = (Tuple) t.get(7);
assertEquals(23.45f, column.get(1));
// col_inet
column = (Tuple) t.get(8);
assertEquals("127.0.0.1", column.get(1));
// col_int
column = (Tuple) t.get(9);
assertEquals(23, column.get(1));
// col_text
column = (Tuple) t.get(10);
assertEquals("hello", column.get(1));
// col_timestamp
column = (Tuple) t.get(11);
assertEquals(1296705900000L, column.get(1));
// col_timeuuid
column = (Tuple) t.get(12);
assertEquals(new DataByteArray((TimeUUIDType.instance.fromString("e23f450f-53a6-11e2-7f7f-7f7f7f7f7f7f").array())), column.get(1));
// col_uuid
column = (Tuple) t.get(13);
assertEquals(new DataByteArray((UUIDType.instance.fromString("550e8400-e29b-41d4-a716-446655440000").array())), column.get(1));
// col_varint
column = (Tuple) t.get(14);
assertEquals(12345, column.get(1));
pig.registerQuery("cc_rows = LOAD 'cassandra://thrift_ks/cc?" + defaultParameters + "' USING CassandraStorage();");
t = pig.openIterator("cc_rows").next();
assertEquals("chuck", t.get(0));
DataBag columns = (DataBag) t.get(1);
column = columns.iterator().next();
assertEquals("kick", column.get(0));
assertEquals(3L, column.get(1));
}
}

View File

@ -20,27 +20,20 @@ package org.apache.cassandra.pig;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.util.Iterator;
import org.apache.cassandra.cli.CliMain;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.thrift.AuthenticationException;
import org.apache.cassandra.thrift.AuthorizationException;
import org.apache.cassandra.thrift.Cassandra;
import org.apache.cassandra.thrift.ColumnOrSuperColumn;
import org.apache.cassandra.thrift.ColumnPath;
import org.apache.cassandra.thrift.ConsistencyLevel;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.cassandra.thrift.NotFoundException;
import org.apache.cassandra.thrift.TimedOutException;
import org.apache.cassandra.thrift.UnavailableException;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.DataByteArray;
import org.apache.pig.data.Tuple;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
@ -48,171 +41,159 @@ import org.junit.Test;
public class ThriftColumnFamilyTest extends PigTestBase
{
private static String[] statements = {
"create keyspace thriftKs with placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy' and" +
" strategy_options={replication_factor:1};",
"use thriftKs;",
"DROP KEYSPACE IF EXISTS thrift_ks",
"CREATE KEYSPACE thrift_ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};",
"USE thrift_ks;",
"create column family SomeApp " +
" with comparator = UTF8Type " +
" and default_validation_class = UTF8Type " +
" and key_validation_class = UTF8Type " +
" and column_metadata = [{column_name: name, validation_class: UTF8Type, index_type: KEYS}, " +
"{column_name: vote_type, validation_class: UTF8Type}, " +
"{column_name: rating, validation_class: Int32Type}, " +
"{column_name: score, validation_class: LongType}, " +
"{column_name: percent, validation_class: FloatType}, " +
"{column_name: atomic_weight, validation_class: DoubleType}, " +
"{column_name: created, validation_class: DateType},]; ",
"CREATE TABLE some_app (" +
"key text PRIMARY KEY," +
"name text," +
"vote_type text," +
"rating int," +
"score bigint," +
"percent float," +
"atomic_weight double," +
"created timestamp)" +
" WITH COMPACT STORAGE;",
"create column family CopyOfSomeApp " +
"with key_validation_class = UTF8Type " +
"and default_validation_class = UTF8Type " +
"and comparator = UTF8Type " +
"and column_metadata = " +
"[ " +
"{column_name: name, validation_class: UTF8Type, index_type: KEYS}, " +
"{column_name: vote_type, validation_class: UTF8Type}, " +
"{column_name: rating, validation_class: Int32Type}, " +
"{column_name: score, validation_class: LongType}, " +
"{column_name: percent, validation_class: FloatType}, " +
"{column_name: atomic_weight, validation_class: DoubleType}, " +
"{column_name: created, validation_class: DateType}, " +
"];",
"CREATE INDEX ON some_app(name);",
"set SomeApp['foo']['name'] = 'User Foo';",
"set SomeApp['foo']['vote_type'] = 'like';",
"set SomeApp['foo']['rating'] = 8;",
"set SomeApp['foo']['score'] = 125000;",
"set SomeApp['foo']['percent'] = '85.0';",
"set SomeApp['foo']['atomic_weight'] = '2.7182818284590451';",
"set SomeApp['foo']['created'] = 1335890877;",
"INSERT INTO some_app (key, name, vote_type, rating, score, percent, atomic_weight, created) " +
"VALUES ('foo', 'User Foo', 'like', 8, 125000, 85.0, 2.7182818284590451, 1335890877);",
"set SomeApp['bar']['name'] = 'User Bar';",
"set SomeApp['bar']['vote_type'] = 'like';",
"set SomeApp['bar']['rating'] = 9;",
"set SomeApp['bar']['score'] = 15000;",
"set SomeApp['bar']['percent'] = '35.0';",
"set SomeApp['bar']['atomic_weight'] = '3.1415926535897931';",
"set SomeApp['bar']['created'] = 1335890877;",
"INSERT INTO some_app (key, name, vote_type, rating, score, percent, atomic_weight, created) " +
"VALUES ('bar', 'User Bar', 'like', 9, 15000, 35.0, 3.1415926535897931, 1335890877);",
"set SomeApp['baz']['name'] = 'User Baz';",
"set SomeApp['baz']['vote_type'] = 'dislike';",
"set SomeApp['baz']['rating'] = 3;",
"set SomeApp['baz']['score'] = 512000;",
"set SomeApp['baz']['percent'] = '95.3';",
"set SomeApp['baz']['atomic_weight'] = '1.61803399';",
"set SomeApp['baz']['created'] = 1335890877;",
"set SomeApp['baz']['extra1'] = 'extra1';",
"set SomeApp['baz']['extra2'] = 'extra2';",
"set SomeApp['baz']['extra3'] = 'extra3';",
"INSERT INTO some_app (key, name, vote_type, rating, score, percent, atomic_weight, created) " +
"VALUES ('baz', 'User Baz', 'dislike', 3, 512000, 95.3, 1.61803399, 1335890877);",
"set SomeApp['qux']['name'] = 'User Qux';",
"set SomeApp['qux']['vote_type'] = 'dislike';",
"set SomeApp['qux']['rating'] = 2;",
"set SomeApp['qux']['score'] = 12000;",
"set SomeApp['qux']['percent'] = '64.7';",
"set SomeApp['qux']['atomic_weight'] = '0.660161815846869';",
"set SomeApp['qux']['created'] = 1335890877;",
"set SomeApp['qux']['extra1'] = 'extra1';",
"set SomeApp['qux']['extra2'] = 'extra2';",
"set SomeApp['qux']['extra3'] = 'extra3';",
"set SomeApp['qux']['extra4'] = 'extra4';",
"set SomeApp['qux']['extra5'] = 'extra5';",
"set SomeApp['qux']['extra6'] = 'extra6';",
"set SomeApp['qux']['extra7'] = 'extra7';",
"INSERT INTO some_app (key, name, vote_type, rating, score, percent, atomic_weight, created) " +
"VALUES ('qux', 'User Qux', 'dislike', 2, 12000, 64.7, 0.660161815846869, 1335890877);",
"create column family U8 with " +
"key_validation_class = UTF8Type and " +
"comparator = UTF8Type;",
"create column family Bytes with " +
"key_validation_class = BytesType and " +
"comparator = UTF8Type;",
"CREATE TABLE copy_of_some_app (" +
"key text PRIMARY KEY," +
"name text," +
"vote_type text," +
"rating int," +
"score bigint," +
"percent float," +
"atomic_weight double," +
"created timestamp)" +
" WITH COMPACT STORAGE;",
"set U8['foo']['x'] = ascii('Z');",
"set Bytes[ascii('foo')]['x'] = ascii('Z');",
"CREATE INDEX ON copy_of_some_app(name);",
"create column family CC with " +
"key_validation_class = UTF8Type and " +
"default_validation_class=CounterColumnType " +
"and comparator=UTF8Type;",
"CREATE TABLE u8 (" +
"key text," +
"column1 text," +
"value blob," +
"PRIMARY KEY (key, column1))" +
" WITH COMPACT STORAGE",
"incr CC['chuck']['kick'];",
"incr CC['chuck']['kick'];",
"incr CC['chuck']['kick'];",
"incr CC['chuck']['fist'];",
"INSERT INTO u8 (key, column1, value) VALUES ('foo', 'x', asciiAsBlob('Z'))",
"create column family Compo " +
"with key_validation_class = UTF8Type " +
"and default_validation_class = UTF8Type " +
"and comparator = 'CompositeType(UTF8Type,UTF8Type)';",
"CREATE TABLE bytes (" +
"key blob," +
"column1 text," +
"value blob," +
"PRIMARY KEY (key, column1))" +
" WITH COMPACT STORAGE",
"set Compo['punch']['bruce:lee'] = 'ouch';",
"set Compo['punch']['bruce:bruce'] = 'hunh?';",
"set Compo['kick']['bruce:lee'] = 'oww';",
"set Compo['kick']['bruce:bruce'] = 'watch it, mate';",
"INSERT INTO bytes (key, column1, value) VALUES (asciiAsBlob('foo'), 'x', asciiAsBlob('Z'))",
"create column family CompoInt " +
"with key_validation_class = UTF8Type " +
"and default_validation_class = UTF8Type " +
"and comparator = 'CompositeType(LongType,LongType)';",
"CREATE TABLE cc (key text, name text, value counter, PRIMARY KEY (key, name)) WITH COMPACT STORAGE",
"set CompoInt['clock']['1:0'] = 'z';",
"set CompoInt['clock']['1:30'] = 'zzzz';",
"set CompoInt['clock']['2:30'] = 'daddy?';",
"set CompoInt['clock']['6:30'] = 'coffee...';",
"UPDATE cc SET value = value + 3 WHERE key = 'chuck' AND name = 'kick'",
"UPDATE cc SET value = value + 1 WHERE key = 'chuck' AND name = 'fist'",
"create column family CompoIntCopy " +
"with key_validation_class = UTF8Type " +
"and default_validation_class = UTF8Type " +
"and comparator = 'CompositeType(LongType,LongType)';",
"CREATE TABLE compo (" +
"key text," +
"column1 text," +
"column2 text," +
"value text," +
"PRIMARY KEY (key, column1, column2))" +
" WITH COMPACT STORAGE",
"create column family CompoKey " +
"with key_validation_class = 'CompositeType(UTF8Type,LongType)' " +
"and default_validation_class = UTF8Type " +
"and comparator = LongType;",
"INSERT INTO compo (key, column1, column2, value) VALUES ('punch', 'bruce', 'lee', 'ouch');",
"INSERT INTO compo (key, column1, column2, value) VALUES ('punch', 'bruce', 'bruce', 'hunh?');",
"INSERT INTO compo (key, column1, column2, value) VALUES ('kick', 'bruce', 'lee', 'oww');",
"INSERT INTO compo (key, column1, column2, value) VALUES ('kick', 'bruce', 'bruce', 'watch it, mate');",
"set CompoKey['clock:10']['1'] = 'z';",
"set CompoKey['clock:20']['1'] = 'zzzz';",
"set CompoKey['clock:30']['2'] = 'daddy?';",
"set CompoKey['clock:40']['6'] = 'coffee...';",
"CREATE TABLE compo_int (" +
"key text," +
"column1 bigint," +
"column2 bigint," +
"value text," +
"PRIMARY KEY (key, column1, column2))" +
" WITH COMPACT STORAGE",
"create column family CompoKeyCopy " +
"with key_validation_class = 'CompositeType(UTF8Type,LongType)' " +
"and default_validation_class = UTF8Type " +
"and comparator = LongType;"
"INSERT INTO compo_int (key, column1, column2, value) VALUES ('clock', 1, 0, 'z');",
"INSERT INTO compo_int (key, column1, column2, value) VALUES ('clock', 1, 30, 'zzzz');",
"INSERT INTO compo_int (key, column1, column2, value) VALUES ('clock', 2, 30, 'daddy?');",
"INSERT INTO compo_int (key, column1, column2, value) VALUES ('clock', 6, 30, 'coffee...');",
"CREATE TABLE compo_int_copy (" +
"key text," +
"column1 bigint," +
"column2 bigint," +
"value text," +
"PRIMARY KEY (key, column1, column2))" +
" WITH COMPACT STORAGE",
"CREATE TABLE compo_key (" +
"key text," +
"column1 bigint," +
"column2 bigint," +
"value text," +
"PRIMARY KEY ((key, column1), column2))" +
" WITH COMPACT STORAGE",
"INSERT INTO compo_key (key, column1, column2, value) VALUES ('clock', 10, 1, 'z');",
"INSERT INTO compo_key (key, column1, column2, value) VALUES ('clock', 20, 1, 'zzzz');",
"INSERT INTO compo_key (key, column1, column2, value) VALUES ('clock', 30, 2, 'daddy?');",
"INSERT INTO compo_key (key, column1, column2, value) VALUES ('clock', 40, 6, 'coffee...');",
"CREATE TABLE compo_key_copy (" +
"key text," +
"column1 bigint," +
"column2 bigint," +
"value text," +
"PRIMARY KEY ((key, column1), column2))" +
" WITH COMPACT STORAGE",
};
private static String[] deleteCopyOfSomeAppTableData = { "use thriftKs;",
"DEL CopyOfSomeApp ['foo']",
"DEL CopyOfSomeApp ['bar']",
"DEL CopyOfSomeApp ['baz']",
"DEL CopyOfSomeApp ['qux']"
private static String[] deleteCopyOfSomeAppTableData = {
"use thrift_ks;",
"DELETE FROM copy_of_some_app WHERE key = 'foo';",
"DELETE FROM copy_of_some_app WHERE key = 'bar';",
"DELETE FROM copy_of_some_app WHERE key = 'baz';",
"DELETE FROM copy_of_some_app WHERE key = 'qux';",
};
@BeforeClass
public static void setup() throws TTransportException, IOException, InterruptedException, ConfigurationException,
AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, CharacterCodingException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException
public static void setup() throws IOException, InterruptedException, ConfigurationException, TException,
ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException
{
startCassandra();
setupDataByCli(statements);
executeCQLStatements(statements);
startHadoopCluster();
}
@Test
public void testCqlNativeStorage() throws IOException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException, AuthenticationException, AuthorizationException
public void testCqlNativeStorage() throws IOException, ClassNotFoundException, TException, NoSuchFieldException,
IllegalAccessException, InstantiationException
{
//regular thrift column families
//input_cql=select * from "SomeApp" where token(key) > ? and token(key) <= ?
cqlStorageTest("data = load 'cql://thriftKs/SomeApp?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20%22SomeApp%22%20where%20token(key)%20%3E%20%3F%20and%20token(key)%20%3C%3D%20%3F' using CqlNativeStorage();");
//input_cql=select * from "some_app" where token(key) > ? and token(key) <= ?
cqlStorageTest("data = load 'cql://thrift_ks/some_app?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20%22some_app%22%20where%20token(key)%20%3E%20%3F%20and%20token(key)%20%3C%3D%20%3F' using CqlNativeStorage();");
//Test counter colun family
//input_cql=select * from "CC" where token(key) > ? and token(key) <= ?
cqlStorageCounterTableTest("cc_data = load 'cql://thriftKs/CC?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20%22CC%22%20where%20token(key)%20%3E%20%3F%20and%20token(key)%20%3C%3D%20%3F' using CqlNativeStorage();");
//Test counter column family
//input_cql=select * from "cc" where token(key) > ? and token(key) <= ?
cqlStorageCounterTableTest("cc_data = load 'cql://thrift_ks/cc?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20%22cc%22%20where%20token(key)%20%3E%20%3F%20and%20token(key)%20%3C%3D%20%3F' using CqlNativeStorage();");
//Test composite column family
//input_cql=select * from "Compo" where token(key) > ? and token(key) <= ?
cqlStorageCompositeTableTest("compo_data = load 'cql://thriftKs/Compo?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20%22Compo%22%20where%20token(key)%20%3E%20%3F%20and%20token(key)%20%3C%3D%20%3F' using CqlNativeStorage();");
//input_cql=select * from "compo" where token(key) > ? and token(key) <= ?
cqlStorageCompositeTableTest("compo_data = load 'cql://thrift_ks/compo?" + defaultParameters + nativeParameters + "&input_cql=select%20*%20from%20%22compo%22%20where%20token(key)%20%3E%20%3F%20and%20token(key)%20%3C%3D%20%3F' using CqlNativeStorage();");
}
private void cqlStorageTest(String initialQuery) throws IOException
@ -321,14 +302,12 @@ public class ThriftColumnFamilyTest extends PigTestBase
}
@Test
public void testCassandraStorageSchema() throws IOException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException
public void testCassandraStorageSchema() throws IOException, ClassNotFoundException, TException, NoSuchFieldException,
IllegalAccessException, InstantiationException
{
//results: (qux,(atomic_weight,0.660161815846869),(created,1335890877),(name,User Qux),(percent,64.7),
//(rating,2),(score,12000),(vote_type,dislike),{(extra1,extra1),
//(extra2,extra2),(extra3,extra3),
//(extra4,extra4),(extra5,extra5),
//(extra6,extra6),(extra7,extra7)})
pig.registerQuery("rows = LOAD 'cassandra://thriftKs/SomeApp?" + defaultParameters + "' USING CassandraStorage();");
//(rating,2),(score,12000),(vote_type,dislike))
pig.registerQuery("rows = LOAD 'cassandra://thrift_ks/some_app?" + defaultParameters + "' USING CassandraStorage();");
//schema: {key: chararray,atomic_weight: (name: chararray,value: double),created: (name: chararray,value: long),
//name: (name: chararray,value: chararray),percent: (name: chararray,value: float),
@ -358,48 +337,39 @@ public class ThriftColumnFamilyTest extends PigTestBase
column = (Tuple) t.get(7);
Assert.assertEquals(column.get(0), "vote_type");
Assert.assertEquals(column.get(1), "dislike");
DataBag columns = (DataBag) t.get(8);
Iterator<Tuple> iter = columns.iterator();
int i = 0;
while(iter.hasNext())
{
i++;
column = iter.next();
Assert.assertEquals(column.get(0), "extra"+i);
}
Assert.assertEquals(7, columns.size());
}
}
}
@Test
public void testCassandraStorageFullCopy() throws IOException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException, AuthenticationException, AuthorizationException
public void testCassandraStorageFullCopy() throws IOException, ClassNotFoundException, TException, NoSuchFieldException,
IllegalAccessException, InstantiationException
{
pig.setBatchOn();
pig.registerQuery("rows = LOAD 'cassandra://thriftKs/SomeApp?" + defaultParameters + "' USING CassandraStorage();");
pig.registerQuery("rows = LOAD 'cassandra://thrift_ks/some_app?" + defaultParameters + "' USING CassandraStorage();");
//full copy
pig.registerQuery("STORE rows INTO 'cassandra://thriftKs/CopyOfSomeApp?" + defaultParameters + "' USING CassandraStorage();");
pig.registerQuery("STORE rows INTO 'cassandra://thrift_ks/copy_of_some_app?" + defaultParameters + "' USING CassandraStorage();");
pig.executeBatch();
Assert.assertEquals("User Qux", getColumnValue("thriftKs", "CopyOfSomeApp", "name", "qux", "UTF8Type"));
Assert.assertEquals("dislike", getColumnValue("thriftKs", "CopyOfSomeApp", "vote_type", "qux", "UTF8Type"));
Assert.assertEquals("64.7", getColumnValue("thriftKs", "CopyOfSomeApp", "percent", "qux", "FloatType"));
Assert.assertEquals("User Qux", getColumnValue("thrift_ks", "copy_of_some_app", "name", "qux", "UTF8Type"));
Assert.assertEquals("dislike", getColumnValue("thrift_ks", "copy_of_some_app", "vote_type", "qux", "UTF8Type"));
Assert.assertEquals("64.7", getColumnValue("thrift_ks", "copy_of_some_app", "percent", "qux", "FloatType"));
}
@Test
public void testCassandraStorageSigleTupleCopy() throws IOException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException, AuthenticationException, AuthorizationException
public void testCassandraStorageSigleTupleCopy() throws IOException, ClassNotFoundException, TException,
NoSuchFieldException, IllegalAccessException, InstantiationException
{
executeCliStatements(deleteCopyOfSomeAppTableData);
executeCQLStatements(deleteCopyOfSomeAppTableData);
pig.setBatchOn();
pig.registerQuery("rows = LOAD 'cassandra://thriftKs/SomeApp?" + defaultParameters + "' USING CassandraStorage();");
pig.registerQuery("rows = LOAD 'cassandra://thrift_ks/some_app?" + defaultParameters + "' USING CassandraStorage();");
//sigle tuple
pig.registerQuery("onecol = FOREACH rows GENERATE key, percent;");
pig.registerQuery("STORE onecol INTO 'cassandra://thriftKs/CopyOfSomeApp?" + defaultParameters + "' USING CassandraStorage();");
pig.registerQuery("STORE onecol INTO 'cassandra://thrift_ks/copy_of_some_app?" + defaultParameters + "' USING CassandraStorage();");
pig.executeBatch();
String value = null;
try
{
value = getColumnValue("thriftKs", "CopyOfSomeApp", "name", "qux", "UTF8Type");
value = getColumnValue("thrift_ks", "copy_of_some_app", "name", "qux", "UTF8Type");
}
catch (NotFoundException e)
{
@ -409,7 +379,7 @@ public class ThriftColumnFamilyTest extends PigTestBase
Assert.fail();
try
{
value = getColumnValue("thriftKs", "CopyOfSomeApp", "vote_type", "qux", "UTF8Type");
value = getColumnValue("thrift_ks", "copy_of_some_app", "vote_type", "qux", "UTF8Type");
}
catch (NotFoundException e)
{
@ -417,23 +387,24 @@ public class ThriftColumnFamilyTest extends PigTestBase
}
if (value != null)
Assert.fail();
Assert.assertEquals("64.7", getColumnValue("thriftKs", "CopyOfSomeApp", "percent", "qux", "FloatType"));
Assert.assertEquals("64.7", getColumnValue("thrift_ks", "copy_of_some_app", "percent", "qux", "FloatType"));
}
@Test
public void testCassandraStorageBagOnlyCopy() throws IOException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException, AuthenticationException, AuthorizationException
public void testCassandraStorageBagOnlyCopy() throws IOException, ClassNotFoundException, TException,
NoSuchFieldException, IllegalAccessException, InstantiationException
{
executeCliStatements(deleteCopyOfSomeAppTableData);
executeCQLStatements(deleteCopyOfSomeAppTableData);
pig.setBatchOn();
pig.registerQuery("rows = LOAD 'cassandra://thriftKs/SomeApp?" + defaultParameters + "' USING CassandraStorage();");
pig.registerQuery("rows = LOAD 'cassandra://thrift_ks/some_app?" + defaultParameters + "' USING CassandraStorage();");
//bag only
pig.registerQuery("other = FOREACH rows GENERATE key, columns;");
pig.registerQuery("STORE other INTO 'cassandra://thriftKs/CopyOfSomeApp?" + defaultParameters + "' USING CassandraStorage();");
pig.registerQuery("STORE other INTO 'cassandra://thrift_ks/copy_of_some_app?" + defaultParameters + "' USING CassandraStorage();");
pig.executeBatch();
String value = null;
try
{
value = getColumnValue("thriftKs", "CopyOfSomeApp", "name", "qux", "UTF8Type");
value = getColumnValue("thrift_ks", "copy_of_some_app", "name", "qux", "UTF8Type");
}
catch (NotFoundException e)
{
@ -443,7 +414,7 @@ public class ThriftColumnFamilyTest extends PigTestBase
Assert.fail();
try
{
value = getColumnValue("thriftKs", "CopyOfSomeApp", "vote_type", "qux", "UTF8Type");
value = getColumnValue("thrift_ks", "copy_of_some_app", "vote_type", "qux", "UTF8Type");
}
catch (NotFoundException e)
{
@ -453,7 +424,7 @@ public class ThriftColumnFamilyTest extends PigTestBase
Assert.fail();
try
{
value = getColumnValue("thriftKs", "CopyOfSomeApp", "percent", "qux", "FloatType");
value = getColumnValue("thrift_ks", "copy_of_some_app", "percent", "qux", "FloatType");
}
catch (NotFoundException e)
{
@ -461,27 +432,27 @@ public class ThriftColumnFamilyTest extends PigTestBase
}
if (value != null)
Assert.fail();
Assert.assertEquals("extra1", getColumnValue("thriftKs", "CopyOfSomeApp", "extra1", "qux", "UTF8Type"));
}
@Test
public void testCassandraStorageFilter() throws IOException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException, AuthenticationException, AuthorizationException
public void testCassandraStorageFilter() throws IOException, ClassNotFoundException, TException, NoSuchFieldException,
IllegalAccessException, InstantiationException
{
executeCliStatements(deleteCopyOfSomeAppTableData);
executeCQLStatements(deleteCopyOfSomeAppTableData);
pig.setBatchOn();
pig.registerQuery("rows = LOAD 'cassandra://thriftKs/SomeApp?" + defaultParameters + "' USING CassandraStorage();");
pig.registerQuery("rows = LOAD 'cassandra://thrift_ks/some_app?" + defaultParameters + "' USING CassandraStorage();");
//filter
pig.registerQuery("likes = FILTER rows by vote_type.value eq 'like' and rating.value > 5;");
pig.registerQuery("STORE likes INTO 'cassandra://thriftKs/CopyOfSomeApp?" + defaultParameters + "' USING CassandraStorage();");
pig.registerQuery("STORE likes INTO 'cassandra://thrift_ks/copy_of_some_app?" + defaultParameters + "' USING CassandraStorage();");
pig.executeBatch();
Assert.assertEquals("like", getColumnValue("thriftKs", "CopyOfSomeApp", "vote_type", "bar", "UTF8Type"));
Assert.assertEquals("like", getColumnValue("thriftKs", "CopyOfSomeApp", "vote_type", "foo", "UTF8Type"));
Assert.assertEquals("like", getColumnValue("thrift_ks", "copy_of_some_app", "vote_type", "bar", "UTF8Type"));
Assert.assertEquals("like", getColumnValue("thrift_ks", "copy_of_some_app", "vote_type", "foo", "UTF8Type"));
String value = null;
try
{
value = getColumnValue("thriftKs", "CopyOfSomeApp", "vote_type", "qux", "UTF8Type");
value = getColumnValue("thrift_ks", "copy_of_some_app", "vote_type", "qux", "UTF8Type");
}
catch (NotFoundException e)
{
@ -491,7 +462,7 @@ public class ThriftColumnFamilyTest extends PigTestBase
Assert.fail();
try
{
value = getColumnValue("thriftKs", "CopyOfSomeApp", "vote_type", "baz", "UTF8Type");
value = getColumnValue("thrift_ks", "copy_of_some_app", "vote_type", "baz", "UTF8Type");
}
catch (NotFoundException e)
{
@ -500,19 +471,18 @@ public class ThriftColumnFamilyTest extends PigTestBase
if (value != null)
Assert.fail();
executeCliStatements(deleteCopyOfSomeAppTableData);
executeCQLStatements(deleteCopyOfSomeAppTableData);
pig.setBatchOn();
pig.registerQuery("rows = LOAD 'cassandra://thriftKs/SomeApp?" + defaultParameters + "' USING CassandraStorage();");
pig.registerQuery("dislikes_extras = FILTER rows by vote_type.value eq 'dislike' AND COUNT(columns) > 0;");
pig.registerQuery("STORE dislikes_extras INTO 'cassandra://thriftKs/CopyOfSomeApp?" + defaultParameters + "' USING CassandraStorage();");
pig.registerQuery("visible = FILTER rows BY COUNT(columns) == 0;");
pig.registerQuery("rows = LOAD 'cassandra://thrift_ks/some_app?" + defaultParameters + "' USING CassandraStorage();");
pig.registerQuery("dislikes_extras = FILTER rows by vote_type.value eq 'dislike';");
pig.registerQuery("STORE dislikes_extras INTO 'cassandra://thrift_ks/copy_of_some_app?" + defaultParameters + "' USING CassandraStorage();");
pig.executeBatch();
Assert.assertEquals("dislike", getColumnValue("thriftKs", "CopyOfSomeApp", "vote_type", "baz", "UTF8Type"));
Assert.assertEquals("dislike", getColumnValue("thriftKs", "CopyOfSomeApp", "vote_type", "qux", "UTF8Type"));
Assert.assertEquals("dislike", getColumnValue("thrift_ks", "copy_of_some_app", "vote_type", "baz", "UTF8Type"));
Assert.assertEquals("dislike", getColumnValue("thrift_ks", "copy_of_some_app", "vote_type", "qux", "UTF8Type"));
value = null;
try
{
value = getColumnValue("thriftKs", "CopyOfSomeApp", "vote_type", "bar", "UTF8Type");
value = getColumnValue("thrift_ks", "copy_of_some_app", "vote_type", "bar", "UTF8Type");
}
catch (NotFoundException e)
{
@ -522,7 +492,7 @@ public class ThriftColumnFamilyTest extends PigTestBase
Assert.fail();
try
{
value = getColumnValue("thriftKs", "CopyOfSomeApp", "vote_type", "foo", "UTF8Type");
value = getColumnValue("thrift_ks", "copy_of_some_app", "vote_type", "foo", "UTF8Type");
}
catch (NotFoundException e)
{
@ -533,11 +503,11 @@ public class ThriftColumnFamilyTest extends PigTestBase
}
@Test
public void testCassandraStorageJoin() throws IOException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException, AuthenticationException, AuthorizationException
public void testCassandraStorageJoin() throws IOException, ClassNotFoundException, TException, IllegalAccessException, InstantiationException
{
//test key types with a join
pig.registerQuery("U8 = load 'cassandra://thriftKs/U8?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("Bytes = load 'cassandra://thriftKs/Bytes?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("U8 = load 'cassandra://thrift_ks/u8?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("Bytes = load 'cassandra://thrift_ks/bytes?" + defaultParameters + "' using CassandraStorage();");
//cast key to chararray
pig.registerQuery("b = foreach Bytes generate (chararray)key, columns;");
@ -585,28 +555,24 @@ public class ThriftColumnFamilyTest extends PigTestBase
}
@Test
public void testCassandraStorageCounterCF() throws IOException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException, AuthenticationException, AuthorizationException
public void testCassandraStorageCounterCF() throws IOException, ClassNotFoundException, TException, NoSuchFieldException,
IllegalAccessException, InstantiationException
{
pig.registerQuery("rows = LOAD 'cassandra://thriftKs/SomeApp?" + defaultParameters + "' USING CassandraStorage();");
//Test counter column family support
pig.registerQuery("CC = load 'cassandra://thriftKs/CC?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("CC = load 'cassandra://thrift_ks/cc?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("total_hits = foreach CC generate key, SUM(columns.value);");
//(chuck,4)
Iterator<Tuple> it = pig.openIterator("total_hits");
if (it.hasNext()) {
Tuple t = it.next();
Assert.assertEquals(t.get(0), "chuck");
Assert.assertEquals(t.get(1), 4l);
}
Tuple t = pig.openIterator("total_hits").next();
Assert.assertEquals(t.get(0), "chuck");
Assert.assertEquals(t.get(1), 4l);
}
/** This test case fails due to antlr lib conflicts, Cassandra2.1 uses 3.2, Hive1.2 uses 3.4 */
//@Test
public void testCassandraStorageCompositeColumnCF() throws IOException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException, AuthenticationException, AuthorizationException
@Test
public void testCassandraStorageCompositeColumnCF() throws IOException, ClassNotFoundException, TException,
NoSuchFieldException, IllegalAccessException, InstantiationException
{
//Test CompositeType
pig.registerQuery("compo = load 'cassandra://thriftKs/Compo?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("compo = load 'cassandra://thrift_ks/compo?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("compo = foreach compo generate key as method, flatten(columns);");
pig.registerQuery("lee = filter compo by columns::name == ('bruce','lee');");
@ -626,7 +592,7 @@ public class ThriftColumnFamilyTest extends PigTestBase
Assert.assertEquals(t.get(2), "ouch");
}
Assert.assertEquals(count, 2);
pig.registerQuery("night = load 'cassandra://thriftKs/CompoInt?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("night = load 'cassandra://thrift_ks/compo_int?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("night = foreach night generate flatten(columns);");
pig.registerQuery("night = foreach night generate (int)columns::name.$0+(double)columns::name.$1/60 as hour, columns::value as noise;");
@ -641,10 +607,10 @@ public class ThriftColumnFamilyTest extends PigTestBase
Assert.assertEquals(t.get(1), "daddy?");
}
pig.setBatchOn();
pig.registerQuery("compo_int_rows = LOAD 'cassandra://thriftKs/CompoInt?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("STORE compo_int_rows INTO 'cassandra://thriftKs/CompoIntCopy?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("compo_int_rows = LOAD 'cassandra://thrift_ks/compo_int?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("STORE compo_int_rows INTO 'cassandra://thrift_ks/compo_int_copy?" + defaultParameters + "' using CassandraStorage();");
pig.executeBatch();
pig.registerQuery("compocopy_int_rows = LOAD 'cassandra://thriftKs/CompoIntCopy?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("compocopy_int_rows = LOAD 'cassandra://thrift_ks/compo_int_copy?" + defaultParameters + "' using CassandraStorage();");
//(clock,{((1,0),z),((1,30),zzzz),((2,30),daddy?),((6,30),coffee...)})
it = pig.openIterator("compocopy_int_rows");
count = 0;
@ -652,11 +618,9 @@ public class ThriftColumnFamilyTest extends PigTestBase
Tuple t = it.next();
Assert.assertEquals(t.get(0), "clock");
DataBag columns = (DataBag) t.get(1);
Iterator<Tuple> iter = columns.iterator();
while (iter.hasNext())
for (Tuple t1 : columns)
{
count ++;
Tuple t1 = iter.next();
count++;
Tuple inner = (Tuple) t1.get(0);
if ((Long) inner.get(0) == 1L && (Long) inner.get(1) == 0L)
Assert.assertEquals(t1.get(1), "z");
@ -672,10 +636,11 @@ public class ThriftColumnFamilyTest extends PigTestBase
}
@Test
public void testCassandraStorageCompositeKeyCF() throws IOException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException, AuthenticationException, AuthorizationException
public void testCassandraStorageCompositeKeyCF() throws IOException, ClassNotFoundException, TException,
NoSuchFieldException, IllegalAccessException, InstantiationException
{
//Test CompositeKey
pig.registerQuery("compokeys = load 'cassandra://thriftKs/CompoKey?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("compokeys = load 'cassandra://thrift_ks/compo_key?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("compokeys = filter compokeys by key.$1 == 40;");
//((clock,40),{(6,coffee...)})
Iterator<Tuple> it = pig.openIterator("compokeys");
@ -694,10 +659,10 @@ public class ThriftColumnFamilyTest extends PigTestBase
}
}
pig.setBatchOn();
pig.registerQuery("compo_key_rows = LOAD 'cassandra://thriftKs/CompoKey?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("STORE compo_key_rows INTO 'cassandra://thriftKs/CompoKeyCopy?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("compo_key_rows = LOAD 'cassandra://thrift_ks/compo_key?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("STORE compo_key_rows INTO 'cassandra://thrift_ks/compo_key_copy?" + defaultParameters + "' using CassandraStorage();");
pig.executeBatch();
pig.registerQuery("compo_key_copy_rows = LOAD 'cassandra://thriftKs/CompoKeyCopy?" + defaultParameters + "' using CassandraStorage();");
pig.registerQuery("compo_key_copy_rows = LOAD 'cassandra://thrift_ks/compo_key_copy?" + defaultParameters + "' using CassandraStorage();");
//((clock,10),{(1,z)})
//((clock,20),{(1,zzzz)})
//((clock,30),{(2,daddy?)})
@ -753,11 +718,10 @@ public class ThriftColumnFamilyTest extends PigTestBase
}
}
}
Assert.assertEquals(count, 4);
Assert.assertEquals(4, count);
}
private String getColumnValue(String ks, String cf, String colName, String key, String validator)
throws AuthenticationException, AuthorizationException, InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException, IOException
private String getColumnValue(String ks, String cf, String colName, String key, String validator) throws TException, IOException
{
Cassandra.Client client = getClient();
client.set_keyspace(ks);
@ -770,17 +734,4 @@ public class ThriftColumnFamilyTest extends PigTestBase
ColumnOrSuperColumn got = client.get(key_user_id, cp, ConsistencyLevel.ONE);
return parseType(validator).getString(got.getColumn().value);
}
private void executeCliStatements(String[] statements) throws CharacterCodingException, ClassNotFoundException, TException, TimedOutException, NotFoundException, InvalidRequestException, NoSuchFieldException, UnavailableException, IllegalAccessException, InstantiationException
{
CliMain.connect("127.0.0.1", 9170);
try
{
for (String stmt : statements)
CliMain.processStatement(stmt);
}
catch (Exception e)
{
}
}
}

View File

@ -1,341 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cli;
import org.apache.cassandra.SchemaLoader;
import org.apache.cassandra.config.KSMetaData;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.Schema;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.locator.SimpleStrategy;
import org.apache.cassandra.service.EmbeddedCassandraService;
import org.apache.cassandra.thrift.*;
import org.apache.thrift.TException;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.regex.Pattern;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class CliTest
{
private static final String KEYSPACE1 = "CliTest";
private static final String CF_STANDARD1 = "Standard1";
// please add new statements here so they could be auto-runned by this test.
private String[] statements = {
"use " + KEYSPACE1,
"create column family SecondaryIndicesWithoutIdxName" +
" with comparator = UTF8Type" +
" and default_validation_class = UTF8Type" +
" and column_metadata = [{column_name: profileId, validation_class: UTF8Type, index_type: KEYS}];",
"update column family SecondaryIndicesWithoutIdxName" +
" with column_metadata = " +
"[{column_name: profileId, validation_class: UTF8Type, index_type: KEYS}," +
"{column_name: postedDate, validation_class: LongType}];",
"create column family 123 with comparator=UTF8Type and column_metadata=[{ column_name:world, validation_class:IntegerType, index_type:0, index_name:IdxName }, " +
"{ column_name:world2, validation_class:LongType, index_type:KEYS, index_name:LongIdxName}, " +
"{ column_name:617070, validation_class:UTF8Type, index_type:KEYS }, " +
"{ column_name:'-617071', validation_class:UTF8Type, index_type:KEYS }," +
"{ column_name:time_spent_uuid, validation_class:TimeUUIDType}] and default_validation_class=UTF8Type;",
"assume 123 keys as utf8;",
"set 123[hello][world] = 123848374878933948398384;",
"set 123[hello][test_quote] = 'value\\'';",
"set 123['k\\'ey'][VALUE] = 'VAL';",
"set 123['k\\'ey'][VALUE] = 'VAL\\'';",
"set 123[hello][-31337] = 'some string value';",
"list 123;",
"list 123[:];",
"list 123[456:];",
"list 123 limit 5;",
"list 123[12:15] limit 20;",
"list 123[12:15] columns 2;",
"list 123 columns 2 reversed;",
"list 123 limit 10 columns 2 reversed;",
"get 123[hello][-31337];",
"get 123[hello][world];",
"get 123[hello][test_quote];",
"get 123['k\\'ey'][VALUE]",
"set 123[hello][-31337] = -23876;",
"set 123[hello][world2] = 15;",
"get 123 where world2 = long(15);",
"get 123 where world2 = long(15);",
"get 123 where world2 = long(15);",
"del 123[utf8('hello')][utf8('world')];",
"del 123[hello][world2];",
"set 123['hello'][time_spent_uuid] = timeuuid(a8098c1a-f86e-11da-bd1a-00112444be1e);",
"create column family CF2 with comparator=IntegerType and default_validation_class=AsciiType;",
"assume CF2 keys as utf8;",
"set CF2['key'][98349387493847748398334] = 'some text';",
"get CF2['key'][98349387493847748398334];",
"set CF2['key'][98349387493] = 'some text other';",
"get CF2['key'][98349387493];",
"create column family CF3 with comparator=UTF8Type and column_metadata=[{column_name:'big world', validation_class:LongType, index_type:KEYS, index_name:WorldIdx}];",
"assume CF3 keys as utf8;",
"set CF3['hello']['big world'] = 3748;",
"get CF3['hello']['big world'];",
"list CF3;",
"list CF3[:];",
"list CF3[h:];",
"list CF3 limit 10;",
"list CF3[h:] limit 10;",
"create column family CF4 with comparator=IntegerType and column_metadata=[{column_name:9999, validation_class:LongType}];",
"assume CF4 keys as utf8;",
"set CF4['hello'][9999] = 1234;",
"get CF4['hello'][9999];",
"get CF4['hello'][9999] as Long;",
"get CF4['hello'][9999] as Bytes;",
"set CF4['hello'][9999] = Long(1234);",
"get CF4['hello'][9999];",
"get CF4['hello'][9999] as Long;",
"del CF4['hello'][9999];",
"get CF4['hello'][9999];",
"create column family sCf1 with column_type=Super and comparator=IntegerType and subcomparator=LongType and column_metadata=[{column_name:9999, validation_class:LongType}];",
"assume sCf1 keys as utf8;",
"set sCf1['hello'][1][9999] = 1234;",
"get sCf1['hello'][1][9999];",
"get sCf1['hello'][1][9999] as Long;",
"get sCf1['hello'][1][9999] as Bytes;",
"set sCf1['hello'][1][9999] = Long(1234);",
"set sCf1['hello'][-1][-12] = Long(5678);",
"get sCf1['hello'][-1][-12];",
"set sCf1['hello'][-1][-12] = -340897;",
"set sCf1['hello'][-1][-12] = integer(-340897);",
"get sCf1['hello'][1][9999];",
"get sCf1['hello'][1][9999] as Long;",
"del sCf1['hello'][1][9999];",
"get sCf1['hello'][1][9999];",
"set sCf1['hello'][1][9999] = Long(1234);",
"del sCf1['hello'][9999];",
"get sCf1['hello'][1][9999];",
"create column family 'Counter1' with comparator=UTF8Type and default_validation_class=CounterColumnType;",
"assume Counter1 keys as utf8;",
"incr Counter1['hello']['cassandra'];",
"incr Counter1['hello']['cassandra'] by 3;",
"incr Counter1['hello']['cassandra'] by -2;",
"decr Counter1['hello']['cassandra'];",
"decr Counter1['hello']['cassandra'] by 3;",
"decr Counter1['hello']['cassandra'] by -2;",
"get Counter1['hello']['cassandra'];",
"get Counter1['hello'];",
"truncate 123;",
"drop index on '123'.world2;",
"drop index on '123'.617070;",
"drop index on '123'.'-617071';",
"drop index on CF3.'big world';",
"update keyspace " + KEYSPACE1 + " with durable_writes = false;",
"assume 123 comparator as utf8;",
"assume 123 sub_comparator as integer;",
"assume 123 validator as lexicaluuid;",
"assume 123 keys as timeuuid;",
"create column family CF7;",
"assume CF7 keys as utf8;",
"set CF7[1][timeuuid()] = utf8(test1);",
"set CF7[2][lexicaluuid()] = utf8('hello world!');",
"set CF7[3][lexicaluuid(550e8400-e29b-41d4-a716-446655440000)] = utf8(test2);",
"set CF7[key2][timeuuid()] = utf8(test3);",
"assume CF7 comparator as lexicaluuid;",
"assume CF7 keys as utf8;",
"list CF7;",
"get CF7[3];",
"get CF7[3][lexicaluuid(550e8400-e29b-41d4-a716-446655440000)];",
"get sCf1['hello'][1][9999];",
"set sCf1['hello'][1][9999] = 938;",
"set sCf1['hello'][1][9999] = 938 with ttl = 30;",
"set sCf1['hello'][1][9999] = 938 with ttl = 560;",
"count sCf1[hello];",
"count sCf1[utf8('hello')];",
"count sCf1[utf8('hello')][integer(1)];",
"count sCf1[hello][1];",
"list sCf1;",
"del sCf1['hello'][1][9999];",
"assume sCf1 comparator as utf8;",
"create column family CF8;",
"drop column family cF8;",
"create keyspace TESTIN;",
"drop keyspace tesTIN;",
"update column family 123 with comparator=UTF8Type and column_metadata=[];",
"drop column family 123;",
"create column family myCF with column_type='Super' and comparator='UTF8Type' AND subcomparator='UTF8Type' AND default_validation_class=AsciiType;",
"assume myCF keys as utf8;",
"create column family Countries with comparator=UTF8Type and column_metadata=[ {column_name: name, validation_class: UTF8Type} ];",
"set Countries[11][name] = USA;",
"get Countries[11][name];",
"update column family Countries with compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy';",
"create column family Cities with compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy' and compaction_strategy_options = {min_sstable_size:1024};",
"set myCF['key']['scName']['firstname'] = 'John';",
"get myCF['key']['scName']",
"assume CF3 keys as utf8;",
"use " + KEYSPACE1 + ";",
"update keyspace " + KEYSPACE1 + " with placement_strategy='org.apache.cassandra.locator.NetworkTopologyStrategy';",
"update keyspace " + KEYSPACE1 + " with strategy_options={DC1:3, DC2:4, DC5:1};",
"describe cluster;",
"help describe cluster;",
"show cluster name",
"show api version",
"help help",
"help connect",
"help use",
"help describe",
"HELP exit",
"help QUIT",
"help show cluster name",
"help show keyspaces",
"help show schema",
"help show api version",
"help create keyspace",
"HELP update KEYSPACE",
"HELP CREATE column FAMILY",
"HELP UPDATE COLUMN family",
"HELP drop keyspace",
"help drop column family",
"HELP GET",
"HELP set",
"HELP DEL",
"HELP count",
"HELP list",
"HELP TRUNCATE",
"help assume",
"HELP",
"?",
"show schema",
"show schema " + KEYSPACE1
};
@BeforeClass
public static void defineSchema() throws ConfigurationException
{
SchemaLoader.prepareServer();
SchemaLoader.startGossiper();
SchemaLoader.createKeyspace(KEYSPACE1, true, false,
SimpleStrategy.class,
KSMetaData.optsWithRF(1),
SchemaLoader.standardCFMD(KEYSPACE1, CF_STANDARD1));
}
@Test
public void testCli() throws IOException, TException, TimedOutException, NotFoundException, SchemaDisagreementException, NoSuchFieldException, InvalidRequestException, UnavailableException, InstantiationException, IllegalAccessException
{
Schema.instance.clear(); // Schema are now written on disk and will be reloaded
new EmbeddedCassandraService().start();
// new error/output streams for CliSessionState
ByteArrayOutputStream errStream = new ByteArrayOutputStream();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
// checking if we can connect to the running cassandra node on localhost
CliMain.connect("127.0.0.1", DatabaseDescriptor.getRpcPort());
// setting new output stream
CliMain.sessionState.setOut(new PrintStream(outStream));
CliMain.sessionState.setErr(new PrintStream(errStream));
// re-creating keyspace for tests
try
{
// dropping in case it exists e.g. could be left from previous run
CliMain.processStatement(String.format("drop keyspace %s;", KEYSPACE1));
}
catch (Exception e)
{
// TODO check before drop so we don't have this fragile ignored exception block
}
CliMain.processStatement(String.format("create keyspace %s;", KEYSPACE1));
for (String statement : statements)
{
errStream.reset();
// System.out.println("Executing statement: " + statement);
CliMain.processStatement(statement);
String result = outStream.toString();
// System.out.println("Result:\n" + result);
if (statement.startsWith("show schema"))
assertEquals(errStream.toString() + "processing" + statement,
"\nWARNING: CQL3 tables are intentionally omitted from 'show schema' output." + String.format("%n")
+ "See https://issues.apache.org/jira/browse/CASSANDRA-4377 for details.\n" + String.format("%n"),
errStream.toString());
else
assertEquals(errStream.toString() + " processing " + statement, "", errStream.toString());
if (statement.startsWith("drop ") || statement.startsWith("create ") || statement.startsWith("update "))
{
assert Pattern.compile("(.{8})-(.{4})-(.{4})-(.{4})-(.{12}).*", Pattern.DOTALL).matcher(result).matches()
: String.format("\"%s\" failed: %s", statement, result);
}
else if (statement.startsWith("set "))
{
assertTrue(result.contains("Value inserted."));
assertTrue(result.contains("Elapsed time:"));
}
else if (statement.startsWith("incr "))
{
assertTrue(result.contains("Value incremented."));
}
else if (statement.startsWith("decr "))
{
assertTrue(result.contains("Value decremented."));
}
else if (statement.startsWith("get "))
{
if (statement.contains("where"))
{
assertTrue(result.startsWith("-------------------" + System.getProperty("line.separator") + "RowKey:"));
}
else if (statement.contains("Counter"))
{
assertTrue(result.startsWith("=> (counter=") || result.startsWith("Value was not found"));
}
else
{
assertTrue(result.startsWith("=> (name=") || result.startsWith("Value was not found"));
}
assertTrue(result.contains("Elapsed time:"));
}
else if (statement.startsWith("truncate "))
{
assertTrue(result.contains(" truncated."));
}
else if (statement.startsWith("assume "))
{
assertTrue(result.contains("successfully."));
}
outStream.reset(); // reset stream so we have only output from next statement all the time
errStream.reset(); // no errors to the end user.
}
}
@Test
public void testEscape()
{
//escaped is the string read from the cli.
String escaped = "backspace \\b tab \\t linefeed \\n form feed \\f carriage return \\r duble quote \\\" " +
"single quote \\' backslash \\\\";
String unescaped = "backspace \b tab \t linefeed \n form feed \f carriage return \r duble quote \" " +
"single quote ' backslash \\";
// when read from the cli may have single quotes around it
assertEquals(unescaped, CliUtils.unescapeSQLString("'" + escaped + "'"));
assertEquals(escaped, CliUtils.escapeSQLString(unescaped));
}
}