Welcome
Build a Spring Java Microservice
with Apache Cassandra™
DataStax Developer Advocacy Special Unit
Courses: youtube.com/DataStaxDevs Runtime: dtsx.io/workshop
YouTube
Twitch
Questions: bit.ly/cassandra-workshop Quizz: menti.com
Discord
YouTube
Runtime: dtsx.io/workshop Quizz: menti.com
Disclaimer
This is a coding session. You will need
some experience with the Java language
and have a github account.
You can do these exercises on a local
install, but we will only use Gitpod today
during the workshop
5
Hands-on exercise material
- Get your Astra instance here:
- http://dtsx.io/workshop
- Github repo:
- https://github.com/DataStax-Academy/Spring-boot-todo-app
- Driver documentation:
- https://docs.datastax.com/en/developer/java-driver/4.9/
6
menti.com
87 51 69
Intro to Cassandra for Developers
➔ Demo !
➔ Introduction to Astra
➔ Introduction to Spring and Spring Boot
➔ Plan the Spring Application
➔ Working with Datastax drivers
➔ Build and test the basic CRUD app
What do you do when
you need to learn a new
language ?
9
10
Demo
11
Intro to Cassandra for Developers
➔ Demo
➔ Introduction to Astra
➔ Introduction to Spring and Spring Boot
➔ Plan the Spring Application
➔ Working with Datastax drivers
➔ Build and test the basic CRUD app
Introduction to Astra
==
Fully managed Cassandra
Without the ops!
13
DataStax Astra
Global Scale No Operations 5 Gig Free Tier
Put your data where you need it Launch a database in the cloud
Eliminate the overhead to install,
without compromising performance, with a few clicks, no credit card
operate, and scale Cassandra.
availability, or accessibility. required.
Hands-on prep work: Create your Astra database
- If you are new to Astra, sign up here: dtsx.io/workshop
- add a new keyspace (if you already have one)
- Take a note of the username, password, keyspace of your cluster
- We will be using these defaults:
- keyspace: todoapp
- user name: KVUser
- password: KVPassword
- Download the secure-connect-bundle, this is unique to you and your
database instance
15
Get the secure bundle with curl
right-click to copy the link to
clipboard
(refresh page before copy,
link is only ‘fresh’ for short
time)
curl -L "<insert link here>" > creds.zip
16
Intro to Cassandra for Developers
➔ Demo !
➔ Introduction to Astra
➔ Introduction to Spring and Spring Boot
➔ Plan the Spring Application
➔ Working with Datastax drivers
➔ Build and test the basic CRUD app
Inversion of control : Know only the interface
18
spring.io
19
The Spring Framework provides a comprehensive programming and configuration model
for modern Java-based enterprise applications - on any kind of deployment platform.
spring.io
Core technologies Dependency injection, events, resources, i18n, validation, data binding, AOP.
Web applications Model View Controller (MVC), Rest, Reactive,
Data Access Transactions, DAO support, JDBC, Object Mapping
Testing Mock objects, TestContext
Integrations Remoting, JMS, JCA, JMX, email, tasks, scheduling, cache.
Languages Kotlin, Groovy, dynamic languages.
20
21
Spring Boot Presentation Layer
(Rest API, Controller)
- Create stand-alone Spring applications Inversion of Control
(no need to deploy WAR files)
Business Layer
- Simplify your build configuration (Service, Component)
- Automatically configure Spring and 3rd Inversion of Control
party libraries
- Production-ready features such as Persistence Layer
(Dao, Repository)
- metrics
- health checks Drivers
- externalized configuration
Databases
22
Vocabulary
23
Intro to Cassandra for Developers
➔ Demo
➔ Introduction to Astra
➔ Introduction to Spring and Spring Boot
➔ Plan the Spring Application
➔ Working with Datastax drivers
➔ Build and test the basic CRUD app
What is a microservice?
Microservices - also known as the microservice architecture - is an architectural
style that structures an application as a collection of services that are
- Highly maintainable and testable
- Loosely coupled
- Independently deployable
- Organized around business capabilities
- Owned by a small team
The microservice architecture enables the rapid, frequent and reliable delivery of
large, complex applications. It also enables an organization to evolve its
technology stack. source: https://microservices.io/
25
Microservices, All things distributed
Monolith Multi-Tiers SOA Modern Applications
UI SPA Native Web Components Micro Frontend
Frontend UI UI Multi-channel
Backend for frontend (BFF)
Service
API Gateway Service Mesh
Discovery
ESB
Services Backend SOA Service Service Service Service Microservices
Service Service Service
Service Service Service Service
RDBMS No SQLs DB Ctx1 DB Ctx2 DB Ctx3
Data Data
DATA Layer Data-Mesh
Layer
Hadoop
26
Microservices in a nutshell Martin Fowler
Principles:
✔ Organized around Business Capabilities
✔ Products not Projects
✔ Smart endpoints and dumb pipes
✔ Decentralized Governance
✔ Decentralized Data Management
✔ Infrastructure Automation
✔ Design for failure
✔ Evolutionary Design
ADVANTAGES DISADVANTAGES
-
• Reduce Cost (Scaling, Design) • Complexity (Security, Transaction, Orchestration)
+ • Reduce Risk (resilience)
• Increase Release Speed
• Enable Visibility (security, monitoring)
• Cultural Changes
• Bigger RUN footprint
27
Apache Cassandra MicroServices
• REALTIME REQUESTS & SCALABILITY AT CORE
• DISTRIBUTED ARCHITECTURES
– From ACID to BASE (Basic Availability, Soft-State, Eventual Consistency)
– Implementations: CQRS, Event Sourcing
– Colocate service and Data
• DECOUPLING BY DESIGN
– 1 KEYSPACE = DOMAIN
– 1 QUERY = 1 TABLE
28
28
What service are we building? A ToDo Service
29
The REST Api
30
The full ToDo app architecture
Swagger
Spring-Web
TodoListRepository
todobackend-cassandra
31
The main data entity? Tasks
Tasks
● Task UUID
● title
● completed flag
● order
32
Designing the Cassandra datamodel
Entities & Relationships
Queries
33
The final task model
todo_tasks CREATE TABLE todoapp.todo_tasks (
uid uuid,
uid UUID K title text,
title TEXT completed boolean,
completed BOOLEAN offset int,
offset INT PRIMARY KEY ((uid))
);
34
The ToDoRepository
public interface TodoListRepository {
/** Constants for table todo_tasks to be used in statements */
String TABLE_TODO_TASKS = "todo_tasks";
String TASK_COL_UID = "uid";
String TASK_COL_TITLE = "title";
String TASK_COL_COMPLETED = "completed";
String TASK_COL_OFFSET = "offset";
...
35
What are the queries? CRUD for ToDos
List all tasks
Create a new Task
Mark a task as
completed/uncomplete
Delete a task
Delete all
36
The ToDoListRepository
public interface TodoListRepository {
...
/**
* Find a task from its unique identifier.
*/
Optional<Todo> findById(UUID uid);
/**
* Create a new {@link Todo} providing only a title.
*/
void upsert(Todo title);
/**
* Delete a task identifier
*/
void delete(UUID uid);
...
37
Intro to Cassandra for Developers
➔ Demo
➔ Introduction to Astra
➔ Introduction to Spring and Spring Boot
➔ Plan the Spring Application
➔ Working with Datastax drivers
➔ Build and test the basic CRUD app
Connecting the REST Api to Astra
- Use the Datastax drivers
- Download and use the secure connect bundle
- Pass user name, password, keyspace name and secure connect bundle
to build the cql session
- Astra handles the load balancing to the multinode Cassandra cluster
39
Contact points with Astra
- Download and use the secure
connect bundle proxies proxies proxies
- Pass user name, password, Loadbalanced url
keyspace name and secure
2-ways TLS
connect bundle to build the cql Server name
indication (SNI) connection
session
SecureConnectBundle
40
Datastax Drivers One of set drivers to connect them all - January 2020
Connectivity Query Parsing Results
● Token & Datacenter Aware ● CQL Support ● Lazy Load
● Load Balancing Policies ● Schema Management ● Object Mapper
● Retry Policies ● Sync/Async/Reactive API ● Spring Support
● Reconnection Policies ● Query Builder ● Paging
● Connection Pooling ● Compression
● Health Checks ● Paging
● Authentication | Authorization
● SSL
41
Working with the driver: Open a session
// Explicit Settings
CqlSession cqlSession = CqlSession.builder()
.withCloudSecureConnectBundle(Paths.get("/tmp/secure-connect-bundle.zip"))
.withKeyspace("todoapp")
.withAuthCredentials("KVUser", "KVPassword")
.build();
42
File based driver configuration application.conf
datastax-java-driver {
basic {...
Based on Typesafe Config session-keyspace = killrvideo
Attributes are grouped into basic and cloud {
advanced categories secure-connect-bundle = ...
}
A reference file reference.conf provide
}
default values embedded in the jar file. Can be
advanced {
override with key in application.conf.
auth-provider {
Driver searches application.conf in the class = PlainTextAuthProvider
classpath username = KVUser
password = KVPassword
} ...
43
Open a session with app.conf
// Delegate all configuration to file or default
CqlSession cqlSession = CqlSession.builder().build();
44
Important about the CqlSession
- CqlSession is a stateful object handling communications with each node
- CqlSession should be unique per application (Singleton)
- CqlSession should be closed at application shutdown (shutdown hook) in
order to free opened TCP sockets (stateful)
@PreDestroy
public void cleanup() {
if (null != cqlSession) {
cqlSession.close();
}
}
45
Hands-on Exercise 1:
Test the connection to Astra
mvn test
-Dtest=com.datastax.examples.ConnectivityToAstraExplicitTest#should_connect_to_Astra_static
mvn test
-Dtest=com.datastax.examples.ConnectivityToAstraWithConfTest#should_connect_to_Astra_withConfig
46
Working with the driver: Execute queries
- First job of CqlSession is to execute queries using the execute method.
cqlSession.execute("SELECT * FROM todoapp.tasks");
Statement
47
Working with the driver: Simple Statements
Statement statement = …
// (1) Explicit SimpleStatement Definition
SimpleStatement.newInstance("select * from t1 where c1 = 5");
// (2) Externalize Parameters (no name)
SimpleStatement.builder("select * from t1 where c1 = ?")
.addPositionalValue(5);
// (3) Externalize Parameters (name)
SimpleStatement.builder("select * from t1 where c1 = :myVal")
.addNamedValue("myVal”, 5);
cqlSession.execute(statement);
48
Working with the driver:
Prepare and bind a statement
- Compiled once on each node automatically as needed
- Prepare each statement only once per application
- Use one of the many bind variations to create a BoundStatement
PreparedStatement ps = cqlSession.prepare("SELECT * from t1 where c1 = ?");
BoundStatement bound = ps.bind(5);
cqlSession.execute(bound);
49
Working with the driver: ResultSets
- ResultSet is the object returned for executing query. It contains ROWS (data) and
EXECUTION INFO.
- ResultSet is iterable and as such you can navigate from row to row.
- Results are always paged for you (avoiding memory and response time issues)
ResultSet rs = cqlSession.execute(myStatement);
// Plumbery
ExecutionInfo info = rs.getExecutionInfo();
int executionTime = info.getQueryTrace().getDurationMicros();
// Data: NOT ALL DATA RETRIEVED IMMEDIATELY (only when needed .next())
Iterator<Row> iterRow = rs.iterator();
int itemsFirstCall = rs.getAvailableWithoutFetching();
50
Parsing ResultSets
// We know there is a single row (eg: count)
Row singleRow = resultSet.one();
// We know there are not so many results we can get all (fetch all pages)
List<Row> allRows = resultSet.all();
// Browse iterable
for(Row myRow : resultSet.iterator()) {
// .. Parsing rows
}
// Use Lambda
rs.forEach(row -> { row.getColumnDefinitions(); });
51
Parsing Rows
// Sample row
Row row = resultSet.one();
// Check null before read
Boolean isUsernNameNull = row.isNull("userName");
// Reading Values from row
String userName1 = row.get("username", String.class);
String userName2 = row.getString("username");
String userName3 = row.getString(CqlIdentifier.fromCql("username"));
// Tons of types available
row.getUuid("userid");
row.getBoolean(”register");
row.getCqlDuration(”elapsed");
…
52
Hands-on Exercise 2:
Set up schema and test inserts
mvn test -Dtest=com.datastax.examples.CreateSchemaInAstraTest#should_create_expected_table
mvn test -Dtest=com.datastax.examples.CRUDWithAstraTest#test_Insert
53
Intro to Cassandra for Developers
➔ Demo
➔ Introduction to Astra
➔ Introduction to Spring and Spring Boot
➔ Plan the Spring Application
➔ Working with Datastax drivers
➔ Build and test the basic CRUD app
Building the REST API with Spring Boot
@Repository("todobackend.repo.cassandra-driver")
public interface TodoRepository { public class TodoListRepositoryCassandraDriverImpl
//schema definition implements TodoListRepository {
//query definitions
} @Autowired
public CqlSession cqlSession;
@Configuration
@RestController
public class CassandraDriverConfig {
@RequestMapping("/api/v1/todos")
@Bean
public class TodoListRestController {
public CqlSession cqlSession() {
@Autowired
return CqlSession.builder().build();
@Qualifier("todobackend.repo.cassandra-dri
}
ver")
}
private TodoListRepository todoRepository;
...
}
55
Hands-on Exercise 3:
Configure and run the application
mvn spring-boot:run
56
Hands-on Exercise 4:
Test CRUD with Swagger
57
menti.com
87 51 69
Bonus Exercise:
Test with Todo MVC, client GUI and API specs
59
Learn more?
Micro-service REST Micro-service GraphQL
https://bit.ly/31RL62I https://bit.ly/2MVicup
Micro-service GRPC Micro-service Kafka
https://bit.ly/2pofk0b https://bit.ly/2JwsFdM
Reactive with Webflux Micro-service Serverless
https://bit.ly/34ePzhL https://bit.ly/31VQz8G
60
61