Version 4

    Thanks to our friend Heiko Braun there is a way to embed and manage an Apache Cassandra cluster with WildFly.

    Let's see how we can do it and have a web application taking advantage of this, using this cluster.

    To follow this article you'll need Git, Apache Ant, Apache Maven, and WildFly 8.2.

     

    Let's build Cassandra WildFly extension

     

    The first step is to build Apache Cassandra itself :

     

    git clone  http://git-wip-us.apache.org/repos/asf/cassandra.git cassandra-trunk
    cd cassandra-trunk
    ant mvn-install
    
    
    
    
    
    

     

    Now we need to install WildFly

     

    curl http://download.jboss.org/wildfly/8.2.0.Final/wildfly-8.2.0.Final.tar.gz | tar zx && mv ~/wildfly-8.2.0.Final ~/wildfly
    export WILDFLY_HOME=~/wildfly
    
    
    
    
    
    

     

    Now we can build the WildFly Extension

     

    git clone git@github.com:rhq-project/wildfly-cassandra.git
    mvn clean install
    unzip target/wildfly-cassandra-module.zip -d $WILDFLY_HOME
    
    
    
    
    
    

     

    The Cassandra WildFly Extension provides a sample configuration file : standalone-cassandra.xml, which is a stripped down version of WildFly configuration file.

    This wouldn't let us run our web application, so instead we are going to edit the standalone.xml file to add the WildFly Cassandra Extension to it and thus be able to run wars (even if peace sells, who's buying?).

     

    <?xml version='1.0' encoding='UTF-8'?>
    <server xmlns="urn:jboss:domain:2.2">
        <extensions>
            ...
            <extension module="org.wildfly.extension.cassandra"/>
        </extensions>
        ...
        <profile>
            ...
            <subsystem xmlns="urn:wildfly:cassandra:1.0">
                <cluster name="WildflyCluster" seed-provider-class-name="org.apache.cassandra.locator.SimpleSeedProvider" seed-provider-seeds="${jboss.bind.address:127.0.0.1}" listen-address="${jboss.bind.address:127.0.0.1}" broadcast-address="${jboss.bind.address:127.0.0.1}" start-native-transport="true" start-rpc="true"/>
            </subsystem>
        </profile>
        ...
    </server>
    
    
    
    
    
    

    You can take the attached standalone.xml file which is the result of this editing.

    Now you can run WildFly which should also start Apache Cassandra with the following command :

    cd $WILDFLY_HOME/bin
    ./standalone.sh -b 127.0.0.1 -Dcassandra.boot_without_jna=true
    
    
    
    
    
    

    By launching a jboss-cli

    ./jboss-cli -c
    [standalone@localhost:9990 /] /subsystem=cassandra/cluster=WildflyCluster:read-resource(include-runtime=true)
    {
        "outcome" => "success",
        "result" => {
            "authenticator" => "AllowAllAuthenticator",
            "authorizer" => "AllowAllAuthorizer",
            "broadcast-address" => expression "${jboss.bind.address:127.0.0.1}",
            "client-encryption-enabled" => false,
            "commitlog-directory" => undefined,
            "commitlog-sync" => "periodic",
            "commitlog-sync-period-in-ms" => 10000,
            "data-file-directories" => undefined,
            "debug" => false,
            "endpoint-snitch" => "SimpleSnitch",
            "hinted-handoff-enabled" => true,
            "internode-authenticator" => "org.apache.cassandra.auth.AllowAllInternodeAuthenticator",
            "listen-address" => expression "${jboss.bind.address:127.0.0.1}",
            "native-transport-port" => 9042,
            "num-tokens" => 256,
            "partitioner" => "org.apache.cassandra.dht.Murmur3Partitioner",
            "request-scheduler" => "org.apache.cassandra.scheduler.NoScheduler",
            "rpc-port" => 9160,
            "saved-caches-directory" => undefined,
            "seed-provider-class-name" => "org.apache.cassandra.locator.SimpleSeedProvider",
            "seed-provider-seeds" => expression "${jboss.bind.address:127.0.0.1}",
            "server-encryption-enabled" => false,
            "start-native-transport" => true,
            "start-rpc" => true
        }
    }
    
    
    
    
    
    

    So now that we have an Apache Cassandra cluster running with our WildFly server, let's build and deploy our demo web application.

     

    Achilles without its tortoise

     

    The demo we are going to use is the Achilles Twitter Demo, a cool web application with Angular JS front end.

    Achilles is a full featured object mapper for Cassandra & CQL3. Achilles is using the Java Driver underneath and offers a pull panel of features like advanced CQL3 mapping, complete query API, support for CAS, bean validation, interceptors, etc.

    So let's build our web application:

    git clone git@github.com:doanduyhai/Achilles-Twitter-Demo.git
    mvn clean install -Dachilles.version=3.0.13
    
    
    
    
    
    

    We are overriding the Achilles version because there is a small bug in 3.0.11 that would prevent the demo to be run multiple times.

    In the demo code you might notice a WildFlyPersistenceManagerFactoryBean.java which, as its name doesn't show, is not WildFly specific ;o). This is using pure Achilles code to connect to the Apache Cassndra cluster started with WildFly.

     

    So now, we have a nice war waiting to be deployed but before doing that we need to create the keyspace for it in our running instance of Cassandra.

     

    Let's just do that:

    cassandra-trunk/bin/cqlsh
    Connected to WildflyCluster at 127.0.0.1:9042.
    [cqlsh 5.0.1 | Cassandra 3.0.0-SNAPSHOT | CQL spec 3.2.0 | Native protocol v3]
    Use HELP for help.
    cqlsh> CREATE KEYSPACE achilles WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1};
    cqlsh> exit
    
    
    
    
    
    

     

    Now we can deploy our war either by copying it to $WILDFLY_HOME/standalone/deployments or using the console (web or the cli).

    When the application has successfully deployed, go tohttp://127.0.0.1:8080/achillesTwitter/ and enjoy its scenarios.

     

    A big thanks to Heiko and DuyHai who helped me on the way to Cassandra.