io.teknek:farsandra-core

Cassandra testing framework

License

License

GroupId

GroupId

io.teknek
ArtifactId

ArtifactId

farsandra-core
Last Version

Last Version

0.0.9
Release Date

Release Date

Type

Type

jar
Description

Description

Cassandra testing framework
Source Code Management

Source Code Management

https://github.com/edwardcapriolo/farsandra

Download farsandra-core

How to add to project

<!-- https://jarcasting.com/artifacts/io.teknek/farsandra-core/ -->
<dependency>
    <groupId>io.teknek</groupId>
    <artifactId>farsandra-core</artifactId>
    <version>0.0.9</version>
</dependency>
// https://jarcasting.com/artifacts/io.teknek/farsandra-core/
implementation 'io.teknek:farsandra-core:0.0.9'
// https://jarcasting.com/artifacts/io.teknek/farsandra-core/
implementation ("io.teknek:farsandra-core:0.0.9")
'io.teknek:farsandra-core:jar:0.0.9'
<dependency org="io.teknek" name="farsandra-core" rev="0.0.9">
  <artifact name="farsandra-core" type="jar" />
</dependency>
@Grapes(
@Grab(group='io.teknek', module='farsandra-core', version='0.0.9')
)
libraryDependencies += "io.teknek" % "farsandra-core" % "0.0.9"
[io.teknek/farsandra-core "0.0.9"]

Dependencies

compile (2)

Group / Artifact Type Version
org.apache.commons : commons-compress jar 1.6
log4j : log4j jar 1.2.15

test (3)

Group / Artifact Type Version
org.apache.cassandra : cassandra-thrift jar 2.2.3
org.apache.thrift : libthrift jar 0.9.3
junit : junit jar 4.8.2

Project Modules

There are no modules declared in this project.

farsandra Build status

Slogan "Keep Cassandra close, but your classpath closer"

Run cassandra inside a java project without bring server deps into client classpath.

Farsandra works by downloading and automatically unpacking a cassandra inside $HOME/.farsandra. It then uses some clever string replacement to edit the yaml file, and start the service in the foreground.

You may be saying to yourself: Why would I want to do that? Can't I run cassandra embedded? Well you could, but C* is not re-entrant. You really can't start and stop it, and it is awkward to clean it out each test. Besides that it brings several libraries onto your classpath which you do not need from a client prospective and can cause classpath issues with your code.

Usage

Generally you will be using farsandra inside a unit test.

Farsandra fs = new Farsandra();
fs.withVersion("2.0.3");
...
fs.start();
started.await();
System.out.println("Thrift open. Party time!");
Thread.sleep(10000);
fs.getManager().destroy();

Customizing Cassandra.yaml

Farsandra has methods to allow setting the common parameters inside the yaml file. A simple approach is to append lines ot the bottom.

fs.appendLineToYaml("#this means nothing");

Another option is to search replace

fs.withYamlReplacement("# NOTE:", "# deNOTE:");

Customizing Cassandra-env.sh

We can also append lines to the env file.

fs.appendLinesToEnv("#this also does nothing");

Or do replacements

fs.withEnvReplacement("#MALLOC_ARENA_MAX=4", "#MALLOC_ARENA_MAX=wombat");

Putting listeners on the output and error streams

fs.getManager().addOutLineHandler( new LineHandler(){
    @Override
    public void handleLine(String line) {
      System.out.println("out "+line);
      if (line.contains("Listening for thrift clients...")){
        started.countDown();
      }
    }
  }
);
fs.getManager().addErrLineHandler( new LineHandler(){
  @Override
  public void handleLine(String line) {
    System.out.println("err "+line);
  }
});

Adding an handler to manage process termination

fs.getManager().addProcessHandler(new ProcessHandler() {
    @Override
    public void handleTermination(int exitValue) {
        System.out.println("Cassandra terminated with exit value: " + exitValue);
        started.countDown();
    }
});

Puttingit all together

Farsandra fs = new Farsandra();
fs.withVersion("2.0.3");
fs.withCleanInstanceOnStart(true);
fs.withInstanceName("1");
fs.withCreateConfigurationFiles(true);
fs.withHost("localhost");
fs.withSeeds(Arrays.asList("localhost"));
final CountDownLatch started = new CountDownLatch(1);
fs.getManager().addOutLineHandler( new LineHandler(){
    @Override
    public void handleLine(String line) {
      System.out.println("out "+line);
      if (line.contains("Listening for thrift clients...")){
        started.countDown();
      }
    }
  }
);
fs.getManager().addErrLineHandler( new LineHandler(){
  @Override
  public void handleLine(String line) {
    System.out.println("err "+line);
  }
});
fs.getManager().addProcessHandler(new ProcessHandler() {
    @Override
    public void handleTermination(int exitValue) {
        System.out.println("Cassandra terminated with exit value: " + exitValue);
        started.countDown();
    }
});
fs.start();
started.await();
System.out.println("Thrift open. Party time!");
Thread.sleep(10000);
fs.getManager().destroy();

Farsandra Maven Plugin

The project also includes a Maven plugin that takes care of starting / stopping Farsandra (i.e. Cassandra) before and after the integration-test phase.

How to configure

In your pom.xml, you have to declare the plugin like this:

    <build>
        <plugins>
            <plugin>
                <groupId>org.gazzax.labs</groupId>
                <artifactId>farsandra-maven-plugin</artifactId>
                <version>0.1</version>
                <configuration>
                    <version>2.0.3</version>
                    <instanceName>target/cassandra</instanceName>
                    <stdOutEnabled>false</stdOutEnabled>
                    <stdErrEnabled>false</stdErrEnabled>
                </configuration>
                <executions>
                    <execution>
                        <id>start-cassandra</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>start</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>stop-cassandra</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

That's all: running a build in your project will trigger Farsandra respectively in the pre and post integration-test phases, starting and stopping the requested Cassandra version (see the version parameter) around your integration test suite.
The following table summarizes the configuration parameters available with the current version.

Name Description Default value
version The Cassandra version N.A. (mandatory)
cleanInstanceOnStart If true, cleans the instance directory true
instanceName The instance name, "target/cassandra"
createConfigurationFiles Creates the Cassandra configuration files true
host the instance listen address (hostname or IP) "localhost"
seeds A list of seed nodes ["localhost"]
port The RPC listening port N.A.
jmxPort The JMX listening port N.A
additionalEnvLines A list of Additional lines to be appended in Cassandra environment file N.A
additionalYamlLines A list of additional lines to be appended in Cassandra configuration (yaml) file N.A
yamlReplacements A map of key/value replacements pairs. The key is a line that will be replaced with the corresponding value in the cassandra.yaml configuration file N.A
javaHome The value of the JAVA_HOME environment variable N.A.
stdErrEnabled Enables / disables the standard err false
stdOutEnabled Enables / disables the standard out false

Versions

Version
0.0.9
0.0.8