- Prerequisites
- Start the Demo
- Use CQL API
- Use REST API
- Use Document API
- Use GraphQL API
- Create an Astra Instance
To run the demo you need docker
and docker-compose
. Skip this steps if you have them available already
Docker is an open-source project that automates the deployment of software applications inside containers by providing an additional layer of abstraction and automation of OS-level virtualization on Linux.
: To install on windows please use the following installer Docker Desktop for Windows Installer
: To install on MAC OS use Docker Desktop for MAC Installer or homebrew with following commands:
# Fetch latest version of homebrew and formula.
brew update
# Tap the Caskroom/Cask repository from Github using HTTPS.
brew tap caskroom/cask
# Searches all known Casks for a partial or exact match.
brew search docker
# Displays information about the given Cask
brew cask info docker
# Install the given cask.
brew cask install docker
# Remove any older versions from the cellar.
brew cleanup
# Validate installation
docker -v
: To install on linux (centOS) you can use the following commands
# Remove if already install
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# Utils
sudo yum install -y yum-utils
# Add docker-ce repo
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
# Install
sudo dnf -y install docker-ce --nobest
# Enable service
sudo systemctl enable --now docker
# Get Status
systemctl status docker
# Logout....Lougin
exit
# Create user
sudo usermod -aG docker $USER
newgrp docker
# Validation
docker images
docker run hello-world
docker -v
Docker Compose is a tool for defining and running multi-container Docker applications. It uses YAML files to configure the application's services and performs the creation and start-up process of all the containers with a single command. The docker-compose
CLI utility allows users to run commands on multiple containers at once, for example, building images, scaling containers, running containers that were stopped, and more. Please refer to Reference Documentation if you have for more detailed instructions.
: Already included in the previous package Docker for Windows
: Already included in the previous package Docker for Mac
: To install on linux (centOS) you can use the following commands
# Download deliverable and move to target location
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# Allow execution
sudo chmod +x /usr/local/bin/docker-compose
: Already included as stated here
brew install curl
:Use your package installer like yum
or apt-get
sudo apt-get install curl
β Clone the repository :
Download the repository as a zip [here] or clone with the following git command
git clone https://github.com/datastaxdevs/conference-2020-dataconla-stargate.git
β Start all containers :
We provide a docker-compose.yaml
file ready to go with a Cassandra 3.11.8
backend and stargate in version 0.0.8
To start use the following
docker-compose up -d
ποΈ Expected output
Starting backend-1 ... done
Starting stargate ... done
Starting backend-2 ... done
Starting backend-3 ... done
Wait for all services are up. You need the 4 containers.
You may have to relaunch the command multiple times as stargate need the 3 nodes to be up to join the cluster.
docker ps
ποΈ Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
237d9137884f stargateio/stargate-3_11:v0.0.8 "./starctl" 25 hours ago Up 4 hours 0.0.0.0:8080-8082->8080-8082/tcp, 0.0.0.0:9045->9042/tcp stargate
b3a10c48dccc cassandra:3.11.8 "docker-entrypoint.sβ¦" 25 hours ago Up 4 hours 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp backend-3
68be3b9bfc23 cassandra:3.11.8 "docker-entrypoint.sβ¦" 25 hours ago Up 4 hours 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp backend-2
23b009a08872 cassandra:3.11.8 "docker-entrypoint.sβ¦" 25 hours ago Up 4 hours 7000-7001/tcp, 7199/tcp, 9160/tcp, 0.0.0.0:9044->9042/tcp backend-1
- You should be able to access the GRAPH QL PORTAL on http://localhost:8080/playground
- You should be able to access the Swagger UI on http://localhost:8082/swagger-ui/#/
β Check that everything is OK :
docker exec -it `docker ps | grep backend-1 | cut -b 1-12` nodetool status
ποΈ Expected output
nodetool status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 172.20.0.4 179.98 KiB 8 1.1% 9873d76b-b439-4c81-92d7-4de103052af0 rack1
UN 172.20.0.5 370.43 KiB 256 35.0% 52e259b8-92ee-402c-b3b2-b1b39ad10ebb rack1
UN 172.20.0.2 354.2 KiB 256 34.8% 9dc3b120-19a7-4eda-8828-83532d816fcc rack1
UN 172.20.0.3 341.41 KiB 256 29.1% b385cbc3-7d30-46d3-bd14-f1b8ee01044d rack1
β Get Stargate IP :
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' stargate
ποΈ Expected output
172.20.0.4
β Start CQLSH :
- Use this IP to connect with a cqlsh. Note that the stargate image itself does not provide it we use the cqlsh from backend-1 as a sample client.
docker exec -it `docker ps | grep backend-1 | cut -b 1-12` cqlsh 172.20.0.4
β Create data model :
CREATE KEYSPACE IF NOT EXISTS keyspace1
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '3'}
AND durable_writes = true;
- Create schema a UDT and a table
use keyspace1;
CREATE TYPE IF NOT EXISTS video_format (
width int,
height int
);
CREATE TABLE IF NOT EXISTS videos (
videoid uuid,
title text,
upload timestamp,
email text,
url text,
tags set <text>,
frames list<int>,
formats map <text,frozen<video_format>>,
PRIMARY KEY (videoid)
);
describe keyspace;
β Use the data model :
- Insert value using plain CQL
INSERT INTO videos(videoid, email, title, upload, url, tags, frames, formats)
VALUES(uuid(), 'clu@sample.com', 'sample video',
toTimeStamp(now()), 'http://google.fr',
{ 'cassandra','accelerate','2020'},
[ 1, 2, 3, 4],
{ 'mp4':{width:1,height:1},'ogg':{width:1,height:1}});
- Insert Value using JSON
INSERT INTO videos JSON '{
"videoid":"e466f561-4ea4-4eb7-8dcc-126e0fbfd573",
"email":"clunven@sample.com",
"title":"A Second videos",
"upload":"2020-02-26 15:09:22 +00:00",
"url": "http://google.fr",
"frames": [1,2,3,4],
"tags": [ "cassandra","accelerate", "2020"],
"formats": {
"mp4": {"width":1,"height":1},
"ogg": {"width":1,"height":1}
}
}';
- Read values
select * from videos;
- Read by id
select * from videos where videoid=e466f561-4ea4-4eb7-8dcc-126e0fbfd573;
- Quit
cqlsh
exit
This walkthrough has been realized using the REST API Quick Start
β Generate an auth token :
curl -L -X POST 'http://localhost:8081/v1/auth' \
-H 'Content-Type: application/json' \
--data-raw '{
"username": "cassandra",
"password": "cassandra"
}'
Copy the token value (here 74be42ef-3431-4193-b1c1-cd8bd9f48132
) in your clipboard.
ποΈ Expected output
{"authToken":"74be42ef-3431-4193-b1c1-cd8bd9f48132"}
β List keyspaces :
Locate the SCHEMAS
part of the API
Localt listAllKeyspaces
method on GET
- Click
Try it out
- Provide your token in the field
X-Cassandra-Token
- Click on
Execute
β Creating a keyspace2 :
- createKeyspace
- Data
{"name": "keyspace2","replicas": 3}
β Creating a Table :
- addTable
- X-Cassandra-Token:
<your_token>
- keyspace:
keyspace2
- Data
{
"name": "users",
"columnDefinitions":
[
{
"name": "firstname",
"typeDefinition": "text"
},
{
"name": "lastname",
"typeDefinition": "text"
},
{
"name": "email",
"typeDefinition": "text"
},
{
"name": "favorite color",
"typeDefinition": "text"
}
],
"primaryKey":
{
"partitionKey": ["firstname"],
"clusteringKey": ["lastname"]
},
"tableOptions":
{
"defaultTimeToLive": 0,
"clusteringExpression":
[{ "column": "lastname", "order": "ASC" }]
}
}
Now Locate the DATA
part of the API
β Insert a row :
- createRow
- X-Cassandra-Token:
<your_token>
- keyspace:
keyspace2
- table:
users
- Data
{
"firstname": "Mookie",
"lastname": "Betts",
"email": "mookie.betts@gmail.com",
"favorite color": "blue"
}
{
"firstname": "Janesha",
"lastname": "Doesha",
"email": "janesha.doesha@gmail.com",
"favorite color": "grey"
}
β Read data :
- getAllRows
- X-Cassandra-Token:
<your_token>
- keyspace:
keyspace2
- table:
users
β Update a row :
You can do them in curl
export AUTH_TOKEN=<your_token>
curl --location \
--request PUT 'localhost:8082/v2/keyspaces/users_keyspace/users/Mookie/Betts' \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"email": "mookie.betts.new-email@email.com"
}'
β Delete a row :
curl --location \
--request DELETE 'localhost:8082/v2/keyspaces/users_keyspace/users/Mookie' \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header 'Content-Type: application/json'
This walkthrough has been realized using the Quick Start
β Generate an auth token :
Same as Rest API generate a auth token
curl -L -X POST 'http://localhost:8081/v1/auth' \
-H 'Content-Type: application/json' \
--data-raw '{
"username": "cassandra",
"password": "cassandra"
}'
Save output as an environment variable
export AUTH_TOKEN=5d746e40-97cf-490b-ab0d-68cfbc5d2ef3
β Creating a namespace :
- Access createNamespace in swagger UI
- Fill with Header
X-Cassandra-Token
with<your_token>
- Use this payload as JSON
{ "name": "namespace1", "replicas": 3 }
β Checking namespace existence :
- Access getAllNamespaces in swagger UI
- Fill with Header
X-Cassandra-Token
with<your_token>
- For
raw
you can use eithertrue
orfalse
ποΈ Expected output
{
"data": [
{ "name": "system_distributed" },
{ "name": "system" },
{ "name": "data_endpoint_auth"},
{ "name": "keyspace1" },
{ "name": "namespace1"},
{ "name": "system_schema"},
{ "name": "keyspace2" },
{ "name": "stargate_system"},
{ "name": "system_auth" },
{ "name": "system_traces"}
]
}
β Create a document :
Note: operations requiring providing namespace
and collections
on the swagger UI seems not functional. We are switching to CURL the API is working, this is a documentation bug that has been notified to the development team.
curl --location \
--request POST 'localhost:8082/v2/namespaces/namespace1/collections/videos' \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"videoid":"e466f561-4ea4-4eb7-8dcc-126e0fbfd573",
"email":"clunven@sample.com",
"title":"A Second videos",
"upload":"2020-02-26 15:09:22 +00:00",
"url": "http://google.fr",
"frames": [1,2,3,4],
"tags": [ "cassandra","accelerate", "2020"],
"formats": {
"mp4": {"width":1,"height":1},
"ogg": {"width":1,"height":1}
}
}'
ποΈ Expected output:
{
"documentId":"5d746e40-97cf-490b-ab0d-68cfbc5d2ef3"
}
β Retrieve documents :
curl --location \
--request GET 'localhost:8082/v2/namespaces/namespace1/collections/videos?page-size=3' \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header 'Content-Type: application/json'
ποΈ Expected output:
{
"data":{
"5d746e40-97cf-490b-ab0d-68cfbc5d2ef3":{
"email":"clunven@sample.com",
"formats":{"mp4":{"height":1,"width":1},"ogg":{"height":1,"width":1}},"frames":[1,2,3,4],
"tags":["cassandra","accelerate","2020"],"title":"A Second videos","upload":"2020-02-26 15:09:22 +00:00","url":"http://google.fr","videoid":"e466f561-4ea4-4eb7-8dcc-126e0fbfd573"
}
}
}
β Retrieve 1 document :
curl -L \
-X GET 'localhost:8082/v2/namespaces/namespace1/collections/videos/5d746e40-97cf-490b-ab0d-68cfbc5d2ef3' \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header 'Content-Type: application/json'
ποΈ Expected output:
{
"documentId":"5d746e40-97cf-490b-ab0d-68cfbc5d2ef3",
"data":{
"email":"clunven@sample.com",
"formats":{"mp4":{"height":1,"width":1},"ogg":{"height":1,"width":1}},
"frames":[1,2,3,4],
"tags":["cassandra","accelerate","2020"],
"title":"A Second videos",
"upload":"2020-02-26 15:09:22 +00:00",
"url":"http://google.fr",
"videoid":"e466f561-4ea4-4eb7-8dcc-126e0fbfd573"
}
}
β Search for document by properties :
curl -L -X GET 'localhost:8082/v2/namespaces/namespace1/collections/videos?where=\{"email":\{"$eq":"clunven@sample.com"\}\}' \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header 'Content-Type: application/json'
ποΈ Expected output:
{"data":{
"5d746e40-97cf-490b-ab0d-68cfbc5d2ef3":{
"email":"clunven@sample.com",
"formats":{"mp4":{"height":1,"width":1},"ogg":{"height":1,"width":1}},
"frames":[1,2,3,4],
"tags":["cassandra","accelerate","2020"],
"title":"A Second videos",
"upload":"2020-02-26 15:09:22 +00:00",
"url":"http://google.fr",
"videoid":"e466f561-4ea4-4eb7-8dcc-126e0fbfd573"
}
}
}
This walkthrough has been realized using the GraphQL Quick Start
Same as Rest API generate a auth token
β Generate Auth token :
curl -L -X POST 'http://localhost:8081/v1/auth' \
-H 'Content-Type: application/json' \
--data-raw '{
"username": "cassandra",
"password": "cassandra"
}'
Save output as an environment variable
export AUTH_TOKEN=7c37bda5-7360-4d39-96bc-9765db5773bc
β Open GraphQL Playground :
- You should be able to access the GRAPH QL PORTAL on http://localhost:8080/playground
You can check on the right of the playground that you have access to documentation and schema which is the neat part about graphQL
β Creating a keyspace :
Before you can start using the GraphQL API, you must first create a Cassandra keyspace and at least one table in your database. If you are connecting to a Cassandra database with existing schema, you can skip this step.
Inside the GraphQL playground, navigate to http://localhost:8080/graphql-schema and create a keyspace by executing the following mutation:
mutation createKeyspaceLibrary {
createKeyspace(name:"library", replicas: 1)
}
Add the auth token to the HTTP Headers box in the lower lefthand corner:
{
"x-cassandra-token":"7c37bda5-7360-4d39-96bc-9765db5773bc"
}
β Creating a Table :
- Use this query
mutation {
books: createTable(
keyspaceName:"library",
tableName:"books",
partitionKeys: [ # The keys required to access your data
{ name: "title", type: {basic: TEXT} }
]
values: [ # The values associated with the keys
{ name: "author", type: {basic: TEXT} }
]
)
authors: createTable(
keyspaceName:"library",
tableName:"authors",
partitionKeys: [
{ name: "name", type: {basic: TEXT} }
]
clusteringKeys: [ # Secondary key used to access values within the partition
{ name: "title", type: {basic: TEXT}, order: "ASC" }
]
)
}
β Populating Table :
Any of the created APIs can be used to interact with the GraphQL data, to write or read data.
First, letβs navigate to your new keyspace library
inside the playground. Change tab to graphql
and pick url /graphql/library
.
- Use this query
mutation {
moby: insertBooks(value: {title:"Moby Dick", author:"Herman Melville"}) {
value {
title
}
}
catch22: insertBooks(value: {title:"Catch-22", author:"Joseph Heller"}) {
value {
title
}
}
}
- Don't forget to update the header again
{
"x-cassandra-token":"7c37bda5-7360-4d39-96bc-9765db5773bc"
}
β Read data :
Stay on the same screen and sinmply update the query with
query oneBook {
books (value: {title:"Moby Dick"}) {
values {
title
author
}
}
}
β Create an free-forever Cassandra database with DataStax Astra: click here to get started π
β Use the form to create new database
On the Astra home page locate the Add Database button
Select the free tier plan, this is a true free tier, free forever and no payment method asked π π
Select the proper region and click the configure
button. The number of regions and cloud providers are limited in the free tier but please notice you can run the DB on any cloud with any VPC Peering.
Fill the database name
, keyspace name
, username
and password
. Please remember your password as you will be asked to provide it when application start the first time.
β View your Database and connect
View your database. It may take 2-3 minutes for your database to spin up. You will receive an email at that point.
ποΈ Expected output
Initializing
Once the database is ready, notice how the status changes from pending
to Active
and Astra enables the connect button.