From 2137e67c8209612458ea3ee0235a70648ca35974 Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Wed, 25 Dec 2024 06:36:31 +0000 Subject: [PATCH 1/7] polish --- .../controller/RedisControllerTest.java | 3 +++ jpa/boot-read-replica-postgresql/pom.xml | 2 +- .../demo/readreplica/domain/ArticleDTO.java | 18 ++++++++++++- .../demo/readreplica/domain/CommentDTO.java | 9 ++++++- .../readreplica/service/ArticleService.java | 25 ++----------------- 5 files changed, 31 insertions(+), 26 deletions(-) diff --git a/boot-ultimate-redis/src/test/java/com/example/ultimateredis/controller/RedisControllerTest.java b/boot-ultimate-redis/src/test/java/com/example/ultimateredis/controller/RedisControllerTest.java index da5d7bebe..138a3e789 100644 --- a/boot-ultimate-redis/src/test/java/com/example/ultimateredis/controller/RedisControllerTest.java +++ b/boot-ultimate-redis/src/test/java/com/example/ultimateredis/controller/RedisControllerTest.java @@ -28,6 +28,7 @@ void addRedisKeyValue() throws Exception { .content(objectMapper.writeValueAsString(addRedisRequest)) .assertThat() .hasStatus(HttpStatus.CREATED) + .hasContentType(MediaType.APPLICATION_JSON) .bodyJson() .convertTo(GenericResponse.class) .satisfies(response -> assertThat(response.response()).isEqualTo(true)); @@ -42,6 +43,7 @@ void getFromCache() { .param("key", "junit") .assertThat() .hasStatusOk() + .hasContentType(MediaType.APPLICATION_JSON) .bodyJson() .convertTo(GenericResponse.class) .satisfies(response -> assertThat(response.response()).isEqualTo("JunitValue")); @@ -61,6 +63,7 @@ void expireFromCache() { .param("key", "junit") .assertThat() .hasStatusOk() + .hasContentType(MediaType.APPLICATION_JSON) .bodyJson() .convertTo(GenericResponse.class) .satisfies( diff --git a/jpa/boot-read-replica-postgresql/pom.xml b/jpa/boot-read-replica-postgresql/pom.xml index 97fd825bb..eacacc0ef 100644 --- a/jpa/boot-read-replica-postgresql/pom.xml +++ b/jpa/boot-read-replica-postgresql/pom.xml @@ -109,7 +109,7 @@ - 1.24.0 + 1.25.2 diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/domain/ArticleDTO.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/domain/ArticleDTO.java index 73796a871..4c480bf5f 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/domain/ArticleDTO.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/domain/ArticleDTO.java @@ -1,5 +1,9 @@ package com.example.demo.readreplica.domain; +import static com.example.demo.readreplica.domain.CommentDTO.convertToComment; + +import com.example.demo.readreplica.entities.Article; +import com.example.demo.readreplica.entities.Comment; import java.time.LocalDateTime; import java.util.List; @@ -7,4 +11,16 @@ public record ArticleDTO( String title, LocalDateTime authored, LocalDateTime published, - List commentDTOs) {} + List commentDTOs) { + + public Article convertToArticle() { + Article article = + new Article().setAuthored(authored).setTitle(title).setPublished(published); + commentDTOs.forEach( + commentDTO -> { + Comment comment = convertToComment(commentDTO); + article.addComment(comment); + }); + return article; + } +} diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/domain/CommentDTO.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/domain/CommentDTO.java index 5a34dccc5..e55001748 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/domain/CommentDTO.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/domain/CommentDTO.java @@ -1,3 +1,10 @@ package com.example.demo.readreplica.domain; -public record CommentDTO(String comment) {} +import com.example.demo.readreplica.entities.Comment; + +public record CommentDTO(String comment) { + + static Comment convertToComment(CommentDTO commentDTO) { + return new Comment().setComment(commentDTO.comment()); + } +} diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java index 9665ed99e..abfa0b3fc 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java @@ -3,14 +3,13 @@ import com.example.demo.readreplica.domain.ArticleDTO; import com.example.demo.readreplica.domain.CommentDTO; import com.example.demo.readreplica.entities.Article; -import com.example.demo.readreplica.entities.Comment; import com.example.demo.readreplica.repository.ArticleRepository; -import java.util.List; import java.util.Optional; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service +@Transactional(readOnly = true) public class ArticleService { private final ArticleRepository articleRepository; @@ -25,7 +24,7 @@ public Optional findArticleById(Integer id) { @Transactional public Long saveArticle(ArticleDTO articleDTO) { - Article article = convertToArticle(articleDTO); + Article article = articleDTO.convertToArticle(); Article savedArticle = this.articleRepository.save(article); return savedArticle.getId(); } @@ -39,24 +38,4 @@ private ArticleDTO convertToArticleDTO(Article articleEntity) { .map(comment -> new CommentDTO(comment.getComment())) .toList()); } - - private Article convertToArticle(ArticleDTO articleDTO) { - Article article = new Article(); - article.setAuthored(articleDTO.authored()); - article.setTitle(articleDTO.title()); - article.setPublished(articleDTO.published()); - convertToComment(articleDTO.commentDTOs()).forEach(article::addComment); - return article; - } - - private List convertToComment(List commentDTOs) { - return commentDTOs.stream() - .map( - commentDTO -> { - Comment comment = new Comment(); - comment.setComment(commentDTO.comment()); - return comment; - }) - .toList(); - } } From c996d811c9e23d370a2e63981c02de3377d41f75 Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Wed, 25 Dec 2024 07:24:09 +0000 Subject: [PATCH 2/7] feat : adds new testcases --- jpa/boot-read-replica-postgresql/pom.xml | 4 +- .../controller/ArticleController.java | 13 +++ .../readreplica/service/ArticleService.java | 9 ++ .../controller/ArticleControllerIntTest.java | 104 ++++++++++++++++++ 4 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java diff --git a/jpa/boot-read-replica-postgresql/pom.xml b/jpa/boot-read-replica-postgresql/pom.xml index eacacc0ef..3fd43f429 100644 --- a/jpa/boot-read-replica-postgresql/pom.xml +++ b/jpa/boot-read-replica-postgresql/pom.xml @@ -9,9 +9,9 @@ com.example.demo - boot-jpa-read-replica-postgresql + boot-read-replica-postgresql 0.0.1-SNAPSHOT - boot-jpa-read-replica-postgresql + boot-read-replica-postgresql Demo project for Spring Boot Read Replica diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java index 24e44e806..537dcc161 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java @@ -4,6 +4,7 @@ import com.example.demo.readreplica.service.ArticleService; import java.net.URI; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -34,4 +35,16 @@ ResponseEntity saveArticle(@RequestBody ArticleDTO articleDTO) { Long articleId = this.articleService.saveArticle(articleDTO); return ResponseEntity.created(URI.create("/articles/" + articleId)).build(); } + + @DeleteMapping("/{id}") + ResponseEntity deleteArticle(@PathVariable Long id) { + return this.articleService + .findById(id) + .map( + article -> { + articleService.deleteById(article.getId()); + return ResponseEntity.accepted().build(); + }) + .orElseGet(() -> ResponseEntity.notFound().build()); + } } diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java index abfa0b3fc..6063e910f 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java @@ -29,6 +29,15 @@ public Long saveArticle(ArticleDTO articleDTO) { return savedArticle.getId(); } + public Optional
findById(Long id) { + return articleRepository.findById(id); + } + + @Transactional + public void deleteById(Long id) { + articleRepository.deleteById(id); + } + private ArticleDTO convertToArticleDTO(Article articleEntity) { return new ArticleDTO( articleEntity.getTitle(), diff --git a/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java b/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java new file mode 100644 index 000000000..ea4cfe2e3 --- /dev/null +++ b/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java @@ -0,0 +1,104 @@ +package com.example.demo.readreplica.controller; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.example.demo.readreplica.domain.ArticleDTO; +import com.example.demo.readreplica.domain.CommentDTO; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.LocalDateTime; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.assertj.MockMvcTester; + +@SpringBootTest +@AutoConfigureMockMvc +class ArticleControllerIntTest { + + @Autowired private MockMvcTester mvcTester; + + @Autowired private ObjectMapper objectMapper; + + @Test + void findArticleById() { + + mvcTester + .get() + .uri("/articles/1") + .assertThat() + .hasStatusOk() + .hasContentType(MediaType.APPLICATION_JSON) + .bodyJson() + .convertTo(ArticleDTO.class) + .satisfies( + articleDTO -> { + assertThat(articleDTO.title()) + .isNotNull() + .isEqualTo("Waiter! There is a bug in my JSoup!"); + assertThat(articleDTO.authored()) + .isNotNull() + .isInstanceOf(LocalDateTime.class); + assertThat(articleDTO.published()) + .isNotNull() + .isInstanceOf(LocalDateTime.class); + assertThat(articleDTO.commentDTOs()) + .isNotNull() + .hasSize(2) + .hasOnlyElementsOfType(CommentDTO.class); + }); + } + + @Test + void saveArticle() throws JsonProcessingException { + ArticleDTO articleDTO = + new ArticleDTO( + "junitTitle", + LocalDateTime.now().minusDays(1), + LocalDateTime.now(), + List.of(new CommentDTO("junitComment"))); + AtomicReference location = new AtomicReference<>(); + mvcTester + .post() + .uri("/articles/") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(articleDTO)) + .assertThat() + .hasStatus(HttpStatus.CREATED) + .matches( + result -> { + location.set(result.getResponse().getHeader("Location")); + assertThat(location.get()).isNotBlank().contains("/articles/"); + }); + + mvcTester + .get() + .uri(location.get()) + .assertThat() + .hasStatusOk() + .hasContentType(MediaType.APPLICATION_JSON) + .bodyJson() + .convertTo(ArticleDTO.class) + .satisfies( + response -> { + assertThat(response.title()).isNotNull().isEqualTo("junitTitle"); + assertThat(response.authored()) + .isNotNull() + .isInstanceOf(LocalDateTime.class); + assertThat(response.published()) + .isNotNull() + .isInstanceOf(LocalDateTime.class); + assertThat(response.commentDTOs()) + .isNotNull() + .hasSize(1) + .hasOnlyElementsOfType(CommentDTO.class); + }); + + mvcTester.delete().uri(location.get()).assertThat().hasStatus(HttpStatus.ACCEPTED); + } +} From 90c86766441cf6d3ed21d3f21be8bd4928f17ec6 Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Wed, 25 Dec 2024 07:34:59 +0000 Subject: [PATCH 3/7] fix input type --- .../controller/ArticleController.java | 18 +++++++++--------- .../repository/ArticleRepository.java | 2 +- .../readreplica/service/ArticleService.java | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java index 537dcc161..4d11e7b22 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java @@ -4,13 +4,8 @@ import com.example.demo.readreplica.service.ArticleService; import java.net.URI; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @RestController @RequestMapping("/articles") @@ -23,7 +18,7 @@ class ArticleController { } @GetMapping("/{id}") - ResponseEntity findArticleById(@PathVariable Integer id) { + ResponseEntity findArticleById(@PathVariable Long id) { return this.articleService .findArticleById(id) .map(ResponseEntity::ok) @@ -33,7 +28,12 @@ ResponseEntity findArticleById(@PathVariable Integer id) { @PostMapping("/") ResponseEntity saveArticle(@RequestBody ArticleDTO articleDTO) { Long articleId = this.articleService.saveArticle(articleDTO); - return ResponseEntity.created(URI.create("/articles/" + articleId)).build(); + URI location = + ServletUriComponentsBuilder.fromCurrentRequest() + .path("{id}") + .buildAndExpand(articleId) + .toUri(); + return ResponseEntity.created(location).build(); } @DeleteMapping("/{id}") diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/repository/ArticleRepository.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/repository/ArticleRepository.java index 12e384944..0b735b2df 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/repository/ArticleRepository.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/repository/ArticleRepository.java @@ -11,5 +11,5 @@ public interface ArticleRepository extends JpaRepository { @Transactional(readOnly = true) @Query("select a from Article a left join fetch a.comments where a.id = :articleId ") - Optional
findByArticleId(@Param("articleId") Integer articleId); + Optional
findByArticleId(@Param("articleId") Long articleId); } diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java index 6063e910f..fa4886afe 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java @@ -18,7 +18,7 @@ public class ArticleService { this.articleRepository = articleRepository; } - public Optional findArticleById(Integer id) { + public Optional findArticleById(Long id) { return this.articleRepository.findByArticleId(id).map(this::convertToArticleDTO); } From 8beedfa3ca024173e6af86ee4b71349f0070a306 Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Wed, 25 Dec 2024 17:43:56 +0000 Subject: [PATCH 4/7] fix wildcard import --- .../demo/readreplica/controller/ArticleController.java | 8 +++++++- .../readreplica/controller/ArticleControllerIntTest.java | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java index 4d11e7b22..60a7700a5 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java @@ -4,7 +4,13 @@ import com.example.demo.readreplica.service.ArticleService; import java.net.URI; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @RestController diff --git a/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java b/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java index ea4cfe2e3..0b1fcb806 100644 --- a/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java +++ b/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java @@ -55,7 +55,7 @@ void findArticleById() { } @Test - void saveArticle() throws JsonProcessingException { + void saveArticleRetriveAndDelete() throws JsonProcessingException { ArticleDTO articleDTO = new ArticleDTO( "junitTitle", From d808bebfdaef2ed9699b334236e948bf9f365d5c Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Wed, 25 Dec 2024 18:17:13 +0000 Subject: [PATCH 5/7] polish db operations --- .../controller/ArticleController.java | 17 ++++++++--------- .../repository/ArticleRepository.java | 2 -- .../readreplica/service/ArticleService.java | 8 ++++---- .../src/main/resources/application.yml | 3 +++ .../controller/ArticleControllerIntTest.java | 17 ++++++++++++++++- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java index 60a7700a5..db9fcc3f0 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/controller/ArticleController.java @@ -43,14 +43,13 @@ ResponseEntity saveArticle(@RequestBody ArticleDTO articleDTO) { } @DeleteMapping("/{id}") - ResponseEntity deleteArticle(@PathVariable Long id) { - return this.articleService - .findById(id) - .map( - article -> { - articleService.deleteById(article.getId()); - return ResponseEntity.accepted().build(); - }) - .orElseGet(() -> ResponseEntity.notFound().build()); + ResponseEntity deleteArticle(@PathVariable Long id) { + boolean exists = this.articleService.existsById(id); + if (exists) { + this.articleService.deleteById(id); + return ResponseEntity.accepted().build(); + } else { + return ResponseEntity.notFound().build(); + } } } diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/repository/ArticleRepository.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/repository/ArticleRepository.java index 0b735b2df..e675e7a39 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/repository/ArticleRepository.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/repository/ArticleRepository.java @@ -5,11 +5,9 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import org.springframework.transaction.annotation.Transactional; public interface ArticleRepository extends JpaRepository { - @Transactional(readOnly = true) @Query("select a from Article a left join fetch a.comments where a.id = :articleId ") Optional
findByArticleId(@Param("articleId") Long articleId); } diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java index fa4886afe..e049cd038 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/service/ArticleService.java @@ -22,6 +22,10 @@ public Optional findArticleById(Long id) { return this.articleRepository.findByArticleId(id).map(this::convertToArticleDTO); } + public boolean existsById(Long id) { + return articleRepository.existsById(id); + } + @Transactional public Long saveArticle(ArticleDTO articleDTO) { Article article = articleDTO.convertToArticle(); @@ -29,10 +33,6 @@ public Long saveArticle(ArticleDTO articleDTO) { return savedArticle.getId(); } - public Optional
findById(Long id) { - return articleRepository.findById(id); - } - @Transactional public void deleteById(Long id) { articleRepository.deleteById(id); diff --git a/jpa/boot-read-replica-postgresql/src/main/resources/application.yml b/jpa/boot-read-replica-postgresql/src/main/resources/application.yml index 90cbe6ec0..cd0e7d292 100644 --- a/jpa/boot-read-replica-postgresql/src/main/resources/application.yml +++ b/jpa/boot-read-replica-postgresql/src/main/resources/application.yml @@ -45,6 +45,9 @@ spring: fail_on_pagination_over_collection_fetch: true in_clause_parameter_padding: true plan_cache_max_size: 4096 + mvc: + problemdetails: + enabled: true threads: virtual: enabled: true diff --git a/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java b/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java index 0b1fcb806..59ae70ef2 100644 --- a/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java +++ b/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java @@ -6,6 +6,7 @@ import com.example.demo.readreplica.domain.CommentDTO; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.concurrent.atomic.AtomicReference; @@ -55,7 +56,12 @@ void findArticleById() { } @Test - void saveArticleRetriveAndDelete() throws JsonProcessingException { + void shouldReturn404WhenFetchingNonExistingArticle() { + mvcTester.get().uri("/articles/99999").assertThat().hasStatus(HttpStatus.NOT_FOUND); + } + + @Test + void saveRetrieveAndDeleteArticle() throws JsonProcessingException { ArticleDTO articleDTO = new ArticleDTO( "junitTitle", @@ -90,9 +96,13 @@ void saveArticleRetriveAndDelete() throws JsonProcessingException { assertThat(response.authored()) .isNotNull() .isInstanceOf(LocalDateTime.class); + assertThat(response.authored().toLocalDate()) + .isEqualTo(LocalDate.now().minusDays(1)); assertThat(response.published()) .isNotNull() .isInstanceOf(LocalDateTime.class); + assertThat(response.published().toLocalDate()) + .isEqualTo(LocalDate.now()); assertThat(response.commentDTOs()) .isNotNull() .hasSize(1) @@ -101,4 +111,9 @@ void saveArticleRetriveAndDelete() throws JsonProcessingException { mvcTester.delete().uri(location.get()).assertThat().hasStatus(HttpStatus.ACCEPTED); } + + @Test + void cantDeleteArticleWhenArticleNotFound() { + mvcTester.delete().uri("/articles/99999").assertThat().hasStatus(HttpStatus.NOT_FOUND); + } } From 67f82921c3c2beb27ddac226e40fe065ec7d6540 Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Wed, 25 Dec 2024 18:20:25 +0000 Subject: [PATCH 6/7] fix : spotless --- .../demo/readreplica/controller/ArticleControllerIntTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java b/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java index 444e89afc..59ae70ef2 100644 --- a/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java +++ b/jpa/boot-read-replica-postgresql/src/test/java/com/example/demo/readreplica/controller/ArticleControllerIntTest.java @@ -116,5 +116,4 @@ void saveRetrieveAndDeleteArticle() throws JsonProcessingException { void cantDeleteArticleWhenArticleNotFound() { mvcTester.delete().uri("/articles/99999").assertThat().hasStatus(HttpStatus.NOT_FOUND); } - } From 5705ca8cd3a7f56213fa07a10fc1b8bed46b1c3b Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Wed, 25 Dec 2024 18:23:39 +0000 Subject: [PATCH 7/7] concise code, consider leveraging streams directly --- .../com/example/demo/readreplica/domain/ArticleDTO.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/domain/ArticleDTO.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/domain/ArticleDTO.java index 4c480bf5f..272d6d75a 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/domain/ArticleDTO.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/domain/ArticleDTO.java @@ -1,9 +1,6 @@ package com.example.demo.readreplica.domain; -import static com.example.demo.readreplica.domain.CommentDTO.convertToComment; - import com.example.demo.readreplica.entities.Article; -import com.example.demo.readreplica.entities.Comment; import java.time.LocalDateTime; import java.util.List; @@ -16,11 +13,7 @@ public record ArticleDTO( public Article convertToArticle() { Article article = new Article().setAuthored(authored).setTitle(title).setPublished(published); - commentDTOs.forEach( - commentDTO -> { - Comment comment = convertToComment(commentDTO); - article.addComment(comment); - }); + commentDTOs.stream().map(CommentDTO::convertToComment).forEach(article::addComment); return article; } }