From f0ac06c900242c040213b36e6626aadaaddd7c66 Mon Sep 17 00:00:00 2001 From: Anton Romanov Date: Sun, 11 Nov 2018 01:29:06 +0400 Subject: [PATCH] refactor and db changes --- .../timeline/controller/EventController.java | 7 +- .../java/ru/ulstu/timeline/model/Event.java | 34 +++++--- .../ru/ulstu/timeline/model/EventDto.java | 10 +-- .../timeline/repository/EventRepository.java | 3 + .../timeline/service/EventScheduler.java | 81 ++++++++++--------- .../ulstu/timeline/service/EventService.java | 54 ++++++++----- .../db/changelog-20181111_000000-schema.xml | 26 ++++++ src/main/resources/db/changelog-master.xml | 1 + 8 files changed, 137 insertions(+), 79 deletions(-) create mode 100644 src/main/resources/db/changelog-20181111_000000-schema.xml diff --git a/src/main/java/ru/ulstu/timeline/controller/EventController.java b/src/main/java/ru/ulstu/timeline/controller/EventController.java index 6f79b31..b2e4a23 100644 --- a/src/main/java/ru/ulstu/timeline/controller/EventController.java +++ b/src/main/java/ru/ulstu/timeline/controller/EventController.java @@ -13,6 +13,7 @@ import ru.ulstu.core.model.response.Response; import ru.ulstu.timeline.model.EventDto; import ru.ulstu.timeline.service.EventService; +import javax.validation.Valid; import java.util.List; import static ru.ulstu.timeline.controller.EventController.URL; @@ -30,16 +31,16 @@ public class EventController { @GetMapping public Response> getEvents() { - return new Response<>(eventService.findAll()); + return new Response<>(eventService.findAllDto()); } @PostMapping - public Response createEvent(@RequestBody EventDto timelineDto) { + public Response createEvent(@RequestBody @Valid EventDto timelineDto) { return new Response(eventService.create(timelineDto)); } @PutMapping - public Response updateEvent(@RequestBody EventDto eventDto) { + public Response updateEvent(@RequestBody @Valid EventDto eventDto) { return new Response(eventService.update(eventDto)); } diff --git a/src/main/java/ru/ulstu/timeline/model/Event.java b/src/main/java/ru/ulstu/timeline/model/Event.java index 6a753e8..7ae715d 100644 --- a/src/main/java/ru/ulstu/timeline/model/Event.java +++ b/src/main/java/ru/ulstu/timeline/model/Event.java @@ -4,15 +4,18 @@ import org.hibernate.validator.constraints.NotBlank; import ru.ulstu.core.model.BaseEntity; import ru.ulstu.user.model.User; -import javax.persistence.*; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.FetchType; +import javax.persistence.JoinColumn; import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; import javax.persistence.Temporal; import javax.persistence.TemporalType; +import javax.validation.constraints.NotNull; import java.util.Date; import java.util.List; @@ -38,15 +41,12 @@ public class Event extends BaseEntity { @Enumerated(value = EnumType.STRING) private PeriodEvent period; - @Column(name = "begin_date") - @Temporal(TemporalType.TIMESTAMP) - private Date beginDate; - @Enumerated(value = EnumType.STRING) private EventStatus status; @Column(name = "execute_date") @Temporal(TemporalType.TIMESTAMP) + @NotNull private Date executeDate; @Column(name = "create_date") @@ -62,6 +62,10 @@ public class Event extends BaseEntity { @ManyToMany(fetch = FetchType.EAGER) private List recipients; + @ManyToOne + @JoinColumn(name = "child_id") + private Event child; + public String getTitle() { return title; } @@ -78,13 +82,13 @@ public class Event extends BaseEntity { this.status = status; } - public PeriodEvent getPeriod() {return period;} + public PeriodEvent getPeriod() { + return period; + } - public void setPeriod(PeriodEvent period){this.period = period;} - - public Date getBeginDate() {return beginDate;} - - public void setBeginDate(Date beginDate) {this.beginDate = beginDate;} + public void setPeriod(PeriodEvent period) { + this.period = period; + } public Date getCreateDate() { return createDate; @@ -125,4 +129,12 @@ public class Event extends BaseEntity { public void setExecuteDate(Date executeDate) { this.executeDate = executeDate; } + + public Event getChild() { + return child; + } + + public void setChild(Event child) { + this.child = child; + } } diff --git a/src/main/java/ru/ulstu/timeline/model/EventDto.java b/src/main/java/ru/ulstu/timeline/model/EventDto.java index 4ababa8..0ec07ea 100644 --- a/src/main/java/ru/ulstu/timeline/model/EventDto.java +++ b/src/main/java/ru/ulstu/timeline/model/EventDto.java @@ -2,8 +2,10 @@ package ru.ulstu.timeline.model; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import org.hibernate.validator.constraints.NotBlank; import ru.ulstu.user.model.UserDto; +import javax.validation.constraints.NotNull; import java.util.Date; import java.util.List; @@ -11,10 +13,11 @@ import static ru.ulstu.core.util.StreamApiUtils.convert; public class EventDto { private final Integer id; + @NotBlank private final String title; private final PeriodEvent period; - private final Date beginDate; private final Event.EventStatus status; + @NotNull private final Date executeDate; private final Date createDate; private final Date updateDate; @@ -26,7 +29,6 @@ public class EventDto { @JsonProperty("title") String title, @JsonProperty("status") Event.EventStatus status, @JsonProperty("period") PeriodEvent period, - @JsonProperty("beginDate") Date beginDate, @JsonProperty("executeDate") Date executeDate, @JsonProperty("createDate") Date createDate, @JsonProperty("updateDate") Date updateDate, @@ -35,7 +37,6 @@ public class EventDto { this.id = id; this.title = title; this.period = period; - this.beginDate = beginDate; this.status = status; this.executeDate = executeDate; this.createDate = createDate; @@ -49,7 +50,6 @@ public class EventDto { this.title = event.getTitle(); this.status = event.getStatus(); this.period = event.getPeriod(); - this.beginDate = event.getBeginDate(); this.executeDate = event.getExecuteDate(); this.createDate = event.getCreateDate(); this.updateDate = event.getUpdateDate(); @@ -67,8 +67,6 @@ public class EventDto { public PeriodEvent getPeriod() { return period; } - public Date getBeginDate() { return beginDate; } - public Event.EventStatus getStatus() { return status; } public Date getCreateDate() { diff --git a/src/main/java/ru/ulstu/timeline/repository/EventRepository.java b/src/main/java/ru/ulstu/timeline/repository/EventRepository.java index 6267d51..2829261 100644 --- a/src/main/java/ru/ulstu/timeline/repository/EventRepository.java +++ b/src/main/java/ru/ulstu/timeline/repository/EventRepository.java @@ -9,4 +9,7 @@ import java.util.List; public interface EventRepository extends JpaRepository { @Query("SELECT e FROM Event e WHERE e.executeDate = CURRENT_DATE") List findByCurrentDate(); + + @Query("SELECT e FROM Event e WHERE e.executeDate > CURRENT_DATE") + List findAllFuture(); } diff --git a/src/main/java/ru/ulstu/timeline/service/EventScheduler.java b/src/main/java/ru/ulstu/timeline/service/EventScheduler.java index 7ba07a9..958f20b 100644 --- a/src/main/java/ru/ulstu/timeline/service/EventScheduler.java +++ b/src/main/java/ru/ulstu/timeline/service/EventScheduler.java @@ -1,67 +1,72 @@ package ru.ulstu.timeline.service; +import com.google.common.collect.ImmutableMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; import ru.ulstu.core.util.DateUtils; import ru.ulstu.timeline.model.Event; -import ru.ulstu.timeline.model.EventDto; -import ru.ulstu.timeline.repository.EventRepository; -import ru.ulstu.user.model.UserDto; +import ru.ulstu.timeline.model.PeriodEvent; +import ru.ulstu.user.service.MailService; -import java.sql.Date; -import java.time.LocalDate; -import java.time.Period; -import java.time.ZoneId; -import java.util.ArrayList; -import java.util.Calendar; +import java.util.Date; import java.util.List; +import java.util.Map; - +@Service public class EventScheduler { private final Logger log = LoggerFactory.getLogger(EventScheduler.class); private final EventService eventService; - private final EventRepository eventRepository; + private final MailService mailService; - public EventScheduler(EventRepository eventRepository, EventService eventService) { - this.eventRepository = eventRepository; + public EventScheduler(EventService eventService, + MailService mailService) { this.eventService = eventService; + this.mailService = mailService; } - @Scheduled(cron = "0 0 8/12 * 1 ?") + @Scheduled(cron = "0 0 8 * * ?") + public void sendNotifications() { + List events = eventService.findByCurrentDate(); + events.forEach(event -> { + Map variables = ImmutableMap.of("description", event.getDescription()); + event.getRecipients() + .forEach(recipient -> mailService.sendEmailFromTemplate(variables, recipient, "eventNotification", event.getTitle())); + }); + } + + @Scheduled(cron = "0 */2 * * * ?") public void checkPeriodEvents() { log.debug("EventScheduler.checkPeriodEvents started"); - for (Event event : eventRepository.findAll()) { - if(halfOfThePeriodHasPassed(event)){ - event.setCreateDate(Date.from((LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()))); - event.setBeginDate(DateUtils.addDays(event.getBeginDate(), event.getPeriod().getPeriod().getDays())); - event.setUpdateDate(null); - - - eventService.create(new EventDto( - event.getId(), - event.getTitle(), - event.getStatus(), - event.getPeriod(), - event.getBeginDate(), - event.getExecuteDate(), - event.getCreateDate(), - event.getUpdateDate(), - event.getDescription(), - new ArrayList<>() - )); + for (Event event : eventService.findAllFuture()) { + if (halfOfThePeriodHasPassed(event)) { + eventService.createBasedOn(event, DateUtils.addDays(event.getExecuteDate(), getShiftInDays(event.getPeriod()))); } } log.debug("EventScheduler.checkPeriodEvents finished"); } - private boolean halfOfThePeriodHasPassed(Event event){ - if (Period.between(event.getBeginDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(), - LocalDate.now()).getDays() <= event.getPeriod().getPeriod().getDays() / 2) { - return true; + private int getShiftInDays(PeriodEvent periodEvent) { + switch (periodEvent) { + case EVERY_DAY: + return periodEvent.getPeriod().getDays(); + case EVERY_WEEK: + return periodEvent.getPeriod().getDays(); + case EVERY_MONTH: + return periodEvent.getPeriod().getMonths() * 30; + case EVERY_YEAR: + return periodEvent.getPeriod().getYears() * 365; + default: + throw new RuntimeException("period event not exists"); } - return false; + } + + private boolean halfOfThePeriodHasPassed(Event event) { + return event.getPeriod() != null && event.getChild() == null + && new Date().after( + DateUtils.addDays(event.getExecuteDate(), (int) -Math.round((double) getShiftInDays(event.getPeriod()) / 2))); } } diff --git a/src/main/java/ru/ulstu/timeline/service/EventService.java b/src/main/java/ru/ulstu/timeline/service/EventService.java index 63eb2da..602e7aa 100644 --- a/src/main/java/ru/ulstu/timeline/service/EventService.java +++ b/src/main/java/ru/ulstu/timeline/service/EventService.java @@ -1,18 +1,15 @@ package ru.ulstu.timeline.service; -import com.google.common.collect.ImmutableMap; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.ulstu.timeline.model.Event; import ru.ulstu.timeline.model.EventDto; import ru.ulstu.timeline.repository.EventRepository; import ru.ulstu.user.model.UserDto; -import ru.ulstu.user.service.MailService; import ru.ulstu.user.service.UserService; +import java.util.Date; import java.util.List; -import java.util.Map; import static ru.ulstu.core.util.StreamApiUtils.convert; @@ -21,18 +18,19 @@ public class EventService { private final EventRepository eventRepository; private final UserService userService; - private final MailService mailService; public EventService(EventRepository eventRepository, - UserService userService, - MailService mailService) { + UserService userService) { this.eventRepository = eventRepository; this.userService = userService; - this.mailService = mailService; } - public List findAll() { - return convert(eventRepository.findAll(), EventDto::new); + public List findAllDto() { + return convert(findAll(), EventDto::new); + } + + public List findAll() { + return eventRepository.findAll(); } @Transactional @@ -42,14 +40,13 @@ public class EventService { private Event copyFromDto(Event event, EventDto eventDto) { event.setExecuteDate(eventDto.getExecuteDate()); - event.setCreateDate(eventDto.getCreateDate()); + event.setCreateDate(eventDto.getId() == null ? new Date() : eventDto.getCreateDate()); event.setDescription(eventDto.getDescription()); event.setRecipients(userService.findByIds(convert(eventDto.getRecipients(), UserDto::getId))); event.setTitle(eventDto.getTitle()); event.setPeriod(eventDto.getPeriod()); - event.setBeginDate(eventDto.getBeginDate()); event.setStatus(eventDto.getStatus()); - event.setUpdateDate(eventDto.getUpdateDate()); + event.setUpdateDate(new Date()); return event; } @@ -69,13 +66,28 @@ public class EventService { return eventRepository.findAll(ids); } - @Scheduled(cron = "0 0 8 * * ?") - public void sendNotifications() { - List events = eventRepository.findByCurrentDate(); - events.forEach(event -> { - Map variables = ImmutableMap.of("description", event.getDescription()); - event.getRecipients() - .forEach(recipient -> mailService.sendEmailFromTemplate(variables, recipient, "eventNotification", event.getTitle())); - }); + public void createBasedOn(Event event, Date executeDate) { + //backup event id + Integer parentEventId = event.getId(); + + event.setId(null); + event.setStatus(Event.EventStatus.POSSIBLE); + event.setExecuteDate(executeDate); + event.setCreateDate(new Date()); + event.setUpdateDate(new Date()); + event = eventRepository.save(event); + + //set child to parent + Event parentEvent = eventRepository.findOne(parentEventId); + parentEvent.setChild(event); + eventRepository.save(parentEvent); + } + + public List findByCurrentDate() { + return eventRepository.findByCurrentDate(); + } + + public List findAllFuture() { + return eventRepository.findAllFuture(); } } diff --git a/src/main/resources/db/changelog-20181111_000000-schema.xml b/src/main/resources/db/changelog-20181111_000000-schema.xml new file mode 100644 index 0000000..1aa0c64 --- /dev/null +++ b/src/main/resources/db/changelog-20181111_000000-schema.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/db/changelog-master.xml b/src/main/resources/db/changelog-master.xml index b5d2999..d0199a1 100644 --- a/src/main/resources/db/changelog-master.xml +++ b/src/main/resources/db/changelog-master.xml @@ -15,4 +15,5 @@ + \ No newline at end of file