Added logging. Small refactoring.

This commit is contained in:
Alexey Zinchenko 2019-05-12 03:44:05 +03:00
parent 6402b8220d
commit ffc5647cf9
16 changed files with 205 additions and 62 deletions

32
pom.xml
View File

@ -26,11 +26,12 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>2.3.0</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@ -42,23 +43,30 @@
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.javafaker</groupId>
<artifactId>javafaker</artifactId>

View File

@ -2,6 +2,8 @@ package com.github.prominence.carrepair.controller;
import com.github.prominence.carrepair.model.Client;
import com.github.prominence.carrepair.service.ClientService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
@ -19,6 +21,8 @@ import java.util.Optional;
@RequestMapping("/client")
public class ClientController {
private static final Logger logger = LogManager.getLogger(ClientController.class);
private ClientService clientService;
public ClientController(ClientService clientService) {
@ -28,6 +32,7 @@ public class ClientController {
@GetMapping
public String index(@PageableDefault Pageable pageable, ModelMap modelMap) {
Page<Client> clientList = clientService.findAll(pageable);
logger.trace("Request to open list page for Clients. Returning {} page.", () -> pageable.getPageNumber() + 1);
modelMap.addAttribute("clientList", clientList.getContent());
modelMap.addAttribute("totalPages", clientList.getTotalPages());
@ -37,6 +42,7 @@ public class ClientController {
@GetMapping(value = "/create")
public String create(Model model) {
logger.trace("Request to open create page for Client.");
model.addAttribute("client", new Client());
return "client/edit";
@ -44,19 +50,21 @@ public class ClientController {
@GetMapping(value = "/edit/{id}")
public String edit(@PathVariable Long id, Model model) {
logger.trace("Request to open edit page for Client[{}].", () -> id);
Optional<Client> clientOptional = clientService.findById(id);
if (clientOptional.isPresent()) {
model.addAttribute("client", clientOptional.get());
return "client/edit";
} else {
// TODO: need to show warning
return "redirect:/client";
}
}
@PostMapping(value = "/update/{id}")
public String update(@Valid Client client, BindingResult bindingResult, @PathVariable long id) {
logger.trace("Request to save {}.", () -> client);
if (bindingResult.hasErrors()) {
logger.trace("{} has validation {} errors and won't be saved.", () -> client, bindingResult::getErrorCount);
client.setId(id); // why should we do this?
return "client/edit";
}
@ -67,7 +75,9 @@ public class ClientController {
@PostMapping(value = "/create")
public String save(@Valid Client client, BindingResult bindingResult) {
logger.trace("Request to create {}.", () -> client);
if (bindingResult.hasErrors()) {
logger.trace("{} has validation {} errors and won't be created.", () -> client, bindingResult::getErrorCount);
return "client/edit";
}
@ -77,8 +87,8 @@ public class ClientController {
@DeleteMapping(value = "/delete/{id}")
public ResponseEntity delete(@PathVariable Long id) {
logger.trace("Request to delete Client[{}].", () -> id);
boolean deleteSuccess = clientService.deleteClientById(id);
if (deleteSuccess) {
return ResponseEntity.ok().build();
} else {

View File

@ -1,14 +1,18 @@
package com.github.prominence.carrepair.controller;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/")
public class HomeController {
private static final Logger logger = LogManager.getLogger(HomeController.class);
@RequestMapping
public String index() {
return "home";
logger.trace("Request to open home page.");
return "index";
}
}

View File

@ -3,6 +3,8 @@ package com.github.prominence.carrepair.controller;
import com.github.prominence.carrepair.enums.OrderStatus;
import com.github.prominence.carrepair.model.Mechanic;
import com.github.prominence.carrepair.service.MechanicService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
@ -20,6 +22,7 @@ import java.util.Optional;
@Controller
@RequestMapping("/mechanic")
public class MechanicController {
private static final Logger logger = LogManager.getLogger(MechanicController.class);
private MechanicService mechanicService;
@ -29,16 +32,18 @@ public class MechanicController {
@GetMapping
public String index(@PageableDefault Pageable pageable, ModelMap modelMap) {
Page<Mechanic> clientList = mechanicService.findAll(pageable);
Page<Mechanic> mechanicList = mechanicService.findAll(pageable);
logger.trace("Request to open list page for Mechanics. Returning {} page.", () -> pageable.getPageNumber() + 1);
modelMap.addAttribute("mechanicList", clientList.getContent());
modelMap.addAttribute("totalPages", clientList.getTotalPages());
modelMap.addAttribute("mechanicList", mechanicList.getContent());
modelMap.addAttribute("totalPages", mechanicList.getTotalPages());
return "mechanic/index";
}
@GetMapping(value = "/create")
public String create(Model model) {
logger.trace("Request to open create page for Mechanic.");
model.addAttribute("mechanic", new Mechanic());
return "mechanic/edit";
@ -46,41 +51,45 @@ public class MechanicController {
@GetMapping(value = "/edit/{id}")
public String edit(@PathVariable Long id, Model model) {
Optional<Mechanic> clientOptional = mechanicService.findById(id);
if (clientOptional.isPresent()) {
model.addAttribute("mechanic", clientOptional.get());
logger.trace("Request to open edit page for Mechanic[{}].", () -> id);
Optional<Mechanic> mechanicOptional = mechanicService.findById(id);
if (mechanicOptional.isPresent()) {
model.addAttribute("mechanic", mechanicOptional.get());
return "mechanic/edit";
} else {
// TODO: need to show warning
return "redirect:/mechanic";
}
}
@PostMapping(value = "/update/{id}")
public String update(@Valid Mechanic client, BindingResult bindingResult, @PathVariable long id) {
public String update(@Valid Mechanic mechanic, BindingResult bindingResult, @PathVariable long id) {
logger.trace("Request to save {}.", () -> mechanic);
if (bindingResult.hasErrors()) {
client.setId(id); // why should we do this?
logger.trace("{} has validation {} errors and won't be saved.", () -> mechanic, bindingResult::getErrorCount);
mechanic.setId(id); // why should we do this?
return "mechanic/edit";
}
mechanicService.save(client);
mechanicService.save(mechanic);
return "redirect:/mechanic";
}
@PostMapping(value = "/create")
public String save(@Valid Mechanic client, BindingResult bindingResult) {
public String save(@Valid Mechanic mechanic, BindingResult bindingResult) {
logger.trace("Request to create {}.", () -> mechanic);
if (bindingResult.hasErrors()) {
logger.trace("{} has validation {} errors and won't be created.", () -> mechanic, bindingResult::getErrorCount);
return "mechanic/edit";
}
mechanicService.save(client);
mechanicService.save(mechanic);
return "redirect:/mechanic";
}
@DeleteMapping(value = "/delete/{id}")
public ResponseEntity delete(@PathVariable Long id) {
logger.trace("Request to delete Mechanic[{}].", () -> id);
boolean deleteSuccess = mechanicService.deleteMechanicById(id);
if (deleteSuccess) {
return ResponseEntity.ok().build();
} else {
@ -90,6 +99,7 @@ public class MechanicController {
@GetMapping(value = "/statistics/{id}")
public String statistics(@PathVariable Long id, Model model) {
logger.trace("Request to open statistics for Mechanic[{}].", () -> id);
Map<OrderStatus, Integer> mechanicStatistics = mechanicService.getOrderStatistics(id);
model.addAttribute("statistics", mechanicStatistics);

View File

@ -4,6 +4,8 @@ import com.github.prominence.carrepair.enums.OrderStatus;
import com.github.prominence.carrepair.model.Order;
import com.github.prominence.carrepair.repository.spec.OrderSpecifications;
import com.github.prominence.carrepair.service.OrderService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
@ -19,6 +21,7 @@ import java.util.Optional;
@Controller
@RequestMapping(value = "/order")
public class OrderController {
private static final Logger logger = LogManager.getLogger(OrderController.class);
private OrderService orderService;
@ -30,6 +33,7 @@ public class OrderController {
public String index(@PageableDefault Pageable pageable, @RequestParam(required = false) String client, @RequestParam(required = false) String description,
@RequestParam(required = false) OrderStatus orderStatus, ModelMap modelMap) {
Page<Order> orderList = orderService.findAll(OrderSpecifications.search(client, description, orderStatus), pageable);
logger.trace("Request to open list page for Orders. Returning {} page.", () -> pageable.getPageNumber() + 1);
modelMap.addAttribute("orderList", orderList.getContent());
modelMap.addAttribute("totalPages", orderList.getTotalPages());
@ -40,6 +44,7 @@ public class OrderController {
@GetMapping(value = "/create")
public String create(Model model) {
logger.trace("Request to open create page for Order.");
model.addAttribute("order", new Order());
model.addAttribute("orderStatuses", OrderStatus.values());
@ -48,21 +53,23 @@ public class OrderController {
@GetMapping(value = "/edit/{id}")
public String edit(@PathVariable Long id, Model model) {
logger.trace("Request to open edit page for Order[{}].", () -> id);
Optional<Order> orderOptional = orderService.findById(id);
if (orderOptional.isPresent()) {
model.addAttribute("order", orderOptional.get());
model.addAttribute("orderStatuses", OrderStatus.values());
return "order/edit";
} else {
// TODO: need to show warning
return "redirect:/order";
}
}
@PostMapping(value = "/update/{id}")
public String update(Order order, BindingResult bindingResult, @PathVariable long id, Long clientId, Long mechanicId, Model model) {
logger.trace("Request to save {}.", () -> order);
orderService.fetchNestedObjectsAndValidate(order, clientId, mechanicId, bindingResult);
if (bindingResult.hasErrors()) {
logger.trace("{} has validation {} errors and won't be saved.", () -> order, bindingResult::getErrorCount);
order.setId(id); // why should we do this?
model.addAttribute("orderStatuses", OrderStatus.values());
return "order/edit";
@ -74,8 +81,10 @@ public class OrderController {
@PostMapping(value = "/create")
public String save(Order order, BindingResult bindingResult, Long clientId, Long mechanicId, Model model) {
logger.trace("Request to create {}.", () -> order);
orderService.fetchNestedObjectsAndValidate(order, clientId, mechanicId, bindingResult);
if (bindingResult.hasErrors()) {
logger.trace("{} has validation {} errors and won't be created.", () -> order, bindingResult::getErrorCount);
model.addAttribute("orderStatuses", OrderStatus.values());
return "order/edit";
}
@ -86,8 +95,8 @@ public class OrderController {
@DeleteMapping(value = "/delete/{id}")
public ResponseEntity delete(@PathVariable Long id) {
logger.trace("Request to delete Order[{}].", () -> id);
boolean deleteSuccess = orderService.deleteOrderById(id);
if (deleteSuccess) {
return ResponseEntity.ok().build();
} else {

View File

@ -9,6 +9,8 @@ import com.github.prominence.carrepair.service.ClientService;
import com.github.prominence.carrepair.service.MechanicService;
import com.github.prominence.carrepair.service.OrderService;
import org.apache.commons.lang3.RandomUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.PageRequest;
@ -26,8 +28,10 @@ import java.util.stream.Stream;
@Component
public class DemoDataPopulator {
private static final int COUNT = 100;
private static final int DEFAULT_PAGE_SIZE = 10;
private final Logger logger = LogManager.getLogger(DemoDataPopulator.class);
private Faker faker = new Faker();
private final Faker faker = new Faker();
@Bean
public CommandLineRunner clientDemoData(ClientService clientService) {
@ -37,9 +41,9 @@ public class DemoDataPopulator {
client.setLastName(faker.name().lastName());
client.setMiddleName(faker.name().username());
client.setPhoneNo(faker.phoneNumber().phoneNumber());
System.out.println(client); // demo output
return client;
}).limit(COUNT).collect(Collectors.toList());
logger.info("[Demo Data] Populated {} clients.", demoClientList::size);
return args -> demoClientList.forEach(clientService::save);
}
@ -52,9 +56,9 @@ public class DemoDataPopulator {
mechanic.setLastName(faker.name().lastName());
mechanic.setMiddleName(faker.name().username());
mechanic.setHourlyPayment(BigDecimal.valueOf(faker.number().randomDouble(3, 100, 999)));
System.out.println(mechanic); // demo output
return mechanic;
}).limit(COUNT).collect(Collectors.toList());
logger.info("[Demo Data] Populated {} mechanics.", demoMechanicList::size);
return args -> demoMechanicList.forEach(mechanicService::save);
}
@ -80,22 +84,22 @@ public class DemoDataPopulator {
final Client randomClient = clientListSlice.get(RandomUtils.nextInt(0, clientListSlice.size()));
order.setClient(randomClient);
final List<Mechanic> mechanicListSlise = mechanicService.findAll(getRandomPageable(mechanicsCount)).getContent();
final Mechanic randomMechanic = mechanicListSlise.get(RandomUtils.nextInt(0, mechanicListSlise.size()));
final List<Mechanic> mechanicListSlice = mechanicService.findAll(getRandomPageable(mechanicsCount)).getContent();
final Mechanic randomMechanic = mechanicListSlice.get(RandomUtils.nextInt(0, mechanicListSlice.size()));
order.setMechanic(randomMechanic);
System.out.println(order); // demo output
return order;
}).limit(COUNT).collect(Collectors.toList());
logger.info("[Demo Data] Populated {} orders.", demoOrderList::size);
return args -> demoOrderList.forEach(orderService::save);
}
private Pageable getRandomPageable(long totalRecords) {
final int size = 10;
final int totalPages = (int) (totalRecords / size);
return PageRequest.of(RandomUtils.nextInt(0, totalPages), size);
final int totalPages = (int) (totalRecords / DEFAULT_PAGE_SIZE);
final PageRequest pageRequest = PageRequest.of(RandomUtils.nextInt(0, totalPages), DEFAULT_PAGE_SIZE);
logger.trace("[Demo Data] Random page: {}", () -> pageRequest);
return pageRequest;
}
}

View File

@ -1,5 +1,7 @@
package com.github.prominence.carrepair.formatter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.format.Formatter;
import org.springframework.stereotype.Component;
@ -10,13 +12,19 @@ import java.util.Locale;
@Component
public class CustomDateTimeFormatter implements Formatter<LocalDateTime> {
private static final Logger logger = LogManager.getLogger(CustomDateTimeFormatter.class);
@Override
public LocalDateTime parse(String text, Locale locale) throws ParseException {
return LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
final LocalDateTime parsedDateTime = LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
logger.trace("Parsing String[{}] to LocalDateTime instance: {}.", () -> text, () -> parsedDateTime);
return parsedDateTime;
}
@Override
public String print(LocalDateTime object, Locale locale) {
return object.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
final String formattedString = object.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
logger.trace("Formatting LocalDateTime[{}] to String instance: {}.", () -> object, () -> formattedString);
return formattedString;
}
}

View File

@ -2,6 +2,8 @@ package com.github.prominence.carrepair.formatter;
import com.github.prominence.carrepair.enums.OrderStatus;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.format.Formatter;
import org.springframework.stereotype.Component;
@ -10,13 +12,19 @@ import java.util.Locale;
@Component
public class OrderStatusFormatter implements Formatter<OrderStatus> {
private static final Logger logger = LogManager.getLogger(OrderStatusFormatter.class);
@Override
public OrderStatus parse(String text, Locale locale) throws ParseException {
return OrderStatus.valueOf(text.toUpperCase());
final OrderStatus parsedOrderStatus = OrderStatus.valueOf(text.toUpperCase());
logger.trace("Parsing String[{}] to OrderStatus instance: {}.", () -> text, () -> parsedOrderStatus);
return parsedOrderStatus;
}
@Override
public String print(OrderStatus object, Locale locale) {
return StringUtils.capitalize(object.toString().toLowerCase());
final String formattedOrderStatus = StringUtils.capitalize(object.toString().toLowerCase());
logger.trace("Formatting OrderStatus[{}] to String instance: {}.", () -> object, () -> formattedOrderStatus);
return formattedOrderStatus;
}
}

View File

@ -4,6 +4,8 @@ import com.github.prominence.carrepair.enums.OrderStatus;
import com.github.prominence.carrepair.model.Client;
import com.github.prominence.carrepair.model.Order;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
@ -13,8 +15,11 @@ import java.util.ArrayList;
import java.util.List;
public class OrderSpecifications {
private static final Logger logger = LogManager.getLogger(OrderSpecifications.class);
public static Specification<Order> search(@Nullable String clientQuery, @Nullable String orderDescriptionQuery, @Nullable OrderStatus orderStatusQuery) {
logger.debug("Creating specification for order search. Params: clientQuery=[{}], orderDescriptionQuery=[{}], orderStatusQuery=[{}]",
() -> clientQuery, () -> orderDescriptionQuery, () -> orderStatusQuery);
return (root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
if (!StringUtils.isEmpty(clientQuery)) {

View File

@ -2,6 +2,8 @@ package com.github.prominence.carrepair.service;
import com.github.prominence.carrepair.model.Client;
import com.github.prominence.carrepair.repository.ClientRepository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
@ -11,6 +13,7 @@ import java.util.Optional;
@Service
public class ClientService {
private static final Logger logger = LogManager.getLogger(ClientService.class);
private ClientRepository clientRepository;
@ -19,31 +22,43 @@ public class ClientService {
}
public Page<Client> findAll(Pageable pageable) {
return clientRepository.findAll(pageable);
final Page<Client> clientPage = clientRepository.findAll(pageable);
logger.trace(clientPage);
return clientPage;
}
public Optional<Client> findById(Long id) {
return clientRepository.findById(id);
final Optional<Client> clientOptional = clientRepository.findById(id);
logger.debug("{} found by id={}", () -> clientOptional, () -> id);
return clientOptional;
}
public Client save(Client client) {
return clientRepository.save(client);
final Client clientToSave = clientRepository.save(client);
logger.trace("[{}] was saved.", () -> clientToSave);
return clientToSave;
}
public boolean deleteClientById(Long id) {
try {
clientRepository.deleteById(id);
logger.debug("Client[id={}] was deleted.", () -> id);
return true;
} catch (Exception e) {
logger.error("Client[id={}] wasn't deleted. Exception: {}", () -> id, e::getMessage);
return false;
}
}
public long getClientCount() {
return clientRepository.count();
final long clientCount = clientRepository.count();
logger.trace("Found {} clients.", () -> clientCount);
return clientCount;
}
public List<Client> searchByInitials(String query) {
return clientRepository.findAllByInitials(query);
final List<Client> allByInitials = clientRepository.findAllByInitials(query);
logger.debug("Found {} clients by initials: {}.", allByInitials::size, () -> query);
return allByInitials;
}
}

View File

@ -5,6 +5,8 @@ import com.github.prominence.carrepair.model.Mechanic;
import com.github.prominence.carrepair.model.Order;
import com.github.prominence.carrepair.repository.MechanicRepository;
import com.github.prominence.carrepair.repository.OrderRepository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
@ -16,6 +18,7 @@ import java.util.Optional;
@Service
public class MechanicService {
private static final Logger logger = LogManager.getLogger(MechanicService.class);
private MechanicRepository mechanicRepository;
private OrderRepository orderRepository;
@ -26,22 +29,30 @@ public class MechanicService {
}
public Page<Mechanic> findAll(Pageable pageable) {
return mechanicRepository.findAll(pageable);
final Page<Mechanic> mechanicPage = mechanicRepository.findAll(pageable);
logger.trace(mechanicPage);
return mechanicPage;
}
public Optional<Mechanic> findById(Long id) {
return mechanicRepository.findById(id);
final Optional<Mechanic> mechanicOptional = mechanicRepository.findById(id);
logger.debug("{} found by id={}", () -> mechanicOptional, () -> id);
return mechanicOptional;
}
public Mechanic save(Mechanic client) {
return mechanicRepository.save(client);
final Mechanic mechanicToSave = mechanicRepository.save(client);
logger.trace("[{}] was saved.", () -> mechanicToSave);
return mechanicToSave;
}
public boolean deleteMechanicById(Long id) {
try {
mechanicRepository.deleteById(id);
logger.debug("Mechanic[id={}] was deleted.", () -> id);
return true;
} catch (Exception e) {
logger.error("Mechanic[id={}] wasn't deleted. Exception: {}", () -> id, e::getMessage);
return false;
}
}
@ -55,15 +66,20 @@ public class MechanicService {
List<Order> mechanicOrders = orderRepository.findAllByMechanic_Id(mechanicId);
mechanicOrders.forEach(order -> statistics.merge(order.getOrderStatus(), 1, Integer::sum));
logger.trace("Mechanic statistics by ID={}: {}", () -> mechanicId, () -> statistics);
return statistics;
}
public long getMechanicCount() {
return mechanicRepository.count();
final long mechanicCount = mechanicRepository.count();
logger.trace("Found {} mechanics.", () -> mechanicCount);
return mechanicCount;
}
public List<Mechanic> searchByInitials(String query) {
return mechanicRepository.findAllByInitials(query);
final List<Mechanic> allByInitials = mechanicRepository.findAllByInitials(query);
logger.debug("Found {} mechanics by initials: {}.", allByInitials::size, () -> query);
return allByInitials;
}
}

View File

@ -3,6 +3,8 @@ package com.github.prominence.carrepair.service;
import com.github.prominence.carrepair.model.Order;
import com.github.prominence.carrepair.repository.OrderRepository;
import com.github.prominence.carrepair.validation.OrderValidator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
@ -14,6 +16,7 @@ import java.util.Optional;
@Service
public class OrderService {
private static final Logger logger = LogManager.getLogger(OrderService.class);
private OrderRepository orderRepository;
@ -31,35 +34,47 @@ public class OrderService {
}
public Page<Order> findAll(Specification<Order> specification, Pageable pageable) {
return orderRepository.findAll(specification, pageable);
final Page<Order> orderPage = orderRepository.findAll(specification, pageable);
logger.trace(orderPage);
return orderPage;
}
public Optional<Order> findById(Long id) {
return orderRepository.findById(id);
final Optional<Order> orderOptional = orderRepository.findById(id);
logger.debug("{} found by id={}", () -> orderOptional, () -> id);
return orderOptional;
}
public Order save(Order client) {
return orderRepository.save(client);
public Order save(Order order) {
final Order orderToSave = orderRepository.save(order);
logger.trace("[{}] was saved.", () -> orderToSave);
return orderToSave;
}
public boolean deleteOrderById(Long id) {
try {
orderRepository.deleteById(id);
logger.debug("Order[id={}] was deleted.", () -> id);
return true;
} catch (Exception e) {
logger.error("Order[id={}] wasn't deleted. Exception: {}", () -> id, e::getMessage);
return false;
}
}
public long getOrderCount() {
return orderRepository.count();
final long orderCount = orderRepository.count();
logger.trace("Found {} orders.", () -> orderCount);
return orderCount;
}
public void fetchNestedObjectsAndValidate(Order order, Long clientId, Long mechanicId, BindingResult bindingResult) {
if (clientId != null) {
logger.trace("Fetching Client[{}] for {}.", () -> clientId, () -> order);
clientService.findById(clientId).ifPresent(order::setClient);
}
if (mechanicId != null) {
logger.trace("Fetching Mechanic[{}] for {}.", () -> clientId, () -> order);
mechanicService.findById(mechanicId).ifPresent(order::setMechanic);
}
smartValidator.validate(order, bindingResult);

View File

@ -2,6 +2,8 @@ package com.github.prominence.carrepair.validation;
import com.github.prominence.carrepair.enums.OrderStatus;
import com.github.prominence.carrepair.model.Order;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
@ -10,6 +12,8 @@ import java.time.LocalDateTime;
@Component
public class OrderValidator implements Validator {
private static final Logger logger = LogManager.getLogger(OrderValidator.class);
@Override
public boolean supports(Class<?> aClass) {
return Order.class.isAssignableFrom(aClass);
@ -20,12 +24,16 @@ public class OrderValidator implements Validator {
Order order = (Order) o;
LocalDateTime finishedOn = order.getFinishedOn();
if (finishedOn != null) {
LocalDateTime startedOn = order.getCreatedOn();
if (startedOn != null && order.getFinishedOn().isBefore(order.getCreatedOn())) {
LocalDateTime createdOn = order.getCreatedOn();
if (createdOn != null && order.getFinishedOn().isBefore(order.getCreatedOn())) {
logger.debug("[{}] validation error: \"finishedOn\" value[{}] is before \"createdOn\"[{}].",
() -> order, () -> finishedOn, () -> createdOn);
errors.rejectValue("finishedOn", "error.finishedOn.finishedBeforeStarted");
}
if (order.getOrderStatus() != OrderStatus.ACCEPTED) {
logger.debug("[{}] validation error: \"finishedOn\" cannot be set for order in status differ from {}.",
() -> order, () -> OrderStatus.ACCEPTED);
errors.rejectValue("finishedOn", "error.finishedOn.incompatibleStatus");
}
}

View File

@ -11,7 +11,7 @@ spring.datasource.password=carrepair
# JPA / HIBERNATE
# ===============================
spring.jpa.show-sql=true
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect

View File

@ -0,0 +1,23 @@
name = LoggingsConfig
property.filename = logs
appenders = console, file
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
appender.file.type = File
appender.file.name = LOGFILE
appender.file.fileName=${filename}/application.log
appender.file.layout.type=PatternLayout
appender.file.layout.pattern=[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
loggers = base
logger.base.name = com.github.prominence
logger.base.level = DEBUG
rootLogger.level = info
rootLogger.appenderRefs = stdout
rootLogger.appenderRef.stdout.ref = STDOUT