CRUD tested
This commit is contained in:
36
pom.xml
36
pom.xml
@@ -16,6 +16,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<java.version>16</java.version>
|
<java.version>16</java.version>
|
||||||
<swagger.version>3.0.0</swagger.version>
|
<swagger.version>3.0.0</swagger.version>
|
||||||
|
<mapstruct.version>1.4.2.Final</mapstruct.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -77,7 +78,11 @@
|
|||||||
<groupId>io.springfox</groupId>
|
<groupId>io.springfox</groupId>
|
||||||
<artifactId>springfox-swagger-ui</artifactId>
|
<artifactId>springfox-swagger-ui</artifactId>
|
||||||
<version>3.0.0</version>
|
<version>3.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct</artifactId>
|
||||||
|
<version>${mapstruct.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.springfox</groupId>
|
<groupId>io.springfox</groupId>
|
||||||
@@ -100,6 +105,35 @@
|
|||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-processor</artifactId>
|
||||||
|
<version>${mapstruct.version}</version>
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
</path>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok-mapstruct-binding</artifactId>
|
||||||
|
<version>0.2.0</version>
|
||||||
|
</dependency>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
<compilerArgs>
|
||||||
|
<compilerArg>
|
||||||
|
-Amapstruct.defaultComponentModel=spring
|
||||||
|
</compilerArg>
|
||||||
|
</compilerArgs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|||||||
@@ -2,26 +2,10 @@ package dev.enblng.api;
|
|||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
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
|
@SpringBootApplication
|
||||||
public class ApiApplication {
|
public class ApiApplication {
|
||||||
|
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
SpringApplication.run(ApiApplication.class, 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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package dev.enblng.api.api;
|
|||||||
|
|
||||||
import dev.enblng.api.dto.CommentTO;
|
import dev.enblng.api.dto.CommentTO;
|
||||||
import dev.enblng.api.services.CommentService;
|
import dev.enblng.api.services.CommentService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
@@ -16,6 +17,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(CommentController.PATH)
|
@RequestMapping(CommentController.PATH)
|
||||||
|
@Api(tags = "Comments")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class CommentController {
|
public class CommentController {
|
||||||
static final String PATH = "comments";
|
static final String PATH = "comments";
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package dev.enblng.api.api;
|
|||||||
|
|
||||||
import dev.enblng.api.dto.PostTO;
|
import dev.enblng.api.dto.PostTO;
|
||||||
import dev.enblng.api.services.PostService;
|
import dev.enblng.api.services.PostService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@@ -15,6 +16,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(PostController.PATH)
|
@RequestMapping(PostController.PATH)
|
||||||
|
@Api(tags = "Posts")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PostController {
|
public class PostController {
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,22 @@ package dev.enblng.api.config;
|
|||||||
import org.modelmapper.ModelMapper;
|
import org.modelmapper.ModelMapper;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
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
|
//TODO: delete
|
||||||
@Configuration
|
@Configuration
|
||||||
public class BeanConfig {
|
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
|
@Bean
|
||||||
public ModelMapper modelMapper() {
|
public ModelMapper modelMapper() {
|
||||||
final ModelMapper modelMapper = new ModelMapper();
|
final ModelMapper modelMapper = new ModelMapper();
|
||||||
@@ -17,5 +29,26 @@ public class BeanConfig {
|
|||||||
return modelMapper;
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ public class CommentTO {
|
|||||||
@Size(min = 5, max = 255)
|
@Size(min = 5, max = 255)
|
||||||
String title;
|
String title;
|
||||||
|
|
||||||
@ApiModelProperty(position = 2, value = ONLY_FOR_GET_MESSAGE)
|
@ApiModelProperty(position = 2, value = ONLY_FOR_GET_MESSAGE, example = "George")
|
||||||
@NotNull
|
@NotNull
|
||||||
String author;
|
String author;
|
||||||
|
|
||||||
@ApiModelProperty(position = 3, required = true)
|
@ApiModelProperty(position = 3, required = true, example = "Hello hello")
|
||||||
@Size(min = 10)
|
@Size(min = 10)
|
||||||
@NotNull
|
@NotNull
|
||||||
String content;
|
String content;
|
||||||
@@ -38,8 +38,6 @@ public class CommentTO {
|
|||||||
@ApiModelProperty(position = 5, value = ONLY_FOR_GET_MESSAGE)
|
@ApiModelProperty(position = 5, value = ONLY_FOR_GET_MESSAGE)
|
||||||
String updateTime;
|
String updateTime;
|
||||||
|
|
||||||
@ApiModelProperty(position = 4, value = ONLY_FOR_GET_MESSAGE)
|
|
||||||
String creationTime;
|
|
||||||
|
|
||||||
@ApiModelProperty(position = 6, value = FOREIGN_KEY_MESSAGE)
|
@ApiModelProperty(position = 6, value = FOREIGN_KEY_MESSAGE)
|
||||||
UUID postId;
|
UUID postId;
|
||||||
@@ -50,10 +48,9 @@ public class CommentTO {
|
|||||||
final String author,
|
final String author,
|
||||||
final String content,
|
final String content,
|
||||||
final String updateTime,
|
final String updateTime,
|
||||||
final String creationTime,
|
|
||||||
final UUID postId
|
final UUID postId
|
||||||
) {
|
) {
|
||||||
return new CommentTO(id, title, author, content, updateTime, creationTime, postId);
|
return new CommentTO(id, title, author, content, updateTime, postId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class PostTO {
|
|||||||
@ApiModelProperty(value = UUID_MESSAGE)
|
@ApiModelProperty(value = UUID_MESSAGE)
|
||||||
UUID id;
|
UUID id;
|
||||||
|
|
||||||
@ApiModelProperty(position = 1, required = true)
|
@ApiModelProperty(position = 1, required = true, example = "Hello title")
|
||||||
@Size(min = 5, max = 255)
|
@Size(min = 5, max = 255)
|
||||||
@NotNull
|
@NotNull
|
||||||
String title;
|
String title;
|
||||||
@@ -30,7 +30,7 @@ public class PostTO {
|
|||||||
@ApiModelProperty(value = ONLY_FOR_GET_MESSAGE, position = 2)
|
@ApiModelProperty(value = ONLY_FOR_GET_MESSAGE, position = 2)
|
||||||
String author;
|
String author;
|
||||||
|
|
||||||
@ApiModelProperty(position = 3, required = true)
|
@ApiModelProperty(position = 3, required = true, example = "Hello hello")
|
||||||
@Size(min = 10)
|
@Size(min = 10)
|
||||||
@NotNull
|
@NotNull
|
||||||
String content;
|
String content;
|
||||||
@@ -39,18 +39,13 @@ public class PostTO {
|
|||||||
@Null
|
@Null
|
||||||
String updateTime;
|
String updateTime;
|
||||||
|
|
||||||
@ApiModelProperty(value = ONLY_FOR_GET_MESSAGE, position = 4)
|
|
||||||
@Null
|
|
||||||
String creationTime;
|
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
private static PostTO newPostTo(final UUID id,
|
private static PostTO newPostTo(final UUID id,
|
||||||
final String title,
|
final String title,
|
||||||
final String author,
|
final String author,
|
||||||
final String content,
|
final String content,
|
||||||
final String updateTime,
|
final String updateTime
|
||||||
final String creationTime
|
|
||||||
) {
|
) {
|
||||||
return new PostTO(id, title, author, content, updateTime, creationTime);
|
return new PostTO(id, title, author, content, updateTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/main/java/dev/enblng/api/mappers/CommentMapper.java
Normal file
14
src/main/java/dev/enblng/api/mappers/CommentMapper.java
Normal file
@@ -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);
|
||||||
|
}
|
||||||
14
src/main/java/dev/enblng/api/mappers/PostMapper.java
Normal file
14
src/main/java/dev/enblng/api/mappers/PostMapper.java
Normal file
@@ -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);
|
||||||
|
}
|
||||||
@@ -25,5 +25,5 @@ public interface CommentRepository extends BlogRepository<CommentEntity, UUID> {
|
|||||||
final UUID id);
|
final UUID id);
|
||||||
|
|
||||||
|
|
||||||
int deleteById(UUID id);
|
void deleteById(final UUID id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package dev.enblng.api.services.impl;
|
|||||||
|
|
||||||
import dev.enblng.api.dto.CommentTO;
|
import dev.enblng.api.dto.CommentTO;
|
||||||
import dev.enblng.api.entities.CommentEntity;
|
import dev.enblng.api.entities.CommentEntity;
|
||||||
|
import dev.enblng.api.mappers.CommentMapper;
|
||||||
import dev.enblng.api.repositories.CommentRepository;
|
import dev.enblng.api.repositories.CommentRepository;
|
||||||
import dev.enblng.api.services.CommentService;
|
import dev.enblng.api.services.CommentService;
|
||||||
import org.modelmapper.ModelMapper;
|
import org.modelmapper.ModelMapper;
|
||||||
@@ -17,27 +18,31 @@ import java.util.stream.Collectors;
|
|||||||
@Service
|
@Service
|
||||||
public class CommentServiceImpl implements CommentService {
|
public class CommentServiceImpl implements CommentService {
|
||||||
|
|
||||||
private final ModelMapper modelMapper;
|
|
||||||
private final CommentRepository commentRepository;
|
private final CommentRepository commentRepository;
|
||||||
|
private final CommentMapper commentMapper;
|
||||||
|
|
||||||
public CommentServiceImpl(final ModelMapper modelMapper, final CommentRepository commentRepository) {
|
public CommentServiceImpl(
|
||||||
this.modelMapper = modelMapper;
|
final ModelMapper modelMapper,
|
||||||
|
final CommentRepository commentRepository,
|
||||||
|
final CommentMapper commentMapper
|
||||||
|
) {
|
||||||
|
this.commentMapper = commentMapper;
|
||||||
this.commentRepository = commentRepository;
|
this.commentRepository = commentRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public CommentTO save(final CommentTO comment) {
|
public CommentTO save(final CommentTO comment) {
|
||||||
final CommentEntity entity = modelMapper.map(comment, CommentEntity.class);
|
final CommentEntity entity = commentMapper.toEntity(comment);
|
||||||
entity.setId(UUID.randomUUID());
|
entity.setId(UUID.randomUUID());
|
||||||
return modelMapper.map(commentRepository.save(entity), CommentTO.CommentTOBuilder.class).build();
|
return commentMapper.toTransferObject(commentRepository.save(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public List<CommentTO> getByPostId(final UUID id, final Pageable pageable) {
|
public List<CommentTO> getByPostId(final UUID id, final Pageable pageable) {
|
||||||
return commentRepository.findAllByPostIdOrderByCreationTime(id, pageable)
|
return commentRepository.findAllByPostIdOrderByCreationTime(id, pageable)
|
||||||
.map(commentEntity -> modelMapper.map(commentEntity,
|
.map(commentMapper::toTransferObject)
|
||||||
CommentTO.CommentTOBuilder.class).build())
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,49 +2,57 @@ package dev.enblng.api.services.impl;
|
|||||||
|
|
||||||
import dev.enblng.api.dto.PostTO;
|
import dev.enblng.api.dto.PostTO;
|
||||||
import dev.enblng.api.entities.PostEntity;
|
import dev.enblng.api.entities.PostEntity;
|
||||||
|
import dev.enblng.api.mappers.PostMapper;
|
||||||
import dev.enblng.api.repositories.PostRepository;
|
import dev.enblng.api.repositories.PostRepository;
|
||||||
import dev.enblng.api.services.PostService;
|
import dev.enblng.api.services.PostService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.modelmapper.ModelMapper;
|
import org.modelmapper.ModelMapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.persistence.EntityNotFoundException;
|
import javax.persistence.EntityNotFoundException;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@Slf4j
|
||||||
public class PostServiceImpl implements PostService {
|
public class PostServiceImpl implements PostService {
|
||||||
private final PostRepository postRepository;
|
private final PostRepository postRepository;
|
||||||
private final ModelMapper modelMapper;
|
private final PostMapper postMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public PostServiceImpl(final ModelMapper modelMapper, final PostRepository postRepository) {
|
public PostServiceImpl(final ModelMapper modelMapper,
|
||||||
this.modelMapper = modelMapper;
|
final PostRepository postRepository,
|
||||||
|
final PostMapper postMapper) {
|
||||||
this.postRepository = postRepository;
|
this.postRepository = postRepository;
|
||||||
|
this.postMapper = postMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public PostTO save(final PostTO post) {
|
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());
|
entity.setId(UUID.randomUUID());
|
||||||
return modelMapper.map(postRepository.save(entity), PostTO.PostTOBuilder.class)
|
final PostEntity savedEntity = postRepository.save(entity);
|
||||||
.build();
|
return postMapper.toTransferObject(savedEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PostTO getById(final UUID id) {
|
public PostTO getById(final UUID id) {
|
||||||
final PostEntity entity = postRepository.getById(id)
|
final PostEntity entity = postRepository.getById(id)
|
||||||
.orElseThrow(EntityNotFoundException::new);
|
.orElseThrow(EntityNotFoundException::new);
|
||||||
return modelMapper.map(entity, PostTO.PostTOBuilder.class).build();
|
return postMapper.toTransferObject(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PostTO> findAll(final Pageable pageable) {
|
public List<PostTO> findAll(final Pageable pageable) {
|
||||||
return postRepository.findAll(pageable).get()
|
return postRepository.findAll(pageable).get()
|
||||||
.map(postEntity -> modelMapper.map(postEntity, PostTO.PostTOBuilder.class).build())
|
.map(postMapper::toTransferObject)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user