├── .gitignore ├── .travis.yml ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── zufar │ │ ├── Application.java │ │ ├── configuration │ │ ├── CustomUserDetails.java │ │ ├── CustomUserDetailsService.java │ │ └── SecurityConfig.java │ │ ├── exception │ │ ├── ItemNotFoundException.java │ │ ├── OrderNotFoundException.java │ │ ├── ProductNotFoundException.java │ │ ├── StatusNotFoundException.java │ │ └── UserNotFoundException.java │ │ ├── item │ │ ├── Item.java │ │ ├── ItemController.java │ │ ├── ItemDTO.java │ │ ├── ItemRepository.java │ │ └── ItemService.java │ │ ├── order │ │ ├── Order.java │ │ ├── OrderController.java │ │ ├── OrderDTO.java │ │ ├── OrderRepository.java │ │ └── OrderService.java │ │ ├── product │ │ ├── Product.java │ │ ├── ProductController.java │ │ ├── ProductDTO.java │ │ ├── ProductRepository.java │ │ └── ProductService.java │ │ ├── service │ │ └── DaoService.java │ │ ├── status │ │ ├── Status.java │ │ ├── StatusController.java │ │ ├── StatusDTO.java │ │ ├── StatusRepository.java │ │ └── StatusService.java │ │ └── user │ │ ├── Role.java │ │ ├── User.java │ │ ├── UserController.java │ │ ├── UserDTO.java │ │ ├── UserRepository.java │ │ └── UserService.java └── resources │ ├── application.yaml │ └── banner.txt └── test └── java └── com └── zufar └── service ├── OrderServiceTest.java └── StatusServiceTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | nb-configuration.xml 3 | *.iml 4 | /.idea/ 5 | *.NavData -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | - oraclejdk9 5 | - openjdk8 6 | os: windows 7 | 8 | branches: 9 | only: 10 | - master 11 | - develop 12 | cache: 13 | directories: 14 | - $HOME/.m2/repository 15 | 16 | notifications: 17 | email: 18 | - zuf999@mail.ru 19 | 20 | script: 21 | - mvn clean install 22 | 23 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 4.0.0 7 | 8 | com.zufar 9 | OrderManagementSystem 10 | 1.0-SNAPSHOT 11 | war 12 | 13 | Order Management System 14 | 15 | 16 | 17 | Zufar Sunagatov 18 | zufar.sunagatov@gmail.com 19 | https://vk.com/person99 20 | 21 | architect 22 | developer 23 | tester 24 | 25 | Samara (UTC+4:00) 26 | 27 | 28 | 29 | 30 | 31 | UTF-8 32 | 1.7 33 | 1.7 34 | 35 | 2.1.5.RELEASE 36 | 37 | 42.2.5 38 | 6.0.1 39 | 40 | 4.12 41 | 1.3 42 | 2.1.5.RELEASE 43 | 5.2.0.RELEASE 44 | 45 | 2.8.2 46 | 2.8.2 47 | 48 | 1.18.8 49 | 50 | 51 | 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-starter-web 56 | ${spring.framework.boot-starter.version} 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-starter-tomcat 61 | provided 62 | ${spring.framework.boot-starter.version} 63 | 64 | 65 | org.springframework.boot 66 | spring-boot-starter-security 67 | ${spring.framework.boot-starter.version} 68 | 69 | 70 | 71 | org.postgresql 72 | postgresql 73 | ${postgressql.version} 74 | 75 | 76 | org.springframework.boot 77 | spring-boot-starter-data-jpa 78 | ${spring.framework.boot-starter.version} 79 | 80 | 81 | 82 | org.springframework.boot 83 | spring-boot-starter-test 84 | test 85 | ${spring-boot-starter-test.version} 86 | 87 | 88 | org.springframework.security 89 | spring-security-test 90 | ${spring-boot-starter-security-test.version} 91 | test 92 | 93 | 94 | junit 95 | junit 96 | ${junit.version} 97 | test 98 | 99 | 100 | org.hamcrest 101 | hamcrest-all 102 | ${org.hamcrest.version} 103 | test 104 | 105 | 106 | 107 | org.apache.logging.log4j 108 | log4j-api 109 | ${log4j.api.version} 110 | 111 | 112 | org.apache.logging.log4j 113 | log4j-core 114 | ${log4j.core.version} 115 | 116 | 117 | 118 | org.projectlombok 119 | lombok 120 | ${org.projectlombok.version} 121 | provided 122 | 123 | 124 | 125 | 126 | 127 | OrderManagementSystem 128 | 129 | 130 | org.springframework.boot 131 | spring-boot-maven-plugin 132 | 133 | true 134 | -Xms128m -Xmx2048m 135 | 136 | 137 | 138 | org.apache.maven.plugins 139 | maven-compiler-plugin 140 | 141 | 8 142 | 8 143 | 144 | 145 | 146 | org.apache.maven.plugins 147 | maven-war-plugin 148 | 2.6 149 | 150 | false 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/Application.java: -------------------------------------------------------------------------------- 1 | package com.zufar; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 7 | 8 | @SpringBootApplication 9 | public class Application { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(Application.class, args); 13 | } 14 | 15 | @Bean 16 | public BCryptPasswordEncoder getEncoder() { 17 | return new BCryptPasswordEncoder(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/configuration/CustomUserDetails.java: -------------------------------------------------------------------------------- 1 | package com.zufar.configuration; 2 | 3 | import com.zufar.user.Role; 4 | import org.springframework.security.core.userdetails.UserDetails; 5 | import java.util.Collection; 6 | 7 | import lombok.AllArgsConstructor; 8 | import lombok.Builder; 9 | import lombok.Data; 10 | import lombok.NoArgsConstructor; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class CustomUserDetails implements UserDetails { 17 | 18 | private String password; 19 | private String username; 20 | private boolean accountNonExpired; 21 | private boolean accountNonLocked; 22 | private boolean credentialsNonExpired; 23 | private boolean enabled; 24 | private Collection authorities; 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/configuration/CustomUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.zufar.configuration; 2 | 3 | import com.zufar.user.UserDTO; 4 | import com.zufar.user.UserService; 5 | 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.security.core.userdetails.UserDetails; 11 | import org.springframework.security.core.userdetails.UserDetailsService; 12 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 13 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 14 | import org.springframework.stereotype.Service; 15 | import org.springframework.transaction.annotation.Transactional; 16 | 17 | @Service("customUserDetailsService") 18 | public class CustomUserDetailsService implements UserDetailsService { 19 | 20 | private static final Logger LOGGER = LogManager.getLogger(CustomUserDetailsService.class); 21 | 22 | private final UserService userService; 23 | private final BCryptPasswordEncoder passwordEncoder; 24 | 25 | @Autowired 26 | public CustomUserDetailsService(UserService userService, BCryptPasswordEncoder passwordEncoder) { 27 | this.userService = userService; 28 | this.passwordEncoder = passwordEncoder; 29 | } 30 | 31 | @Override 32 | @Transactional(readOnly = true) 33 | public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException { 34 | final UserDTO user; 35 | try { 36 | user = userService.getByLogin(login); 37 | } catch (Exception exc) { 38 | final String errorMessage = "Loading user details is impossible."; 39 | LOGGER.error(exc.getMessage() + errorMessage, exc); 40 | throw new UsernameNotFoundException(errorMessage, exc); 41 | } 42 | return CustomUserDetails.builder() 43 | .username(user.getName()) 44 | .password(passwordEncoder.encode(user.getPassword())) 45 | .authorities(user.getRoles()) 46 | .credentialsNonExpired(true) 47 | .accountNonExpired(true) 48 | .accountNonLocked(true) 49 | .enabled(true) 50 | .build(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/configuration/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.zufar.configuration; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Qualifier; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 8 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 10 | import org.springframework.security.core.userdetails.UserDetailsService; 11 | import org.springframework.security.crypto.password.PasswordEncoder; 12 | import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 13 | 14 | @Configuration 15 | @EnableWebSecurity 16 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 17 | 18 | @Autowired 19 | private PasswordEncoder passwordEncoder; 20 | 21 | @Autowired 22 | @Qualifier("customUserDetailsService") 23 | private UserDetailsService userDetailsService; 24 | 25 | @Autowired 26 | public void configureUserDetails(AuthenticationManagerBuilder auth) throws Exception { 27 | auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder); 28 | } 29 | 30 | @Override 31 | protected void configure(HttpSecurity http) throws Exception { 32 | http.authorizeRequests() 33 | .antMatchers("/css/*").permitAll() 34 | .anyRequest().authenticated() 35 | .antMatchers("customers/*") 36 | .access("hasRole('ADMIN_ROLE')") 37 | .antMatchers("orders/*") 38 | .access("hasRole('ADMIN_ROLE')") 39 | .antMatchers("items/*") 40 | .access("hasRole('ADMIN_ROLE')") 41 | .antMatchers("statuses/*") 42 | .access("hasRole('ADMIN_ROLE')") 43 | .antMatchers("/products/*") 44 | .access("hasRole('USER_ROLE')") 45 | .and() 46 | .formLogin().disable() 47 | .httpBasic() 48 | .and() 49 | .csrf().disable() 50 | .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll(); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/exception/ItemNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.zufar.exception; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.web.bind.annotation.ResponseStatus; 5 | 6 | @ResponseStatus(value = HttpStatus.NOT_FOUND) 7 | public class ItemNotFoundException extends RuntimeException { 8 | 9 | public ItemNotFoundException() { 10 | super(); 11 | } 12 | public ItemNotFoundException(String message, Throwable cause) { 13 | super(message, cause); 14 | } 15 | public ItemNotFoundException(String message) { 16 | super(message); 17 | } 18 | public ItemNotFoundException(Throwable cause) { 19 | super(cause); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/exception/OrderNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.zufar.exception; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.web.bind.annotation.ResponseStatus; 5 | 6 | @ResponseStatus(value = HttpStatus.NOT_FOUND) 7 | public class OrderNotFoundException extends RuntimeException { 8 | 9 | public OrderNotFoundException() { 10 | super(); 11 | } 12 | public OrderNotFoundException(String message, Throwable cause) { 13 | super(message, cause); 14 | } 15 | public OrderNotFoundException(String message) { 16 | super(message); 17 | } 18 | public OrderNotFoundException(Throwable cause) { 19 | super(cause); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/exception/ProductNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.zufar.exception; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.web.bind.annotation.ResponseStatus; 5 | 6 | @ResponseStatus(value = HttpStatus.NOT_FOUND) 7 | public class ProductNotFoundException extends RuntimeException { 8 | 9 | public ProductNotFoundException() { 10 | super(); 11 | } 12 | public ProductNotFoundException(String message, Throwable cause) { 13 | super(message, cause); 14 | } 15 | public ProductNotFoundException(String message) { 16 | super(message); 17 | } 18 | public ProductNotFoundException(Throwable cause) { 19 | super(cause); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/exception/StatusNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.zufar.exception; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.web.bind.annotation.ResponseStatus; 5 | 6 | @ResponseStatus(value = HttpStatus.NOT_FOUND) 7 | public class StatusNotFoundException extends RuntimeException { 8 | 9 | public StatusNotFoundException() { 10 | super(); 11 | } 12 | public StatusNotFoundException(String message, Throwable cause) { 13 | super(message, cause); 14 | } 15 | public StatusNotFoundException(String message) { 16 | super(message); 17 | } 18 | public StatusNotFoundException(Throwable cause) { 19 | super(cause); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/exception/UserNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.zufar.exception; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.web.bind.annotation.ResponseStatus; 5 | 6 | @ResponseStatus(value = HttpStatus.NOT_FOUND) 7 | public class UserNotFoundException extends RuntimeException { 8 | 9 | public UserNotFoundException() { 10 | super(); 11 | } 12 | public UserNotFoundException(String message, Throwable cause) { 13 | super(message, cause); 14 | } 15 | public UserNotFoundException(String message) { 16 | super(message); 17 | } 18 | public UserNotFoundException(Throwable cause) { 19 | super(cause); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/item/Item.java: -------------------------------------------------------------------------------- 1 | package com.zufar.item; 2 | 3 | import com.zufar.product.Product; 4 | 5 | import lombok.Setter; 6 | import lombok.Getter; 7 | import lombok.AllArgsConstructor; 8 | import lombok.EqualsAndHashCode; 9 | import lombok.NoArgsConstructor; 10 | import lombok.ToString; 11 | 12 | import org.hibernate.annotations.Fetch; 13 | import org.hibernate.annotations.FetchMode; 14 | 15 | import javax.persistence.Entity; 16 | import javax.persistence.Table; 17 | import javax.persistence.Id; 18 | import javax.persistence.GeneratedValue; 19 | import javax.persistence.SequenceGenerator; 20 | import javax.persistence.Column; 21 | import javax.persistence.FetchType; 22 | import javax.persistence.OneToOne; 23 | import javax.persistence.JoinColumn; 24 | import javax.persistence.GenerationType; 25 | 26 | @Entity 27 | @Getter 28 | @Setter 29 | @EqualsAndHashCode 30 | @ToString 31 | @AllArgsConstructor 32 | @NoArgsConstructor 33 | @Table(name = "order_items") 34 | public class Item { 35 | 36 | @Id 37 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "order_item_sequence") 38 | @SequenceGenerator(name = "order_item_sequence", sequenceName = "order_item_seq") 39 | private Long id; 40 | 41 | @OneToOne(fetch = FetchType.EAGER) 42 | @Fetch(value = FetchMode.JOIN) 43 | @JoinColumn(name = "product_id") 44 | private Product product; 45 | 46 | @Column(name = "quantity", nullable = false) 47 | private Long quantity; 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/item/ItemController.java: -------------------------------------------------------------------------------- 1 | package com.zufar.item; 2 | 3 | import com.zufar.service.DaoService; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.ResponseBody; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.DeleteMapping; 13 | import org.springframework.web.bind.annotation.RequestBody; 14 | import org.springframework.web.bind.annotation.PostMapping; 15 | import org.springframework.web.bind.annotation.PutMapping; 16 | 17 | import java.util.Collection; 18 | 19 | @RestController 20 | @RequestMapping(value = "items", produces = {MediaType.APPLICATION_JSON_VALUE}) 21 | public class ItemController { 22 | 23 | private final DaoService orderItemService; 24 | 25 | @Autowired 26 | public ItemController(ItemService itemService) { 27 | this.orderItemService = itemService; 28 | } 29 | 30 | @GetMapping 31 | public @ResponseBody 32 | Collection getOrderItems() { 33 | return this.orderItemService.getAll(); 34 | } 35 | 36 | @GetMapping(value = "/{id}") 37 | public @ResponseBody 38 | ItemDTO getItem(@PathVariable Long id) { 39 | return this.orderItemService.getById(id); 40 | } 41 | 42 | @DeleteMapping(value = "/{id}") 43 | public void deleteItem(@PathVariable Long id) { 44 | this.orderItemService.getById(id); 45 | } 46 | 47 | @PostMapping 48 | public @ResponseBody 49 | ItemDTO saveItem(@RequestBody ItemDTO item) { 50 | return this.orderItemService.save(item); 51 | } 52 | 53 | @PutMapping 54 | public @ResponseBody 55 | ItemDTO updateItem(@RequestBody ItemDTO item) { 56 | return this.orderItemService.update(item); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/item/ItemDTO.java: -------------------------------------------------------------------------------- 1 | package com.zufar.item; 2 | 3 | import com.zufar.product.ProductDTO; 4 | 5 | import lombok.Setter; 6 | import lombok.Getter; 7 | import lombok.AllArgsConstructor; 8 | import lombok.EqualsAndHashCode; 9 | import lombok.NoArgsConstructor; 10 | import lombok.ToString; 11 | 12 | @Getter 13 | @Setter 14 | @EqualsAndHashCode 15 | @ToString 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class ItemDTO { 19 | 20 | private Long id; 21 | private ProductDTO product; 22 | private Long quantity; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/item/ItemRepository.java: -------------------------------------------------------------------------------- 1 | package com.zufar.item; 2 | 3 | import org.springframework.data.repository.PagingAndSortingRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public interface ItemRepository extends PagingAndSortingRepository { 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/item/ItemService.java: -------------------------------------------------------------------------------- 1 | package com.zufar.item; 2 | 3 | import com.zufar.product.Product; 4 | import com.zufar.product.ProductDTO; 5 | import com.zufar.exception.ItemNotFoundException; 6 | import com.zufar.exception.StatusNotFoundException; 7 | import com.zufar.product.ProductService; 8 | import com.zufar.service.DaoService; 9 | 10 | import org.apache.logging.log4j.LogManager; 11 | import org.apache.logging.log4j.Logger; 12 | 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.data.domain.Sort; 15 | import org.springframework.stereotype.Service; 16 | import org.springframework.transaction.annotation.Transactional; 17 | 18 | import java.util.Collection; 19 | import java.util.Objects; 20 | import java.util.stream.Collectors; 21 | 22 | @Service 23 | @Transactional 24 | public class ItemService implements DaoService { 25 | 26 | private static final Logger LOGGER = LogManager.getLogger(ItemService.class); 27 | private final ItemRepository itemRepository; 28 | 29 | @Autowired 30 | public ItemService(ItemRepository itemRepository) { 31 | this.itemRepository = itemRepository; 32 | } 33 | 34 | @Override 35 | public Collection getAll() { 36 | return ((Collection) this.itemRepository.findAll()) 37 | .stream() 38 | .map(ItemService::convertToOrderItemDTO) 39 | .collect(Collectors.toList()); 40 | } 41 | 42 | @Override 43 | public Collection getAll(String sortBy) { 44 | return ((Collection) this.itemRepository.findAll(Sort.by(sortBy))) 45 | .stream() 46 | .map(ItemService::convertToOrderItemDTO) 47 | .collect(Collectors.toList()); 48 | } 49 | 50 | @Override 51 | public ItemDTO getById(Long id) { 52 | Item orderEntity = this.itemRepository.findById(id).orElseThrow(() -> { 53 | final String errorMessage = "The orderItem with id = " + id + " not found."; 54 | ItemNotFoundException itemNotFoundException = new ItemNotFoundException(errorMessage); 55 | LOGGER.error(errorMessage, itemNotFoundException); 56 | return itemNotFoundException; 57 | }); 58 | return ItemService.convertToOrderItemDTO(orderEntity); 59 | } 60 | 61 | @Override 62 | public ItemDTO save(ItemDTO item) { 63 | Item itemEntity = ItemService.convertToOrderItem(item); 64 | itemEntity = this.itemRepository.save(itemEntity); 65 | return ItemService.convertToOrderItemDTO(itemEntity); 66 | } 67 | 68 | @Override 69 | public ItemDTO update(ItemDTO item) { 70 | this.isExists(item.getId()); 71 | Item itemEntity = ItemService.convertToOrderItem(item); 72 | itemEntity = this.itemRepository.save(itemEntity); 73 | return ItemService.convertToOrderItemDTO(itemEntity); 74 | } 75 | 76 | @Override 77 | public void deleteById(Long id) { 78 | this.isExists(id); 79 | this.itemRepository.deleteById(id); 80 | } 81 | 82 | @Override 83 | public Boolean isExists(Long id) { 84 | if (!this.itemRepository.existsById(id)) { 85 | final String errorMessage = "The orderItem with id = " + id + " not found."; 86 | StatusNotFoundException statusNotFoundException = new StatusNotFoundException(errorMessage); 87 | LOGGER.error(errorMessage, statusNotFoundException); 88 | throw statusNotFoundException; 89 | } 90 | return true; 91 | } 92 | 93 | public static ItemDTO convertToOrderItemDTO(Item item) { 94 | Objects.requireNonNull(item, "There is no orderItem to convert."); 95 | final ProductDTO product = ProductService.convertToProductDTO(item.getProduct()); 96 | return new ItemDTO( 97 | item.getId(), 98 | product, 99 | item.getQuantity() 100 | ); 101 | } 102 | 103 | public static Item convertToOrderItem(ItemDTO item) { 104 | Objects.requireNonNull(item, "There is no item to convert."); 105 | final Product product = ProductService.convertToProduct(item.getProduct()); 106 | return new Item( 107 | item.getId(), 108 | product, 109 | item.getQuantity() 110 | ); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/order/Order.java: -------------------------------------------------------------------------------- 1 | package com.zufar.order; 2 | 3 | import com.zufar.item.Item; 4 | import com.zufar.status.Status; 5 | import com.zufar.user.User; 6 | 7 | import lombok.Setter; 8 | import lombok.Getter; 9 | import lombok.AllArgsConstructor; 10 | import lombok.EqualsAndHashCode; 11 | import lombok.NoArgsConstructor; 12 | import lombok.ToString; 13 | 14 | import org.hibernate.annotations.Fetch; 15 | import org.hibernate.annotations.FetchMode; 16 | 17 | import javax.persistence.Entity; 18 | import javax.persistence.Table; 19 | import javax.persistence.Id; 20 | import javax.persistence.GeneratedValue; 21 | import javax.persistence.SequenceGenerator; 22 | import javax.persistence.Column; 23 | import javax.persistence.CascadeType; 24 | import javax.persistence.OneToMany; 25 | import javax.persistence.JoinTable; 26 | import javax.persistence.FetchType; 27 | import javax.persistence.OneToOne; 28 | import javax.persistence.JoinColumn; 29 | import javax.persistence.GenerationType; 30 | import java.time.LocalDateTime; 31 | 32 | import java.util.Set; 33 | 34 | @Entity 35 | @Getter 36 | @Setter 37 | @EqualsAndHashCode 38 | @ToString 39 | @AllArgsConstructor 40 | @NoArgsConstructor 41 | @Table(name = "orders") 42 | public class Order { 43 | 44 | @Id 45 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "order_sequence") 46 | @SequenceGenerator(name = "order_sequence", sequenceName = "order_seq") 47 | private Long id; 48 | 49 | @Column(name = "title", length = 256, nullable = false) 50 | private String title; 51 | 52 | @Column(name = "creation_date", nullable = false) 53 | private LocalDateTime creationDate; 54 | 55 | @Column(name = "last_modified_date", nullable = false) 56 | private LocalDateTime lastModifiedDate; 57 | 58 | @OneToOne(fetch = FetchType.EAGER) 59 | @Fetch(value = FetchMode.JOIN) 60 | @JoinColumn(name = "status_id") 61 | private Status status; 62 | 63 | @OneToOne(fetch = FetchType.EAGER) 64 | @Fetch(value = FetchMode.JOIN) 65 | @JoinColumn(name = "user_id") 66 | private User user; 67 | 68 | 69 | @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) 70 | @Fetch(FetchMode.JOIN) 71 | @JoinTable(name = "order_order_items", 72 | joinColumns = {@JoinColumn(name = "order_id")}, 73 | inverseJoinColumns = {@JoinColumn(name = "order_item_id")}) 74 | private Set items; 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/order/OrderController.java: -------------------------------------------------------------------------------- 1 | package com.zufar.order; 2 | 3 | import com.zufar.status.StatusDTO; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import org.springframework.web.bind.annotation.RequestParam; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.ResponseBody; 12 | import org.springframework.web.bind.annotation.PathVariable; 13 | import org.springframework.web.bind.annotation.DeleteMapping; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.PostMapping; 16 | import org.springframework.web.bind.annotation.PutMapping; 17 | 18 | import java.util.Collection; 19 | 20 | @RestController 21 | @RequestMapping(value = "orders", produces = {MediaType.APPLICATION_JSON_VALUE}) 22 | public class OrderController { 23 | 24 | private final OrderService orderService; 25 | 26 | @Autowired 27 | public OrderController(OrderService orderService) { 28 | this.orderService = orderService; 29 | } 30 | 31 | @GetMapping 32 | public @ResponseBody 33 | Collection getOrders(@RequestParam(required = false) String sortBy) { 34 | if (sortBy == null) { 35 | return this.orderService.getAll(); 36 | } else { 37 | return this.orderService.getAll(sortBy); 38 | } 39 | } 40 | 41 | @GetMapping(value = "/{id}") 42 | public @ResponseBody 43 | OrderDTO getOrder(@PathVariable Long id) { 44 | return this.orderService.getById(id); 45 | } 46 | 47 | @DeleteMapping(value = "/{id}") 48 | public void deleteOrder(@PathVariable Long id) { 49 | this.orderService.deleteById(id); 50 | } 51 | 52 | @PostMapping 53 | public @ResponseBody 54 | OrderDTO saveOrder(@RequestBody OrderDTO order) { 55 | return this.orderService.save(order); 56 | } 57 | 58 | @PutMapping 59 | public @ResponseBody 60 | OrderDTO updateOrder(@RequestBody OrderDTO order) { 61 | return this.orderService.update(order); 62 | } 63 | 64 | @PutMapping(value = "/{orderId}") 65 | public @ResponseBody 66 | OrderDTO changeOrderStatus(@RequestBody StatusDTO status, @RequestParam Long orderId) { 67 | return orderService.updateStatus(status, orderId); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/order/OrderDTO.java: -------------------------------------------------------------------------------- 1 | package com.zufar.order; 2 | 3 | import com.zufar.status.StatusDTO; 4 | import com.zufar.user.UserDTO; 5 | import com.zufar.item.ItemDTO; 6 | 7 | import lombok.Setter; 8 | import lombok.Getter; 9 | import lombok.AllArgsConstructor; 10 | import lombok.EqualsAndHashCode; 11 | import lombok.NoArgsConstructor; 12 | import lombok.ToString; 13 | 14 | import java.time.LocalDateTime; 15 | import java.util.Set; 16 | 17 | @Getter 18 | @Setter 19 | @EqualsAndHashCode 20 | @ToString 21 | @AllArgsConstructor 22 | @NoArgsConstructor 23 | public class OrderDTO { 24 | 25 | private Long id; 26 | private String title; 27 | private LocalDateTime creationDate; 28 | private LocalDateTime lastModifiedDate; 29 | private StatusDTO status; 30 | private UserDTO user; 31 | private Set Items; 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/order/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.zufar.order; 2 | 3 | import org.springframework.data.repository.PagingAndSortingRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public interface OrderRepository extends PagingAndSortingRepository { 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/order/OrderService.java: -------------------------------------------------------------------------------- 1 | package com.zufar.order; 2 | 3 | import com.zufar.user.UserService; 4 | import com.zufar.item.Item; 5 | import com.zufar.user.UserDTO; 6 | import com.zufar.item.ItemDTO; 7 | import com.zufar.status.StatusDTO; 8 | import com.zufar.exception.OrderNotFoundException; 9 | import com.zufar.user.User; 10 | import com.zufar.status.Status; 11 | import com.zufar.service.DaoService; 12 | import com.zufar.item.ItemService; 13 | import com.zufar.status.StatusService; 14 | 15 | import org.apache.logging.log4j.LogManager; 16 | import org.apache.logging.log4j.Logger; 17 | import org.springframework.beans.factory.annotation.Autowired; 18 | import org.springframework.data.domain.Sort; 19 | import org.springframework.stereotype.Service; 20 | import org.springframework.transaction.annotation.Transactional; 21 | 22 | import java.util.Collection; 23 | import java.util.Objects; 24 | import java.util.Set; 25 | import java.util.stream.Collectors; 26 | 27 | @Service 28 | @Transactional 29 | public class OrderService implements DaoService { 30 | 31 | private static final Logger LOGGER = LogManager.getLogger(OrderService.class); 32 | private final OrderRepository orderRepository; 33 | 34 | @Autowired 35 | public OrderService(OrderRepository orderRepository) { 36 | this.orderRepository = orderRepository; 37 | } 38 | 39 | @Override 40 | public Collection getAll() { 41 | return ((Collection) this.orderRepository.findAll()) 42 | .stream() 43 | .map(OrderService::convertToOrderDTO) 44 | .collect(Collectors.toList()); 45 | } 46 | 47 | @Override 48 | public Collection getAll(String sortBy) { 49 | return ((Collection) this.orderRepository.findAll(Sort.by(sortBy))) 50 | .stream() 51 | .map(OrderService::convertToOrderDTO) 52 | .collect(Collectors.toList()); 53 | } 54 | 55 | @Override 56 | public OrderDTO getById(Long id) { 57 | Order statusEntity = this.orderRepository.findById(id).orElseThrow(() -> { 58 | final String errorMessage = "Getting an order with id=" + id + " is impossible. There is no a sort attribute."; 59 | OrderNotFoundException orderNotFoundException = new OrderNotFoundException(errorMessage); 60 | LOGGER.error(errorMessage, orderNotFoundException); 61 | return orderNotFoundException; 62 | }); 63 | return OrderService.convertToOrderDTO(statusEntity); 64 | } 65 | 66 | @Override 67 | public OrderDTO save(OrderDTO order) { 68 | Order orderEntity = OrderService.convertToOrder(order); 69 | orderEntity = this.orderRepository.save(orderEntity); 70 | return OrderService.convertToOrderDTO(orderEntity); 71 | } 72 | 73 | @Override 74 | public OrderDTO update(OrderDTO order) { 75 | this.isExists(order.getId()); 76 | Order orderEntity = OrderService.convertToOrder(order); 77 | orderEntity = this.orderRepository.save(orderEntity); 78 | return OrderService.convertToOrderDTO(orderEntity); 79 | } 80 | 81 | @Override 82 | public void deleteById(Long id) { 83 | this.isExists(id); 84 | this.orderRepository.deleteById(id); 85 | } 86 | 87 | @Override 88 | public Boolean isExists(Long id) { 89 | if (!this.orderRepository.existsById(id)) { 90 | final String errorMessage = "The order with id = " + id + " not found."; 91 | OrderNotFoundException orderNotFoundException = new OrderNotFoundException(errorMessage); 92 | LOGGER.error(errorMessage, orderNotFoundException); 93 | throw orderNotFoundException; 94 | } 95 | return true; 96 | } 97 | 98 | public OrderDTO updateStatus(StatusDTO status, Long id) { 99 | OrderDTO order = this.getById(id); 100 | order.setStatus(status); 101 | order = this.save(order); 102 | return order; 103 | } 104 | 105 | public static OrderDTO convertToOrderDTO(Order order) { 106 | Objects.requireNonNull(order, "There is no order to convert."); 107 | final StatusDTO status = StatusService.convertToStatusDTO(order.getStatus()); 108 | final UserDTO user = UserService.convertToUserDTO(order.getUser()); 109 | final Set items = order.getItems() 110 | .stream() 111 | .map(ItemService::convertToOrderItemDTO) 112 | .collect(Collectors.toSet()); 113 | return new OrderDTO( 114 | order.getId(), 115 | order.getTitle(), 116 | order.getCreationDate(), 117 | order.getLastModifiedDate(), 118 | status, 119 | user, 120 | items 121 | ); 122 | } 123 | 124 | public static Order convertToOrder(OrderDTO order) { 125 | Objects.requireNonNull(order, "There is no order to convert."); 126 | Set dtoItems = order.getItems(); 127 | if (dtoItems == null) { 128 | final String errorMessage = "No order items in the order"; 129 | final IllegalArgumentException illegalArgumentException = new IllegalArgumentException(errorMessage); 130 | LOGGER.error(errorMessage, illegalArgumentException); 131 | throw illegalArgumentException; 132 | } 133 | Set items = dtoItems 134 | .stream() 135 | .map(ItemService::convertToOrderItem) 136 | .collect(Collectors.toSet()); 137 | final Status status = StatusService.convertToStatus(order.getStatus()); 138 | final User user = UserService.convertToUser(order.getUser()); 139 | return new Order( 140 | order.getId(), 141 | order.getTitle(), 142 | order.getCreationDate(), 143 | order.getLastModifiedDate(), 144 | status, 145 | user, 146 | items 147 | ); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/product/Product.java: -------------------------------------------------------------------------------- 1 | package com.zufar.product; 2 | 3 | import lombok.Setter; 4 | import lombok.Getter; 5 | import lombok.AllArgsConstructor; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.ToString; 9 | 10 | import javax.persistence.Entity; 11 | import javax.persistence.Table; 12 | import javax.persistence.Id; 13 | import javax.persistence.GeneratedValue; 14 | import javax.persistence.SequenceGenerator; 15 | import javax.persistence.Column; 16 | import javax.persistence.GenerationType; 17 | 18 | @Entity 19 | @Getter 20 | @Setter 21 | @EqualsAndHashCode 22 | @ToString 23 | @AllArgsConstructor 24 | @NoArgsConstructor 25 | @Table(name = "products") 26 | public class Product { 27 | 28 | @Id 29 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "product_sequence") 30 | @SequenceGenerator(name = "product_sequence", sequenceName = "product_seq") 31 | private Long id; 32 | 33 | @Column(name = "name", length = 256, nullable = false, unique = true) 34 | private String name; 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/product/ProductController.java: -------------------------------------------------------------------------------- 1 | package com.zufar.product; 2 | 3 | import com.zufar.service.DaoService; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.ResponseBody; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.DeleteMapping; 13 | import org.springframework.web.bind.annotation.RequestBody; 14 | import org.springframework.web.bind.annotation.PostMapping; 15 | import org.springframework.web.bind.annotation.PutMapping; 16 | 17 | import java.util.Collection; 18 | 19 | @RestController 20 | @RequestMapping(value = "products", produces = {MediaType.APPLICATION_JSON_VALUE}) 21 | public class ProductController { 22 | 23 | private final DaoService productService; 24 | 25 | @Autowired 26 | public ProductController(ProductService productService) { 27 | this.productService = productService; 28 | } 29 | 30 | @GetMapping 31 | public @ResponseBody 32 | Collection getProducts() { 33 | return this.productService.getAll(); 34 | } 35 | 36 | @GetMapping(value = "/{id}") 37 | public @ResponseBody 38 | ProductDTO getProduct(@PathVariable Long id) { 39 | return this.productService.getById(id); 40 | } 41 | 42 | @DeleteMapping(value = "/{id}") 43 | public void deleteProduct(@PathVariable Long id) { 44 | this.productService.deleteById(id); 45 | } 46 | 47 | @PostMapping 48 | public @ResponseBody 49 | ProductDTO saveProduct(@RequestBody ProductDTO product) { 50 | return this.productService.save(product); 51 | } 52 | 53 | @PutMapping 54 | public @ResponseBody 55 | ProductDTO updateProduct(@RequestBody ProductDTO product) { 56 | return this.productService.update(product); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/product/ProductDTO.java: -------------------------------------------------------------------------------- 1 | package com.zufar.product; 2 | 3 | import lombok.Setter; 4 | import lombok.Getter; 5 | import lombok.AllArgsConstructor; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.ToString; 9 | 10 | @Getter 11 | @Setter 12 | @EqualsAndHashCode 13 | @ToString 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class ProductDTO { 17 | 18 | private Long id; 19 | private String name; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/product/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package com.zufar.product; 2 | 3 | import org.springframework.data.repository.PagingAndSortingRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public interface ProductRepository extends PagingAndSortingRepository { 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/product/ProductService.java: -------------------------------------------------------------------------------- 1 | package com.zufar.product; 2 | 3 | import com.zufar.exception.ProductNotFoundException; 4 | import com.zufar.service.DaoService; 5 | 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.data.domain.Sort; 10 | import org.springframework.stereotype.Service; 11 | import org.springframework.transaction.annotation.Transactional; 12 | 13 | import java.util.Collection; 14 | import java.util.Objects; 15 | import java.util.stream.Collectors; 16 | 17 | @Service 18 | @Transactional 19 | public class ProductService implements DaoService { 20 | 21 | private static final Logger LOGGER = LogManager.getLogger(ProductService.class); 22 | private final ProductRepository productRepository; 23 | 24 | @Autowired 25 | public ProductService(ProductRepository productRepository) { 26 | this.productRepository = productRepository; 27 | } 28 | 29 | @Override 30 | public Collection getAll() { 31 | return ((Collection) this.productRepository.findAll()) 32 | .stream() 33 | .map(ProductService::convertToProductDTO) 34 | .collect(Collectors.toList()); 35 | } 36 | 37 | @Override 38 | public Collection getAll(String sortBy) { 39 | return ((Collection) this.productRepository.findAll(Sort.by(sortBy))) 40 | .stream() 41 | .map(ProductService::convertToProductDTO) 42 | .collect(Collectors.toList()); 43 | } 44 | 45 | @Override 46 | public ProductDTO getById(Long id) { 47 | Product productEntity = this.productRepository.findById(id).orElseThrow(() -> { 48 | final String errorMessage = "The product with id = " + id + " not found."; 49 | ProductNotFoundException productNotFoundException = new ProductNotFoundException(errorMessage); 50 | LOGGER.error(errorMessage, productNotFoundException); 51 | return productNotFoundException; 52 | }); 53 | return ProductService.convertToProductDTO(productEntity); 54 | } 55 | 56 | @Override 57 | public ProductDTO save(ProductDTO product) { 58 | Product productEntity = ProductService.convertToProduct(product); 59 | productEntity = this.productRepository.save(productEntity); 60 | return ProductService.convertToProductDTO(productEntity); 61 | } 62 | 63 | @Override 64 | public ProductDTO update(ProductDTO product) { 65 | this.isExists(product.getId()); 66 | Product productEntity = ProductService.convertToProduct(product); 67 | productEntity = this.productRepository.save(productEntity); 68 | return ProductService.convertToProductDTO(productEntity); 69 | } 70 | 71 | @Override 72 | public void deleteById(Long id) { 73 | this.isExists(id); 74 | this.productRepository.deleteById(id); 75 | } 76 | 77 | @Override 78 | public Boolean isExists(Long id) { 79 | if (!this.productRepository.existsById(id)) { 80 | final String errorMessage = "The product with id = " + id + " not found."; 81 | ProductNotFoundException productNotFoundException = new ProductNotFoundException(errorMessage); 82 | LOGGER.error(errorMessage, productNotFoundException); 83 | throw productNotFoundException; 84 | } 85 | return true; 86 | } 87 | 88 | public static Product convertToProduct(ProductDTO product) { 89 | Objects.requireNonNull(product, "There is no product to convert."); 90 | return new Product( 91 | product.getId(), 92 | product.getName()); 93 | } 94 | 95 | public static ProductDTO convertToProductDTO(Product product) { 96 | Objects.requireNonNull(product, "There is no product to convert."); 97 | return new ProductDTO( 98 | product.getId(), 99 | product.getName()); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/service/DaoService.java: -------------------------------------------------------------------------------- 1 | package com.zufar.service; 2 | 3 | import java.util.Collection; 4 | 5 | public interface DaoService { 6 | 7 | Collection getAll(); 8 | Collection getAll(String sortBy); 9 | T getById(Long id); 10 | T save(T entity); 11 | T update(T entity); 12 | void deleteById(Long id) ; 13 | Boolean isExists(Long id) ; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/status/Status.java: -------------------------------------------------------------------------------- 1 | package com.zufar.status; 2 | 3 | import lombok.Setter; 4 | import lombok.Getter; 5 | import lombok.AllArgsConstructor; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.ToString; 9 | 10 | import javax.persistence.Entity; 11 | import javax.persistence.Table; 12 | import javax.persistence.Id; 13 | import javax.persistence.GeneratedValue; 14 | import javax.persistence.SequenceGenerator; 15 | import javax.persistence.Column; 16 | import javax.persistence.GenerationType; 17 | 18 | @Entity 19 | @Getter 20 | @Setter 21 | @EqualsAndHashCode 22 | @ToString 23 | @AllArgsConstructor 24 | @NoArgsConstructor 25 | @Table(name = "statuses") 26 | public class Status { 27 | 28 | @Id 29 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "status_sequence") 30 | @SequenceGenerator(name = "status_sequence", sequenceName = "status_seq") 31 | private Long id; 32 | 33 | @Column(name = "name", length = 256, nullable = false, unique = true) 34 | private String name; 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/status/StatusController.java: -------------------------------------------------------------------------------- 1 | package com.zufar.status; 2 | 3 | import com.zufar.service.DaoService; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.ResponseBody; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.DeleteMapping; 13 | import org.springframework.web.bind.annotation.RequestBody; 14 | import org.springframework.web.bind.annotation.PostMapping; 15 | import org.springframework.web.bind.annotation.PutMapping; 16 | 17 | import java.util.Collection; 18 | 19 | @RestController 20 | @RequestMapping(value = "statuses", produces = {MediaType.APPLICATION_JSON_VALUE}) 21 | public class StatusController { 22 | 23 | private final DaoService statusService; 24 | 25 | @Autowired 26 | public StatusController(StatusService statusService) { 27 | this.statusService = statusService; 28 | } 29 | 30 | @GetMapping 31 | public @ResponseBody 32 | Collection getStatuses() { 33 | return this.statusService.getAll(); 34 | } 35 | 36 | @GetMapping(value = "/{id}") 37 | public @ResponseBody 38 | StatusDTO getStatus(@PathVariable Long id) { 39 | return this.statusService.getById(id); 40 | } 41 | 42 | @DeleteMapping(value = "/{id}") 43 | public void deleteStatus(@PathVariable Long id) { 44 | this.statusService.deleteById(id); 45 | } 46 | 47 | @PostMapping 48 | public @ResponseBody 49 | StatusDTO saveStatus(@RequestBody StatusDTO status) { 50 | return this.statusService.save(status); 51 | } 52 | 53 | @PutMapping 54 | public @ResponseBody 55 | StatusDTO updateStatus(@RequestBody StatusDTO status) { 56 | return this.statusService.update(status); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/status/StatusDTO.java: -------------------------------------------------------------------------------- 1 | package com.zufar.status; 2 | 3 | import lombok.Setter; 4 | import lombok.Getter; 5 | import lombok.AllArgsConstructor; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.ToString; 9 | 10 | @Getter 11 | @Setter 12 | @EqualsAndHashCode 13 | @ToString 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class StatusDTO { 17 | 18 | private Long id; 19 | private String name; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/status/StatusRepository.java: -------------------------------------------------------------------------------- 1 | package com.zufar.status; 2 | 3 | import org.springframework.data.repository.PagingAndSortingRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public interface StatusRepository extends PagingAndSortingRepository { 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/status/StatusService.java: -------------------------------------------------------------------------------- 1 | package com.zufar.status; 2 | 3 | import com.zufar.exception.StatusNotFoundException; 4 | import com.zufar.service.DaoService; 5 | 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.data.domain.Sort; 10 | import org.springframework.stereotype.Service; 11 | import org.springframework.transaction.annotation.Transactional; 12 | 13 | import java.util.Collection; 14 | import java.util.Objects; 15 | import java.util.stream.Collectors; 16 | 17 | @Service 18 | @Transactional 19 | public class StatusService implements DaoService { 20 | 21 | private static final Logger LOGGER = LogManager.getLogger(StatusService.class); 22 | private final StatusRepository statusRepository; 23 | 24 | @Autowired 25 | public StatusService(StatusRepository statusRepository) { 26 | this.statusRepository = statusRepository; 27 | } 28 | 29 | @Override 30 | public Collection getAll() { 31 | return ((Collection) this.statusRepository.findAll()) 32 | .stream() 33 | .map(StatusService::convertToStatusDTO) 34 | .collect(Collectors.toList()); 35 | } 36 | 37 | @Override 38 | public Collection getAll(String sortBy) { 39 | return ((Collection) this.statusRepository.findAll(Sort.by(sortBy))) 40 | .stream() 41 | .map(StatusService::convertToStatusDTO) 42 | .collect(Collectors.toList()); 43 | } 44 | 45 | @Override 46 | public StatusDTO getById(Long id) { 47 | Status statusEntity = this.statusRepository.findById(id).orElseThrow(() -> { 48 | final String errorMessage = "The status with id = " + id + " not found."; 49 | StatusNotFoundException statusNotFoundException = new StatusNotFoundException(errorMessage); 50 | LOGGER.error(errorMessage, statusNotFoundException); 51 | return statusNotFoundException; 52 | }); 53 | return StatusService.convertToStatusDTO(statusEntity); 54 | } 55 | 56 | @Override 57 | public StatusDTO save(StatusDTO status) { 58 | Status statusEntity = StatusService.convertToStatus(status); 59 | statusEntity = this.statusRepository.save(statusEntity); 60 | return StatusService.convertToStatusDTO(statusEntity); 61 | } 62 | 63 | @Override 64 | public StatusDTO update(StatusDTO status) { 65 | this.isExists(status.getId()); 66 | Status statusEntity = StatusService.convertToStatus(status); 67 | statusEntity = this.statusRepository.save(statusEntity); 68 | return StatusService.convertToStatusDTO(statusEntity); 69 | } 70 | 71 | @Override 72 | public void deleteById(Long id) { 73 | this.isExists(id); 74 | this.statusRepository.deleteById(id); 75 | } 76 | 77 | @Override 78 | public Boolean isExists(Long id) { 79 | if (!this.statusRepository.existsById(id)) { 80 | final String errorMessage = "The status with id = " + id + " not found."; 81 | StatusNotFoundException statusNotFoundException = new StatusNotFoundException(errorMessage); 82 | LOGGER.error(errorMessage, statusNotFoundException); 83 | throw statusNotFoundException; 84 | } 85 | return true; 86 | } 87 | 88 | public static StatusDTO convertToStatusDTO(Status status) { 89 | Objects.requireNonNull(status, "There is no status to convert."); 90 | return new StatusDTO( 91 | status.getId(), 92 | status.getName()); 93 | } 94 | 95 | public static Status convertToStatus(StatusDTO status) { 96 | Objects.requireNonNull(status, "There is no status to convert."); 97 | return new Status( 98 | status.getId(), 99 | status.getName()); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/user/Role.java: -------------------------------------------------------------------------------- 1 | package com.zufar.user; 2 | 3 | import lombok.Setter; 4 | import lombok.Getter; 5 | import lombok.AllArgsConstructor; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.ToString; 9 | 10 | import javax.persistence.Entity; 11 | import javax.persistence.Table; 12 | import javax.persistence.Id; 13 | import javax.persistence.GeneratedValue; 14 | import javax.persistence.SequenceGenerator; 15 | import javax.persistence.Column; 16 | import javax.persistence.GenerationType; 17 | 18 | import org.springframework.security.core.GrantedAuthority; 19 | 20 | @Entity 21 | @Getter 22 | @Setter 23 | @EqualsAndHashCode 24 | @ToString 25 | @AllArgsConstructor 26 | @NoArgsConstructor 27 | @Table(name = "roles") 28 | public class Role implements GrantedAuthority { 29 | 30 | @Id 31 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "role_sequence") 32 | @SequenceGenerator(name = "role_sequence", sequenceName = "role_seq") 33 | private Long id; 34 | 35 | @Column(name = "name", length = 256, nullable = false, unique = true) 36 | private String name; 37 | 38 | @Override 39 | public String getAuthority() { 40 | return name; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/user/User.java: -------------------------------------------------------------------------------- 1 | package com.zufar.user; 2 | 3 | import lombok.Setter; 4 | import lombok.Getter; 5 | import lombok.AllArgsConstructor; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.ToString; 9 | 10 | import org.hibernate.annotations.Fetch; 11 | import org.hibernate.annotations.FetchMode; 12 | 13 | import javax.persistence.Entity; 14 | import javax.persistence.Table; 15 | import javax.persistence.Id; 16 | import javax.persistence.GeneratedValue; 17 | import javax.persistence.OneToMany; 18 | import javax.persistence.JoinTable; 19 | import javax.persistence.JoinColumn; 20 | import javax.persistence.FetchType; 21 | import javax.persistence.SequenceGenerator; 22 | import javax.persistence.Column; 23 | import javax.persistence.CascadeType; 24 | import javax.persistence.GenerationType; 25 | 26 | import java.util.Set; 27 | 28 | @Entity 29 | @Getter 30 | @Setter 31 | @EqualsAndHashCode 32 | @ToString 33 | @AllArgsConstructor 34 | @NoArgsConstructor 35 | @Table(name = "users") 36 | public class User { 37 | 38 | @Id 39 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_sequence") 40 | @SequenceGenerator(name = "user_sequence", sequenceName = "user_seq") 41 | private Long id; 42 | 43 | @Column(name = "name", length = 256, nullable = false) 44 | private String name; 45 | 46 | @Column(name = "email", length = 256, nullable = false) 47 | private String email; 48 | 49 | @Column(name = "login", length = 256, nullable = false, unique = true) 50 | private String login; 51 | 52 | @Column(name = "password", length = 256, nullable = false) 53 | private String password; 54 | 55 | @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) 56 | @Fetch(FetchMode.JOIN) 57 | @JoinTable(name = "user_roles", 58 | joinColumns = {@JoinColumn(name = "user_id")}, 59 | inverseJoinColumns = {@JoinColumn(name = "role_id")}) 60 | private Set roles; 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/user/UserController.java: -------------------------------------------------------------------------------- 1 | package com.zufar.user; 2 | 3 | import com.zufar.service.DaoService; 4 | 5 | import java.util.Collection; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.http.MediaType; 9 | import org.springframework.web.bind.annotation.RestController; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.ResponseBody; 13 | import org.springframework.web.bind.annotation.PathVariable; 14 | import org.springframework.web.bind.annotation.DeleteMapping; 15 | import org.springframework.web.bind.annotation.RequestBody; 16 | import org.springframework.web.bind.annotation.PostMapping; 17 | import org.springframework.web.bind.annotation.PutMapping; 18 | 19 | @RestController 20 | @RequestMapping(value = "users", produces = {MediaType.APPLICATION_JSON_VALUE}) 21 | public class UserController { 22 | 23 | private final DaoService userService; 24 | 25 | @Autowired 26 | public UserController(UserService userService) { 27 | this.userService = userService; 28 | } 29 | 30 | @GetMapping 31 | public @ResponseBody 32 | Collection getUsers() { 33 | return this.userService.getAll(); 34 | } 35 | 36 | @GetMapping(value = "/{id}") 37 | public @ResponseBody 38 | UserDTO getUser(@PathVariable Long id) { 39 | return this.userService.getById(id); 40 | } 41 | 42 | @DeleteMapping(value = "/{id}") 43 | public void deleteUser(@PathVariable Long id) { 44 | this.userService.deleteById(id); 45 | } 46 | 47 | @PostMapping 48 | public @ResponseBody 49 | UserDTO saveUser(@RequestBody UserDTO user) { 50 | return this.userService.save(user); 51 | } 52 | 53 | @PutMapping 54 | public @ResponseBody 55 | UserDTO updateUser(@RequestBody UserDTO user) { 56 | return this.userService.update(user); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/user/UserDTO.java: -------------------------------------------------------------------------------- 1 | package com.zufar.user; 2 | 3 | import lombok.Setter; 4 | import lombok.Getter; 5 | import lombok.AllArgsConstructor; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.ToString; 9 | 10 | import java.util.Set; 11 | 12 | @Getter 13 | @Setter 14 | @EqualsAndHashCode 15 | @ToString 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class UserDTO { 19 | 20 | private Long id; 21 | private String name; 22 | private String email; 23 | private String login; 24 | private String password; 25 | private Set roles; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/user/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.zufar.user; 2 | 3 | import org.springframework.data.repository.PagingAndSortingRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | import java.util.Optional; 7 | 8 | @Repository 9 | public interface UserRepository extends PagingAndSortingRepository { 10 | Optional findByLogin(String login); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/zufar/user/UserService.java: -------------------------------------------------------------------------------- 1 | package com.zufar.user; 2 | 3 | import com.zufar.exception.UserNotFoundException; 4 | import com.zufar.service.DaoService; 5 | 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.data.domain.Sort; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.transaction.annotation.Transactional; 13 | 14 | import java.util.Collection; 15 | import java.util.Objects; 16 | import java.util.stream.Collectors; 17 | 18 | @Service 19 | @Transactional 20 | public class UserService implements DaoService { 21 | 22 | private static final Logger LOGGER = LogManager.getLogger(UserService.class); 23 | private final UserRepository userRepository; 24 | 25 | @Autowired 26 | public UserService(UserRepository userRepository) { 27 | this.userRepository = userRepository; 28 | } 29 | 30 | @Override 31 | public Collection getAll() { 32 | return ((Collection) this.userRepository.findAll()) 33 | .stream() 34 | .map(UserService::convertToUserDTO) 35 | .collect(Collectors.toList()); 36 | } 37 | 38 | @Override 39 | public Collection getAll(String sortBy) { 40 | return ((Collection) this.userRepository.findAll(Sort.by(sortBy))) 41 | .stream() 42 | .map(UserService::convertToUserDTO) 43 | .collect(Collectors.toList()); 44 | } 45 | 46 | @Override 47 | public UserDTO getById(Long id) { 48 | User userEntity = this.userRepository.findById(id).orElseThrow(() -> { 49 | final String errorMessage = "The user with id = " + id + " not found."; 50 | UserNotFoundException userNotFoundException = new UserNotFoundException(errorMessage); 51 | LOGGER.error(errorMessage, userNotFoundException); 52 | return userNotFoundException; 53 | }); 54 | return UserService.convertToUserDTO(userEntity); 55 | } 56 | 57 | public UserDTO getByLogin(String login) { 58 | User userEntity = this.userRepository.findByLogin(login).orElseThrow(() -> { 59 | final String errorMessage = "The user with login = " + login + " not found."; 60 | UserNotFoundException userNotFoundException = new UserNotFoundException(errorMessage); 61 | LOGGER.error(errorMessage, userNotFoundException); 62 | return userNotFoundException; 63 | }); 64 | return UserService.convertToUserDTO(userEntity); 65 | } 66 | 67 | 68 | @Override 69 | public UserDTO save(UserDTO user) { 70 | User userEntity = UserService.convertToUser(user); 71 | userEntity = this.userRepository.save(userEntity); 72 | return UserService.convertToUserDTO(userEntity); 73 | } 74 | 75 | @Override 76 | public UserDTO update(UserDTO user) { 77 | this.isExists(user.getId()); 78 | User userEntity = UserService.convertToUser(user); 79 | userEntity = this.userRepository.save(userEntity); 80 | return UserService.convertToUserDTO(userEntity); 81 | } 82 | 83 | @Override 84 | public void deleteById(Long id) { 85 | this.isExists(id); 86 | this.userRepository.deleteById(id); 87 | } 88 | 89 | @Override 90 | public Boolean isExists(Long id) { 91 | if (!this.userRepository.existsById(id)) { 92 | final String errorMessage = "The user with id = " + id + " not found."; 93 | UserNotFoundException userNotFoundException = new UserNotFoundException(errorMessage); 94 | LOGGER.error(errorMessage, userNotFoundException); 95 | throw userNotFoundException; 96 | } 97 | return true; 98 | } 99 | 100 | public static User convertToUser(UserDTO user) { 101 | Objects.requireNonNull(user, "There is no user to convert."); 102 | return new User( 103 | user.getId(), 104 | user.getName(), 105 | user.getEmail(), 106 | user.getLogin(), 107 | user.getPassword(), 108 | user.getRoles()); 109 | } 110 | 111 | public static UserDTO convertToUserDTO(User user) { 112 | Objects.requireNonNull(user, "There is no user to convert."); 113 | return new UserDTO( 114 | user.getId(), 115 | user.getName(), 116 | user.getEmail(), 117 | user.getLogin(), 118 | user.getPassword(), 119 | user.getRoles()); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: 'jdbc:postgresql://localhost:5432/order' 4 | username: 'zufar' 5 | password: 'zufar' 6 | driver-class-name: org.postgresql.Driver 7 | hikari: 8 | connectionTimeout: 20000 9 | maximumPoolSize: 5 10 | jpa: 11 | hibernate: 12 | ddl-auto: update 13 | properties: 14 | hibernate: 15 | dialect: 'org.hibernate.dialect.PostgreSQLDialect' 16 | banner: 17 | location: 'classpath:/banner.txt' 18 | -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | ___ ____ ____ ____ ____ ___ ___ ___ __ __ ___ ___ ____ ___ ___ ____ __ __ ______ __ _ _ __ ______ ____ ___ ___ 2 | // \\ || \\ || \\ || || \\ ||\\//|| // \\ ||\ || // \\ // \\ || ||\\//|| || ||\ || | || | (( \ \\// (( \ | || | || ||\\//|| 3 | (( )) ||_// || )) ||== ||_// || \/ || ||=|| ||\\|| ||=|| (( ___ ||== || \/ || ||== ||\\|| || \\ )/ \\ || ||== || \/ || 4 | \\_// || \\ ||_// ||___ || \\ || || || || || \|| || || \\_|| ||___ || || ||___ || \|| || \_)) // \_)) || ||___ || || 5 | 6 | -------------------------------------------------------------------------------- /src/test/java/com/zufar/service/OrderServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.zufar.service; 2 | 3 | import com.zufar.user.Role; 4 | import com.zufar.user.User; 5 | import com.zufar.user.UserDTO; 6 | import com.zufar.item.Item; 7 | import com.zufar.item.ItemDTO; 8 | import com.zufar.order.Order; 9 | import com.zufar.order.OrderDTO; 10 | import com.zufar.order.OrderRepository; 11 | import com.zufar.order.OrderService; 12 | import com.zufar.product.Product; 13 | import com.zufar.product.ProductDTO; 14 | import com.zufar.status.Status; 15 | import com.zufar.status.StatusDTO; 16 | import com.zufar.exception.OrderNotFoundException; 17 | 18 | import org.junit.BeforeClass; 19 | import org.junit.Test; 20 | import org.junit.runner.RunWith; 21 | 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.beans.factory.annotation.Qualifier; 24 | import org.springframework.boot.test.context.SpringBootTest; 25 | import org.springframework.boot.test.mock.mockito.MockBean; 26 | import org.springframework.data.domain.Sort; 27 | import org.springframework.test.context.junit4.SpringRunner; 28 | 29 | import java.time.LocalDateTime; 30 | import java.util.stream.Collectors; 31 | import java.util.Collection; 32 | import java.util.ArrayList; 33 | import java.util.Comparator; 34 | import java.util.List; 35 | import java.util.Optional; 36 | import java.util.HashSet; 37 | import java.util.Set; 38 | 39 | import static org.junit.Assert.assertEquals; 40 | import static org.junit.Assert.assertNotNull; 41 | import static org.mockito.Mockito.when; 42 | import static org.mockito.Mockito.verify; 43 | import static org.mockito.Mockito.times; 44 | import static org.mockito.Mockito.doNothing; 45 | 46 | 47 | @SpringBootTest 48 | @RunWith(SpringRunner.class) 49 | public class OrderServiceTest { 50 | 51 | @Autowired 52 | @Qualifier("orderService") 53 | private DaoService orderService; 54 | 55 | @MockBean 56 | private OrderRepository orderRepository; 57 | 58 | private static final long ORDER_ID = 1L; 59 | private static final String ORDER_TITLE = "My first order"; 60 | private static final LocalDateTime ORDER_CREATION_DATE_TIME = LocalDateTime.of(2019, 9, 1, 5, 2, 4); 61 | private static final LocalDateTime ORDER_FINISHED_DATE_TIME = LocalDateTime.of(2020, 10, 11, 4, 6, 3); 62 | private static Collection ENTITY_ORDERS = new ArrayList<>(); 63 | private static Collection ORDERS = new ArrayList<>(); 64 | private static OrderDTO ORDER; 65 | private static Order ORDER_ENTITY; 66 | 67 | @BeforeClass 68 | public static void setUp() { 69 | ORDER_ENTITY = getOrderEntity(); 70 | ENTITY_ORDERS.add(ORDER_ENTITY); 71 | ORDER = getOrder(); 72 | ORDERS.add(ORDER); 73 | } 74 | 75 | @Test 76 | public void whenGetAllCalledOrdersShouldReturned() { 77 | when(orderRepository.findAll()).thenReturn(ENTITY_ORDERS); 78 | 79 | Collection actual = orderService.getAll(); 80 | 81 | verify(orderRepository, times(1)).findAll(); 82 | assertNotNull(actual); 83 | assertEquals(ORDERS, actual); 84 | } 85 | 86 | @Test 87 | public void whenGetAllWithSortByCalledOrdersShouldReturned() { 88 | List orders = ENTITY_ORDERS 89 | .stream() 90 | .sorted(Comparator.comparing(Order::getId)) 91 | .collect(Collectors.toList()); 92 | when(orderRepository.findAll(Sort.by("id"))).thenReturn(orders); 93 | 94 | Collection actual = orderService.getAll("id"); 95 | 96 | verify(orderRepository, times(1)).findAll(Sort.by("id")); 97 | assertNotNull(actual); 98 | assertEquals(ORDERS, actual); 99 | } 100 | 101 | @Test 102 | public void whenGetByIdCalledOrderShouldReturned() { 103 | when(orderRepository.findById(ORDER_ID)).thenReturn(Optional.of(ORDER_ENTITY)); 104 | 105 | OrderDTO actual = orderService.getById(ORDER_ID); 106 | 107 | verify(orderRepository, times(1)).findById(ORDER_ID); 108 | assertNotNull(actual); 109 | assertEquals(ORDER, actual); 110 | } 111 | 112 | @Test(expected = OrderNotFoundException.class) 113 | public void whenGetByInvalidIdCalledThrowOrderNotFoundException() { 114 | long INVALID_STATUS_ID = 55555L; 115 | when(orderRepository.existsById(INVALID_STATUS_ID)).thenReturn(false); 116 | 117 | orderService.getById(INVALID_STATUS_ID); 118 | } 119 | 120 | @Test 121 | public void whenSaveCalledThenOrderShouldBeReturned() { 122 | Order orderEntity = ORDER_ENTITY; 123 | orderEntity.setId(null); 124 | when(orderRepository.save(orderEntity)).thenReturn(ORDER_ENTITY); 125 | OrderDTO order = ORDER; 126 | order.setId(null); 127 | 128 | OrderDTO actual = orderService.save(order); 129 | 130 | verify(orderRepository, times(1)).save(orderEntity); 131 | assertNotNull(actual); 132 | assertEquals(ORDER, actual); 133 | } 134 | 135 | @Test 136 | public void whenUpdateCalledThenOrderShouldBeReturned() { 137 | when(orderRepository.save(ORDER_ENTITY)).thenReturn(ORDER_ENTITY); 138 | when(orderRepository.existsById(ORDER_ID)).thenReturn(true); 139 | 140 | OrderDTO actual = orderService.update(ORDER); 141 | 142 | verify(orderRepository, times(1)).existsById(ORDER_ID); 143 | verify(orderRepository, times(1)).save(ORDER_ENTITY); 144 | assertNotNull(actual); 145 | assertEquals(ORDER, actual); 146 | } 147 | 148 | @Test 149 | public void whenConvertOrderEntityCalledThenOrderDTOShouldBeReturned() { 150 | OrderDTO actual = OrderService.convertToOrderDTO(ORDER_ENTITY); 151 | 152 | assertNotNull(actual); 153 | assertEquals(ORDER, actual); 154 | } 155 | 156 | @Test 157 | public void whenConvertOrderDTOCalledThenOrderEntityShouldBeReturned() { 158 | Order actual = OrderService.convertToOrder(ORDER); 159 | 160 | assertNotNull(actual); 161 | assertEquals(ORDER_ENTITY, actual); 162 | } 163 | 164 | @Test 165 | public void whenDeleteOrderByIdCalled() { 166 | when(orderRepository.existsById(ORDER_ID)).thenReturn(true); 167 | doNothing().when(orderRepository).deleteById(ORDER_ID); 168 | 169 | orderService.deleteById(ORDER_ID); 170 | 171 | verify(orderRepository, times(1)).existsById(ORDER_ID); 172 | verify(orderRepository, times(1)).deleteById(ORDER_ID); 173 | } 174 | 175 | private static Order getOrderEntity() { 176 | Status STATUS_ENTITY = new Status(1L, "Active"); 177 | Set roles = new HashSet<>(); 178 | roles.add(new Role(1L, "ROLE_ADMIN")); 179 | User User_ENTITY = new User(1L, "Zufar Sunagatov", "zuf999@mail.ru", "Alice", 180 | "YOU_KNOW", roles); 181 | Product PIZZA_PRODUCT_ENTITY = new Product(1L, "Pizza"); 182 | Product JUICE_PRODUCT_ENTITY = new Product(1L, "JUICE"); 183 | Set ENTITY_ITEMS = new HashSet<>(); 184 | Item PIZZA_ITEM_ENTITY = new Item(1L, PIZZA_PRODUCT_ENTITY, 3L); 185 | Item JUICE_ITEM_ENTITY = new Item(2L, JUICE_PRODUCT_ENTITY, 5L); 186 | ENTITY_ITEMS.add(PIZZA_ITEM_ENTITY); 187 | ENTITY_ITEMS.add(JUICE_ITEM_ENTITY); 188 | return new Order(ORDER_ID, ORDER_TITLE, ORDER_CREATION_DATE_TIME, ORDER_FINISHED_DATE_TIME, STATUS_ENTITY, 189 | User_ENTITY, ENTITY_ITEMS); 190 | } 191 | 192 | private static OrderDTO getOrder() { 193 | StatusDTO STATUS = new StatusDTO(1L, "Active"); 194 | Set roles = new HashSet<>(); 195 | roles.add(new Role(1L, "ROLE_ADMIN")); 196 | UserDTO CUSTOMER = new UserDTO(1L, "Zufar Sunagatov", "zuf999@mail.ru", "Alice", 197 | "YOU_KNOW", roles); 198 | ProductDTO PIZZA_PRODUCT = new ProductDTO(1L, "Pizza"); 199 | ProductDTO JUICE_PRODUCT = new ProductDTO(1L, "JUICE"); 200 | Set ITEMS = new HashSet<>(); 201 | ItemDTO PIZZA_ITEM = new ItemDTO(1L, PIZZA_PRODUCT, 3L); 202 | ItemDTO JUICE_ITEM = new ItemDTO(2L, JUICE_PRODUCT, 5L); 203 | ITEMS.add(PIZZA_ITEM); 204 | ITEMS.add(JUICE_ITEM); 205 | return new OrderDTO(ORDER_ID, ORDER_TITLE, ORDER_CREATION_DATE_TIME, ORDER_FINISHED_DATE_TIME, STATUS, CUSTOMER, 206 | ITEMS); 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/test/java/com/zufar/service/StatusServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.zufar.service; 2 | 3 | 4 | import com.zufar.status.Status; 5 | import com.zufar.status.StatusRepository; 6 | import com.zufar.status.StatusService; 7 | import com.zufar.status.StatusDTO; 8 | import com.zufar.exception.StatusNotFoundException; 9 | 10 | import org.junit.BeforeClass; 11 | import org.junit.Test; 12 | import org.junit.runner.RunWith; 13 | 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.beans.factory.annotation.Qualifier; 16 | import org.springframework.boot.test.context.SpringBootTest; 17 | import org.springframework.boot.test.mock.mockito.MockBean; 18 | import org.springframework.data.domain.Sort; 19 | import org.springframework.test.context.junit4.SpringRunner; 20 | 21 | import java.util.*; 22 | import java.util.stream.Collectors; 23 | 24 | import static org.junit.Assert.assertEquals; 25 | import static org.junit.Assert.assertNotNull; 26 | import static org.mockito.Mockito.*; 27 | 28 | @SpringBootTest 29 | @RunWith(SpringRunner.class) 30 | public class StatusServiceTest { 31 | 32 | @Autowired 33 | @Qualifier("statusService") 34 | private DaoService statusService; 35 | 36 | @MockBean 37 | private StatusRepository statusRepository; 38 | 39 | private static final long ACTIVE_STATUS_ID = 1L; 40 | private static final String ACTIVE_STATUS_NAME = "Active"; 41 | private static final Status ACTIVE_STATUS_ENTITY = new Status(ACTIVE_STATUS_ID, ACTIVE_STATUS_NAME); 42 | private static final StatusDTO ACTIVE_STATUS = new StatusDTO(ACTIVE_STATUS_ID, ACTIVE_STATUS_NAME); 43 | 44 | 45 | private static final long IN_PROCESS_STATUS_ID = 2L; 46 | private static final String IN_PROCESS_STATUS_NAME = "In-progress"; 47 | private static final Status IN_PROCESS_STATUS_ENTITY = new Status(IN_PROCESS_STATUS_ID, IN_PROCESS_STATUS_NAME); 48 | private static final StatusDTO IN_PROCESS_STATUS = new StatusDTO(IN_PROCESS_STATUS_ID, IN_PROCESS_STATUS_NAME); 49 | 50 | private static final long COMPLETE_STATUS_ID = 3L; 51 | private static final String COMPLETE_STATUS_NAME = "Completed"; 52 | private static final Status COMPLETE_STATUS_ENTITY = new Status(COMPLETE_STATUS_ID, COMPLETE_STATUS_NAME); 53 | private static final StatusDTO COMPLETE_STATUS = new StatusDTO(COMPLETE_STATUS_ID, COMPLETE_STATUS_NAME); 54 | 55 | private static final Collection ENTITY_STATUSES = new ArrayList<>(); 56 | 57 | @BeforeClass 58 | public static void setUp() { 59 | ENTITY_STATUSES.add(ACTIVE_STATUS_ENTITY); 60 | ENTITY_STATUSES.add(COMPLETE_STATUS_ENTITY); 61 | ENTITY_STATUSES.add(IN_PROCESS_STATUS_ENTITY); 62 | } 63 | 64 | @Test 65 | public void whenGetAllCalledThenCollectionShouldBeFound() { 66 | when(statusRepository.findAll()).thenReturn(ENTITY_STATUSES); 67 | 68 | Collection expected = this.getExampleStatuses(); 69 | Collection actual = this.statusService.getAll(); 70 | 71 | verify(statusRepository, times(1)).findAll(); 72 | assertNotNull(actual); 73 | assertEquals(expected, actual); 74 | } 75 | 76 | @Test 77 | public void whenGetAllWithSortByCalledThenCollectionShouldBeFound() { 78 | final String SORT_BY_ATTRIBUTE_ID = "id"; 79 | Collection statuses = ENTITY_STATUSES 80 | .stream() 81 | .sorted(Comparator.comparing(Status::getId)) 82 | .collect(Collectors.toList()); 83 | 84 | 85 | when(statusRepository.findAll(Sort.by(SORT_BY_ATTRIBUTE_ID))).thenReturn(statuses); 86 | 87 | 88 | Collection expected = this.getExampleStatuses() 89 | .stream() 90 | .sorted(Comparator.comparing(StatusDTO::getId)) 91 | .collect(Collectors.toList()); 92 | Collection actual = this.statusService.getAll(SORT_BY_ATTRIBUTE_ID); 93 | 94 | 95 | verify(statusRepository, times(1)).findAll(Sort.by(SORT_BY_ATTRIBUTE_ID)); 96 | assertNotNull(actual); 97 | assertEquals(expected, actual); 98 | } 99 | 100 | @Test 101 | public void whenValidIdThenStatusShouldBeFound() { 102 | when(statusRepository.findById(ACTIVE_STATUS_ID)).thenReturn(Optional.of(ACTIVE_STATUS_ENTITY)); 103 | 104 | StatusDTO actual = statusService.getById(ACTIVE_STATUS_ID); 105 | StatusDTO expected = getExpectedStatus(); 106 | 107 | verify(statusRepository, times(1)).findById(ACTIVE_STATUS_ID); 108 | assertNotNull(actual); 109 | assertEquals(expected, actual); 110 | } 111 | 112 | @Test(expected = StatusNotFoundException.class) 113 | public void whenInvalidIdThenStatusNotFoundExceptionShouldThrow() { 114 | Long INVALID_STATUS_ID = 55555L; 115 | when(statusRepository.existsById(INVALID_STATUS_ID)).thenReturn(false); 116 | 117 | statusService.getById(INVALID_STATUS_ID); 118 | } 119 | 120 | @Test 121 | public void whenSaveCalledThenStatusShouldBeReturned() { 122 | final Status status = new Status(null, ACTIVE_STATUS_NAME); 123 | 124 | when(statusRepository.save(status)).thenReturn(ACTIVE_STATUS_ENTITY); 125 | 126 | StatusDTO actual = statusService.save(new StatusDTO(null, ACTIVE_STATUS_NAME)); 127 | StatusDTO expected = getExpectedStatus(); 128 | 129 | verify(statusRepository, times(1)).save(status); 130 | assertNotNull(actual); 131 | assertEquals(expected, actual); 132 | } 133 | 134 | @Test 135 | public void whenUpdateCalledThenStatusShouldBeReturned() { 136 | when(statusRepository.save(ACTIVE_STATUS_ENTITY)).thenReturn(ACTIVE_STATUS_ENTITY); 137 | when(statusRepository.existsById(ACTIVE_STATUS_ID)).thenReturn(true); 138 | 139 | StatusDTO actual = statusService.update(ACTIVE_STATUS); 140 | StatusDTO expected = getExpectedStatus(); 141 | 142 | verify(statusRepository, times(1)).save(ACTIVE_STATUS_ENTITY); 143 | verify(statusRepository, times(1)).existsById(ACTIVE_STATUS_ID); 144 | assertNotNull(actual); 145 | assertEquals(expected, actual); 146 | } 147 | 148 | @Test 149 | public void whenConvertStatusEntityCalledThenStatusDTOShouldBeReturned() { 150 | StatusDTO actual = StatusService.convertToStatusDTO(ACTIVE_STATUS_ENTITY); 151 | StatusDTO expected = getExpectedStatus(); 152 | 153 | assertNotNull(actual); 154 | assertEquals(expected, actual); 155 | } 156 | 157 | @Test 158 | public void whenConvertStatusDTOCalledThenStatusEntityShouldBeReturned() { 159 | Status actual = StatusService.convertToStatus(ACTIVE_STATUS); 160 | Status expected = getExpectedStatusEntity(); 161 | 162 | assertNotNull(actual); 163 | assertEquals(expected, actual); 164 | } 165 | 166 | @Test 167 | public void whenDeleteStatusByIdCalled() { 168 | when(statusRepository.existsById(ACTIVE_STATUS_ID)).thenReturn(true); 169 | doNothing().when(statusRepository).deleteById(ACTIVE_STATUS_ID); 170 | 171 | statusService.deleteById(ACTIVE_STATUS_ID); 172 | 173 | verify(statusRepository, times(1)).existsById(ACTIVE_STATUS_ID); 174 | verify(statusRepository, times(1)).deleteById(ACTIVE_STATUS_ID); 175 | } 176 | 177 | private Collection getExampleStatuses() { 178 | Collection exampleStatuses = new ArrayList<>(); 179 | exampleStatuses.add(ACTIVE_STATUS); 180 | exampleStatuses.add(COMPLETE_STATUS); 181 | exampleStatuses.add(IN_PROCESS_STATUS); 182 | return exampleStatuses; 183 | } 184 | 185 | private StatusDTO getExpectedStatus() { 186 | return ACTIVE_STATUS; 187 | } 188 | 189 | private Status getExpectedStatusEntity() { 190 | return ACTIVE_STATUS_ENTITY; 191 | } 192 | } 193 | --------------------------------------------------------------------------------