Cassandra plugin
Overview
The Cassandra plugin connects QALIPSIS to Apache Cassandra.
It enables interaction with Apache Cassandra clusters for testing distributed data storage and retrieval, as well as accessing data generated by the system under test. It provides three key steps: poll, save, and search.
This page explains configuration, important concepts, and provides examples of usage (poll, save, search).
- Technologies addressed
-
-
Cassandra: Apache Cassandra
-
Cassandra Query Language: The Cassandra Query Language (CQL)
-
DataStax Driver: DataStax
-
- Dependency
-
io.qalipsis.plugin:qalipsis-plugin-cassandra - Namespace in scenario
-
cassandra() - Client library
-
DataStax: a modern, feature-rich and highly tunable Java client library for Apache Cassandra using Cassandra’s binary protocol and Cassandra Query Language.
Supported steps
Poll step
The poll step within the Cassandra plugin polls the newest records from the database table.
- Ancestor
-
Scenario or Step
- Functionality
-
The
pollstep is created only once in a scenario; it is then used throughout the scenario. Thepollstep within the Cassandra plugin uses a strategy of “delivered at least once." That means the same logical record might be delivered more than once (for example, on retries or restarts).
To correctly and efficiently poll only new data, the plugin uses:-
An ORDER BY clause in the query (for example ORDER BY timestamp).
-
A tieBreaker configuration that identifies the column used to compare the "last seen" value (example a timestamp or an increasing id).
-
- Example
-
This example demonstrates how to configure a poll step using the timestamp as a tiebreaker.
cassandra().poll {
connect { (1)
name = "my-poll-step"
servers = listOf("localhost:9042")
keyspace = "iot"
datacenterName = "datacenter1"
}
query("SELECT deviceid, timestamp, batterylevel FROM batteryState
WHERE company = ? ORDER BY timestamp") (2)
parameters("ACME Inc.") (3)
tieBreaker { (4)
name = "timestamp"
type = GenericType.INSTANT
}
pollDelay(Duration.ofSeconds(1)) (5)
}
| 1 | Define the connection parameters to the cassandra cluster. |
| 2 | Define the prepared statement to execute when polling. |
| 3 | Bind values to the clauses of the prepared query. |
| 4 | Repeat the first column used for sorting and comparison ( ⇐ or >=, depending on the ascending or descending order). |
| 5 | Specify the delay between query executions. |
- Tips
-
-
Use the
pollstep with a left join operator to verify the values saved by your tested system in the database. -
queryrequires at least one sorting field (tiebreakerin the example) to filter the newest results and not fetch the same records repeatedly. -
The latest known value for
tiebreakeris used to filter out values already received from the database. -
Call
flatten()after the poll step to transform the list of records into a map of column identifier [CQLIdentifier] to values.
-
- Reference documentation
-
Refer to the Apache Cassandra documentation for further parameter and configuration information.
Save step
The save step within the Cassandra plugin persists records into a cassandra database using the save query with The Cassandra Query Language (CQL).
- Ancestor
-
Step
- Functionality
-
The
savestep’s input and step context are used to generate documents to save into a database. - Example
previousStep.cassandra().save { (1)
name = "my-save-step"
connect { (2)
servers = listOf("localhost:9042")
keyspace = "iot"
datacenterName = "datacenter1"
}
table { stepContext, input -> (3)
"batteryState"
}
columns { stepContext, input -> (4)
listOf(
"company",
"deviceid",
"timestamp",
"batterylevel"
)
}
rows { stepContext, input -> (5)
listOf(
CassandraSaveRow(
"'ACME Inc.'",
"'${input.deviceId}'",
"'${input.timestamp}'",
input.batteryLevel
)
)
}
}
| 1 | Set a placeholder for any preceding step (e.g. execute(), verify(), map(), etc.). |
| 2 | Define the connection parameters to the cassandra cluster. |
| 3 | Name the output table, that can be resolved from the context and input. |
| 4 | Define column names for the output table, that can be resolved from the context and input. |
| 5 | Define how input fields are extracted and formatted to the output tables, using the step context and input. |
- Tips
-
-
Use the
savestep after acollectstep to reduce the number of queries executed onto the database and reduce the load your scenario generates on it. -
The
savestep is extremely flexible; table, rows, and columns depend on the context and input value received from the previous step.
-
- Reference documentation
-
Refer to the Apache Cassandra documentation for further parameter and configuration information.
Search step
The search step within the Cassandra plugin searches records in the database using a search query.
- Ancestor
-
Step
- Functionality
-
The
searchstep’s input and step context are used to complete the search; the list of results is then forwarded to the next step(s). - Example
previousStep.cassandra().search {
name = "my-search-step"
connect { (1)
servers = listOf("localhost:9042")
keyspace = "iot"
datacenterName = "datacenter1"
}
query { stepContext, input -> (2)
"SELECT * FROM batteryState WHERE company= ?
AND deviceid = ? AND timestamp = ?"
}
parameters { stepContext, input -> (3)
listOf("ACME Inc.", input.input.deviceId, input.input.timestamp)
}
}
| 1 | Define the connection parameters to the cassandra cluster. |
| 2 | Define the query statement, that can be resolved from the context and input. |
| 3 | Define the query parameters, using the step context and input. |
- Tips
-
-
Use the
searchstep after acollect()step to reduce the number of queries executed onto the database and to reduce the load the scenario generates on the test system. -
The
queryparameter may contain ordering clauses.
-
- Reference documentation
-
-
Refer to the Apache Cassandra documentation for further parameter and configuration information.
-
Configuration
DSL parameters
Available parameters are described in the table below.
Refer to the Apache Cassandra documentation for further parameter and configuration information.
| Parameter | Description |
|---|---|
|
Defines the connection parameters to Apache Cassandra. Example
|
|
List of servers available for the connection. Example
|
|
Name of the keyspace to use. A keyspace defines how data is replicated across the cluster (replication strategy and replication factor). Example
|
|
Name of the datacenter where data is stored. Example
|
|
Determines how the DataStax driver selects the Cassandra datacenter to be used for routing requests. Applicable Steps: Poll, Search Example
|
|
Defines the prepared statement to query or execute. Example (Poll)
Example (Search)
|
|
Poll: Binds values to the clauses of the prepared query. Example (Poll)
Example (Search)
|
|
Configures the tiebreaker column used to track the "last seen" value for polling. Example
|
|
Data type to help the datastax driver interpret a value. Example
|
|
Name of the column used as a tiebreaker. Example
|
|
Delay between two polling executions. Example
|
|
Computes the output table name using the step context and input. Example
|
|
Computes the list of column names for the output table using the step context and input. Example
|
|
Computes the list of Example (Single row table)
Example (Multi-row table)
|
|
Configures how polled results are delivered to scenario minions. |
|
Configures QALIPSIS monitoring (meters/events) for the step. |
Shared defaults for Cassandra steps
You can define defaults once in the scenario section or just after, and let all following Cassandra steps inherit them.
scenario {
cassandra().defaults { (1)
connect {
servers = listOf("localhost:9042")
keyspace = "iot"
datacenterName = "datacenter1"
}
monitoring {
events = true
meters = true
}
}
}
| 1 | Defaults are applied to subsequent Cassandra steps in the same scenario. Individual steps can still override values. |