Permalink
Please sign in to comment.
Showing
with
3,438 additions
and 0 deletions.
- +14 −0 .classpath
- +5 −0 .gitignore
- +19 −0 .project
- +72 −0 CassandraAstyanaxGrailsPlugin.groovy
- +6 −0 application.properties
- +36 −0 grails-app/conf/BuildConfig.groovy
- +24 −0 grails-app/conf/Config.groovy
- +32 −0 grails-app/conf/DataSource.groovy
- +13 −0 grails-app/conf/UrlMappings.groovy
- +122 −0 grails-app/services/com/reachlocal/grails/plugins/cassandra/astyanax/AstyanaxService.groovy
- +54 −0 grails-app/views/error.gsp
- BIN lib/apache-cassandra-1.0.0.jar
- BIN lib/apache-cassandra-thrift-1.0.0.jar
- BIN lib/astyanax-0.8.10-SNAPSHOT.jar
- BIN lib/cassandra-jdbc-1.0.5-SNAPSHOT.jar
- BIN lib/libthrift-0.6.jar
- +10 −0 scripts/_Install.groovy
- +5 −0 scripts/_Uninstall.groovy
- +10 −0 scripts/_Upgrade.groovy
- +58 −0 src/groovy/com/reachlocal/grails/plugins/cassandra/OrmPersistenceMethods.groovy
- +74 −0 src/groovy/com/reachlocal/grails/plugins/cassandra/astyanax/AstyanaxDynamicMethods.groovy
- +127 −0 src/groovy/com/reachlocal/grails/plugins/cassandra/astyanax/AstyanaxPersistenceMethods.groovy
- +81 −0 src/groovy/com/reachlocal/grails/plugins/cassandra/uuid/UuidDynamicMethods.groovy
- +156 −0 test/integration/com/reachlocal/grails/plugins/cassandra/test/AstyanaxDynamicMethodsTests.groovy
- +215 −0 test/integration/com/reachlocal/grails/plugins/cassandra/test/AstyanaxPersistenceMethodsTests.groovy
- +67 −0 test/integration/com/reachlocal/grails/plugins/cassandra/test/AstyanaxServiceTests.groovy
- +87 −0 test/integration/com/reachlocal/grails/plugins/cassandra/test/UuidDynamicMethodsTests.groovy
- +42 −0 web-app/WEB-INF/applicationContext.xml
- +14 −0 web-app/WEB-INF/sitemesh.xml
- +563 −0 web-app/WEB-INF/tld/c.tld
- +671 −0 web-app/WEB-INF/tld/fmt.tld
- +550 −0 web-app/WEB-INF/tld/grails.tld
- +311 −0 web-app/WEB-INF/tld/spring.tld
14
.classpath
@@ -0,0 +1,14 @@ | ||
+<classpath> | ||
+ <classpathentry kind="src" path="src/java"/> | ||
+ <classpathentry kind="src" path="src/groovy"/> | ||
+ <classpathentry kind="src" path="grails-app/conf"/> | ||
+ <classpathentry kind="src" path="grails-app/controllers"/> | ||
+ <classpathentry kind="src" path="grails-app/domain"/> | ||
+ <classpathentry kind="src" path="grails-app/services"/> | ||
+ <classpathentry kind="src" path="grails-app/taglib"/> | ||
+ <classpathentry kind="src" path="test/integration"/> | ||
+ <classpathentry kind="src" path="test/unit"/> | ||
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | ||
+ <classpathentry kind="con" path="com.springsource.sts.grails.core.CLASSPATH_CONTAINER"/> | ||
+ <classpathentry kind="output" path="web-app/WEB-INF/classes"/> | ||
+</classpath> |
@@ -0,0 +1,5 @@ | ||
+.idea/ | ||
+.settings/ | ||
+*.iml | ||
+stacktrace.log | ||
+target/ |
19
.project
@@ -0,0 +1,19 @@ | ||
+<?xml version="1.0" encoding="UTF-8"?> | ||
+<projectDescription> | ||
+ <name>cassandra-astyanax</name> | ||
+ <comment></comment> | ||
+ <projects> | ||
+ </projects> | ||
+ <buildSpec> | ||
+ <buildCommand> | ||
+ <name>org.eclipse.jdt.core.javabuilder</name> | ||
+ <arguments> | ||
+ </arguments> | ||
+ </buildCommand> | ||
+ </buildSpec> | ||
+ <natures> | ||
+ <nature>com.springsource.sts.grails.core.nature</nature> | ||
+ <nature>org.eclipse.jdt.groovy.core.groovyNature</nature> | ||
+ <nature>org.eclipse.jdt.core.javanature</nature> | ||
+ </natures> | ||
+</projectDescription> |
@@ -0,0 +1,72 @@ | ||
+import com.reachlocal.grails.plugins.cassandra.astyanax.AstyanaxDynamicMethods | ||
+import com.reachlocal.grails.plugins.cassandra.uuid.UuidDynamicMethods | ||
+ | ||
+/* | ||
+ * Copyright 2012 ReachLocal Inc. | ||
+ * | ||
+ * Licensed 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. | ||
+ */ | ||
+ | ||
+class CassandraAstyanaxGrailsPlugin | ||
+{ | ||
+ // the plugin version | ||
+ def version = "0.1" | ||
+ // the version or versions of Grails the plugin is designed for | ||
+ def grailsVersion = "1.3.7 > *" | ||
+ // the other plugins this plugin depends on | ||
+ def dependsOn = [:] | ||
+ // resources that are excluded from plugin packaging | ||
+ def pluginExcludes = [ | ||
+ "grails-app/views/error.gsp" | ||
+ ] | ||
+ | ||
+ // TODO Fill in these fields | ||
+ def author = "Your name" | ||
+ def authorEmail = "" | ||
+ def title = "Plugin summary/headline" | ||
+ def description = '''\\ | ||
+Brief description of the plugin. | ||
+''' | ||
+ | ||
+ // URL to the plugin's documentation | ||
+ def documentation = "http://grails.org/plugin/cassandra-astyanax" | ||
+ | ||
+ def doWithWebDescriptor = { xml -> | ||
+ // TODO Implement additions to web.xml (optional), this event occurs before | ||
+ } | ||
+ | ||
+ def doWithSpring = { | ||
+ // TODO Implement runtime spring config (optional) | ||
+ } | ||
+ | ||
+ def doWithDynamicMethods = { ctx -> | ||
+ // Dynamic methods to make Astyanax groovier | ||
+ AstyanaxDynamicMethods.addAll() | ||
+ UuidDynamicMethods.addAll() | ||
+ } | ||
+ | ||
+ def doWithApplicationContext = { applicationContext -> | ||
+ // TODO Implement post initialization spring config (optional) | ||
+ } | ||
+ | ||
+ def onChange = { event -> | ||
+ // TODO Implement code that is executed when any artefact that this plugin is | ||
+ // watching is modified and reloaded. The event contains: event.source, | ||
+ // event.application, event.manager, event.ctx, and event.plugin. | ||
+ } | ||
+ | ||
+ def onConfigChange = { event -> | ||
+ // TODO Implement code that is executed when the project configuration changes. | ||
+ // The event is the same as for 'onChange'. | ||
+ } | ||
+} |
@@ -0,0 +1,6 @@ | ||
+#Grails Metadata file | ||
+#Mon Mar 19 18:51:57 EDT 2012 | ||
+app.grails.version=1.3.7 | ||
+app.name=cassandra-astyanax | ||
+plugins.hibernate=1.3.7 | ||
+plugins.tomcat=1.3.7 |
@@ -0,0 +1,36 @@ | ||
+grails.project.class.dir = "target/classes" | ||
+grails.project.test.class.dir = "target/test-classes" | ||
+grails.project.test.reports.dir = "target/test-reports" | ||
+//grails.project.war.file = "target/${appName}-${appVersion}.war" | ||
+grails.project.dependency.resolution = { | ||
+ // inherit Grails' default dependencies | ||
+ inherits("global") { | ||
+ // uncomment to disable ehcache | ||
+ // excludes 'ehcache' | ||
+ } | ||
+ log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose' | ||
+ repositories { | ||
+ grailsPlugins() | ||
+ grailsHome() | ||
+ grailsCentral() | ||
+ | ||
+ // uncomment the below to enable remote dependency resolution | ||
+ // from public Maven repositories | ||
+ //mavenLocal() | ||
+ mavenCentral() | ||
+ //mavenRepo "http://snapshots.repository.codehaus.org" | ||
+ //mavenRepo "http://repository.codehaus.org" | ||
+ //mavenRepo "http://download.java.net/maven/2/" | ||
+ //mavenRepo "http://repository.jboss.com/maven2/" | ||
+ } | ||
+ dependencies { | ||
+ // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg. | ||
+ | ||
+ // runtime 'mysql:mysql-connector-java:5.1.13' | ||
+ runtime 'joda-time:joda-time:2.0' | ||
+ runtime 'org.apache.servicemix.bundles:org.apache.servicemix.bundles.commons-csv:1.0-r706900_3' | ||
+ runtime 'com.github.stephenc.high-scale-lib:high-scale-lib:1.1.1' | ||
+ runtime 'com.google.guava:guava:11.0.2' | ||
+ runtime 'com.github.stephenc.eaio-uuid:uuid:3.2.0' | ||
+ } | ||
+} |
@@ -0,0 +1,24 @@ | ||
+// configuration for plugin testing - will not be included in the plugin zip | ||
+ | ||
+log4j = { | ||
+ // Example of changing the log pattern for the default console | ||
+ // appender: | ||
+ // | ||
+ //appenders { | ||
+ // console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n') | ||
+ //} | ||
+ | ||
+ error 'org.codehaus.groovy.grails.web.servlet', // controllers | ||
+ 'org.codehaus.groovy.grails.web.pages', // GSP | ||
+ 'org.codehaus.groovy.grails.web.sitemesh', // layouts | ||
+ 'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping | ||
+ 'org.codehaus.groovy.grails.web.mapping', // URL mapping | ||
+ 'org.codehaus.groovy.grails.commons', // core / classloading | ||
+ 'org.codehaus.groovy.grails.plugins', // plugins | ||
+ 'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration | ||
+ 'org.springframework', | ||
+ 'org.hibernate', | ||
+ 'net.sf.ehcache.hibernate' | ||
+ | ||
+ warn 'org.mortbay.log' | ||
+} |
@@ -0,0 +1,32 @@ | ||
+dataSource { | ||
+ pooled = true | ||
+ driverClassName = "org.hsqldb.jdbcDriver" | ||
+ username = "sa" | ||
+ password = "" | ||
+} | ||
+hibernate { | ||
+ cache.use_second_level_cache = true | ||
+ cache.use_query_cache = true | ||
+ cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider' | ||
+} | ||
+// environment specific settings | ||
+environments { | ||
+ development { | ||
+ dataSource { | ||
+ dbCreate = "create-drop" // one of 'create', 'create-drop','update' | ||
+ url = "jdbc:hsqldb:mem:devDB" | ||
+ } | ||
+ } | ||
+ test { | ||
+ dataSource { | ||
+ dbCreate = "update" | ||
+ url = "jdbc:hsqldb:mem:testDb" | ||
+ } | ||
+ } | ||
+ production { | ||
+ dataSource { | ||
+ dbCreate = "update" | ||
+ url = "jdbc:hsqldb:file:prodDb;shutdown=true" | ||
+ } | ||
+ } | ||
+} |
@@ -0,0 +1,13 @@ | ||
+class UrlMappings { | ||
+ | ||
+ static mappings = { | ||
+ "/$controller/$action?/$id?"{ | ||
+ constraints { | ||
+ // apply constraints here | ||
+ } | ||
+ } | ||
+ | ||
+ "/"(view:"/index") | ||
+ "500"(view:'/error') | ||
+ } | ||
+} |
@@ -0,0 +1,122 @@ | ||
+/* | ||
+ * Copyright 2012 ReachLocal Inc. | ||
+ * | ||
+ * Licensed 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 com.reachlocal.grails.plugins.cassandra.astyanax | ||
+ | ||
+import org.codehaus.groovy.grails.commons.ConfigurationHolder | ||
+import com.netflix.astyanax.thrift.ThriftFamilyFactory | ||
+import com.netflix.astyanax.connectionpool.impl.CountingConnectionPoolMonitor | ||
+import com.netflix.astyanax.connectionpool.impl.ConnectionPoolConfigurationImpl | ||
+import com.netflix.astyanax.impl.AstyanaxConfigurationImpl | ||
+import com.netflix.astyanax.AstyanaxContext | ||
+import com.netflix.astyanax.serializers.StringSerializer | ||
+import com.netflix.astyanax.model.ColumnFamily | ||
+import com.netflix.astyanax.util.RangeBuilder | ||
+ | ||
+import groovy.sql.Sql | ||
+ | ||
+/** | ||
+ * @author Bob Florian | ||
+ * | ||
+ */ | ||
+class AstyanaxService | ||
+{ | ||
+ def port = ConfigurationHolder.config?.cassandra?.port ?: 9160 | ||
+ def host = ConfigurationHolder.config?.cassandra?.host ?: "127.0.0.1" | ||
+ def seeds = ConfigurationHolder.config?.cassandra?.seeds ?: "${host}:${port}" | ||
+ def maxConsPerHost = ConfigurationHolder.config?.cassandra?.maxConsPerHost ?: 10 | ||
+ def cluster = ConfigurationHolder.config?.cassandra?.cluster ?: "Test Cluster" | ||
+ def connectionPoolName = ConfigurationHolder.config?.cassandra?.connectionPoolName ?: "MyConnectionPool" | ||
+ def discoveryType = ConfigurationHolder.config?.cassandra?.discoveryType ?: com.netflix.astyanax.connectionpool.NodeDiscoveryType.NONE | ||
+ def defaultKeyspace = ConfigurationHolder.config?.cassandra?.keySpace ?: "AstyanaxTest" | ||
+ | ||
+ def cqlDriver = "org.apache.cassandra.cql.jdbc.CassandraDriver" | ||
+ | ||
+ /** | ||
+ * Constructs an Astyanax context and passed execution to a closure | ||
+ * | ||
+ * @param keyspace name of the keyspace | ||
+ * @param block closure to be executed | ||
+ * @throws Exception | ||
+ */ | ||
+ void execute(keyspace=defaultKeyspace, block) throws Exception | ||
+ { | ||
+ def context = new AstyanaxContext.Builder() | ||
+ .forCluster(cluster) | ||
+ .forKeyspace(keyspace) | ||
+ .withAstyanaxConfiguration(new AstyanaxConfigurationImpl() | ||
+ .setDiscoveryType(discoveryType) | ||
+ ) | ||
+ .withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl(connectionPoolName) | ||
+ .setPort(port) | ||
+ .setMaxConnsPerHost(maxConsPerHost) | ||
+ .setSeeds(seeds) | ||
+ ) | ||
+ .withConnectionPoolMonitor(new CountingConnectionPoolMonitor()) | ||
+ .buildKeyspace(ThriftFamilyFactory.getInstance()); | ||
+ | ||
+ context.start() | ||
+ | ||
+ try { | ||
+ block(context.entity) | ||
+ } | ||
+ finally { | ||
+ context.shutdown() | ||
+ } | ||
+ } | ||
+ | ||
+ /** | ||
+ * Initialized a CQL JDBC connection | ||
+ * | ||
+ * @param keyspace name of the keyspace | ||
+ * @return initialized JDBC/CQL connection object | ||
+ * @throws Exception | ||
+ */ | ||
+ Sql cql(keyspace=defaultKeyspace) throws Exception | ||
+ { | ||
+ Sql.newInstance("jdbc:cassandra://localhost:${port}/${keyspace}", cqlDriver) | ||
+ } | ||
+ | ||
+ /** | ||
+ * Utility method to print out readable version of column family for debugging purposes | ||
+ * | ||
+ * @param names list of column family names to display | ||
+ * @param keyspace name of the keyspace | ||
+ * @param maxRows the maximum number of rows to print | ||
+ * @param maxColumns the maximum number of columns to print for each row | ||
+ * @param out the print writer to use, defaults to System.out | ||
+ */ | ||
+ void showColumnFamilies (Collection names, String keyspace=defaultKeyspace, Integer maxRows=50, Integer maxColumns=10, out=System.out) { | ||
+ names.each {String cf -> | ||
+ execute(keyspace) {ks -> | ||
+ out.println "${cf}:" | ||
+ ks.prepareQuery(new ColumnFamily(cf, StringSerializer.get(), StringSerializer.get())) | ||
+ .getAllRows() | ||
+ .setRowLimit(maxRows) | ||
+ .withColumnRange(new RangeBuilder().setMaxSize(maxColumns).build()) | ||
+ .execute() | ||
+ .result.each{row -> | ||
+ | ||
+ out.println " ${row.key} =>" | ||
+ row.columns.each {col -> | ||
+ out.println " ${col.name} => '${col.stringValue}'" | ||
+ } | ||
+ } | ||
+ out.println"" | ||
+ } | ||
+ } | ||
+ } | ||
+} |

Oops, something went wrong.
0 comments on commit
4d76a43