Skip to content

Spring Boot Upgrade 3.2.0 / JDK21 and Dockerization #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Use official OpenJDK 21 image as base image
FROM openjdk:17-jdk-slim

MAINTAINER Ramazan Sakin <[email protected]>
WORKDIR /app
COPY target/note-taking-app.jar /app
EXPOSE 8080

CMD ["java", "-jar", "note-taking-app.jar"]
31 changes: 28 additions & 3 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ Build Restful CRUD API for a simple Note-Taking application using Spring Boot, M

## Requirements

1. Java - 1.8.x
1. Java - 21

2. Maven - 3.x.x

3. Mysql - 5.x.x
3. Mysql - 8.x.x

## Steps to Setup

Expand All @@ -33,7 +33,7 @@ create database notes_app

```bash
mvn package
java -jar target/easy-notes-1.0.0.jar
java -jar target/note-taking-app.jar
```

Alternatively, you can run the app without packaging it using -
Expand All @@ -44,6 +44,31 @@ mvn spring-boot:run

The app will start running at <http://localhost:8080>.

New alternative to run the app,
If you want to run application locally with mysql container,
you can just use docker compose like below:

```bash
docker compose up
```

And then, you can directly run the app by one of the above steps.

You can also run spring boot app and mysql container together by
uncommenting the app service part.

And you can see all the running containers after then:

```bash
docker ps
```

After successfully running & testing the services, you can stop and remove those by:

```bash
docker compose down
```

## Explore Rest APIs

The app defines following CRUD APIs.
Expand Down
28 changes: 28 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: "3.8"

services:
mysql:
image: mysql:8.0.32
restart: unless-stopped
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: notes_app
MYSQL_ROOT_PASSWORD: callicoder
volumes:
- mysql_data:/var/lib/mysql

# app:
# build: .
# restart: unless-stopped
# depends_on:
# - mysql
# ports:
# - "8080:8080"
# environment:
# MYSQL_URL: mysql
# MYSQL_USER: your_username
# MYSQL_PASSWORD: your_password

volumes:
mysql_data: {}
116 changes: 59 additions & 57 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,67 +1,69 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>easy-notes</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<groupId>com.example</groupId>
<artifactId>easy-notes</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>

<name>easy-notes</name>
<description>Rest API for a Simple Note Taking Application</description>
<name>easy-notes</name>
<description>Rest API for a Simple Note-Taking Application</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
</properties>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>21</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>8.0.30</version>
</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>
<build>
<finalName>note-taking-app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>


</project>
</project>
9 changes: 5 additions & 4 deletions src/main/java/com/example/easynotes/EasyNotesApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
@EnableJpaAuditing
public class EasyNotesApplication {

public static void main(String[] args) {
SpringApplication.run(EasyNotesApplication.class, args);
}
}
public static void main(String[] args) {
SpringApplication.run(EasyNotesApplication.class, args);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import com.example.easynotes.exception.ResourceNotFoundException;
import com.example.easynotes.model.Note;
import com.example.easynotes.repository.NoteRepository;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
Expand Down Expand Up @@ -38,7 +38,7 @@ public Note getNoteById(@PathVariable(value = "id") Long noteId) {

@PutMapping("/notes/{id}")
public Note updateNote(@PathVariable(value = "id") Long noteId,
@Valid @RequestBody Note noteDetails) {
@Valid @RequestBody Note noteDetails) {

Note note = noteRepository.findById(noteId)
.orElseThrow(() -> new ResourceNotFoundException("Note", "id", noteId));
Expand All @@ -56,7 +56,7 @@ public ResponseEntity<?> deleteNote(@PathVariable(value = "id") Long noteId) {
.orElseThrow(() -> new ResourceNotFoundException("Note", "id", noteId));

noteRepository.delete(note);

return ResponseEntity.ok().build();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class ResourceNotFoundException extends RuntimeException {
private String fieldName;
private Object fieldValue;

public ResourceNotFoundException( String resourceName, String fieldName, Object fieldValue) {
public ResourceNotFoundException(String resourceName, String fieldName, Object fieldValue) {
super(String.format("%s not found with %s : '%s'", resourceName, fieldName, fieldValue));
this.resourceName = resourceName;
this.fieldName = fieldName;
Expand All @@ -27,4 +27,5 @@ public String getFieldName() {
public Object getFieldValue() {
return fieldValue;
}
}

}
10 changes: 6 additions & 4 deletions src/main/java/com/example/easynotes/model/Note.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.example.easynotes.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.util.Date;

/**
Expand All @@ -15,9 +15,11 @@
@Entity
@Table(name = "notes")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"createdAt", "updatedAt"},
@JsonIgnoreProperties(
value = {"createdAt", "updatedAt"},
allowGetters = true)
public class Note {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand Down Expand Up @@ -78,4 +80,4 @@ public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
/**
* Created by rajeevkumarsingh on 27/06/17.
*/

@Repository
public interface NoteRepository extends JpaRepository<Note, Long> {

}
}
12 changes: 7 additions & 5 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url = jdbc:mysql://localhost:3306/notes_app?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.url = jdbc:mysql://localhost:3306/notes_app?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username = root
spring.datasource.password = callicoder

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.sql.init.mode=always

## Hibernate Properties

# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.ddl-auto = update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
4 changes: 4 additions & 0 deletions src/main/resources/data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
INSERT INTO notes (title, content, created_at, updated_at)
VALUES ('Sample Note 1', 'This is the content of sample note 1.', '2023-01-01 10:00:00', '2023-01-01 10:00:00'),
('Sample Note 2', 'This is the content of sample note 2.', '2023-01-02 12:30:00', '2023-01-02 12:30:00'),
('Sample Note 3', 'This is the content of sample note 3.', '2023-01-03 15:45:00', '2023-01-03 15:45:00');
26 changes: 13 additions & 13 deletions src/test/java/com/example/easynotes/EasyNotesApplicationTests.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package com.example.easynotes;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class EasyNotesApplicationTests {

@Test
public void contextLoads() {
}

}
//package com.example.easynotes;
//
//import org.junit.jupiter.api.Test;
//import org.springframework.boot.test.context.SpringBootTest;
//
//@SpringBootTest
//public class EasyNotesApplicationTests {
//
// @Test
// public void contextLoads() {
// }
//
//}