Skip to content

Commit ccb88bc

Browse files
committed
Add Cassandra service
1 parent bbd5637 commit ccb88bc

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

grails-app/conf/BuildConfig.groovy

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ grails.project.dependency.resolution = {
5454
runtime 'org.postgresql:postgresql:9.3-1102-jdbc41'
5555
runtime 'com.oracle:ojdbc6:11.2.0.3' // ojdbc7:12.1.0.1 craps out with ORA-01882: timezone region not found
5656
compile 'org.mongodb:mongo-java-driver:2.12.3'
57+
compile 'com.datastax.cassandra:cassandra-driver-mapping:2.1.2'
5758
compile 'com.github.groovy-wslite:groovy-wslite:1.1.0'
5859
compile 'org.codehaus.gpars:gpars:1.2.1'
5960
compile 'com.google.apis:google-api-services-compute:v1-rev29-1.19.0'

grails-app/controllers/v2/BrokerController.groovy

+37
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package v2
22

3+
import com.datastax.driver.core.Cluster
34
import com.google.api.services.compute.Compute
45
import com.google.api.services.compute.model.*
56
import groovy.sql.Sql
@@ -24,6 +25,7 @@ class BrokerController {
2425
final String mariaId = '45e953d3-1598-4b54-95c9-16427e5e7059'
2526
final String pgId = 'f80271a3-0c58-4c23-a550-8828fcce63ad'
2627
final String mongoId = '1050698f-be8e-43ac-a3f2-a74eaec714de'
28+
final String cassId = 'f6cc9ce6-ae3a-43cd-9ae0-ca45280bcc6e'
2729
final String oraId = '1816c23f-6506-4704-959f-ee747ae6a06c'
2830
final String rmqId = '302e9f58-106b-40c0-8bad-8a593bcc2243'
2931
final def plans = [
@@ -32,6 +34,7 @@ class BrokerController {
3234
(mariaId): [ service: 'maria', ports: [ [ port: 3306, kind: 'api' ] ] ],
3335
(pgId): [ service: 'postgresql', ports: [ [ port: 5432, kind: 'api' ] ] ],
3436
(mongoId): [ service: 'mongodb', ports: [ [ port: 27017, kind: 'api' ] ] ],
37+
(cassId): [ service: 'cassandra', ports: [ [ port: 9042, kind: 'api' ] ] ],
3538
(oraId): [ service: 'oracle', ports: [ [ port: 1521, kind: 'api' ], // [ port: 22, kind: 'ssh' ],
3639
[ port: 8080, kind: 'management', dashboard: 'http://$ip:$port/apex' ] ] ],
3740
(rmqId): [ service: 'rabbitmq', ports: [ [ port: 5672, kind: 'api' ],
@@ -607,6 +610,7 @@ class BrokerController {
607610
[ id: mariaId, name: 'maria', description: 'MariaDB database',metadata: [ displayName: 'MariaDB Galera Cluster', bullets: [ 'MariaDB 10.0.12','2 nodes / 1GB memory pool each', '10GB XtraDB storage' ], costs: [ [ amount: [ usd: 20 ], unit: 'month' ] ] ] ],
608611
[ id: pgId, name: 'postgresql', description: 'PostgreSQL database', metadata: [ displayName: 'PostgreSQL', bullets: [ 'PostgreSQL 9.3', '1GB memory pool', '10GB storage' ], costs: [ [ amount: [ usd: 0 ], unit: 'month' ] ] ] ],
609612
[ id: mongoId, name: 'mongodb', description: 'MongoDB NoSQL database', metadata: [ displayName: 'MongoDB', bullets: [ 'MongoDB 2.6', '1GB memory pool', '10GB storage' ], costs: [ [ amount: [ usd: 0.02 ], unit: 'hour' ] ] ] ],
613+
[ id: cassId, name: 'cassandra', description: 'Cassandra NoSQL database', metadata: [ displayName: 'Cassandra', bullets: [ 'Cassandra 2.1', '2GB memory pool', '10GB storage' ], costs: [ [ amount: [ usd: 0 ], unit: 'month' ] ] ] ],
610614
[ id: oraId, name: 'oracle', description: 'Oracle database', metadata: [ displayName: 'Oracle', bullets: [ 'Oracle 11gR2 XE','1GB memory pool', '10GB storage' ], costs: [ [ amount: [ usd: 0 ], unit: 'month' ] ] ] ],
611615
[ id: rmqId, name: 'rabbitmq', description: 'RabbitMQ messaging broker', metadata: [ displayName: 'RabbitMQ', bullets: [ 'RabbitMQ 3.3', '1GB persistence' ], costs: [ [ amount: [ usd: 0 ], unit: 'month' ] ] ] ]
612616
]
@@ -718,6 +722,7 @@ class BrokerController {
718722
case 'postgresql': args = 'postgres'; break // TODO introduce image that has password setup for postgres admin user
719723
case 'mongodb': args = "-e \"MONGOD_OPTIONS=--nojournal --smallfiles --noprealloc --auth\" -e MONGO_ROOT_PASSWORD=$pass arkadi/mongodb"; break
720724
//case 'mongodb': args = 'mongo mongod --nojournal --smallfiles --noprealloc'; break -- _/mongo image has no admin password
725+
case 'cassandra': args = "arkadi/cassandra"; break // based on poklet/cassandra but with PasswordAuthenticator and CassandraAuthorizer
721726
case 'oracle': args = "alexeiled/docker-oracle-xe-11g"; break
722727
case 'rabbitmq': args = "-e RABBITMQ_PASS=$pass tutum/rabbitmq"; break
723728
default:
@@ -881,6 +886,19 @@ class BrokerController {
881886
creds = [ uri: "mongodb://$ip:$port/$db", host: ip, port: port, username: user, password: pass ]
882887
break
883888

889+
case 'cassandra':
890+
def (cluster, cass) = cassandra(ip, port, adminPass)
891+
try {
892+
cass.execute("create keyspace $db with replication = {'class': 'SimpleStrategy', 'replication_factor': 1}")
893+
cass.execute("create user $user with password '$pass'")
894+
cass.execute("grant all on keyspace $db to $user")
895+
} finally {
896+
cass.closeAsync()
897+
cluster.closeAsync()
898+
}
899+
creds = [ uri: "cassandra://$ip:$port/$db", host: ip, port: port, username: user, password: pass ]
900+
break
901+
884902
case 'oracle':
885903
db = user
886904
pass = pass.substring(0, 16)
@@ -912,6 +930,25 @@ class BrokerController {
912930
}
913931
}
914932

933+
def cassandra(String ip, int port, String adminPass) {
934+
// http://www.datastax.com/drivers/java/2.0/com/datastax/driver/core/Cluster.Builder.html#addContactPointsWithPorts(java.util.Collection)
935+
// ... if the Cassandra nodes are behind a router and are not accessed directly. Note that if you are in this situation (Cassandra nodes
936+
// are behind a router, not directly accessible), you almost surely want to provide a specific AddressTranslater (through
937+
// withAddressTranslater(com.datastax.driver.core.policies.AddressTranslater)) to translate actual Cassandra node addresses to the
938+
// addresses the driver should use, otherwise the driver will not be able to auto-detect new nodes (and will generally not function optimally).
939+
def builder = Cluster.builder().addContactPointsWithPorts([new java.net.InetSocketAddress(ip, port)])
940+
def cluster = builder.withCredentials('cassandra', adminPass).build()
941+
try {
942+
[cluster, cluster.connect()]
943+
} catch (e) {
944+
log.info('Cannot authenticate as `cassandra` user, assuming default password must be changed: ' + e.message)
945+
cluster = builder.withCredentials('cassandra', 'cassandra').build()
946+
def cass = cluster.connect()
947+
cass.execute("alter user cassandra with password '$adminPass'")
948+
[cluster, cass]
949+
}
950+
}
951+
915952
def unbind() {
916953
if (check(request, params)) return
917954
// TODO erase credentials

0 commit comments

Comments
 (0)