Thursday, November 18, 2021

Spring Boot 2 Spring Data Kotlin Cassandra CRUD

we're integration Spring Boot Kotlin Cassandra  CRUD.

  • Configuration Spring boot, Spring Data, Kotlin with Cassandra Database.
  • Define Data's Models, Repository and Services.
  • Spring Rest Controllers  

Spring Boot Kotlin Cassandra Rest CRUD API 

These are APIs that we need to provide:

MethodsUrls
POST /services/ws/save
GET /services/ws/users
PUT /services/ws/update/:email
DELETE /services/ws/delete/:email

Technology

  • Kotlin 1.5.31
  • Java 11
  • Spring Boot 2.5.6
  • Cassandra 4.0.1
  • Cqlsh 6.0.0
  • Maven 3.6.3
  • IntelliJ IDEA 2021.2.3 
  • Docker

Project Structure






















Configuration Spring Boot kotlin Cassandra project 

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>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.henry</groupId>
<artifactId>SpringBootCassandraKotlin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBootCassandraKotlin</name>
<description>Crud Cassandra with kotlin</description>
<properties>
<java.version>11</java.version>
<kotlin.version>1.5.31</kotlin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

</project>

application.yml

server:
servlet:
context-path: /services
port: 9000

spring:
data:
cassandra:
keyspace-name: test_keyspace
contact-points: localhost:9042
local-datacenter: datacenter1


Set up Cassandra by Docker


docker pull cassandra

 docker run --name cassandra -p 127.0.0.1:9042:9042 -p 127.0.0.1:9160:9160   -d cassandra

 docker exec -it cassandra /bin/bash

 #cqlsh






Check datacenter name:

cqlsh> use system;
cqlsh:system> select data_center from local;

 data_center
-------------
 datacenter1

(1 rows)
cqlsh:system>

 
We Created keyspaces: test_keyspace.

create keyspace test_keyspace with replication={'class':'SimpleStrategy', 'replication_factor':1};

use test_keyspace;

create table users
(
    email varchar primary key,
    name varchar,
    age int
);


Data class model

package com.henry.model

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

@Table
data class Users(@PrimaryKey
var email: String, var name: String, var age: Int)


Repository Interface

package com.henry.repository

import com.henry.model.Users
import org.springframework.data.cassandra.repository.CassandraRepository

interface UserRepository : CassandraRepository<Users,String> {
fun findByNameContaining(name: String?): List<Users?>?

}

Service Interface

package com.henry.services

import com.henry.model.Users

interface UserService {
fun byContName(name: String): List<Users?>?
fun findAllUsers(): MutableList<Users>;
fun saveUser(user: Users): Users
fun updateUser(email: String, user: Users): Users
fun deleteUser(email: String)
}

Service Class

package com.henry.services.impl

import com.henry.model.Users
import com.henry.repository.UserRepository
import com.henry.services.UserService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.util.*

@Service
class UserServiceImpl : UserService {

@Autowired
lateinit var userRepository: UserRepository;

override fun byContName(name: String): List<Users?>? {
return userRepository.findByNameContaining(name)
}

override fun findAllUsers(): MutableList<Users> {
return userRepository.findAll()
}

override fun saveUser(user: Users): Users {
return userRepository.save(user)
}

override fun updateUser(email: String, user: Users): Users {
val obj: Optional<Users> = userRepository.findById(email)
obj.get().age = user.age
obj.get().name = user.name
return userRepository.save(obj.get())

}

override fun deleteUser(email: String) {
userRepository.deleteById(email)
}
}

Spring Rest APIs Controller

package com.henry.controller

import com.henry.model.Users
import com.henry.services.UserService
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*


@CrossOrigin(origins = ["http://localhost:9000"])
@RestController
@RequestMapping("/ws")
class UserController(private val userService: UserService) {

@GetMapping("/users")
fun getAllUsers(): ResponseEntity<MutableList<Users>>? {
return ResponseEntity(userService.findAllUsers(), HttpStatus.OK)
}

@PostMapping("/save")
fun save(@RequestBody user: Users): ResponseEntity<Users>?{
return ResponseEntity(userService.saveUser(user), HttpStatus.OK)
}

@PutMapping("/update/{email:.*}")
fun update(@PathVariable email: String, @RequestBody user: Users): ResponseEntity<Users>?{
return ResponseEntity(userService.updateUser(email, user), HttpStatus.OK)
}

@DeleteMapping("/delete/{email:.*}")
fun delete(@PathVariable email: String): ResponseEntity<Unit> {
return ResponseEntity(userService.deleteUser(email), HttpStatus.OK)
}




}

Run & Test

Run Spring Boot application with command: mvn spring-boot:run. by console, IntelliJ etc.

POST.








































GET.



































PUT.























DELETE.




















Source Code

Here on Github.


References.

https://www.bezkoder.com/spring-boot-cassandra-crud/
https://www.youtube.com/channel/UCHRnRlWQuZYDmnuB7SbXIpQ





Monday, November 15, 2021

Apache Cassandra with Ubuntu 20.04

Apache Cassandra with docker.

1.     Installed from docker 

    $    docker pull cassandra:latest

    $   docker run --name you_cass_cluster cassandra:latest

    $   docker ps


    

$   docker exec -it you_cass_cluster cqlsh

    



    

2.    Supported Data Types.

Supported Data Types
CQL TypeDescription
asciiUS-ASCII character string
bigint64-bit signed long
blobArbitrary bytes (no validation), expressed as hexadecimal
booleantrue or false
counterDistributed counter value (64-bit long)
decimalVariable-precision decimal
double64-bit IEEE-754 floating point
float32-bit IEEE-754 floating point
int32-bit signed integer
textUTF-8 encoded string
timestampDate plus time, encoded as 8 bytes since epoch
uuidType 1 or type 4 UUID
timeuuidType 1 UUID only (CQL3)
varcharUTF-8 encoded string
varintArbitrary-precision integer


3.    Created on KEYSPACES with next command.

        CREATE KEYSPACE test_kesypace WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} AND durable_writes = 'true';

4.     Created Tables 

    use test_kesypace;

    CREATE TABLE employee_by_id

  (
     id       INT PRIMARY KEY,
     name     TEXT,
     position TEXT
  ); 

CREATE TABLE employee_by_car_make
  (
     car_make  TEXT,
     id        INT,
     car_model TEXT,
     PRIMARY KEY(car_make, id)

  );    

CREATE TABLE employee_by_car_make_sorted
  (
     car_make TEXT,
     age      INT,
     id       INT,
     name     TEXT,
     PRIMARY KEY(car_make, age, id)
  ); 

CREATE TABLE employee_by_car_make_and_model
             (
                          car_make TEXT,
                          car_model TEXT,
                          id INT,
                          name TEXT,
                          PRIMARY KEY((car_make, car_model), id)
             );

5.     Insert and update

INSERT INTO employee_by_id
            (id,
             name,
             position)
VALUES      ( 1,
             'Henry',
             'Developer'); 


UPDATE employee_by_car_make
using  ttl 60
SET    car_model = 'Truck'
WHERE  car_make ='TOYOTA'
AND    id = 1;

6. SELECT 

Cassandra DB just search by id.

SELECT *
FROM   employee_by_id
WHERE  id = 1; 


            






References:

https://www.youtube.com/channel/UCHRnRlWQuZYDmnuB7SbXIpQ



        


Creating REST APIs with OpenAPI, Spring Boot 3.3.3, Java 21, and Jakarta

 Introduction In today's software landscape, designing robust and scalable REST APIs is a crucial aspect of application development. Wit...