- •Credits
- •About the Authors
- •About the Reviewers
- •www.PacktPub.com
- •Table of Contents
- •Preface
- •Introduction
- •Installing Groovy on Windows
- •Installing Groovy on Linux and OS X
- •Executing Groovy code from the command line
- •Using Groovy as a command-line text file editor
- •Running Groovy with invokedynamic support
- •Building Groovy from source
- •Managing multiple Groovy installations on Linux
- •Using groovysh to try out Groovy commands
- •Starting groovyConsole to execute Groovy snippets
- •Configuring Groovy in Eclipse
- •Configuring Groovy in IntelliJ IDEA
- •Introduction
- •Using Java classes from Groovy
- •Embedding Groovy into Java
- •Compiling Groovy code
- •Generating documentation for Groovy code
- •Introduction
- •Searching strings with regular expressions
- •Writing less verbose Java Beans with Groovy Beans
- •Inheriting constructors in Groovy classes
- •Defining code as data in Groovy
- •Defining data structures as code in Groovy
- •Implementing multiple inheritance in Groovy
- •Defining type-checking rules for dynamic code
- •Adding automatic logging to Groovy classes
- •Introduction
- •Reading from a file
- •Reading a text file line by line
- •Processing every word in a text file
- •Writing to a file
- •Replacing tabs with spaces in a text file
- •Deleting a file or directory
- •Walking through a directory recursively
- •Searching for files
- •Changing file attributes on Windows
- •Reading data from a ZIP file
- •Reading an Excel file
- •Extracting data from a PDF
- •Introduction
- •Reading XML using XmlSlurper
- •Reading XML using XmlParser
- •Reading XML content with namespaces
- •Searching in XML with GPath
- •Searching in XML with XPath
- •Constructing XML content
- •Modifying XML content
- •Sorting XML nodes
- •Serializing Groovy Beans to XML
- •Introduction
- •Parsing JSON messages with JsonSlurper
- •Constructing JSON messages with JsonBuilder
- •Modifying JSON messages
- •Validating JSON messages
- •Converting JSON message to XML
- •Converting JSON message to Groovy Bean
- •Using JSON to configure your scripts
- •Introduction
- •Creating a database table
- •Connecting to an SQL database
- •Modifying data in an SQL database
- •Calling a stored procedure
- •Reading BLOB/CLOB from a database
- •Building a simple ORM framework
- •Using Groovy to access Redis
- •Using Groovy to access MongoDB
- •Using Groovy to access Apache Cassandra
- •Introduction
- •Downloading content from the Internet
- •Executing an HTTP GET request
- •Executing an HTTP POST request
- •Constructing and modifying complex URLs
- •Issuing a REST request and parsing a response
- •Issuing a SOAP request and parsing a response
- •Consuming RSS and Atom feeds
- •Using basic authentication for web service security
- •Using OAuth for web service security
- •Introduction
- •Querying methods and properties
- •Dynamically extending classes with new methods
- •Overriding methods dynamically
- •Adding performance logging to methods
- •Adding transparent imports to a script
- •DSL for executing commands over SSH
- •DSL for generating reports from logfiles
- •Introduction
- •Processing collections concurrently
- •Downloading files concurrently
- •Splitting a large task into smaller parallel jobs
- •Running tasks in parallel and asynchronously
- •Using actors to build message-based concurrency
- •Using STM to atomically update fields
- •Using dataflow variables for lazy evaluation
- •Index
Working with Databases in Groovy
There's more...
Similar to the Using Groovy to access Redis recipe, we are going to show a simple way to store
Groovy objects (POGO) to MongoDB. Let's define a Todo class and instantiate it:
class Todo { def name def priority def context
}
def td = new Todo(name: 'open account', priority: 1,
context: 'finance')
Now, the getProperties method in Groovy returns a Map of the object's properties, including some properties we don't want to store in MongoDB, such as class or metaClass.
db.todos << td.properties.findAll { !['class', 'metaClass'].contains(it.key)
}
println db.todos.findOne(name:'open account')
The output will be as follows:
> [_id:50b2a8b21a8820042e85bc6b, context:finance, priority:1, name:open account]
In the previous snippets, the properties method is invoked on the Todo instance and some properties are filtered out. The resulting Map is simply added to the todos collection.
See also
ff http://www.mongodb.org/
ff https://github.com/poiati/gmongo ff http://blog.paulopoiati.com/
Using Groovy to access Apache Cassandra
The Apache Cassandra project was started at Facebook in 2007 to offer users a better experience when searching their inbox. The challenges that Facebook engineers had to face was mostly related to massive amount of data, very high throughput, and scalability at a mind-blowing rate.
256
www.it-ebooks.info
Chapter 7
Cassandra is a distributed column-oriented database designed to manage humongous amounts of structured data in a decentralized, highly scalable way. The absence of a single point of failure makes Cassandra highly available and fault tolerant.
While Cassandra resembles a traditional database and shares some design strategies, it does not support a full relational data model. On the contrary, the Cassandra's data model is flexible, because each row can contain a variable number of columns.
In this recipe, we will go through different aspects of connecting and querying a Cassandra database.
Getting ready
For this recipe, we assume that the reader has already some familiarity with the Cassandra core concepts and data model (columns, super columns, column family, and keyspaces). Installing Cassandra is straightforward.
The only requirement for running Cassandra is a Java 1.6 JVM. Just download the distribution from the product website (http://cassandra.apache.org/download/), unzip it, and run the bin/cassandra or bin/cassandra.bat executable to start a single node.
Before we start, we have to create a couple of entities in Cassandra, a Keyspace and a Column Family. Fire up the CQLSH console located in the bin folder and type:
create keyspace hr with strategy_class='SimpleStrategy' and strategy_options:replication_factor=1;
use hr;
create columnfamily employee (empid int primary key);
These commands create a Keyspace named hr and a column family named employee.
The column family has one field only, which is also a primary key (of type int).
How to do it...
There are several client strategies to interact with Cassandra. In this recipe, we are going to use the open source library Hector, which is a well-established high level Java client.
The Hector APIs are not very fluent, and it takes a lot of boilerplate code to insert or manipulate data with it.
257
www.it-ebooks.info
Working with Databases in Groovy
Why not create a simpler, more fluent wrapper on top of the Hector API using Groovy?
@Grab('org.hectorclient:hector-core:1.1-2') @GrabExclude('org.apache.httpcomponents:httpcore') import me.prettyprint.hector.api.Cluster
import me.prettyprint.hector.api.factory.HFactory import me.prettyprint.hector.api.Keyspace
import me.prettyprint.cassandra.serializers.* import me.prettyprint.hector.api.Serializer import me.prettyprint.hector.api.mutation.Mutator import me.prettyprint.hector.api.ddl.*
import me.prettyprint.hector.api.beans.ColumnSlice
class Gassandra {
def cluster def keyspace def colFamily
Serializer serializer
def stringSerializer = StringSerializer.get()
private Gassandra (Keyspace keyspace) { this.keyspace = keyspace
}
Gassandra() {}
void connect(clusterName, host, port) { cluster = HFactory.
getOrCreateCluster(
clusterName, "$host:$port"
)
}
List<KeyspaceDefinition> getKeyspaces() { cluster.describeKeyspaces()
}
Gassandra withKeyspace(keyspaceName) { keyspace = HFactory.
createKeyspace(
keyspaceName, cluster
258
www.it-ebooks.info
Chapter 7
)
new Gassandra(keyspace)
}
Gassandra withColumnFamily(columnFamily, Serializer c) { colFamily = columnFamily
serializer = c this
}
Gassandra insert(key, columnName, value) { def mutator = HFactory.
createMutator(
keyspace, serializer
)
def column = HFactory. createStringColumn(
columnName, value
)
mutator.insert(key, colFamily, column) this
}
Gassandra insert(key, Map args) { def mutator = HFactory.
createMutator(
keyspace, serializer
)
args.each { mutator.insert(
key,
colFamily,
HFactory.
createStringColumn(
it.key,
it.value
)
)
}
this
}
259
www.it-ebooks.info
Working with Databases in Groovy
ColumnSlice findByKey(key) { def sliceQuery = HFactory. createSliceQuery(
keyspace,
serializer,
stringSerializer, stringSerializer
)
sliceQuery. setColumnFamily(colFamily). setKey(key).
setRange('', '', false, 100). execute().
get()
}
}
How it works...
The Gassandra class exposes a very simple, fluent interface that leverages the dynamic nature of Groovy. The class imports the Hector API and allows writing code as follows:
def g = new Gassandra() g.connect('test', 'localhost', '9160')
def employee = g
.withKeyspace('hr')
.withColumnFamily('employee', IntegerSerializer.get()) employee.insert(5005, 'name', 'Zoe')
employee.insert(5005, 'lastName', 'Ross') employee.insert(5005, 'age', '31')
The withKeySpace and withColumnFamily methods are written in a fluent style, so that we can pass the relevant information to Hector. Note that the withColumnFamily requires a Serializer type to specify the type of the primary key.
The insert method accepts a Map as well, so that the previous code can be rewritten as:
employee.insert('5005', ['name': 'Zoe', 'lastName': 'Ross', 'age': '31'
])
260
www.it-ebooks.info
Chapter 7
To find a row by primary key, there is a findByKey method that returns a me.prettyprint. hector.api.beans.ColumnSlice object.
println employee.findByKey(5005)
The previous statement will output:
ColumnSlice([HColumn(age=31),
HColumn(lastName=Ross),
HColumn(name=Zoe)])
The Gassandra class lacks many basic methods to update or delete rows and other advanced query features. We leave them to the reader as an exercise.
See also
ff http://cassandra.apache.org/
ff http://hector-client.github.com/hector/build/html/index.html
261
www.it-ebooks.info
www.it-ebooks.info