Skip to content

Commit 9c6dd91

Browse files
committed
Initial commit
0 parents  commit 9c6dd91

File tree

111 files changed

+23841
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+23841
-0
lines changed

.github/workflows/ci.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: CI
2+
on: [push]
3+
env:
4+
CI: 'true'
5+
jobs:
6+
tests:
7+
strategy:
8+
matrix:
9+
java: [1.8,8]
10+
os: [ubuntu-latest]
11+
runs-on: ${{ matrix.os }}
12+
name: ci tests java-${{ matrix.java }}
13+
steps:
14+
- uses: actions/checkout@v1
15+
- uses: docker-practice/actions-setup-docker@master
16+
- uses: actions/cache@v1
17+
with:
18+
path: ~/.docker
19+
key: ${{ runner.os }}-docker-${{ hashFiles('**/Dockerfile') }}
20+
restore-keys: |
21+
${{ runner.os }}-docker-
22+
- uses: actions/setup-java@v1
23+
with:
24+
java-version: ${{ matrix.java }}
25+
- run: cd $GITHUB_WORKSPACE && docker-compose build
26+
- run: cd $GITHUB_WORKSPACE && docker-compose up -d
27+
- run: |
28+
( cd $GITHUB_WORKSPACE && docker-compose logs -f -t & ) || echo oops..
29+
sleep 1m
30+
cd $GITHUB_WORKSPACE && docker-compose down -v

.gitignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
### IntelliJ IDEA ###
2+
.idea
3+
*.iws
4+
*.iml
5+
*.ipr
6+
*.log*
7+
.gradle/
8+
target/
9+
build/
10+
out/
11+
.cache/
12+
.DS_Store
13+
node_modules/
14+
#package-lock.json
15+
#src/main/resources/static/
16+
17+
### STS ###
18+
.apt_generated
19+
.classpath
20+
.factorypath
21+
.project
22+
.settings
23+
.springBeans
24+
.sts4-cache
25+
26+
### NetBeans ###
27+
/nbproject/private/
28+
/nbbuild/
29+
/dist/
30+
/nbdist/
31+
/.nb-gradle/
32+
33+
### VS Code ###
34+
.vscode/

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# spring-boot mysql jwt security react [![CI](https://github.com/daggerok/spring-boot-jpa-react-jwt-auth-app/workflows/CI/badge.svg)](https://github.com/daggerok/spring-boot-jpa-react-jwt-auth-app/actions?query=workflow%3ACI)
2+
Spring Boot MySQL JPA Backend | React Frontend | JWT Secured App
3+
4+
1. get
5+
```bash
6+
git clone ... ; cd ...
7+
```
8+
1. build and run
9+
```bash
10+
docker-compose up --build --force-recreate
11+
```
12+
1. open http://127.0.0.1:80/
13+
1. sign up
14+
1. sign in
15+
1. create pool
16+
1. vote
17+
1. cleanup
18+
```bash
19+
docker-compose down -v --remove-orphans
20+
```
21+
22+
[YouTube: How to Work with Various Kubernetes Objects to Host a Spring Boot App](https://www.youtube.com/watch?v=V2FQuFGrmXQ)

Readme.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
## Building a Full Stack Polls app similar to twitter polls with Spring Boot, Spring Security, JWT, React and Ant Design
2+
3+
![App Screenshot](screenshot.png)
4+
5+
### Tutorials
6+
7+
I've written a complete tutorial series for this application on The CalliCoder Blog -
8+
9+
+ [Part 1: Bootstrapping the Project and creating the basic domain models and repositories](https://www.callicoder.com/spring-boot-spring-security-jwt-mysql-react-app-part-1/)
10+
11+
+ [Part 2: Configuring Spring Security along with JWT authentication and Building Rest APIs for Login and SignUp](https://www.callicoder.com/spring-boot-spring-security-jwt-mysql-react-app-part-2/)
12+
13+
+ [Part 3: Building Rest APIs for creating Polls, voting for a choice in a Poll, retrieving user profile etc](https://www.callicoder.com/spring-boot-spring-security-jwt-mysql-react-app-part-3/)
14+
15+
+ [Part 4: Building the front-end using React and Ant Design](https://www.callicoder.com/spring-boot-spring-security-jwt-mysql-react-app-part-4/)
16+
17+
## Steps to Setup the Spring Boot Back end app (polling-app-server)
18+
19+
1. **Clone the application**
20+
21+
```bash
22+
git clone https://github.com/callicoder/spring-security-react-ant-design-polls-app.git
23+
cd polling-app-server
24+
```
25+
26+
2. **Create MySQL database**
27+
28+
```bash
29+
create database polling_app
30+
```
31+
32+
3. **Change MySQL username and password as per your MySQL installation**
33+
34+
+ open `src/main/resources/application.properties` file.
35+
36+
+ change `spring.datasource.username` and `spring.datasource.password` properties as per your mysql installation
37+
38+
4. **Run the app**
39+
40+
You can run the spring boot app by typing the following command -
41+
42+
```bash
43+
mvn spring-boot:run
44+
```
45+
46+
The server will start on port 8080.
47+
48+
You can also package the application in the form of a `jar` file and then run it like so -
49+
50+
```bash
51+
mvn package
52+
java -jar target/polls-0.0.1-SNAPSHOT.jar
53+
```
54+
5. **Default Roles**
55+
56+
The spring boot app uses role based authorization powered by spring security. To add the default roles in the
57+
database, I have added the following sql queries in `src/main/resources/db/migration/V2__user_role.sql` and
58+
`src/main/resources/db/migration/V3__admin_role.sql` files.
59+
Spring boot will automatically execute this script on startup -
60+
61+
```sql
62+
INSERT IGNORE INTO roles(name) VALUES('ROLE_USER');
63+
INSERT IGNORE INTO roles(name) VALUES('ROLE_ADMIN');
64+
```
65+
66+
Any new user who signs up to the app is assigned the `ROLE_USER` by default.
67+
68+
## Steps to Setup the React Front end app (polling-app-client)
69+
70+
First go to the `polling-app-client` folder -
71+
72+
```bash
73+
cd polling-app-client
74+
```
75+
76+
Then type the following command to install the dependencies and start the application -
77+
78+
```bash
79+
npm install && npm start
80+
```
81+
82+
The front-end server will start on port `3000`.

deployments/kustomization.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# The secrets file should not be checked into Git. It's published only for demonstration purpose.
2+
secretGenerator:
3+
- name: mysql-root-pass
4+
literals:
5+
- password=R00t
6+
- name: mysql-user-pass
7+
literals:
8+
- username=callicoder
9+
- password=c@ll1c0d3r
10+
- name: mysql-db-url
11+
literals:
12+
- database=polls
13+
- url=jdbc:mysql://polling-app-mysql:3306/polls?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
14+
resources:
15+
- mysql-deployment.yaml
16+
- polling-app-server.yaml
17+
- polling-app-client.yaml

deployments/mysql-deployment.yaml

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
apiVersion: v1
2+
kind: PersistentVolume # Create a PersistentVolume
3+
metadata:
4+
name: mysql-pv
5+
labels:
6+
type: local
7+
spec:
8+
storageClassName: standard # Storage class. A PV Claim requesting the same storageClass can be bound to this volume.
9+
capacity:
10+
storage: 250Mi
11+
accessModes:
12+
- ReadWriteOnce
13+
hostPath: # hostPath PersistentVolume is used for development and testing. It uses a file/directory on the Node to emulate network-attached storage
14+
path: "/mnt/data"
15+
persistentVolumeReclaimPolicy: Retain # Retain the PersistentVolume even after PersistentVolumeClaim is deleted. The volume is considered “released”. But it is not yet available for another claim because the previous claimant’s data remains on the volume.
16+
---
17+
apiVersion: v1
18+
kind: PersistentVolumeClaim # Create a PersistentVolumeClaim to request a PersistentVolume storage
19+
metadata: # Claim name and labels
20+
name: mysql-pv-claim
21+
labels:
22+
app: polling-app
23+
spec: # Access mode and resource limits
24+
storageClassName: standard # Request a certain storage class
25+
accessModes:
26+
- ReadWriteOnce # ReadWriteOnce means the volume can be mounted as read-write by a single Node
27+
resources:
28+
requests:
29+
storage: 250Mi
30+
---
31+
apiVersion: v1 # API version
32+
kind: Service # Type of kubernetes resource
33+
metadata:
34+
name: polling-app-mysql # Name of the resource
35+
labels: # Labels that will be applied to the resource
36+
app: polling-app
37+
spec:
38+
ports:
39+
- port: 3306
40+
selector: # Selects any Pod with labels `app=polling-app,tier=mysql`
41+
app: polling-app
42+
tier: mysql
43+
clusterIP: None
44+
---
45+
apiVersion: apps/v1
46+
kind: Deployment # Type of the kubernetes resource
47+
metadata:
48+
name: polling-app-mysql # Name of the deployment
49+
labels: # Labels applied to this deployment
50+
app: polling-app
51+
spec:
52+
selector:
53+
matchLabels: # This deployment applies to the Pods matching the specified labels
54+
app: polling-app
55+
tier: mysql
56+
strategy:
57+
type: Recreate
58+
template: # Template for the Pods in this deployment
59+
metadata:
60+
labels: # Labels to be applied to the Pods in this deployment
61+
app: polling-app
62+
tier: mysql
63+
spec: # The spec for the containers that will be run inside the Pods in this deployment
64+
containers:
65+
- image: mysql:5.6 # The container image
66+
name: mysql
67+
env: # Environment variables passed to the container
68+
- name: MYSQL_ROOT_PASSWORD
69+
valueFrom: # Read environment variables from kubernetes secrets
70+
secretKeyRef:
71+
name: mysql-root-pass
72+
key: password
73+
- name: MYSQL_DATABASE
74+
valueFrom:
75+
secretKeyRef:
76+
name: mysql-db-url
77+
key: database
78+
- name: MYSQL_USER
79+
valueFrom:
80+
secretKeyRef:
81+
name: mysql-user-pass
82+
key: username
83+
- name: MYSQL_PASSWORD
84+
valueFrom:
85+
secretKeyRef:
86+
name: mysql-user-pass
87+
key: password
88+
ports:
89+
- containerPort: 3306 # The port that the container exposes
90+
name: mysql
91+
volumeMounts:
92+
- name: mysql-persistent-storage # This name should match the name specified in `volumes.name`
93+
mountPath: /var/lib/mysql
94+
volumes: # A PersistentVolume is mounted as a volume to the Pod
95+
- name: mysql-persistent-storage
96+
persistentVolumeClaim:
97+
claimName: mysql-pv-claim

deployments/polling-app-client.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
apiVersion: apps/v1 # API version
2+
kind: Deployment # Type of kubernetes resource
3+
metadata:
4+
name: polling-app-client # Name of the kubernetes resource
5+
spec:
6+
replicas: 1 # No of replicas/pods to run
7+
selector:
8+
matchLabels: # This deployment applies to Pods matching the specified labels
9+
app: polling-app-client
10+
template: # Template for creating the Pods in this deployment
11+
metadata:
12+
labels: # Labels that will be applied to all the Pods in this deployment
13+
app: polling-app-client
14+
spec: # Spec for the containers that will run inside the Pods
15+
containers:
16+
- name: polling-app-client
17+
image: callicoder/polling-app-client:1.0.0
18+
imagePullPolicy: IfNotPresent
19+
ports:
20+
- name: http
21+
containerPort: 80 # Should match the Port that the container listens on
22+
resources:
23+
limits:
24+
cpu: 0.2
25+
memory: "10Mi"
26+
---
27+
apiVersion: v1 # API version
28+
kind: Service # Type of kubernetes resource
29+
metadata:
30+
name: polling-app-client # Name of the kubernetes resource
31+
spec:
32+
type: NodePort # Exposes the service by opening a port on each node
33+
selector:
34+
app: polling-app-client # Any Pod matching the label `app=polling-app-client` will be picked up by this service
35+
ports: # Forward incoming connections on port 80 to the target port 80 in the Pod
36+
- name: http
37+
port: 80
38+
targetPort: 80

deployments/polling-app-server.yaml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
apiVersion: apps/v1 # API version
2+
kind: Deployment # Type of kubernetes resource
3+
metadata:
4+
name: polling-app-server # Name of the kubernetes resource
5+
labels: # Labels that will be applied to this resource
6+
app: polling-app-server
7+
spec:
8+
replicas: 1 # No. of replicas/pods to run in this deployment
9+
selector:
10+
matchLabels: # The deployment applies to any pods mayching the specified labels
11+
app: polling-app-server
12+
template: # Template for creating the pods in this deployment
13+
metadata:
14+
labels: # Labels that will be applied to each Pod in this deployment
15+
app: polling-app-server
16+
spec: # Spec for the containers that will be run in the Pods
17+
containers:
18+
- name: polling-app-server
19+
image: callicoder/polling-app-server:1.0.0
20+
imagePullPolicy: IfNotPresent
21+
ports:
22+
- name: http
23+
containerPort: 8080 # The port that the container exposes
24+
resources:
25+
limits:
26+
cpu: 0.2
27+
memory: "200Mi"
28+
env: # Environment variables supplied to the Pod
29+
- name: SPRING_DATASOURCE_USERNAME # Name of the environment variable
30+
valueFrom: # Get the value of environment variable from kubernetes secrets
31+
secretKeyRef:
32+
name: mysql-user-pass
33+
key: username
34+
- name: SPRING_DATASOURCE_PASSWORD
35+
valueFrom:
36+
secretKeyRef:
37+
name: mysql-user-pass
38+
key: password
39+
- name: SPRING_DATASOURCE_URL
40+
valueFrom:
41+
secretKeyRef:
42+
name: mysql-db-url
43+
key: url
44+
---
45+
apiVersion: v1 # API version
46+
kind: Service # Type of the kubernetes resource
47+
metadata:
48+
name: polling-app-server # Name of the kubernetes resource
49+
labels: # Labels that will be applied to this resource
50+
app: polling-app-server
51+
spec:
52+
type: NodePort # The service will be exposed by opening a Port on each node and proxying it.
53+
selector:
54+
app: polling-app-server # The service exposes Pods with label `app=polling-app-server`
55+
ports: # Forward incoming connections on port 8080 to the target port 8080
56+
- name: http
57+
port: 8080
58+
targetPort: 8080

0 commit comments

Comments
 (0)