1. Getting Started

1.1. Overview

The goal of this document is to provide comprehensive reference documentation for programmers using Embedded Cassandra.

1.1.1. Introducing

Embedded Cassandra provides an easy way to start and stop Apache Cassandra as an embedded database.

Primary features are:

  • Support different versions.

  • Supports multiple platforms: Windows, Linux and OSX.

  • Provides different extensions for popular frameworks: JUnit4, JUnit5, TestNG, Spring Framework.

1.1.2. Getting Help

Ask Embedded Cassandra related questions on Stack Overflow.

1.1.3. Issues

Embedded Cassandra uses GitHub’s issue tracking system to report bugs and feature requests. If you want to raise an issue, please follow this link

1.1.4. License

Embedded Cassandra is released under the Apache License 2.0

1.1.5. Get Source

Embedded Cassandra repository can be found here

1.1.6. Build Source

Embedded Cassandra can be easily built with the maven wrapper. You also need JDK 1.8.

$ ./mvnw clean verify

1.1.7. Modules

Name

Description

embedded-cassandra

This module contains items that allows the Apache Cassandra to be started and stopped.

embedded-cassandra-annotations

This module contains JSR305 annotations.

embedded-cassandra-api

This module contains Embedded Cassandra API classes.

embedded-cassandra-commons

This module contains Embedded Cassandra common classes.

embedded-cassandra-docs

This module contains Embedded Cassandra Reference Documentation.

embedded-cassandra-junit4-test

This module contains Embedded Cassandra JUnit4 classes.

embedded-cassandra-junit5-test

This module contains Embedded Cassandra JUnit5 classes.

embedded-cassandra-spring-test

This module contains Embedded Cassandra Spring classes.

embedded-cassandra-testng-test

This module contains Embedded Cassandra TestNG classes.

embedded-cassandra-mock

This module contains Embedded Cassandra Mock classes.

1.1.8. Contributing to Embedded Cassandra

Embedded Cassandra welcomes contributions from everyone.

Contributions to Embedded Cassandra should be made in the form of GitHub pull requests.

Pull Request Checklist
  • Branch from the master branch and, if needed, rebase to the current master branch before submitting your pull request.

  • Commits should be as small as possible.

  • Add tests relevant to the fixed bug or new feature.

1.2. Quick Start

1.2.1. Maven

<dependency>
    <groupId>com.github.nosan</groupId>
    <artifactId>embedded-cassandra</artifactId>
    <version>3.1.0</version>
</dependency>

1.2.2. Gradle

compile group: 'com.github.nosan', name: 'embedded-cassandra', version: '3.1.0'

1.2.3. Quick Start

The Apache Cassandra can be started using the following lines of code:

import com.github.nosan.embedded.cassandra.EmbeddedCassandraFactory;
import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.api.connection.DefaultCassandraConnectionFactory;
import com.github.nosan.embedded.cassandra.api.cql.CqlDataSet;

public class QuickStart {

    public static void main(String[] args) {
        EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
        Cassandra cassandra = cassandraFactory.create();
        cassandra.start();
        DefaultCassandraConnectionFactory cassandraConnectionFactory = new DefaultCassandraConnectionFactory();
        try (CassandraConnection connection = cassandraConnectionFactory.create(cassandra)) {
            CqlDataSet.ofClasspaths("schema.cql").forEachStatement(connection::execute);
        }
        finally {
            cassandra.stop();
        }
    }

}
schema.cql
CREATE KEYSPACE test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1}
The first start can take a while because Apache Casandra must be initialized. Current implementation downloads the archive just once and then initialize Apache Cassandra with it.

2. Features

This section describes key features that you may want to use and customize.

2.1. Configuration

This section covers how to configure Embedded Cassandra.

2.1.1. Configure Version

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.setArtifact(Artifact.ofVersion("3.11.9"));
Default version is 3.11.9

2.1.2. Configure Config

Sets Cassandra’s configuration file (cassandra.yaml)

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.setConfig(new ClassPathResource("cassandra.yaml"));

2.1.3. Configure Config Properties

These properties override any Cassandra’s properties in the (cassandra.yaml).

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.getConfigProperties().put("start_rpc", false);
More about configuration properties here

2.1.4. Configure Rack Config

Sets Cassandra’s rack properties (cassandra-rackdc.properties)

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.setRackConfig(new ClassPathResource("cassandra-rackdc.properties"));

2.1.5. Configure Topology Config

Sets Cassandra’s topology properties (cassandra-topology.properties)

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.setTopologyConfig(new ClassPathResource("cassandra-topology.properties"));

2.1.6. Configure System Properties

System properties that should be passed to Cassandra’s process.

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.getSystemProperties().put("cassandra.start_rpc", false);
More about startup parameters you can read here

2.1.7. Configure Environment Variables

Environment variables that should be passed to Cassandra’s process.

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.getEnvironmentVariables().put("JAVA_HOME", System.getenv("JAVA_HOME"));

2.1.8. Configure JVM Options

JVM options that should be passed to Cassandra’s process.

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.getJvmOptions().addAll(Arrays.asList("-Xms512m", "-Xmx512m"));

2.1.9. Configure Java Home

Sets the Java Home. This home used by Cassandra’s process.

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.setJavaHome(Paths.get(System.getenv("JAVA_HOME")));

2.1.10. Configure SSL

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
Path keystore = new ClassPathResource("keystore.node0").toPath();
Path truststore = new ClassPathResource("truststore.node0").toPath();
Map<String, Object> sslOptions = new LinkedHashMap<>();
sslOptions.put("enabled", true);
sslOptions.put("require_client_auth", true);
sslOptions.put("optional", false);
sslOptions.put("keystore", keystore.toString());
sslOptions.put("keystore_password", "cassandra");
sslOptions.put("truststore", truststore.toString());
sslOptions.put("truststore_password", "cassandra");
cassandraFactory.getConfigProperties().put("client_encryption_options", sslOptions);

2.1.11. Configure Authentication/Authorization

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.getConfigProperties().put("authenticator", "PasswordAuthenticator");
cassandraFactory.getConfigProperties().put("authorizer", "CassandraAuthorizer");
cassandraFactory.getSystemProperties().put("cassandra.superuser_setup_delay_ms", 0);

2.1.12. Configure Ports

By default, EmbeddedCassandra is running on default ports. There are several methods that can be used to set ports.

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
//set random ports
//if start_native_transport = true
cassandraFactory.setPort(0);
//if client encryption options enabled
cassandraFactory.setSslPort(0);
//set cassandra.jmx.local.port
cassandraFactory.setJmxLocalPort(0);
//if rpc_start = true
cassandraFactory.setRpcPort(0);
cassandraFactory.setStoragePort(0);
//if server encryption options enabled
cassandraFactory.setSslStoragePort(0);
//only for Cassandra version >=4
Map<String, Object> result = new LinkedHashMap<>();
result.put("class_name", "org.apache.cassandra.locator.SimpleSeedProvider");
result.put("parameters", Collections.singletonList(Collections.singletonMap("seeds",
        //localhost == listen_address
        //0 means that set storage_port
        "localhost:0")));
cassandraFactory.getConfigProperties().put("seed_provider", Collections.singletonList(result));
Use 0 for a random port.

2.1.13. Configure Proxy

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
RemoteArtifact artifact = new RemoteArtifact(Version.of("3.11.9"));
artifact.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("my.proxy", 80)));
cassandraFactory.setArtifact(artifact);

2.2. CQL Support

Embedded Cassandra project provides high-level support for CQL scripts.

2.2.1. Load Cql Statements

CQL statements can be easily loaded from various sources.

void classpaths() {
    CqlDataSet dataSet = CqlDataSet.ofClasspaths("schema.cql");
    List<String> statements = dataSet.getStatements();
    //...
}

void resources() {
    CqlDataSet dataSet = CqlDataSet.ofResources(new ClassPathResource("schema.cql"));
    List<String> statements = dataSet.getStatements();
    //...
}

void strings() {
    CqlDataSet dataSet = CqlDataSet.ofStrings(
            "CREATE KEYSPACE test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1}");
    List<String> statements = dataSet.getStatements();
    //...
}

void scripts() {
    CqlDataSet dataSet = CqlDataSet.ofScripts(CqlScript.ofClasspath("schema.cql"),
            CqlScript.ofClasspath("schema1.cql"));
    List<String> statements = dataSet.getStatements();
    //...
}
schema.cql
CREATE KEYSPACE test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1}
More about CQL you can find here

3. Testing

Embedded Cassandra provides a number of extensions to help when testing your application.

3.1. Using JUnit5

Cassandra can be easily started using CassandraExtension. This extension allows the Cassandra to be started and stopped. Cassandra will be started only once before any test method is executed and stopped after the last test method has executed.

3.1.1. Maven

<dependency>
    <groupId>com.github.nosan</groupId>
    <artifactId>embedded-cassandra-junit5-test</artifactId>
    <version>3.1.0</version>
</dependency>

3.1.2. Gradle

compile group: 'com.github.nosan', name: 'embedded-cassandra-junit5-test', version: '3.1.0'

3.1.3. Run Cassandra JUnit5

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.junit5.test.CassandraExtension;

class CassandraJUnit5Tests {

    @RegisterExtension
    static final CassandraExtension CASSANDRA_EXTENSION = new CassandraExtension();

    @Test
    void test() {
        Cassandra cassandra = CASSANDRA_EXTENSION.getCassandra();
        CassandraConnection cassandraConnection = CASSANDRA_EXTENSION.getCassandraConnection();
    }

}

The following properties will be added to System Properties after Cassandra has started:

  • embedded.cassandra.version

  • embedded.cassandra.address

  • embedded.cassandra.port

  • embedded.cassandra.ssl-port

  • embedded.cassandra.rpc-port

3.1.4. Customize Default Cassandra Factory

It is possible to customize default EmbeddedCassandraFactory via (CassandraFactoryCustomizer<T>) customizers.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.junit5.test.CassandraExtension;

class CassandraDefaultFactoryCustomizerJUnit5Tests {

    @RegisterExtension
    static final CassandraExtension CASSANDRA_EXTENSION = new CassandraExtension(
            cassandraFactory -> cassandraFactory.setPort(9042));

    @Test
    void test() {
        Cassandra cassandra = CASSANDRA_EXTENSION.getCassandra();
        CassandraConnection cassandraConnection = CASSANDRA_EXTENSION.getCassandraConnection();
    }

}

3.1.5. Configure Custom Cassandra Factory

Besides that, custom CassandraFactory also can be used to control the Cassandra instance.

import java.time.Duration;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import com.github.nosan.embedded.cassandra.EmbeddedCassandraBuilder;
import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.junit5.test.CassandraExtension;

class CassandraCustomFactoryJUnit5Tests {

    @RegisterExtension
    static final CassandraExtension CASSANDRA_EXTENSION = new CassandraExtension()
            .withCassandraFactory(new EmbeddedCassandraBuilder().withTimeout(Duration.ofSeconds(30)));

    @Test
    void test() {
        Cassandra cassandra = CASSANDRA_EXTENSION.getCassandra();
        CassandraConnection cassandraConnection = CASSANDRA_EXTENSION.getCassandraConnection();
    }

}

3.1.6. Configure Cql Scripts

Apache Cassandra can be initialized with CqlDataSet.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.api.cql.CqlDataSet;
import com.github.nosan.embedded.cassandra.junit5.test.CassandraExtension;

class CassandraCqlDataSetJUnit5Tests {

    @RegisterExtension
    static final CassandraExtension CASSANDRA_EXTENSION = new CassandraExtension()
            .withCqlDataSet(CqlDataSet.ofClasspaths("schema.cql"));

    @Test
    void test() {
        Cassandra cassandra = CASSANDRA_EXTENSION.getCassandra();
        CassandraConnection cassandraConnection = CASSANDRA_EXTENSION.getCassandraConnection();
    }

}
schema.cql
CREATE KEYSPACE test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1}

3.1.7. Configure Custom Cassandra Connection Factory

CassandraConnection which is provided by CassandraExtension can be configured via CassandraConnectionFactory.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.api.connection.CqlSessionCassandraConnectionBuilder;
import com.github.nosan.embedded.cassandra.junit5.test.CassandraExtension;

class CassandraConnectionJUnit5Tests {

    @RegisterExtension
    static final CassandraExtension CASSANDRA_EXTENSION = new CassandraExtension()
            .withCassandraConnectionFactory(new CqlSessionCassandraConnectionBuilder()
                    .withSslEnabled(true));

    @Test
    void test() {
        Cassandra cassandra = CASSANDRA_EXTENSION.getCassandra();
        CassandraConnection cassandraConnection = CASSANDRA_EXTENSION.getCassandraConnection();
    }

}

3.2. Using JUnit4

Cassandra can be started via CassandraRule. CassandraRule is TestRule that allows the Cassandra to be started and stopped. Cassandra declared as static field with a @ClassRule annotation will be started only once before any test method is executed and stopped after the last test method has executed. Cassandra declared as instance field with a @Rule annotation will be started and stopped for every test method.

3.2.1. Maven

<dependency>
    <groupId>com.github.nosan</groupId>
    <artifactId>embedded-cassandra-junit4-test</artifactId>
    <version>3.1.0</version>
</dependency>

3.2.2. Gradle

compile group: 'com.github.nosan', name: 'embedded-cassandra-junit4-test', version: '3.1.0'

3.2.3. Run Cassandra JUnit4

import org.junit.ClassRule;
import org.junit.Test;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.junit4.test.CassandraRule;

public class CassandraJUnit4Tests {

    @ClassRule
    public static final CassandraRule CASSANDRA_RULE = new CassandraRule();

    @Test
    public void testCassandra() {
        Cassandra cassandra = CASSANDRA_RULE.getCassandra();
        CassandraConnection cassandraConnection = CASSANDRA_RULE.getCassandraConnection();
    }

}

The following properties will be added to System Properties after Cassandra has started:

  • embedded.cassandra.version

  • embedded.cassandra.address

  • embedded.cassandra.port

  • embedded.cassandra.ssl-port

  • embedded.cassandra.rpc-port

3.2.4. Customize Default Cassandra Factory

Default EmbeddedCassandraFactory can be customized via (CassandraFactoryCustomizer<T>) customizers.

import org.junit.ClassRule;
import org.junit.Test;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.junit4.test.CassandraRule;

public class CassandraDefaultFactoryCustomizerJUnit4Tests {

    @ClassRule
    public static final CassandraRule CASSANDRA_RULE = new CassandraRule(
            cassandraFactory -> cassandraFactory.setPort(9042));

    @Test
    public void testCassandra() {
        Cassandra cassandra = CASSANDRA_RULE.getCassandra();
        CassandraConnection cassandraConnection = CASSANDRA_RULE.getCassandraConnection();
    }

}

3.2.5. Configure Custom Cassandra Factory

There is also possible to use your own CassandraFactory.

import org.junit.ClassRule;
import org.junit.Test;

import com.github.nosan.embedded.cassandra.EmbeddedCassandraBuilder;
import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.artifact.Artifact;
import com.github.nosan.embedded.cassandra.junit4.test.CassandraRule;

public class CassandraCustomFactoryJUnit4Tests {

    @ClassRule
    public static final CassandraRule CASSANDRA_RULE = new CassandraRule()
            .withCassandraFactory(new EmbeddedCassandraBuilder()
                    .withArtifact(Artifact.ofVersion("3.11.9")));

    @Test
    public void testCassandra() {
        Cassandra cassandra = CASSANDRA_RULE.getCassandra();
        CassandraConnection cassandraConnection = CASSANDRA_RULE.getCassandraConnection();
    }

}

3.2.6. Configure Cql Scripts

CassandraRule provides a way to initialize Apache Cassandra with CqlDataSet.

import org.junit.ClassRule;
import org.junit.Test;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.api.cql.CqlDataSet;
import com.github.nosan.embedded.cassandra.junit4.test.CassandraRule;

public class CassandraCqlDataSetJUnit4Tests {

    @ClassRule
    public static final CassandraRule CASSANDRA_RULE = new CassandraRule()
            .withCqlDataSet(CqlDataSet.ofClasspaths("schema.cql"));

    @Test
    public void testCassandra() {
        Cassandra cassandra = CASSANDRA_RULE.getCassandra();
        CassandraConnection cassandraConnection = CASSANDRA_RULE.getCassandraConnection();
    }

}
schema.cql
CREATE KEYSPACE test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1}

3.2.7. Configure Custom Cassandra Connection Factory

CassandraConnection which is provided by CassandraRule can be configured via CassandraConnectionFactory.

import org.junit.ClassRule;
import org.junit.Test;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.api.connection.ClusterCassandraConnectionBuilder;
import com.github.nosan.embedded.cassandra.junit4.test.CassandraRule;

public class CassandraConnectionJUnit4Tests {

    @ClassRule
    public static final CassandraRule CASSANDRA_RULE = new CassandraRule()
            .withCassandraConnectionFactory(new ClusterCassandraConnectionBuilder()
                    .withUsername("cassandra")
                    .withPassword("cassandra"));

    @Test
    public void testCassandra() {
        Cassandra cassandra = CASSANDRA_RULE.getCassandra();
        CassandraConnection cassandraConnection = CASSANDRA_RULE.getCassandraConnection();
    }

}

3.3. Using TestNG

To start Cassandra with TestNG, AbstractCassandraTests class has to be extended. AbstractCassandraTests class allows the Cassandra to be started and stopped. Cassandra will be started only once before any test method is executed and stopped after the last test method has executed.

3.3.1. Maven

<dependency>
    <groupId>com.github.nosan</groupId>
    <artifactId>embedded-cassandra-testng-test</artifactId>
    <version>3.1.0</version>
</dependency>

3.3.2. Gradle

compile group: 'com.github.nosan', name: 'embedded-cassandra-testng-test', version: '3.1.0'

3.3.3. Run Cassandra TestNG

import org.testng.annotations.Test;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.testng.AbstractCassandraTests;

public class CassandraTestNGTests extends AbstractCassandraTests {

    @Test
    public void test() {
        Cassandra cassandra = getCassandra();
        CassandraConnection cassandraConnection = getCassandraConnection();
    }

}

The following properties will be added to System Properties after Cassandra has started:

  • embedded.cassandra.version

  • embedded.cassandra.address

  • embedded.cassandra.port

  • embedded.cassandra.ssl-port

  • embedded.cassandra.rpc-port

3.3.4. Customize Default Cassandra Factory

AbstractCassandraTests also provides a way to customize a default EmbeddedCassandraFactory via (CassandraFactoryCustomizer<T>) customizers.

import org.testng.annotations.Test;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.testng.AbstractCassandraTests;

public class CassandraDefaultFactoryCustomizerTestNGTests extends AbstractCassandraTests {

    public CassandraDefaultFactoryCustomizerTestNGTests() {
        super(cassandraFactory -> cassandraFactory.setPort(9042));
    }

    @Test
    public void test() {
        Cassandra cassandra = getCassandra();
        CassandraConnection cassandraConnection = getCassandraConnection();
    }

}

3.3.5. Configure Custom Cassandra Factory

The same as for JUnit4 and JUnit5 it is possible to set your own CassandraFactory.

import org.testng.annotations.Test;

import com.github.nosan.embedded.cassandra.EmbeddedCassandraBuilder;
import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.commons.io.ClassPathResource;
import com.github.nosan.embedded.cassandra.testng.AbstractCassandraTests;

public class CassandraCustomFactoryTestNGTests extends AbstractCassandraTests {

    public CassandraCustomFactoryTestNGTests() {
        setCassandraFactory(new EmbeddedCassandraBuilder()
                .withConfig(new ClassPathResource("cassandra.yaml")));
    }

    @Test
    public void test() {
        Cassandra cassandra = getCassandra();
        CassandraConnection cassandraConnection = getCassandraConnection();
    }

}

3.3.6. Configure Cql Scripts

AbstractCassandraTests also provides a way to initialize Apache Cassandra with CqlDataSet.

import org.testng.annotations.Test;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.api.cql.CqlDataSet;
import com.github.nosan.embedded.cassandra.testng.AbstractCassandraTests;

public class CassandraCqlDataSetTestNGTests extends AbstractCassandraTests {

    public CassandraCqlDataSetTestNGTests() {
        setCqlDataSet(CqlDataSet.ofClasspaths("schema.cql"));
    }

    @Test
    public void test() {
        Cassandra cassandra = getCassandra();
        CassandraConnection cassandraConnection = getCassandraConnection();
    }

}
schema.cql
CREATE KEYSPACE test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1}

3.3.7. Configure Custom Cassandra Connection Factory

CassandraConnection which is provided by AbstractCassandraTests can be configured via CassandraConnectionFactory.

import org.testng.annotations.Test;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.api.connection.CqlSessionCassandraConnectionFactory;
import com.github.nosan.embedded.cassandra.testng.AbstractCassandraTests;

public class CassandraConnectionTestNGTests extends AbstractCassandraTests {

    public CassandraConnectionTestNGTests() {
        setCassandraConnectionFactory(new CqlSessionCassandraConnectionFactory());
    }

    @Test
    public void test() {
        Cassandra cassandra = getCassandra();
        CassandraConnection cassandraConnection = getCassandraConnection();
    }

}

3.4. Using Spring Test

For running Apache Cassandra using Spring Test, @EmbeddedCassandra annotation has to be used. This annotation allows the Cassandra to be started and stopped.

3.4.1. Maven

<dependency>
    <groupId>com.github.nosan</groupId>
    <artifactId>embedded-cassandra-spring-test</artifactId>
    <version>3.1.0</version>
</dependency>

3.4.2. Gradle

compile group: 'com.github.nosan', name: 'embedded-cassandra-spring-test', version: '3.1.0'

3.4.3. Run Cassandra Spring Test

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.spring.test.EmbeddedCassandra;

@EmbeddedCassandra
@ExtendWith(SpringExtension.class)
class CassandraSpringTests {

    @Test
    void testCassandra(@Autowired Cassandra cassandra, @Autowired CassandraConnection cassandraConnection) {
    }

}

The following properties will be added to Environment after Cassandra has started:

  • embedded.cassandra.version

  • embedded.cassandra.address

  • embedded.cassandra.port

  • embedded.cassandra.ssl-port

  • embedded.cassandra.rpc-port

3.4.4. Configure Custom Cassandra Factory

It is possible to register you own CassandraFactory to control Cassandra instance.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import com.github.nosan.embedded.cassandra.EmbeddedCassandraFactory;
import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.CassandraFactory;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.spring.test.EmbeddedCassandra;

@EmbeddedCassandra
@ExtendWith(SpringExtension.class)
class CassandraCustomFactoryTests {

    @Test
    void testCassandra(@Autowired Cassandra cassandra, @Autowired CassandraConnection cassandraConnection) {
        //
    }

    @Configuration
    static class TestConfig {

        @Bean
        CassandraFactory cassandraFactory() {
            EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
            //configure me
            return cassandraFactory;
        }

    }

}

3.4.5. Customize Default Cassandra Factory

Additional to the above, there is also possible to register CassandraFactoryCustomizer<T> @Bean(s) to customize a default EmbeddedCassandraFactory before the Cassandra itself is started.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import com.github.nosan.embedded.cassandra.EmbeddedCassandraFactory;
import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.CassandraFactoryCustomizer;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.spring.test.EmbeddedCassandra;

@EmbeddedCassandra
@ExtendWith(SpringExtension.class)
class CassandraDefaultFactoryCustomizerSpringTests {

    @Test
    void test(@Autowired Cassandra cassandra, @Autowired CassandraConnection cassandraConnection) {
    }

    @Configuration
    static class TestConfig {

        @Bean
        public CassandraFactoryCustomizer<EmbeddedCassandraFactory> portCasandraFactoryCustomizer() {
            return cassandraFactory -> cassandraFactory.setPort(9042);
        }

    }

}

3.4.6. Configure Cql Scripts

CQL Scripts are executed by CassandraConnection. By default, CassandraConnection implementation is detected based on the classpath, however, CassandraConnectionFactory can be registered as a @Bean to control scripts execution.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.spring.test.EmbeddedCassandra;

@EmbeddedCassandra(scripts = "schema.cql")
@ExtendWith(SpringExtension.class)
class CassandraCqlSpringTests {

    @Test
    void testCassandra(@Autowired Cassandra cassandra, @Autowired CassandraConnection cassandraConnection) {
    }

}
schema.cql
CREATE KEYSPACE test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1}

3.4.7. Configure Custom Cassandra Connection Factory

CassandraConnectionFactory bean can be registered to control CassandraConnection instance.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.api.connection.CqlSessionCassandraConnectionFactory;
import com.github.nosan.embedded.cassandra.spring.test.EmbeddedCassandra;

@EmbeddedCassandra
@ExtendWith(SpringExtension.class)
class CassandraConnectionSpringTests {

    @Test
    void testCassandra(@Autowired Cassandra cassandra, @Autowired CassandraConnection cassandraConnection) {
    }

    @Configuration
    static class TestConfig {

        @Bean
        CqlSessionCassandraConnectionFactory cqlSessionCassandraConnectionFactory() {
            return new CqlSessionCassandraConnectionFactory();
        }

    }

}

3.4.8. Using Spring Boot Test

There is no much difference between Spring Boot Test and Spring Test, hence, to start Cassandra, @EmbeddedCassandra can be used.

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import com.github.nosan.embedded.cassandra.api.Cassandra;
import com.github.nosan.embedded.cassandra.api.connection.CassandraConnection;
import com.github.nosan.embedded.cassandra.spring.test.EmbeddedCassandra;

@EmbeddedCassandra(scripts = "schema.cql")
@SpringBootTest(properties = {"spring.data.cassandra.port=${embedded.cassandra.port}",
        "spring.data.cassandra.contact-points=${embedded.cassandra.address}",
        "spring.data.cassandra.keyspace-name=test"})
class CassandraSpringBootTests {

    @Test
    void testCassandra(@Autowired Cassandra cassandra, @Autowired CassandraConnection cassandraConnection) {

    }

}
schema.cql
CREATE KEYSPACE test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1}
${embedded.cassandra.port} and ${embedded.cassandra.address} properties are exposed by @EmbeddedCassandra.

4. ‘How-to’ guides

This section provides answers to some common ‘how do I do that…​’ questions that often arise when using Embedded Cassandra.

4.1. Running more than one Cassandra instance

There is possible to start more than one Cassandra instance

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.setPort(0);
cassandraFactory.setSslPort(0); // if SSL client options enabled
cassandraFactory.setRpcPort(0);
cassandraFactory.setJmxLocalPort(0);
cassandraFactory.setStoragePort(0);
cassandraFactory.setSslStoragePort(0); // // if SSL server options enabled

Cassandra cassandra1 = cassandraFactory.create();
Cassandra cassandra2 = cassandraFactory.create();

cassandra1.start();
cassandra2.start();

try {
    //...
}
finally {
    cassandra1.stop();
    cassandra2.stop();
}

4.2. Using Local Archive

Cassandra can be started with your own archive file.

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
Version version = Version.of("3.11.9");
ClassPathResource archiveFile = new ClassPathResource("apache-cassandra-3.11.9-bin.tar.gz");
cassandraFactory.setArtifact(new ArchiveArtifact(version, archiveFile));
Cassandra cassandra = cassandraFactory.create();
cassandra.start();
try {
    //..
}
finally {
    cassandra.stop();
}

4.3. Using Local Directory

There is also possible to start/stop Cassandra using a local directory.

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
Path directory = Paths.get("<path to Cassandra's home>");
Version version = Version.of("3.11.9");
cassandraFactory.setArtifact(new DefaultArtifact(version, directory));
Cassandra cassandra = cassandraFactory.create();
cassandra.start();
try {
    //..
}
finally {
    cassandra.stop();
}

4.4. Run with Java > 1.8

There are several ways to use Java > 1.8:

  • Use Apache-Cassandra 4.X.X version

  • Use a custom java home directory with Java 8.

EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.setArtifact(Artifact.ofVersion("4.0-beta2"));
EmbeddedCassandraFactory cassandraFactory = new EmbeddedCassandraFactory();
cassandraFactory.setJavaHome(Paths.get("JAVA8_HOME"));

Copyright © 2019-2020