I've been chatting with a few folks that run akka-persistence backed by cassandra using either the akka-persistence-cassandra project directly or via the Lagom micro services framework. These folks are often big fans of cassandra's peer to peer distributed architecture, it's availability and performance capabilities, it's active active geo-reduncancy, and it's scalability characteristics.

For a lot of these folks, running cassandra clusters is not their main passion. They'd rather spend time thinking about cqrs, event sourcing, actors, fancy scala things like @transient, and of course their business logic.

Zero Ops?

Today, you don't have to manage your own cassandra clusters, just use Astra!

Dependency fun

If you are a lagom or akka-persistence user trying to switch over to dbaas you may have landed at the astra java driver docs and seen that to use the secure-connect-bundle you need a recent version of the Cassandra Java Driver.

This is both true and not true, but first what even is this secure-connect-bundle thing?

What even is a secure-connect-bundle?

Connections to Astra are secure by default and support two way TLS over the wire. In order to achieve this, there are a multiple settings in the driver that need to be configured when instantiating your cql session.

To make things easier for users, Astra replaces this complex configuration with a single line that points to a compressed file (the secure-connect-bundle).

These are the Java driver versions that support scb (naturally newer dot versions will also support it):

DataStax Java driver for Apache Cassandra 4.x

<dependency>   <groupId>com.datastax.oss</groupId>   <artifactId>java-driver-core</artifactId>   <version>4.6.0</version> </dependency>

DataStax Java driver for Apache Cassandra 3.x

<dependency>   <groupId>com.datastax.cassandra</groupId>   <artifactId>cassandra-driver-core</artifactId>   <version>3.8.0</version> </dependency>

DSE Java 2.x

<dependency>   <groupId>com.datastax.dse</groupId>   <artifactId>dse-java-driver-core</artifactId>   <version>2.3.0</version> </dependency>

DSE Java 1.x

<dependency>   <groupId>com.datastax.dse</groupId>   <artifactId>dse-java-driver-core</artifactId>   <version>1.9.0</version> </dependency>

Source DataStax Drivers Docs

What if I can't upgrade?

Driver upgrades are often just a simple dependency change but with frameworks like `lagom` and `akka-persistence-cassandra` that take care of session management and querying for you, you need the library to upgrade *it's* depentencies.

`lagom` depends on `akka-persistence-cassandra` which inherits the java driver version from `alpakka`.

As of the time of this writing (July 8, 2020) `alpakka` is updated to java driver 4.6.1 (which supports SCB), unfortunately this is only on the master branch today (Chris Batey pushed the dependency in this PR https://github.com/akka/alpakka/pull/2320).

Until this makes it into a release and that release gets pulled by an `akka-persistence-cassandra` release and that gets pulled into a `lagom` release, we'll need a work around.

Workaround

I spent some time and figured out how to get current versions of `akka-persistence-cassandra` to connect to lagom.

application.conf

# Configuration for akka-persistence-cassandra
akka.persistence.cassandra {
  events-by-tag {
    bucket-size = "Day"
    # for reduced latency
    eventual-consistency-delay = 200ms
    flush-interval = 50ms
    pubsub-notification = on
    first-time-bucket = "20200115T00:00"
  }

  query {
    refresh-interval = 2s
  }

  # don't use autocreate in production
  journal.keyspace-autocreate = off
  journal.tables-autocreate = on
  snapshot.keyspace-autocreate = off
  snapshot.tables-autocreate = on
  journal.keyspace = "<ASTRA_KEYSPACE>"
  snapshot.keyspace = "<ASTRA_KEYSPACE>"
}

datastax-java-driver {
  advanced.reconnect-on-init = on
  basic.contact-points = [ "<ASTRA_DNS>:<ASTRA_CQL_PORT>" ]
  basic.load-balancing-policy.local-datacenter = caas-dc
  local-datacenter = caas-dc
  advanced.ssl-engine-factory {
    class = DefaultSslEngineFactory


    hostname-validation = false

    truststore-path = ./<PATH_TO_UNZIPPED_SCB>/trustStore.jks
    truststore-password = <TRUSTSTORE_PASSWORD>
    keystore-path = ./<PATH_TO_UNZIPPED_SCB>/identity.jks
    keystore-password = <KEYSTORE_PASSWORD>
  }

  advanced.auth-provider {
    class = PlainTextAuthProvider
    username = <ASTRA_C*_DB_USERNAME>
    password = <ASTRA_C*DB_PASSWORD>
  }

}

akka.projection.cassandra.offset-store.keyspace = "<ASTRA_KEYSPACE>"

First, download your secure-connect-bundle from the Astra UI and unzip it in a directory in the host where you are running akka-persistence-cassandra.

Next, take a look at config.json and cqlshrc. You can pull the fields in <> in the config above from these two files:

$ cat scb/config.json 
{
  "host": "<ASTRA_DNS>",
  "port": <ASTRA_METADATA_PORT_THIS_IS_NOT_THE_CQL_PORT>,
  "keyspace": "<ASTRA_KEYSPACE>",
  "localDC": "caas-dc",
  "caCertLocation": "./ca.crt",
  "keyLocation": "./key",
  "certLocation": "./cert",
  "keyStoreLocation": "./identity.jks",
  "keyStorePassword": "<ASTRA_KEYSTORE_PASSWORD>",
  "trustStoreLocation": "./trustStore.jks",
  "trustStorePassword": "<ASTRA_TRUSTSTORE_PASSWORD>",
  "csvLocation": "./data",
  "pfxCertPassword": "Lkl08BhEVq2e4bw6m"
}
$ cat scb/cqlshrc 
[connection]
hostname = <ASTRA_DNS>
port = <ASTRA_CQL_PORT>
ssl = true

[ssl]
validate = true
certfile = ./ca.crt
userkey = ./key
usercert = ./cert

The config is kept in this gist for your viewing and sharing pleasure and will be updated if things change.

Future

The DataStax team is working with the community to help get the driver version updated and documented. Stay tuned!