PolarSPARC

Cassandra Quick Notes :: Part - 4


Bhaskar S *UPDATED*12/01/2023


Overview


In Part-1 of this article series, we performed the necessary setup, started a single-node Apache Cassandra cluster and got our hands dirty with CQL operations.

In Part-2 of this article series, we performed the necessary setup to start a 3-node Apache Cassandra cluster and got our hands dirty with some Cassandra concepts.

In Part-3 of this article series, we leverage the 3-node Apache Cassandra cluster setup and got our hands dirty with additional Cassandra concepts.

In this part, we will demonstrate how to work with Apache Cassandra via an application code using both Python and Spring Boot Java.


Hands-on with Python Cassandra Driver


Ensure the Python Cassandra driver is installed by executing the following commands:

$ sudo apt install pip3 -y

$ sudo pip3 install cassandra-driver

To setup the Python directory structure for the demonstrations, execute the following commands:

$ cd $CASSANDRA_HOME

$ mkdir -p python

$ cd $CASSANDRA_HOME/python

For the demonstration, we don't need all the nodes in the cluster running. Ensure that the single-node Apache Cassandra cluster is up and running. Else, execute the following command:


$ docker run --rm --name cas-node-1 --hostname cas-node-1 --network cassandra-db-net -p 7199:7199 -p 9042:9042 -u $(id -u $USER):$(id -g $USER) -v $CASSANDRA_HOME/data:/var/lib/cassandra/data -v $CASSANDRA_HOME/etc/cassandra:/etc/cassandra -v $CASSANDRA_HOME/logs:/opt/cassandra/logs cassandra:5.0

To import the required Python modules and initialize some variables, execute the following code snippet:


import logging
from cassandra.cluster import Cluster, ExecutionProfile, EXEC_PROFILE_DEFAULT
from cassandra.policies import WhiteListRoundRobinPolicy

CASSANDRA_PORT = 9042
CASSANDRA_HOST = '127.0.0.1'
CASSANDRA_KS = 'my_test_ks'
CASSANDRA_TABLE = 'book_catalog'

logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO)

To interact with a Cassandra cluster, one needs to create a cluster connection by providing some configuration options, such as, the load balancing strategy, the network port, the protocol version, etc. An instance of the Python class Cluster allows one to do just that. To create a connection to the single-node Cassandra cluster, execute the following code snippet:


def get_cluster_session(host, port):
  logging.info(f'Connecting to {host} at port {port}')
  profile = ExecutionProfile(load_balancing_policy=WhiteListRoundRobinPolicy([host]))
  cluster = Cluster(execution_profiles={EXEC_PROFILE_DEFAULT: profile},
                    port=port,
                    protocol_version=5)
  session = cluster.connect()
  logging.info(f'Connection successful !!!')
  return cluster, session

Note that an instance of the Python class ExecutionProfile indicates the load balancing strategy.

To create and use a desired Keyspace in Cassandra, execute the following code snippet:


def set_keyspace(session, ks):
  logging.info(f'Checking for existence of keyspace {ks}')
  rows = session.execute('SELECT keyspace_name FROM system_schema.keyspaces')
  if ks not in [row[0] for row in rows]:
    session.execute("""
        CREATE KEYSPACE %s
            WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1};
        """ % ks)
  session.set_keyspace(ks)
  logging.info(f'Set keyspace successful !!!')

To create a Table in Cassandra within a Keyspace, execute the following code snippet:


def create_table(session, ks, table):
  logging.info(f'Checking for existence of table {table}')
  rows = session.execute("SELECT table_name FROM system_schema.tables WHERE keyspace_name='" + ks + "'")
  if table not in [row[0] for row in rows]:
    session.execute("""
        CREATE TABLE %s (
            isbn text,
            title text,
            year int,
            price float,
            PRIMARY KEY (isbn))
        """ % table)
  logging.info(f'Create table successful !!!')

To insert a new row into a Table in Cassandra, execute the following code snippet:


def insert_row(session, table, isbn, title=None, year=0, price=0.0):
  logging.info(f'Inserting row in table {table} for key {isbn}')
  session.execute("""
      INSERT INTO %s (isbn, title, year, price)
          VALUES ('%s', '%s', %d, %f)
      """ % (table, isbn, title, year, price))
  logging.info(f'Insert into table successful !!!')

To query all the rows from a Table in Cassandra, execute the following code snippet:


def select_all_rows(session, table):
  logging.info(f'Querying from table {table}')
  rows = session.execute("""
            SELECT *
            FROM %s
            """ % table)
  for row in rows:
    if row.year is None:
      logging.info(f'>>> {row.isbn}, {row.title}, null, null')
    else:
      logging.info(f'>>> {row.isbn}, {row.title}, {row.year}, {row.price:.02f}')
  logging.info(f'Query from table successful !!!')

To update a row from a Table in Cassandra for a given key, execute the following code snippet:


def update_row(session, table, isbn, title=None, year=0, price=0.0):
  logging.info(f'Updating row in table {table} for key {isbn}')
  session.execute("""
      UPDATE %s SET price = %f,
          title = '%s',
          year = %d
          WHERE isbn = '%s'
      """ % (table, price, title, year, isbn))
  logging.info(f'Update of table successful !!!')

To delete few columns from a Table in Cassandra for a given key, execute the following code snippet:


def delete_columns(session, table, isbn):
  logging.info(f'Deleting columns from table {table} for key {isbn}')
  session.execute("""
      DELETE price, year
          FROM %s
          WHERE isbn = '%s';
      """ % (table, isbn))
  logging.info(f'Delete of columns from table successful !!!')

To clean up all the used resources and disconnect from Cassandra cluster, execute the following code snippet:


def clean_up(cluster, session, ks, table):
  logging.info(f'Ready to perform cleanup')
  session.execute("""DROP TABLE %s""" % table)
  session.execute("""DROP KEYSPACE %s""" % ks)
  session.shutdown()
  cluster.shutdown()
  logging.info(f'Cleanup successful !!!')

To test the CRUD operations in the Cassandra cluster, execute the following code snippet:


if __name__ == '__main__':
  c_cluster, c_session = get_cluster_session(CASSANDRA_HOST, CASSANDRA_PORT)
  set_keyspace(c_session, CASSANDRA_KS)
  create_table(c_session, CASSANDRA_KS, CASSANDRA_TABLE)
  insert_row(c_session, CASSANDRA_TABLE, isbn='ISBN-111')
  select_all_rows(c_session, CASSANDRA_TABLE)
  update_row(c_session, CASSANDRA_TABLE, isbn='ISBN-111', title='Cassandra Quick Notes', year=2023, price=2.99)
  select_all_rows(c_session, CASSANDRA_TABLE)
  insert_row(c_session, CASSANDRA_TABLE, isbn='ISBN-222', title='Cassandra Guide', year=2021, price=4.99)
  insert_row(c_session, CASSANDRA_TABLE, isbn='ISBN-333', title='Cassandra For Developers', year=2019, price=3.99)
  select_all_rows(c_session, CASSANDRA_TABLE)
  delete_columns(c_session, CASSANDRA_TABLE, isbn='ISBN-333')
  select_all_rows(c_session, CASSANDRA_TABLE)
  clean_up(c_cluster, c_session, CASSANDRA_KS, CASSANDRA_TABLE)

The following would be the typical output:


Output.1

2023-11-30 11:53:18,914 - Connecting to 127.0.0.1 at port 9042
2023-11-30 11:53:18,934 - Connection successful !!!
2023-11-30 11:53:18,934 - Checking for existence of keyspace my_test_ks
2023-11-30 11:53:18,971 - Set keyspace successful !!!
2023-11-30 11:53:18,972 - Checking for existence of table book_catalog
2023-11-30 11:53:19,080 - Create table successful !!!
2023-11-30 11:53:19,080 - Inserting row in table book_catalog for key ISBN-111
2023-11-30 11:53:19,081 - Insert into table successful !!!
2023-11-30 11:53:19,081 - Querying from table book_catalog
2023-11-30 11:53:19,082 - >>> ISBN-111, None, 0, 0.00
2023-11-30 11:53:19,082 - Query from table successful !!!
2023-11-30 11:53:19,082 - Updating row in table book_catalog for key ISBN-111
2023-11-30 11:53:19,083 - Update of table successful !!!
2023-11-30 11:53:19,083 - Querying from table book_catalog
2023-11-30 11:53:19,083 - >>> ISBN-111, Cassandra Quick Notes, 2023, 2.99
2023-11-30 11:53:19,084 - Query from table successful !!!
2023-11-30 11:53:19,084 - Inserting row in table book_catalog for key ISBN-222
2023-11-30 11:53:19,084 - Insert into table successful !!!
2023-11-30 11:53:19,084 - Inserting row in table book_catalog for key ISBN-333
2023-11-30 11:53:19,085 - Insert into table successful !!!
2023-11-30 11:53:19,085 - Querying from table book_catalog
2023-11-30 11:53:19,086 - >>> ISBN-333, Cassandra For Developers, 2019, 3.99
2023-11-30 11:53:19,086 - >>> ISBN-111, Cassandra Quick Notes, 2023, 2.99
2023-11-30 11:53:19,086 - >>> ISBN-222, Cassandra Guide, 2021, 4.99
2023-11-30 11:53:19,086 - Query from table successful !!!
2023-11-30 11:53:19,086 - Deleting columns from table book_catalog for key ISBN-333
2023-11-30 11:53:19,086 - Delete of columns from table successful !!!
2023-11-30 11:53:19,086 - Querying from table book_catalog
2023-11-30 11:53:19,087 - >>> ISBN-333, Cassandra For Developers, null, null
2023-11-30 11:53:19,087 - >>> ISBN-111, Cassandra Quick Notes, 2023, 2.99
2023-11-30 11:53:19,087 - >>> ISBN-222, Cassandra Guide, 2021, 4.99
2023-11-30 11:53:19,087 - Query from table successful !!!
2023-11-30 11:53:19,087 - Ready to perform cleanup
2023-11-30 11:53:19,733 - Cleanup successful !!!

This wraps on how to work with Apache Cassandra using Python.


Hands-on with Cassandra using Spring Boot


To setup the Java directory structure for the demonstrations, execute the following commands:

$ cd $HOME

$ mkdir -p java/springboot/cassandra

$ cd $HOME/java/springboot/cassandra

$ mkdir -p src/main/java src/main/resources target

$ mkdir -p src/main/java/com/polarsparc/cassandra

$ mkdir -p src/main/java/com/polarsparc/cassandra/config

$ mkdir -p src/main/java/com/polarsparc/cassandra/model

$ mkdir -p src/main/java/com/polarsparc/cassandra/repository

$ mkdir -p src/main/java/com/polarsparc/cassandra/service src/main/java/com/polarsparc/cassandra/service/impl

For the Spring Boot based demonstration, we will leverage Maven to manage the build as well as the package dependencies.

The following is the Maven file pom.xml that is located in the directory $HOME/java/cassandra:


pom.xml
<?xml version="1.0" encoding="UTF-8"?>
  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.0</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <groupId>com.polarsparc</groupId>
  <artifactId>Cassandra</artifactId>
  <version>1.0</version>
  <name>Cassandra</name>
  <description>Cassandra</description>
  <properties>
    <java.version>17</java.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-cassandra</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

The following are the contents of the Spring Boot application properties file called application.properties , which defines the logging level and some Cassandra configuration options:


application.properties
#
# @Author: Bhaskar S
# @Blog:   https://www.polarsparc.com
# @Date:   30 Nov 2023
#

logging.level.root=INFO

spring.cassandra.contact-points=127.0.0.1
spring.cassandra.port=9042
spring.cassandra.keyspace-name=my_test_ks
spring.cassandra.schema-action=NONE

The property spring.cassandra.schema-action with a value of NONE means - don't create the Cassandra database on startup.


The following are the contents of the Java POJO BookCatalog.java which represents a row in the Cassandra database:


BookCatalog.java
/*
    @Author: Bhaskar S
    @Blog:   https://www.polarsparc.com
    @Date:   30 Nov 2023
*/

package com.polarsparc.cassandra.model;

import org.springframework.data.cassandra.core.mapping.Column;
import org.springframework.data.cassandra.core.mapping.PrimaryKey;
import org.springframework.data.cassandra.core.mapping.Table;

@Table("book_catalog")
public class BookCatalog {
    @PrimaryKey
    @Column
    private String isbn;

    @Column
    private String title;

    @Column
    private int year;

    @Column
    private double price;

    public BookCatalog() {
        this.isbn = null;
        this.title = null;
        this.year = 0;
        this.price = 0.0;
    }

    public BookCatalog(String isbn, String title, int year, double price) {
        this.isbn = isbn;
        this.title = title;
        this.year = year;
        this.price = price;
    }

    public BookCatalog(String isbn) {
        this(isbn, null, 0, 0.0);
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "BookCatalog{" +
                "isbn='" + isbn + '\'' +
                ", title='" + title + '\'' +
                ", year=" + year +
                ", price=" + price +
                '}';
    }
}

For any Spring Boot application that wants to interact with Cassandra, it needs a connection (session) to the cluster. The application.properties indicates the values for where to connect, which Keyspace to use and so on. That information needs to be translated into a configuration bean for Spring Boot to access, so that it can create the necessary session bean.

The following are the contents of the Spring Boot configuration Java bean CassandraConfig.java located in the directory src/main/java/com/polarsparc/cassandra/config:


CassandraConfig.java
package com.polarsparc.cassandra.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.AbstractCassandraConfiguration;
import org.springframework.data.cassandra.config.SchemaAction;
import org.springframework.lang.NonNull;

@Configuration
public class CassandraConfig extends AbstractCassandraConfiguration {
    @Value("${spring.cassandra.keyspace-name}")
    private String keySpace;

    @Value("${spring.cassandra.contact-points}")
    private String contactPoints;

    @Value("${spring.cassandra.port}")
    private int port;

    @Value("${spring.cassandra.schema-action}")
    private String schemaAction;

    @Override
    @NonNull
    protected String getKeyspaceName() {
        return keySpace;
    }
    @Override
    @NonNull
    protected String getContactPoints() {
        return contactPoints;
    }

    @Override
    protected int getPort() {
        return port;
    }

    @Override
    @NonNull
    public SchemaAction getSchemaAction() {
        return SchemaAction.valueOf(schemaAction);
    }
}

The following are the contents of the Java service interface called BookCatalogService.java which defines the various CRUD operations on the Cassandra database and is located in the directory src/main/java/com/polarsparc/cassandra/service:


BookCatalogService.java
/*
    @Author: Bhaskar S
    @Blog:   https://www.polarsparc.com
    @Date:   30 Nov 2023
*/

package com.polarsparc.cassandra.service;

public interface BookCatalogService {
    void insertBookCatalog(String isbn, String title, int year, double price);
    void queryBookCatalogs();
    void removeBookCatalogs();
    void removePriceAndYear(String isbn);
    void updateBookCatalog(String isbn, String title, int year, double price);
}

The following are the contents of the Java class called BookCatalogServiceImpl.java which implements the Java service interface BookCatalogService, and is located in the directory src/main/java/com/polarsparc/cassandra/service/impl:


BookCatalogService.java
/*
    @Author: Bhaskar S
    @Blog:   https://www.polarsparc.com
    @Date:   30 Nov 2023
*/

package com.polarsparc.cassandra.service.impl;

import com.polarsparc.cassandra.model.BookCatalog;
import com.polarsparc.cassandra.repository.BookCatalogRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.polarsparc.cassandra.service.BookCatalogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class BookCatalogServiceImpl implements BookCatalogService {
    private final static Logger LOGGER = LoggerFactory.getLogger(BookCatalogServiceImpl.class.getName());

    private BookCatalogRepository repository;

    @Autowired
    public void setRepository(BookCatalogRepository repository) {
        this.repository = repository;
    }

    @Override
    public void insertBookCatalog(String isbn, String title, int year, double price) {
        BookCatalog bookCatalog = new BookCatalog(isbn, title, year, price);
        LOGGER.info(String.format("Inserting row for %s in book_catalog", isbn));
        repository.insert(bookCatalog);
    }

    @Override
    public void queryBookCatalogs() {
        LOGGER.info(String.format("Count of rows in book_catalog: %d", repository.count()));
        LOGGER.info("Querying all rows in book_catalog");
        repository.findAll().forEach(row -> LOGGER.info(row.toString()));
    }

    @Override
    public void removeBookCatalogs() {
        LOGGER.info("Removing all rows from book_catalog");
        repository.deleteAll();
    }

    @Override
    public void removePriceAndYear(String isbn) {
        LOGGER.info(String.format("Removing price and year for %s in book_catalog", isbn));
        Optional<BookCatalog> bookCatalog = repository.findById(isbn);
        if (bookCatalog.isPresent()) {
            LOGGER.info(String.format("Found row for %s in book_catalog", isbn));
            BookCatalog bc = bookCatalog.get();
            bc.setPrice(0.0);
            bc.setYear(0);
            LOGGER.info(String.format("Updating row for %s in book_catalog", isbn));
            repository.save(bc);
        } else {
            LOGGER.warn(String.format("No row for %s in book_catalog", isbn));
        }
    }

    @Override
    public void updateBookCatalog(String isbn, String title, int year, double price) {
        LOGGER.info(String.format("Querying row for %s in book_catalog", isbn));
        Optional<BookCatalog> bookCatalog = repository.findById(isbn);
        if (bookCatalog.isPresent()) {
            LOGGER.info(String.format("Found row for %s in book_catalog", isbn));
            BookCatalog bc = bookCatalog.get();
            bc.setTitle(title);
            bc.setPrice(price);
            bc.setYear(year);
            LOGGER.info(String.format("Updating row for %s in book_catalog", isbn));
            repository.save(bc);
        } else {
            LOGGER.warn(String.format("No row for %s in book_catalog", isbn));
        }
    }
}

The following are the contents of the Spring Boot repository interface called BookCatalogRepository.java that defines all the CRUD operations on the Cassandra database and is located in the directory src/main/java/com/polarsparc/cassandra/repository:


BookCatalogRepository.java
/*
    @Author: Bhaskar S
    @Blog:   https://www.polarsparc.com
    @Date:   30 Nov 2023
*/

package com.polarsparc.cassandra.repository;

import com.polarsparc.cassandra.model.BookCatalog;
import org.springframework.data.cassandra.repository.CassandraRepository;

public interface BookCatalogRepository extends CassandraRepository {}

Finally, the following are the contents of the Spring Boot application called CassandraApplication.java that performs all the CRUD operations on the Cassandra database:


CassandraApplication.java
/*
        @Author: Bhaskar S
        @Blog:   https://www.polarsparc.com
        @Date:   30 Nov 2023
    */
    
    package com.polarsparc.cassandra;
    
    import com.polarsparc.cassandra.repository.BookCatalogRepository;
    import com.polarsparc.cassandra.service.BookCatalogService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
    
    @SpringBootApplication
    @EnableCassandraRepositories(basePackageClasses = BookCatalogRepository.class)
    public class CassandraApplication implements CommandLineRunner {
      private ConfigurableApplicationContext context;
    
      private BookCatalogService service;
    
      @Autowired
      public void setContext(ConfigurableApplicationContext context) {
        this.context = context;
      }
    
      @Autowired
      public void setService(BookCatalogService service) {
        this.service = service;
      }
    
      public static void main(String[] args) {
        SpringApplication.run(CassandraApplication.class, args);
      }
    
      @Override
      public void run(String... args) {
        service.insertBookCatalog("ISBN-111", null, 0, 0.0);
        service.queryBookCatalogs();
        service.updateBookCatalog("ISBN-111", "Cassandra Quick Notes", 2023, 2.99);
        service.queryBookCatalogs();
        service.insertBookCatalog("ISBN-222", "Cassandra Guide", 2021, 4.99);
        service.insertBookCatalog("ISBN-333", "Cassandra For Developers", 2019, 3.99);
        service.queryBookCatalogs();
        service.removePriceAndYear("ISBN-333");
        service.queryBookCatalogs();
        service.removeBookCatalogs();
        service.queryBookCatalogs();
    
        System.exit(SpringApplication.exit(context));
      }
    }

Launch the CQL command-line interface by executing the following command:


$ docker run -it --rm --name cas-client --network cassandra-db-net cassandra:5.0 cqlsh cas-node-1


The following will be the output:


Output.2

WARNING: cqlsh was built against 5.0-alpha2, but this server is 5.0.  All features may not work!
Connected to Cassandra Cluster at cas-node-1:9042
[cqlsh 6.2.0 | Cassandra 5.0-alpha2 | CQL spec 3.4.7 | Native protocol v5]
Use HELP for help.
cqlsh>

On success, CQL will change the command prompt to "cqlsh>".

To create a Keyspace called my_test_ks, input the following command at the "cqlsh>" prompt:


cqlsh> CREATE KEYSPACE IF NOT EXISTS my_test_ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};


There will be no output.

To use the Keyspace called my_test_ks, input the following command at the "cqlsh>" prompt:


cqlsh> USE my_test_ks;


There will be no output and the input prompt would change to "cqlsh:my_test_ks>".

To create a Table called book_catalog with a Primary Key, input the following command at the "cqlsh:my_test_ks>" prompt:


cqlsh:my_test_ks> CREATE TABLE IF NOT EXISTS book_catalog (isbn text, title text, year int, price double, PRIMARY KEY (isbn));


There will be no output.

Run the the Spring Boot application called CassandraApplication and following will be the typical output:


Output.3

2023-12-01T13:46:47.121-05:00  INFO 24098 --- [           main] c.p.cassandra.CassandraApplication       : Starting CassandraApplication using Java 21 with PID 24098 (/home/bswamina/MyProjects/Java/SpringBoot/Cassandra/target/classes started by bswamina in /home/bswamina/MyProjects/Java/SpringBoot/Cassandra)
2023-12-01T13:46:47.123-05:00  INFO 24098 --- [           main] c.p.cassandra.CassandraApplication       : No active profile set, falling back to 1 default profile: "default"
2023-12-01T13:46:47.250-05:00  INFO 24098 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Cassandra repositories in DEFAULT mode.
2023-12-01T13:46:47.265-05:00  INFO 24098 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 13 ms. Found 1 Cassandra repository interface.
2023-12-01T13:46:47.294-05:00  INFO 24098 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Reactive Cassandra repositories in DEFAULT mode.
2023-12-01T13:46:47.298-05:00  INFO 24098 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Reactive Cassandra repository interfaces.
2023-12-01T13:46:47.481-05:00  INFO 24098 --- [           main] c.d.o.d.i.core.DefaultMavenCoordinates   : DataStax Java driver for Apache Cassandra(R) (com.datastax.oss:java-driver-core) version 4.17.0
2023-12-01T13:46:47.526-05:00  INFO 24098 --- [           main] c.d.o.d.i.c.c.CqlPrepareAsyncProcessor   : Adding handler to invalidate cached prepared statements on type changes
2023-12-01T13:46:47.667-05:00  INFO 24098 --- [     s0-admin-0] c.d.oss.driver.internal.core.time.Clock  : Using native clock for microsecond precision
2023-12-01T13:46:47.916-05:00  INFO 24098 --- [           main] c.d.o.d.i.c.c.CqlPrepareAsyncProcessor   : Adding handler to invalidate cached prepared statements on type changes
2023-12-01T13:46:47.917-05:00  INFO 24098 --- [     s1-admin-0] c.d.oss.driver.internal.core.time.Clock  : Using native clock for microsecond precision
2023-12-01T13:46:48.127-05:00  INFO 24098 --- [           main] c.p.cassandra.CassandraApplication       : Started CassandraApplication in 1.161 seconds (process running for 1.427)
2023-12-01T13:46:48.128-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Inserting row for ISBN-111 in book_catalog
2023-12-01T13:46:48.175-05:00  WARN 24098 --- [        s1-io-3] c.d.o.d.i.core.cql.CqlRequestHandler     : Query '[0 values] SELECT count(1) FROM book_catalog' generated server side warning(s): Aggregation query used without partition key
2023-12-01T13:46:48.176-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Count of rows in book_catalog: 1
2023-12-01T13:46:48.176-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Querying all rows in book_catalog
2023-12-01T13:46:48.185-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : BookCatalog{isbn='ISBN-111', title='null', year=0, price=0.0}
2023-12-01T13:46:48.185-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Querying row for ISBN-111 in book_catalog
2023-12-01T13:46:48.189-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Found row for ISBN-111 in book_catalog
2023-12-01T13:46:48.189-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Updating row for ISBN-111 in book_catalog
2023-12-01T13:46:48.193-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Count of rows in book_catalog: 1
2023-12-01T13:46:48.193-05:00  WARN 24098 --- [        s1-io-3] c.d.o.d.i.core.cql.CqlRequestHandler     : Query '[0 values] SELECT count(1) FROM book_catalog' generated server side warning(s): Aggregation query used without partition key
2023-12-01T13:46:48.193-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Querying all rows in book_catalog
2023-12-01T13:46:48.194-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : BookCatalog{isbn='ISBN-111', title='Cassandra Quick Notes', year=2023, price=2.99}
2023-12-01T13:46:48.194-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Inserting row for ISBN-222 in book_catalog
2023-12-01T13:46:48.195-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Inserting row for ISBN-333 in book_catalog
2023-12-01T13:46:48.197-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Count of rows in book_catalog: 3
2023-12-01T13:46:48.197-05:00  WARN 24098 --- [        s1-io-3] c.d.o.d.i.core.cql.CqlRequestHandler     : Query '[0 values] SELECT count(1) FROM book_catalog' generated server side warning(s): Aggregation query used without partition key
2023-12-01T13:46:48.197-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Querying all rows in book_catalog
2023-12-01T13:46:48.198-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : BookCatalog{isbn='ISBN-333', title='Cassandra For Developers', year=2019, price=3.99}
2023-12-01T13:46:48.198-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : BookCatalog{isbn='ISBN-111', title='Cassandra Quick Notes', year=2023, price=2.99}
2023-12-01T13:46:48.198-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : BookCatalog{isbn='ISBN-222', title='Cassandra Guide', year=2021, price=4.99}
2023-12-01T13:46:48.198-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Removing price and year for ISBN-333 in book_catalog
2023-12-01T13:46:48.199-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Found row for ISBN-333 in book_catalog
2023-12-01T13:46:48.199-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Updating row for ISBN-333 in book_catalog
2023-12-01T13:46:48.201-05:00  WARN 24098 --- [        s1-io-3] c.d.o.d.i.core.cql.CqlRequestHandler     : Query '[0 values] SELECT count(1) FROM book_catalog' generated server side warning(s): Aggregation query used without partition key
2023-12-01T13:46:48.201-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Count of rows in book_catalog: 3
2023-12-01T13:46:48.201-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Querying all rows in book_catalog
2023-12-01T13:46:48.202-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : BookCatalog{isbn='ISBN-333', title='Cassandra For Developers', year=0, price=0.0}
2023-12-01T13:46:48.202-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : BookCatalog{isbn='ISBN-111', title='Cassandra Quick Notes', year=2023, price=2.99}
2023-12-01T13:46:48.202-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : BookCatalog{isbn='ISBN-222', title='Cassandra Guide', year=2021, price=4.99}
2023-12-01T13:46:48.202-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Removing all rows from book_catalog
2023-12-01T13:46:48.275-05:00  WARN 24098 --- [        s1-io-3] c.d.o.d.i.core.cql.CqlRequestHandler     : Query '[0 values] SELECT count(1) FROM book_catalog' generated server side warning(s): Aggregation query used without partition key
2023-12-01T13:46:48.275-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Count of rows in book_catalog: 0
2023-12-01T13:46:48.275-05:00  INFO 24098 --- [           main] c.p.c.s.impl.BookCatalogServiceImpl      : Querying all rows in book_catalog

To drop the entire table book_catalog, input the following command at the " cqlsh:my_test_ks>" prompt:

cqlsh:my_test_ks> DROP TABLE book_catalog;


There will be no output.

To drop the entire keyspace my_test_ks, input the following command at the " cqlsh:my_test_ks>" prompt:


cqlsh:my_test_ks> DROP KEYSPACE my_test_ks;


There will be no output.

To exit the CQL command-line interface, input the following command at the " cqlsh:my_test_ks>" prompt:


cqlsh:my_test_ks> exit;


There will be no output.

To stop the single-node Apache Cassandra cluster, execute the following command:


$ docker stop cas-node-1

This concludes the hands-on demonstration on how to work with Apache Cassandra via an application code using both Python and Spring Boot Java !!!


References

DataStax Python Driver

Cassandra Quick Notes :: Part - 3

Cassandra Quick Notes :: Part - 2

Cassandra Quick Notes :: Part - 1


© PolarSPARC