Friday, February 3, 2012

Cassandra Validation Classes / Types


Cassandra validates column names and row keys using validation classes.
This is put in place when you construct a columnFamily.

As an example, in the Thrift API:

CfDef columnFamily = new CfDef(KEYSPACE, COLUMN_FAMILY);
columnFamily.setKey_validation_class("UTF8Type");
columnFamily.setDefault_validation_class("UTF8Type");



The default_validation_class is used to validate row keys.
The key_validation_class is used to validate column names.

Googling didn't provide a handy list of validation classes for Cassandra.
So, here it is:

AsciiType.java BooleanType.java 
BytesType.java 
CompositeType.java 
DateType.java 
DecimalType.java 
DoubleType.java 
DynamicCompositeType.java 
FloatType.java 
Int32Type.java 
IntegerType.java 
LexicalUUIDType.java 
LocalByPartionerType.java 
LongType.java 
ReversedType.java 
TimeUUIDType.java 
TypeParser.java 
UTF8Type.java 
UUIDType.java

Wednesday, February 1, 2012

Bundling Gems in Jars/Wars for Jruby

As part of Virgil's ability to deploy ruby scripts to a remote Hadoop cluster, we needed to package gems' into that Hadoop jar.  After a bit of monkeying around, we got it.

This is the key piece of information:
"Because the operation of Java's classpath and Ruby's load path are so similar, especially under JRuby, they are unified in JRuby 1.1. This results in a number of unified capabilities:...

  • Everything in the Java classpath is considered to be a load path entry, so .rb scripts, for example, contained in JAR files, are loadable."
First thing you need is to actually get your hands on the gem.  To do this, you can run jruby to grab the gem.

java -jar jruby-complete-1.6.0.jar -S gem install -i rest-client rest-client --no-rdoc --no-ri


This will fetch the gems and install them into the current directory under the directory "rest-client".  In that subdirectory you'll find: bin, cache, doc, gems and specifications.  The actual code for the gems is found in the gems directory.  In the case of rest-client, you'll find two directories that contain the code: mime-types-1.17.2 and rest-client-1.6.7.

This is what you need to bundle into the jar.  We copied those two directories into our java project under src/main/resources/gems/.

One approach would be to simply include those directories on your classpath.  Another approach is to programmatically adjust the loadpath to include those directories.   You can do this with the following lines:

List paths = new ArrayList(); 
paths.add("gems/rest-client-1.6.7/lib/"); 
paths.add("gems/mime-types-1.17.2/lib/"); 
this.rubyContainer = new ScriptingContainer(LocalContextScope.CONCURRENT); this.rubyContainer.setLoadPaths(paths);

Then, when using this.rubyContainer you'll be able to run ruby files that require the rest-client.

Since the ruby scripts are actually loaded via the classpath (from the loadpath), jruby is happy loading them from within a jar.  In our case, we built the jar using maven and the gems were included in the jar because we put them under src/main/resources/gems.

Its that easy.  Happy rubying.