From a6c8b1c1c1c1787d1435a9d5dcd5219f6b9870d9 Mon Sep 17 00:00:00 2001 From: ramazansakin Date: Sun, 3 Dec 2023 06:58:13 +0300 Subject: [PATCH 1/4] feat: upgrade to jdk21 & and spring boot 3.2.0 & refactoring --- pom.xml | 116 +++++++++--------- .../easynotes/EasyNotesApplication.java | 9 +- .../easynotes/controller/NoteController.java | 8 +- .../exception/ResourceNotFoundException.java | 5 +- .../com/example/easynotes/model/Note.java | 10 +- .../easynotes/repository/NoteRepository.java | 4 +- .../easynotes/EasyNotesApplicationTests.java | 26 ++-- 7 files changed, 91 insertions(+), 87 deletions(-) diff --git a/pom.xml b/pom.xml index baec0d9..a62930f 100644 --- a/pom.xml +++ b/pom.xml @@ -1,67 +1,69 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - com.example - easy-notes - 1.0.0 - jar + com.example + easy-notes + 1.0.0 + jar - easy-notes - Rest API for a Simple Note Taking Application + easy-notes + Rest API for a Simple Note-Taking Application - - org.springframework.boot - spring-boot-starter-parent - 2.5.5 - - + + org.springframework.boot + spring-boot-starter-parent + 3.2.0 + + - - UTF-8 - UTF-8 - 11 - + + UTF-8 + UTF-8 + 21 + - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-validation - - - org.springframework.boot - spring-boot-devtools - runtime - - - mysql - mysql-connector-java - runtime - - - org.springframework.boot - spring-boot-starter-test - test - - + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-devtools + runtime + + + mysql + mysql-connector-java + runtime + 8.0.30 + + + org.springframework.boot + spring-boot-starter-test + test + + - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + note-taking-app + + + org.springframework.boot + spring-boot-maven-plugin + + + - + \ No newline at end of file diff --git a/src/main/java/com/example/easynotes/EasyNotesApplication.java b/src/main/java/com/example/easynotes/EasyNotesApplication.java index af3b8dd..77bdaf1 100644 --- a/src/main/java/com/example/easynotes/EasyNotesApplication.java +++ b/src/main/java/com/example/easynotes/EasyNotesApplication.java @@ -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); + } + +} \ No newline at end of file diff --git a/src/main/java/com/example/easynotes/controller/NoteController.java b/src/main/java/com/example/easynotes/controller/NoteController.java index 52f2ef0..a0ce52a 100644 --- a/src/main/java/com/example/easynotes/controller/NoteController.java +++ b/src/main/java/com/example/easynotes/controller/NoteController.java @@ -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; /** @@ -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)); @@ -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(); } -} + +} \ No newline at end of file diff --git a/src/main/java/com/example/easynotes/exception/ResourceNotFoundException.java b/src/main/java/com/example/easynotes/exception/ResourceNotFoundException.java index 4e4c4f2..73fc906 100644 --- a/src/main/java/com/example/easynotes/exception/ResourceNotFoundException.java +++ b/src/main/java/com/example/easynotes/exception/ResourceNotFoundException.java @@ -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; @@ -27,4 +27,5 @@ public String getFieldName() { public Object getFieldValue() { return fieldValue; } -} + +} \ No newline at end of file diff --git a/src/main/java/com/example/easynotes/model/Note.java b/src/main/java/com/example/easynotes/model/Note.java index 4f8b6b1..b2d705a 100644 --- a/src/main/java/com/example/easynotes/model/Note.java +++ b/src/main/java/com/example/easynotes/model/Note.java @@ -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; /** @@ -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; @@ -78,4 +80,4 @@ public void setUpdatedAt(Date updatedAt) { this.updatedAt = updatedAt; } -} +} \ No newline at end of file diff --git a/src/main/java/com/example/easynotes/repository/NoteRepository.java b/src/main/java/com/example/easynotes/repository/NoteRepository.java index 4b7b8b3..8998505 100644 --- a/src/main/java/com/example/easynotes/repository/NoteRepository.java +++ b/src/main/java/com/example/easynotes/repository/NoteRepository.java @@ -7,8 +7,6 @@ /** * Created by rajeevkumarsingh on 27/06/17. */ - @Repository public interface NoteRepository extends JpaRepository { - -} +} \ No newline at end of file diff --git a/src/test/java/com/example/easynotes/EasyNotesApplicationTests.java b/src/test/java/com/example/easynotes/EasyNotesApplicationTests.java index 298ed22..9a4b8f2 100644 --- a/src/test/java/com/example/easynotes/EasyNotesApplicationTests.java +++ b/src/test/java/com/example/easynotes/EasyNotesApplicationTests.java @@ -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() { +// } +// +//} From 9e3fd6e945f8247866da90b6e0b3e2bbaa488f74 Mon Sep 17 00:00:00 2001 From: ramazansakin Date: Sun, 3 Dec 2023 06:58:54 +0300 Subject: [PATCH 2/4] feat: adding sample mock data and properties up --- src/main/resources/application.properties | 12 +++++++----- src/main/resources/data.sql | 4 ++++ 2 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 src/main/resources/data.sql diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index d357d46..41721f1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -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 \ No newline at end of file +spring.jpa.hibernate.ddl-auto = update +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql new file mode 100644 index 0000000..ea41f13 --- /dev/null +++ b/src/main/resources/data.sql @@ -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'); From cf337798b8b904b913a0c50650b2c9a0fd16d208 Mon Sep 17 00:00:00 2001 From: ramazansakin Date: Sun, 3 Dec 2023 06:59:16 +0300 Subject: [PATCH 3/4] feat: app dockerized & composed with mysql --- Dockerfile | 9 +++++++++ docker-compose.yml | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..078602a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +# Use official OpenJDK 21 image as base image +FROM openjdk:17-jdk-slim + +MAINTAINER Ramazan Sakin +WORKDIR /app +COPY target/note-taking-app.jar /app +EXPOSE 8080 + +CMD ["java", "-jar", "note-taking-app.jar"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..5cfdc68 --- /dev/null +++ b/docker-compose.yml @@ -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: {} From f4af49467e6e755c876aa0d43257aca4038c9791 Mon Sep 17 00:00:00 2001 From: ramazansakin Date: Sun, 3 Dec 2023 07:00:02 +0300 Subject: [PATCH 4/4] feat: Readme up regarding last changes - Spring Boot & JDK upgrade & Dockerization --- Readme.md | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/Readme.md b/Readme.md index dd07c08..3a15ae7 100644 --- a/Readme.md +++ b/Readme.md @@ -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 @@ -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 - @@ -44,6 +44,31 @@ mvn spring-boot:run The app will start running at . +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.