From 42e1b153227d42158a84e3d8c6682ac2b1a3d892 Mon Sep 17 00:00:00 2001 From: Catalin Patrut Date: Sun, 8 Aug 2021 13:39:11 +0200 Subject: [PATCH] CRUD tested --- pom.xml | 36 ++++++++++++++++++- .../java/dev/enblng/api/ApiApplication.java | 16 --------- .../dev/enblng/api/api/CommentController.java | 2 ++ .../dev/enblng/api/api/PostController.java | 2 ++ .../dev/enblng/api/config/BeanConfig.java | 33 +++++++++++++++++ .../java/dev/enblng/api/dto/CommentTO.java | 9 ++--- src/main/java/dev/enblng/api/dto/PostTO.java | 13 +++---- .../dev/enblng/api/mappers/CommentMapper.java | 14 ++++++++ .../dev/enblng/api/mappers/PostMapper.java | 14 ++++++++ .../api/repositories/CommentRepository.java | 2 +- .../api/services/impl/CommentServiceImpl.java | 19 ++++++---- .../api/services/impl/PostServiceImpl.java | 24 ++++++++----- 12 files changed, 136 insertions(+), 48 deletions(-) create mode 100644 src/main/java/dev/enblng/api/mappers/CommentMapper.java create mode 100644 src/main/java/dev/enblng/api/mappers/PostMapper.java diff --git a/pom.xml b/pom.xml index ea280bf..a68e507 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ 16 3.0.0 + 1.4.2.Final @@ -77,7 +78,11 @@ io.springfox springfox-swagger-ui 3.0.0 - + + + org.mapstruct + mapstruct + ${mapstruct.version} io.springfox @@ -100,6 +105,35 @@ + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + org.projectlombok + lombok + ${lombok.version} + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + + + + + -Amapstruct.defaultComponentModel=spring + + + + diff --git a/src/main/java/dev/enblng/api/ApiApplication.java b/src/main/java/dev/enblng/api/ApiApplication.java index d484544..908485d 100644 --- a/src/main/java/dev/enblng/api/ApiApplication.java +++ b/src/main/java/dev/enblng/api/ApiApplication.java @@ -2,26 +2,10 @@ package dev.enblng.api; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; -import org.springframework.web.bind.annotation.RestController; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; @SpringBootApplication public class ApiApplication { - public static void main(final String[] args) { SpringApplication.run(ApiApplication.class, args); } - - @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)) - .paths(PathSelectors.any()) - .build(); - } } diff --git a/src/main/java/dev/enblng/api/api/CommentController.java b/src/main/java/dev/enblng/api/api/CommentController.java index 3924fe1..0bb5fe2 100644 --- a/src/main/java/dev/enblng/api/api/CommentController.java +++ b/src/main/java/dev/enblng/api/api/CommentController.java @@ -2,6 +2,7 @@ package dev.enblng.api.api; import dev.enblng.api.dto.CommentTO; import dev.enblng.api.services.CommentService; +import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; @@ -16,6 +17,7 @@ import java.util.UUID; @RestController @RequestMapping(CommentController.PATH) +@Api(tags = "Comments") @Slf4j public class CommentController { static final String PATH = "comments"; diff --git a/src/main/java/dev/enblng/api/api/PostController.java b/src/main/java/dev/enblng/api/api/PostController.java index 4208b13..5bd1565 100644 --- a/src/main/java/dev/enblng/api/api/PostController.java +++ b/src/main/java/dev/enblng/api/api/PostController.java @@ -2,6 +2,7 @@ package dev.enblng.api.api; import dev.enblng.api.dto.PostTO; import dev.enblng.api.services.PostService; +import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.PageRequest; import org.springframework.http.HttpStatus; @@ -15,6 +16,7 @@ import java.util.UUID; @RestController @RequestMapping(PostController.PATH) +@Api(tags = "Posts") @Slf4j public class PostController { diff --git a/src/main/java/dev/enblng/api/config/BeanConfig.java b/src/main/java/dev/enblng/api/config/BeanConfig.java index 3159bf0..6ef0c58 100644 --- a/src/main/java/dev/enblng/api/config/BeanConfig.java +++ b/src/main/java/dev/enblng/api/config/BeanConfig.java @@ -3,10 +3,22 @@ package dev.enblng.api.config; import org.modelmapper.ModelMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; //TODO: delete @Configuration public class BeanConfig { + private static final String SNAPSHOT = "1.0"; + private static final String HTTP_WWW_APACHE_ORG_LICENSES_LICENSE_2_0_HTML = "Usage of this code is forbidden without consent"; + private static final String APACHE_2_0 = "Apache 2.0"; + @Bean public ModelMapper modelMapper() { final ModelMapper modelMapper = new ModelMapper(); @@ -17,5 +29,26 @@ public class BeanConfig { return modelMapper; } + @Bean + public Docket api() { + + return new Docket(DocumentationType.SWAGGER_2) + .useDefaultResponseMessages(false) + .select() + .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)) + .paths(PathSelectors.any()) + .build() + .apiInfo(apiEndPointsInfo()); + } + + private ApiInfo apiEndPointsInfo() { + return new ApiInfoBuilder().title("Blog API") + .description("Example of a blog API") + .contact(new Contact("Catalin Patrut", "NO URL", "api@cpatrut.ro")) + .license(APACHE_2_0) + .licenseUrl(HTTP_WWW_APACHE_ORG_LICENSES_LICENSE_2_0_HTML) + .version(SNAPSHOT) + .build(); + } } diff --git a/src/main/java/dev/enblng/api/dto/CommentTO.java b/src/main/java/dev/enblng/api/dto/CommentTO.java index a52389a..0a3e328 100644 --- a/src/main/java/dev/enblng/api/dto/CommentTO.java +++ b/src/main/java/dev/enblng/api/dto/CommentTO.java @@ -26,11 +26,11 @@ public class CommentTO { @Size(min = 5, max = 255) String title; - @ApiModelProperty(position = 2, value = ONLY_FOR_GET_MESSAGE) + @ApiModelProperty(position = 2, value = ONLY_FOR_GET_MESSAGE, example = "George") @NotNull String author; - @ApiModelProperty(position = 3, required = true) + @ApiModelProperty(position = 3, required = true, example = "Hello hello") @Size(min = 10) @NotNull String content; @@ -38,8 +38,6 @@ public class CommentTO { @ApiModelProperty(position = 5, value = ONLY_FOR_GET_MESSAGE) String updateTime; - @ApiModelProperty(position = 4, value = ONLY_FOR_GET_MESSAGE) - String creationTime; @ApiModelProperty(position = 6, value = FOREIGN_KEY_MESSAGE) UUID postId; @@ -50,10 +48,9 @@ public class CommentTO { final String author, final String content, final String updateTime, - final String creationTime, final UUID postId ) { - return new CommentTO(id, title, author, content, updateTime, creationTime, postId); + return new CommentTO(id, title, author, content, updateTime, postId); } } diff --git a/src/main/java/dev/enblng/api/dto/PostTO.java b/src/main/java/dev/enblng/api/dto/PostTO.java index c86255c..4c7fa3e 100644 --- a/src/main/java/dev/enblng/api/dto/PostTO.java +++ b/src/main/java/dev/enblng/api/dto/PostTO.java @@ -22,7 +22,7 @@ public class PostTO { @ApiModelProperty(value = UUID_MESSAGE) UUID id; - @ApiModelProperty(position = 1, required = true) + @ApiModelProperty(position = 1, required = true, example = "Hello title") @Size(min = 5, max = 255) @NotNull String title; @@ -30,7 +30,7 @@ public class PostTO { @ApiModelProperty(value = ONLY_FOR_GET_MESSAGE, position = 2) String author; - @ApiModelProperty(position = 3, required = true) + @ApiModelProperty(position = 3, required = true, example = "Hello hello") @Size(min = 10) @NotNull String content; @@ -39,18 +39,13 @@ public class PostTO { @Null String updateTime; - @ApiModelProperty(value = ONLY_FOR_GET_MESSAGE, position = 4) - @Null - String creationTime; - @Builder private static PostTO newPostTo(final UUID id, final String title, final String author, final String content, - final String updateTime, - final String creationTime + final String updateTime ) { - return new PostTO(id, title, author, content, updateTime, creationTime); + return new PostTO(id, title, author, content, updateTime); } } diff --git a/src/main/java/dev/enblng/api/mappers/CommentMapper.java b/src/main/java/dev/enblng/api/mappers/CommentMapper.java new file mode 100644 index 0000000..888baa0 --- /dev/null +++ b/src/main/java/dev/enblng/api/mappers/CommentMapper.java @@ -0,0 +1,14 @@ +package dev.enblng.api.mappers; + +import dev.enblng.api.dto.CommentTO; +import dev.enblng.api.entities.CommentEntity; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper +public interface CommentMapper { + @Mapping(target = "creationTime", ignore = true) + CommentEntity toEntity(final CommentTO comment); + + CommentTO toTransferObject(final CommentEntity comment); +} diff --git a/src/main/java/dev/enblng/api/mappers/PostMapper.java b/src/main/java/dev/enblng/api/mappers/PostMapper.java new file mode 100644 index 0000000..ca918d9 --- /dev/null +++ b/src/main/java/dev/enblng/api/mappers/PostMapper.java @@ -0,0 +1,14 @@ +package dev.enblng.api.mappers; + +import dev.enblng.api.dto.PostTO; +import dev.enblng.api.entities.PostEntity; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper +public interface PostMapper { + @Mapping(target = "creationTime", ignore = true) + PostEntity toEntity(final PostTO post); + + PostTO toTransferObject(final PostEntity post); +} diff --git a/src/main/java/dev/enblng/api/repositories/CommentRepository.java b/src/main/java/dev/enblng/api/repositories/CommentRepository.java index 2ecf754..e80b601 100644 --- a/src/main/java/dev/enblng/api/repositories/CommentRepository.java +++ b/src/main/java/dev/enblng/api/repositories/CommentRepository.java @@ -25,5 +25,5 @@ public interface CommentRepository extends BlogRepository { final UUID id); - int deleteById(UUID id); + void deleteById(final UUID id); } diff --git a/src/main/java/dev/enblng/api/services/impl/CommentServiceImpl.java b/src/main/java/dev/enblng/api/services/impl/CommentServiceImpl.java index 2454a7b..8230043 100644 --- a/src/main/java/dev/enblng/api/services/impl/CommentServiceImpl.java +++ b/src/main/java/dev/enblng/api/services/impl/CommentServiceImpl.java @@ -2,6 +2,7 @@ package dev.enblng.api.services.impl; import dev.enblng.api.dto.CommentTO; import dev.enblng.api.entities.CommentEntity; +import dev.enblng.api.mappers.CommentMapper; import dev.enblng.api.repositories.CommentRepository; import dev.enblng.api.services.CommentService; import org.modelmapper.ModelMapper; @@ -17,27 +18,31 @@ import java.util.stream.Collectors; @Service public class CommentServiceImpl implements CommentService { - private final ModelMapper modelMapper; private final CommentRepository commentRepository; + private final CommentMapper commentMapper; - public CommentServiceImpl(final ModelMapper modelMapper, final CommentRepository commentRepository) { - this.modelMapper = modelMapper; + public CommentServiceImpl( + final ModelMapper modelMapper, + final CommentRepository commentRepository, + final CommentMapper commentMapper + ) { + this.commentMapper = commentMapper; this.commentRepository = commentRepository; } @Override + @Transactional public CommentTO save(final CommentTO comment) { - final CommentEntity entity = modelMapper.map(comment, CommentEntity.class); + final CommentEntity entity = commentMapper.toEntity(comment); entity.setId(UUID.randomUUID()); - return modelMapper.map(commentRepository.save(entity), CommentTO.CommentTOBuilder.class).build(); + return commentMapper.toTransferObject(commentRepository.save(entity)); } @Override @Transactional public List getByPostId(final UUID id, final Pageable pageable) { return commentRepository.findAllByPostIdOrderByCreationTime(id, pageable) - .map(commentEntity -> modelMapper.map(commentEntity, - CommentTO.CommentTOBuilder.class).build()) + .map(commentMapper::toTransferObject) .collect(Collectors.toList()); } diff --git a/src/main/java/dev/enblng/api/services/impl/PostServiceImpl.java b/src/main/java/dev/enblng/api/services/impl/PostServiceImpl.java index 88f5b3c..2daf80f 100644 --- a/src/main/java/dev/enblng/api/services/impl/PostServiceImpl.java +++ b/src/main/java/dev/enblng/api/services/impl/PostServiceImpl.java @@ -2,49 +2,57 @@ package dev.enblng.api.services.impl; import dev.enblng.api.dto.PostTO; import dev.enblng.api.entities.PostEntity; +import dev.enblng.api.mappers.PostMapper; import dev.enblng.api.repositories.PostRepository; import dev.enblng.api.services.PostService; +import lombok.extern.slf4j.Slf4j; import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import javax.persistence.EntityNotFoundException; +import javax.transaction.Transactional; import java.time.ZonedDateTime; import java.util.List; import java.util.UUID; import java.util.stream.Collectors; @Service +@Slf4j public class PostServiceImpl implements PostService { private final PostRepository postRepository; - private final ModelMapper modelMapper; + private final PostMapper postMapper; @Autowired - public PostServiceImpl(final ModelMapper modelMapper, final PostRepository postRepository) { - this.modelMapper = modelMapper; + public PostServiceImpl(final ModelMapper modelMapper, + final PostRepository postRepository, + final PostMapper postMapper) { this.postRepository = postRepository; + this.postMapper = postMapper; } @Override + @Transactional public PostTO save(final PostTO post) { - final PostEntity entity = modelMapper.map(post, PostEntity.class); + final PostEntity entity = postMapper.toEntity(post); + log.debug(post.toString()); entity.setId(UUID.randomUUID()); - return modelMapper.map(postRepository.save(entity), PostTO.PostTOBuilder.class) - .build(); + final PostEntity savedEntity = postRepository.save(entity); + return postMapper.toTransferObject(savedEntity); } @Override public PostTO getById(final UUID id) { final PostEntity entity = postRepository.getById(id) .orElseThrow(EntityNotFoundException::new); - return modelMapper.map(entity, PostTO.PostTOBuilder.class).build(); + return postMapper.toTransferObject(entity); } @Override public List findAll(final Pageable pageable) { return postRepository.findAll(pageable).get() - .map(postEntity -> modelMapper.map(postEntity, PostTO.PostTOBuilder.class).build()) + .map(postMapper::toTransferObject) .collect(Collectors.toList()); }