Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[KNIG-17] - Create CRUD for new entity Reminder #63

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
public class Constants {

public static final String API_BASE_URL = "/api";
public static final String API_BASE_URL_V1 = "/api/v1/";
public static final String API_BASE_URL_V1 = "/api/v1";
public static final String API_BASE_TODOS = "/todos";
public static final String API_BASE_DAYS = "/days";
public static final String API_BASE_REMINDER = "/reminders";
public static final String API_BASE_ROUTINES = "/routines";
public static final String API_BASE_ROUTINES_INSTANCES = "/routineInstances";
public static final String API_BASE_ROUTINES_TODO_INSTANCES = "/routineTodoInstances";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.knighttodo.todocore.domain;

import lombok.Builder;
import lombok.Data;
import lombok.Value;
import lombok.experimental.Accessors;

import java.time.LocalDateTime;
import java.util.UUID;

@Data
@Builder
public class ReminderVO {

private UUID id;
private String name;
private String message;
private LocalDateTime reminderDate;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.knighttodo.todocore.exception;

public class InvalidReminderDateException extends RuntimeException {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.knighttodo.todocore.exception;

import lombok.extern.slf4j.Slf4j;

import java.util.UUID;

@Slf4j
public class ReminderNotFoundException extends RuntimeException {

public ReminderNotFoundException(UUID id) {
log.warn("Reminder with id: {} not found", id);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.knighttodo.todocore.exception.handling;

import com.knighttodo.todocore.exception.InvalidReminderDateException;
import com.knighttodo.todocore.exception.ReminderNotFoundException;
import com.knighttodo.todocore.service.privatedb.representation.Reminder;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand All @@ -14,6 +17,16 @@
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

@ExceptionHandler({InvalidReminderDateException.class})
public final ResponseEntity<Void> handleConflictException() {
return ResponseEntity.status(HttpStatus.CONFLICT).build();
}

@ExceptionHandler({ReminderNotFoundException.class})
public final ResponseEntity<Void> handleNotFoundException(Exception e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}

@ExceptionHandler(RuntimeException.class)
public final ResponseEntity<Object> handleCustomRuntimeException(RuntimeException ex, WebRequest request) {
Throwable cause = ex.getCause() == null ? ex : ex.getCause();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.knighttodo.todocore.rest;

import com.knighttodo.todocore.domain.ReminderVO;
import com.knighttodo.todocore.rest.mapper.ReminderRestMapper;
import com.knighttodo.todocore.rest.request.CreateReminderRequestDto;
import com.knighttodo.todocore.rest.request.UpdateReminderRequestDto;
import com.knighttodo.todocore.rest.response.ReminderResponseDto;
import com.knighttodo.todocore.service.ReminderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.UUID;

import static com.knighttodo.todocore.Constants.API_BASE_REMINDER;
import static com.knighttodo.todocore.Constants.API_BASE_URL_V1;

@Api(value = "ReminderResource controller")
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping(API_BASE_URL_V1 + API_BASE_REMINDER)
public class ReminderResource {

private final ReminderRestMapper reminderRestMapper;
private final ReminderService reminderService;

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
@ApiOperation(value = "Add the new Reminder", response = ReminderResponseDto.class)
@ApiResponses(value = {
@ApiResponse(code = 201, message = "Created"),
@ApiResponse(code = 409, message = "Invalid reminder date")
})
public ReminderResponseDto addReminder(@Valid @RequestBody CreateReminderRequestDto requestDto) {
ReminderVO reminderVO = reminderRestMapper.toReminderVO(requestDto);
ReminderVO savedReminderVO = reminderService.save(reminderVO);
return reminderRestMapper.toReminderResponseDto(savedReminderVO);
}

@PutMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
@ApiOperation(value = "Update the new Reminder", response = ReminderResponseDto.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Reminder successfully updated"),
@ApiResponse(code = 409, message = "Invalid reminder date")
})
public ReminderResponseDto updateReminder(@Valid @RequestBody UpdateReminderRequestDto requestDto,
@PathVariable UUID id) {
ReminderVO reminderVO = reminderRestMapper.toReminderVO(requestDto);
ReminderVO updatedReminderVO = reminderService.update(id, reminderVO);
return reminderRestMapper.toReminderResponseDto(updatedReminderVO);
}

@GetMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
@ApiOperation(value = "Get Reminder by id", response = ReminderResponseDto.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "Reminder not found")
})
public ReminderResponseDto getReminderById(@PathVariable UUID id) {
ReminderVO reminderVO = reminderService.findById(id);
return reminderRestMapper.toReminderResponseDto(reminderVO);
}

@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
@ApiOperation(value = "Delete Reminder by id")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "Reminder not found")
})
public void deleteReminderById(@PathVariable UUID id) {
reminderService.deleteById(id);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.knighttodo.todocore.rest.mapper;

import com.knighttodo.todocore.domain.ReminderVO;
import com.knighttodo.todocore.rest.request.CreateReminderRequestDto;
import com.knighttodo.todocore.rest.request.UpdateReminderRequestDto;
import com.knighttodo.todocore.rest.response.ReminderResponseDto;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper(componentModel = "spring")
public interface ReminderRestMapper {

@Mapping(target = "id", ignore = true)
ReminderVO toReminderVO(CreateReminderRequestDto requestDto);

ReminderResponseDto toReminderResponseDto(ReminderVO savedReminderVO);

@Mapping(target = "id", ignore = true)
ReminderVO toReminderVO(UpdateReminderRequestDto requestDto);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.knighttodo.todocore.rest.request;

import lombok.Data;
import lombok.experimental.Accessors;

import java.time.LocalDateTime;

@Data
@Accessors(chain = true)
public class CreateReminderRequestDto {

private String name;
private String message;
private LocalDateTime reminderDate;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.knighttodo.todocore.rest.request;

import lombok.Data;
import lombok.experimental.Accessors;

import java.time.LocalDateTime;

@Data
@Accessors(chain = true)
public class UpdateReminderRequestDto {

private String name;
private String message;
private LocalDateTime reminderDate;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.knighttodo.todocore.rest.response;

import lombok.Data;
import lombok.experimental.Accessors;

import java.time.LocalDateTime;
import java.util.UUID;

@Data
@Accessors(chain = true)
public class ReminderResponseDto {

private UUID id;
private String name;
private String message;
private LocalDateTime reminderDate;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.knighttodo.todocore.service;

import com.knighttodo.todocore.domain.ReminderVO;
import com.knighttodo.todocore.exception.InvalidReminderDateException;
import com.knighttodo.todocore.exception.ReminderNotFoundException;
import com.knighttodo.todocore.service.privatedb.mapper.ReminderMapper;
import com.knighttodo.todocore.service.privatedb.repository.ReminderRepository;
import com.knighttodo.todocore.service.privatedb.representation.Reminder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.UUID;

@RequiredArgsConstructor
@Slf4j
@Service
@Transactional(readOnly = true)
public class ReminderService {

private final ReminderRepository reminderRepository;
private final ReminderMapper reminderMapper;

@Transactional
public ReminderVO save(ReminderVO reminderVO) {
validateReminderDate(reminderVO.getReminderDate());

Reminder reminder = reminderRepository.save(reminderMapper.toReminder(reminderVO));
return reminderMapper.toReminderVO(reminder);
}

public ReminderVO findById(UUID id) {
Reminder reminder = reminderRepository.findById(id)
.orElseThrow(() -> new ReminderNotFoundException(id));
return reminderMapper.toReminderVO(reminder);
}

@Transactional
public void deleteById(UUID id) {
Reminder reminder = reminderRepository.findById(id)
.orElseThrow(() -> new ReminderNotFoundException(id));

reminderRepository.delete(reminder);
}

@Transactional
public ReminderVO update(UUID id, ReminderVO reminderVO) {
validateReminderDate(reminderVO.getReminderDate());
reminderRepository.findById(id)
.orElseThrow(() -> new ReminderNotFoundException(id));

reminderVO.setId(id);
Reminder reminderToUpdate = reminderMapper.toReminder(reminderVO);

return reminderMapper.toReminderVO(reminderRepository.save(reminderToUpdate));
}

private void validateReminderDate(LocalDateTime reminderDate) {
if (reminderDate.isBefore(LocalDateTime.now())) {
log.warn("Invalid reminder date: {}", reminderDate);
throw new InvalidReminderDateException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.knighttodo.todocore.service.privatedb.mapper;

import com.knighttodo.todocore.domain.ReminderVO;
import com.knighttodo.todocore.service.privatedb.representation.Reminder;
import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface ReminderMapper {

Reminder toReminder(ReminderVO reminderVO);

ReminderVO toReminderVO(Reminder reminder);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.knighttodo.todocore.service.privatedb.repository;

import com.knighttodo.todocore.service.privatedb.representation.Reminder;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.UUID;

public interface ReminderRepository extends JpaRepository<Reminder, UUID> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.knighttodo.todocore.service.privatedb.representation;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Entity
@Table(name = "reminder")
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Reminder {

@Id
@GeneratedValue
@Column(name = "id")
private UUID id;

@Column(name = "name")
private String name;

@Column(name = "message")
private String message;

@Column(name = "date")
private LocalDateTime reminderDate;
}
Loading