β οΈ Difficulty:Intermediate
, we expect you to already know Java and Spring.
Learn how to build an app end-to-end application with Spring ecosystem (boot, mvc, security, data, test, thymeleaf) and Apache Cassandraβ’.
- Objectives
- Acknowledgements
- Frequently asked questions
- Materials for the Session
- Create your Database
- Create your Token
- Start and setup Gitpod
- Work with CqlSh
- Load Data with DSBulk
- Use Application as anonymous
- Setup Authentication
- Authenticate and use application
- Homeworks
- Discover how to use the following technologies:
- Spring Data: the Object Mapping layer of Spring
- Spring Data Cassandra: what traps to avoid
- Spring Security: how to handle authentication with OAuth2
- Spring MVC: how to expose REST API and controllers
- Spring Webflux: how to use the new
WebClient
- Thymeleaf: how to build a user interface with Spring
- Spring Test: How to run tests
- Astra DB (a Database-as-a-service built on Apache Cassandra)
- Han fun with an interactive session
This application has been built based on the work of Java Brains, a famous youtuber (500k+ subscribers). On his channel you can find the full Code with me Series, 16 episodes for building this application step-by-step. The link to each episode is provided at the end of this readme.
1οΈβ£ Can I run this workshop on my computer?
There is nothing preventing you from running the workshop on your own machine, If you do so, you will need the following
- git installed on your local system
- JDK 8+ installed on your local system
- Maven 3.6+ installed on your local system
2οΈβ£ What other prerequisites are required?
- You will need an enough *real estate* on screen, we will ask you to open a few windows and it does not file mobiles (tablets should be OK)
- You will need a GitHub account eventually a google account for the Google Authentication (optional)
- You will need an Astra account: don't worry, we'll work through that in the following
- As Intermediate level we expect you to know what java and Spring are.
3οΈβ£ Do I need to pay for anything for this workshop?
No. All tools and services we provide here are FREE. FREE not only during the session but also after.
4οΈβ£ Will I get a certificate if I attend this workshop?
Attending the session is not enough. You need to complete the homeworks detailed below and you will get a nice badge that you can share on linkedin or anywhere else *(open api badge)*
It doesn't matter if you join our workshop live or you prefer to work at your own pace, we have you covered. In this repository, you'll find everything you need for this workshop:
Leveraging Database creation guide create a database. Right-Click the button with Open in a new TAB.
Field | Value |
---|---|
Database Name | workshops |
Keyspace Name | better_reads |
- If you already have a DB, you may need to resume it using the Resuming Guide.
- If yout already have an active DB, simply add a keyspace
better_reads
using theAdd Keyspace
button on the bottom right hand corner of db dashboard page.
Leveraging Token creation guide create a token. (
AstraCS:blablablabla
)
Field | Value |
---|---|
Role | Database Administrator |
- If you already have a token from previous session you can use it. A token is not related to a particular DB by default but to organization.
- Start gitpod with the button below (right-click open in new tab)
- Wait for the environment to initialize until you are asked to provide your token:
β Please paste the Database Admin Token here
- Enter your token
AstraCS;blahblahblah
and press enter. Wait for all the operations to complete.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 18.676 s
[INFO] Finished at: 2022-02-14T13:00:07Z
[INFO] ------------------------------------------------------------------------
It would be handy to have access to this CQLSH while doing the exercises and check the content of the database.
- Open a new terminal with the icon looking like a small table on top right hand corner of the Terminal Panel in gitpod (as shown below)
... zooming in:
/workspace/workshop-betterreads/cqlsh
- It should look like
Connected to cndb at 127.0.0.1:9042.
[cqlsh 6.8.0 | Cassandra 4.0.0.6816 | CQL spec 3.4.5 | Native protocol v4]
Use HELP for help.
token@cqlsh>
- List Keyspaces with
describe keyspaces;
- Check that our keyspace
better_reads
is there
token@cqlsh> describe keyspaces;
system_virtual_schema system_auth data_endpoint_auth system_traces
temporal_visibility system_views better_reads ecommerce
netflix system spring_petclinic todos
system_schema datastax_sla native_java feeds_reader
token@cqlsh>
- List
better_reads
tables
use better_reads;
describe tables;
- Check that expected tables are there
token@cqlsh:better_reads> describe tables;
author_by_id books_by_user book_by_id book_by_user_and_bookid
- Let this panel opened but for following command we will be back to the termimal
- Check you have the dataset ready. In the
BASH
terminal (β οΈ = NOT the cqlsh). You should see the cql filebook_by_id_0.csv
.
ls -l /workspace/workshop-betterreads/dataset/
- Check how many rows. It should have more than 250k.
wc -l /workspace/workshop-betterreads/dataset/book_by_id_0.csv
- Check that Datastax bulk loader is properly installed (It has been installed for you at startup)
/workspace/workshop-betterreads/tools/dsbulk-1.8.0/bin/dsbulk --version
- Import the DataSet with the following command
/workspace/workshop-betterreads/tools/dsbulk-1.8.0/bin/dsbulk load \
-c csv \
-k better_reads \
-t book_by_id \
-u token \
-p ${ASTRA_DB_ADMIN_TOKEN} \
-maxErrors -1 \
-b /home/gitpod/.astra/scb_${ASTRA_DB_ID}_${ASTRA_DB_REGION}.zip \
-url /workspace/workshop-betterreads/dataset/book_by_id_0.csv
- The batch is running and should be able to see the throughput at ~3k records per second.
Picked up JAVA_TOOL_OPTIONS: -Xmx2576m
Username and password provided but auth provider not specified, inferring PlainTextAuthProvider
A cloud secure connect bundle was provided: ignoring all explicit contact points.
A cloud secure connect bundle was provided and selected operation performs writes: changing default consistency level to LOCAL_QUORUM.
Operation directory: /workspace/workshop-betterreads/logs/LOAD_20220214-132501-509314
total | failed | rows/s | p50ms | p99ms | p999ms | batches
17,152 | 0 | 3,074 | 22.68 | 58.98 | 103.81 | 1.00
- The operation should take about 1 minute to complete. The file can have some errors like invalid title with special characters. IT IS NOT A PROBLEM the dataset is not perfect we will have some failed rows.
total | failed | rows/s | p50ms | p99ms | p999ms | batches
250,000 | 183 | 3,684 | 21.44 | 56.10 | 66.32 | 1.00
Operation LOAD_20220214-185449-001328 completed with 183 errors in 1 minute and 7 seconds.
-
In the same way - you can also now import
book_by_id_1.csv
. -
Count Records in the table
book_by_id
/workspace/workshop-betterreads/tools/dsbulk-1.8.0/bin/dsbulk count \
-k better_reads \
-t book_by_id \
-u token \
-p ${ASTRA_DB_ADMIN_TOKEN} \
-b /home/gitpod/.astra/scb_${ASTRA_DB_ID}_${ASTRA_DB_REGION}.zip
- Expected output (about 500.000k), during the live speaker will have more because he imported way more files.
Picked up JAVA_TOOL_OPTIONS: -Xmx2576m
Username and password provided but auth provider not specified, inferring PlainTextAuthProvider
A cloud secure connect bundle was provided: ignoring all explicit contact points.
Operation directory: /workspace/workshop-betterreads/logs/COUNT_20220214-190203-775866
total | failed | rows/s | p50ms | p99ms | p999ms
499,679 | 0 | 57,806 | 210.15 | 6,207.57 | 6,207.57
Operation COUNT_20220214-190203-775866 completed successfully in 8 seconds.
499679
- It would be handy to know the URL of the application
gp url 8080
- Start the app
cd /workspace/workshop-betterreads/better-reads-webapp
mvn spring-boot:run
- Output
________ __ __ ________ .__
\______ \ _____ _/ |______ _______/ |______ ___ ___ \______ \ _______ __ ____ | | ____ ______ ___________ ______
| | \\__ \\ __\__ \ / ___/\ __\__ \ \ \/ / | | \_/ __ \ \/ // __ \| | / _ \\____ \_/ __ \_ __ \/ ___/
| ` \/ __ \| | / __ \_\___ \ | | / __ \_> < | ` \ ___/\ /\ ___/| |_( <_> ) |_> > ___/| | \/\___ \
/_______ (____ /__| (____ /____ > |__| (____ /__/\_ \ /_______ /\___ >\_/ \___ >____/\____/| __/ \___ >__| /____ >
\/ \/ \/ \/ \/ \/ \/ \/ \/ |__| \/ \/
BetterReads with Spring Boot, String Data, Spring NVC, Spring security
An application by JabaBrains.
The application will start at http://localhost:8080
13:37:20.276 INFO com.datastax.astra.sdk.AstraClient : Setup of AstraClient from application.yml
13:37:20.280 INFO com.datastax.astra.sdk.config.AstraClientConfig : Initializing [AstraClient]
13:37:20.459 INFO com.datastax.astra.sdk.AstraClient : + API(s) Devops [ENABLED]
13:37:20.459 INFO com.datastax.astra.sdk.AstraClient : + Db: id [3ed83de7-d97f-4fb6-bf9f-82e9f7eafa23] and region [eu-west-1]
13:37:20.460 INFO com.datastax.astra.sdk.AstraClient : + Downloading bundles in: [/home/gitpod/.astra]
13:37:21.124 INFO com.datastax.astra.sdk.databases.DatabaseClient : + SecureBundle found : scb_3ed83de7-d97f-4fb6-bf9f-82e9f7eafa23_eu-west-1.zip
13:37:21.124 INFO com.datastax.astra.sdk.databases.DatabaseClient : + SecureBundle found : scb_3ed83de7-d97f-4fb6-bf9f-82e9f7eafa23_eu-central-1.zip
13:37:23.041 INFO com.datastax.astra.sdk.AstraClient : [AstraClient] has been initialized.
- Open a new terminal (yes a 3rd one again, 2 previous are busy, same icon) and enter the command.
gp preview $(gp url 8080)
- In the search item look for
Glimpses of ancient Sowams
you can search to whatever you want it will request open library ut during this workshop you only imported a subset of books, let us pick one you imported.
- Select the first item, if you select the second you will hit the page book not found as this book is not in the DB.
This is only what we can do at this point. To mark the book as read we will need to authenticate with Google
or Github
.
-
Connect to Google Cloud Platform
-
Create a new project if needed, on the screens i put
BetterReadsDemoApps
and click[CREATE]]
- Select
[ENABLE APIS AND SERVICES]
in menu
- Search for Gmail and Google Analytics Apis and add them to your project.
- Select
[OAuth consent screen]
in the menu on the left. Provide your application name, a support email and the application logo.
- Check
External
(or internal as you prefer to limit scope).
- On menu in the left select Credentials and use the button on top
[CREATE CREDENTIALS]
/ OAuth ClientID.
- Select
Web Application
and provide it a name
- Add the URL home page. It will the result of
gp url 8080
command on gitpod or http://localhost:8080 if you work locally.
The screenshots below show Google
authentication when the app is running on localhost
. Carefully adjust the URLs accordingly to the Gitpod URL when application is running on Gitpod.
- Add the redirect http://localhost:8080/login/oauth2/code/google if you work locally or the result of
echo $(gp url 8080)/login/oauth2/code/google
on gitpod.
- A new page will open with your
clientId
andclient Secret
. Make sure you copy them locallym you will need to setup your application with it.
You are now doomed we will now mine cryptos with your google account.
Just kidding ^_^
- Open file
src/main/resources/application.yml
in your project
gp open /workspace/workshop-betterreads/better-reads-webapp/src/main/resources/application.yml
- Changes keys
client-id
andclient-secret
with your values for the providerGoogle
.
security:
oauth2:
client:
registration:
google:
client-id: change
client-secret: change
As each attendee has a different URL in gitpod, you will have to create your own github `OAuth Apps - Let's do this together.
- For github settings we will have to enter a callback URL. To know which one enter use the following command
clear
echo $(gp url 8080)/login/oauth2/code/github
- Login to your github account and go to
Organizations
- There scroll down to locate the last item of the menu
Developer Settings
(hopefully you have not as many organizations as me), There pickOAuth Apps
(we are using OAuth)
- Click button
[New OAuth Apps]
on the page
- You will be asked to login again for security reasons, then fill the form to register a new Github App. Thre Register your application
Name | Value |
---|---|
Application name |
The application name shown to user |
Homepage URL |
Can be anything, just the app (gp url 8080) |
Authorization Callback URL |
Call back url the one listed above ${homepage}/login/oauth2/code/github |
- Click
[Register Application]
- The application is created. You got your clientId. You will have to generate a clientSecret now. Once you get both save them on a text file in your machine we will need them later
- When everything is set you can upload am image for your application and save the change with
[Update Application]
.
-
Open
application.yml
-
Open file
src/main/resources/application.yml
in your project
gp open /workspace/workshop-betterreads/better-reads-webapp/src/main/resources/application.yml
- Changes keys
client-id
andclient-secret
with your values for the providerGithub
.
security:
oauth2:
client:
registration:
github:
client-id: change
client-secret: change
- After setting up the connection you can now start the application again :
cd /workspace/workshop-betterreads/better-reads-webapp
mvn spring-boot:run
- On homepage click on
Authenticate with Github
- Eventually you get the SSO screen for you organization
- Then you authorize the application again
HAHAHA EVIL LAUGH
YOU ARE DOOMED AGAIN WE ALSO HAVE YOUR GITHUB ACCOUNT NOW
WE WILL FEED OUR TROLLS AND CODEX.AI WITH IT.
- More seriously, Your are in !
- Use the button
[Login via Google]
- Validate with the familiar Google Screen
- You are in !
Don't forget to complete your assignment and get your verified skill badge! Finish and submit your homework!
-
Complete the practice steps as described below until you have your own app running in Gitpod. (up to step 11)
-
Answer the technical questions in the form (We promise, it is NOT difficult if you follow the workshop).
-
Take a screenshot of you authenticated in the app with a few books
-
Submit your homework here
-
(totally optional) Watch the full course on Javabrains.io
- 01 - Introduction to the series
- 02 - About the app
- 03 - System Design
- 04 - Cassandra Schema
- 05 - Setting up hosted
- 06 - Creating the Data Loader
- 07 - Connecting Spring Boot app to DataStax Astra
- 08 - Using Repository pattern with Spring Data
- 09 - Saving all the authors in the world to Cassandra
- 10 - Setting up books by ID
- 11 - Starting with Spring boot and security
- 12 - Implementing the Book view flow
- 13 - Building book search feature
- 14 - Tracking user interactions with books
- 15 - Building the My Books feature
- 16 - Wrapping Up