From 121b19f8bca5a497f9928c3ca258d45e7da2267c Mon Sep 17 00:00:00 2001 From: upagge Date: Sun, 13 Sep 2020 20:04:16 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=80=D0=BE=D0=B4=D0=B5=20=D0=B2=D1=81?= =?UTF-8?q?=D0=B5=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bitbucketbot/domain/entity/Comment.java | 3 + .../bot/bitbucketbot/domain/entity/Task.java | 17 +- .../dto/bitbucket/CommentJson.java | 4 + .../repository/CommentRepository.java | 2 + .../repository/TaskRepository.java | 4 + .../impl/CommentRepositoryImpl.java | 5 + .../repository/impl/TaskRepositoryImpl.java | 7 + .../repository/jpa/CommentRepositoryJpa.java | 5 + .../repository/jpa/TaskRepositoryJpa.java | 5 + .../parser/CommentAndTaskScheduler.java | 7 +- .../bitbucketbot/service/CommentService.java | 5 + .../bot/bitbucketbot/service/TaskService.java | 9 + ...Comment.java => CommentJsonToComment.java} | 22 ++- ...ert.java => CommentJsonToTaskConvert.java} | 31 ++-- .../converter/CommentToTaskConvert.java | 34 ++++ .../converter/TaskToCommentConvert.java | 32 ++++ .../bitbucketbot/service/executor/Seeker.java | 13 +- .../service/impl/CommentServiceImpl.java | 66 ++++++- .../service/impl/ExecutorScanner.java | 12 +- .../service/impl/TaskServiceImpl.java | 163 ++++++++++++++++-- .../service/parser/CommentAndTaskParser.java | 83 +++++---- src/main/resources/application-dev.yaml | 2 +- .../v.2.0.0/2020-09-06-create-table.xml | 4 + 23 files changed, 430 insertions(+), 105 deletions(-) rename src/main/java/org/sadtech/bot/bitbucketbot/service/converter/{ResultScanToComment.java => CommentJsonToComment.java} (50%) rename src/main/java/org/sadtech/bot/bitbucketbot/service/converter/{ResultScanToTaskConvert.java => CommentJsonToTaskConvert.java} (50%) create mode 100644 src/main/java/org/sadtech/bot/bitbucketbot/service/converter/CommentToTaskConvert.java create mode 100644 src/main/java/org/sadtech/bot/bitbucketbot/service/converter/TaskToCommentConvert.java diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Comment.java b/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Comment.java index 1d1214c..1c0b60f 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Comment.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Comment.java @@ -42,6 +42,9 @@ public class Comment { @Column(name = "author_login") private String author; + @Column(name = "responsible_login") + private String responsible; + @Column(name = "message") private String message; diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Task.java b/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Task.java index bfcf021..0a502e2 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Task.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Task.java @@ -5,17 +5,19 @@ import lombok.Getter; import lombok.Setter; import org.sadtech.bot.bitbucketbot.domain.TaskStatus; +import javax.persistence.CollectionTable; import javax.persistence.Column; +import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import javax.persistence.FetchType; import javax.persistence.Id; -import javax.persistence.JoinTable; -import javax.persistence.OneToMany; +import javax.persistence.JoinColumn; import javax.persistence.Table; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; @Entity @Getter @@ -66,8 +68,9 @@ public class Task { @Column(name = "responsible_login") private String responsible; - @JoinTable - @OneToMany - private List comments = new ArrayList<>(); + @ElementCollection(fetch = FetchType.EAGER) + @CollectionTable(name = "task_comments", joinColumns = @JoinColumn(name = "task_id")) + @Column(name = "comment_id") + private Set answers = new HashSet<>(); } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/dto/bitbucket/CommentJson.java b/src/main/java/org/sadtech/bot/bitbucketbot/dto/bitbucket/CommentJson.java index 195af07..d707752 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/dto/bitbucket/CommentJson.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/dto/bitbucket/CommentJson.java @@ -26,4 +26,8 @@ public class CommentJson { @JsonDeserialize(using = LocalDateTimeFromEpochDeserializer.class) private LocalDateTime updatedDate; + private Long customPullRequestId; + + private String customCommentApiUrl; + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/CommentRepository.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/CommentRepository.java index 4c1d720..a56a682 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/CommentRepository.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/CommentRepository.java @@ -22,4 +22,6 @@ public interface CommentRepository extends SimpleManagerRepository findAllById(@NonNull Set ids); + Set existsById(Set ids); + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/TaskRepository.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/TaskRepository.java index 9e5672b..ba1228c 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/TaskRepository.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/TaskRepository.java @@ -3,10 +3,14 @@ package org.sadtech.bot.bitbucketbot.repository; import org.sadtech.basic.context.repository.SimpleManagerRepository; import org.sadtech.bot.bitbucketbot.domain.entity.Task; +import java.time.LocalDateTime; +import java.util.List; import java.util.Optional; public interface TaskRepository extends SimpleManagerRepository { Optional findFirstByOrderByIdDesc(); + List findByCreateDateBetween(LocalDateTime dateFrom, LocalDateTime dateTo); + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/CommentRepositoryImpl.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/CommentRepositoryImpl.java index db4d1a2..b50798a 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/CommentRepositoryImpl.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/CommentRepositoryImpl.java @@ -42,4 +42,9 @@ public class CommentRepositoryImpl extends AbstractSimpleManagerRepository existsById(Set ids) { + return repositoryJpa.existsAllById(ids); + } + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/TaskRepositoryImpl.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/TaskRepositoryImpl.java index 93cb383..0b30a40 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/TaskRepositoryImpl.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/TaskRepositoryImpl.java @@ -6,6 +6,8 @@ import org.sadtech.bot.bitbucketbot.repository.TaskRepository; import org.sadtech.bot.bitbucketbot.repository.jpa.TaskRepositoryJpa; import org.springframework.stereotype.Repository; +import java.time.LocalDateTime; +import java.util.List; import java.util.Optional; @Repository @@ -23,4 +25,9 @@ public class TaskRepositoryImpl extends AbstractSimpleManagerRepository findByCreateDateBetween(LocalDateTime dateFrom, LocalDateTime dateTo) { + return taskRepositoryJpa.findByCreateDateBetween(dateFrom, dateTo); + } + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/CommentRepositoryJpa.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/CommentRepositoryJpa.java index 30f9e88..1ee56d6 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/CommentRepositoryJpa.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/CommentRepositoryJpa.java @@ -3,10 +3,12 @@ package org.sadtech.bot.bitbucketbot.repository.jpa; import lombok.NonNull; import org.sadtech.bot.bitbucketbot.domain.entity.Comment; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; +import java.util.Set; public interface CommentRepositoryJpa extends JpaRepository { @@ -14,4 +16,7 @@ public interface CommentRepositoryJpa extends JpaRepository { List findByCreateDateBetween(@NonNull LocalDateTime dateFrom, @NonNull LocalDateTime dateTo); + @Query("SELECT c.id FROM Comment c WHERE c.id IN :ids") + Set existsAllById(@NonNull Set ids); + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/TaskRepositoryJpa.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/TaskRepositoryJpa.java index 92409d1..566683c 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/TaskRepositoryJpa.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/TaskRepositoryJpa.java @@ -1,12 +1,17 @@ package org.sadtech.bot.bitbucketbot.repository.jpa; +import lombok.NonNull; import org.sadtech.bot.bitbucketbot.domain.entity.Task; import org.springframework.data.jpa.repository.JpaRepository; +import java.time.LocalDateTime; +import java.util.List; import java.util.Optional; public interface TaskRepositoryJpa extends JpaRepository { Optional findFirstByOrderByIdDesc(); + List findByCreateDateBetween(@NonNull LocalDateTime dateFrom, @NonNull LocalDateTime dateTo); + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/parser/CommentAndTaskScheduler.java b/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/parser/CommentAndTaskScheduler.java index 4fad475..49ef87a 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/parser/CommentAndTaskScheduler.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/parser/CommentAndTaskScheduler.java @@ -16,9 +16,14 @@ public class CommentAndTaskScheduler { commentAndTaskParser.scanNewCommentAndTask(); } - // @Scheduled(cron = "0 */1 * * * *") + @Scheduled(cron = "0 */1 * * * *") public void scanOldComment() { commentAndTaskParser.scanOldComment(); } + @Scheduled(cron = "0 */1 * * * *") + public void scanOldTask() { + commentAndTaskParser.scanOldTask(); + } + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/CommentService.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/CommentService.java index 37a434f..bd2253e 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/CommentService.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/CommentService.java @@ -3,6 +3,7 @@ package org.sadtech.bot.bitbucketbot.service; import lombok.NonNull; import org.sadtech.basic.context.service.SimpleManagerService; import org.sadtech.bot.bitbucketbot.domain.entity.Comment; +import org.sadtech.bot.bitbucketbot.domain.entity.Task; import java.time.LocalDateTime; import java.util.List; @@ -16,4 +17,8 @@ public interface CommentService extends SimpleManagerService { List getAllById(@NonNull Set ids); + Comment convert(@NonNull Task task); + + Set existsById(@NonNull Set ids); + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/TaskService.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/TaskService.java index 7332fea..3a2ce0c 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/TaskService.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/TaskService.java @@ -1,10 +1,19 @@ package org.sadtech.bot.bitbucketbot.service; +import lombok.NonNull; import org.sadtech.basic.context.service.SimpleManagerService; +import org.sadtech.bot.bitbucketbot.domain.entity.Comment; import org.sadtech.bot.bitbucketbot.domain.entity.Task; +import java.time.LocalDateTime; +import java.util.List; + public interface TaskService extends SimpleManagerService { Long getLastTaskId(); + Task convert(@NonNull Comment comment); + + List getAllBetweenDate(@NonNull LocalDateTime dateFrom, @NonNull LocalDateTime dateTo); + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/ResultScanToComment.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/CommentJsonToComment.java similarity index 50% rename from src/main/java/org/sadtech/bot/bitbucketbot/service/converter/ResultScanToComment.java rename to src/main/java/org/sadtech/bot/bitbucketbot/service/converter/CommentJsonToComment.java index b91e056..461f0ba 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/ResultScanToComment.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/CommentJsonToComment.java @@ -3,28 +3,26 @@ package org.sadtech.bot.bitbucketbot.service.converter; import org.sadtech.bot.bitbucketbot.domain.entity.Comment; import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentJson; import org.sadtech.bot.bitbucketbot.dto.bitbucket.Severity; -import org.sadtech.bot.bitbucketbot.service.executor.ResultScan; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; import java.util.stream.Collectors; @Component -public class ResultScanToComment implements Converter { +public class CommentJsonToComment implements Converter { @Override - public Comment convert(ResultScan resultScan) { - final CommentJson commentJson = resultScan.getCommentJson(); + public Comment convert(CommentJson source) { final Comment comment = new Comment(); - comment.setId(commentJson.getId()); - comment.setCreateDate(commentJson.getCreatedDate()); - comment.setAuthor(commentJson.getAuthor().getName()); - comment.setPullRequestId(resultScan.getPullRequestId()); - comment.setMessage(commentJson.getText()); - comment.setUrlApi(resultScan.getCommentApiUrl()); - comment.setBitbucketVersion(commentJson.getVersion()); + comment.setId(source.getId()); + comment.setCreateDate(source.getCreatedDate()); + comment.setAuthor(source.getAuthor().getName()); + comment.setPullRequestId(source.getCustomPullRequestId()); + comment.setMessage(source.getText()); + comment.setUrlApi(source.getCustomCommentApiUrl()); + comment.setBitbucketVersion(source.getVersion()); comment.setAnswers( - commentJson.getComments().stream() + source.getComments().stream() .filter(json -> Severity.NORMAL.equals(json.getSeverity())) .map(CommentJson::getId) .collect(Collectors.toSet()) diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/ResultScanToTaskConvert.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/CommentJsonToTaskConvert.java similarity index 50% rename from src/main/java/org/sadtech/bot/bitbucketbot/service/converter/ResultScanToTaskConvert.java rename to src/main/java/org/sadtech/bot/bitbucketbot/service/converter/CommentJsonToTaskConvert.java index 7fe7689..42be382 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/ResultScanToTaskConvert.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/CommentJsonToTaskConvert.java @@ -5,25 +5,32 @@ import org.sadtech.bot.bitbucketbot.domain.TaskStatus; import org.sadtech.bot.bitbucketbot.domain.entity.Task; import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentJson; import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentState; -import org.sadtech.bot.bitbucketbot.service.executor.ResultScan; +import org.sadtech.bot.bitbucketbot.dto.bitbucket.Severity; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; +import java.util.stream.Collectors; + @Component -public class ResultScanToTaskConvert implements Converter { +public class CommentJsonToTaskConvert implements Converter { @Override - public Task convert(ResultScan resultScan) { - final CommentJson json = resultScan.getCommentJson(); + public Task convert(CommentJson source) { final Task task = new Task(); - task.setId(json.getId()); - task.setAuthor(json.getAuthor().getName()); - task.setDescription(json.getText()); - task.setCreateDate(json.getCreatedDate()); - task.setBitbucketVersion(json.getVersion()); - task.setPullRequestId(resultScan.getPullRequestId()); - task.setStatus(convertState(json.getState())); - task.setUrlApi(resultScan.getCommentApiUrl()); + task.setId(source.getId()); + task.setAuthor(source.getAuthor().getName()); + task.setDescription(source.getText()); + task.setCreateDate(source.getCreatedDate()); + task.setBitbucketVersion(source.getVersion()); + task.setPullRequestId(source.getCustomPullRequestId()); + task.setStatus(convertState(source.getState())); + task.setUrlApi(source.getCustomCommentApiUrl()); + task.setAnswers( + source.getComments().stream() + .filter(json -> Severity.NORMAL.equals(json.getSeverity())) + .map(CommentJson::getId) + .collect(Collectors.toSet()) + ); return task; } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/CommentToTaskConvert.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/CommentToTaskConvert.java new file mode 100644 index 0000000..4e46a4e --- /dev/null +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/CommentToTaskConvert.java @@ -0,0 +1,34 @@ +package org.sadtech.bot.bitbucketbot.service.converter; + +import org.sadtech.bot.bitbucketbot.domain.TaskStatus; +import org.sadtech.bot.bitbucketbot.domain.entity.Comment; +import org.sadtech.bot.bitbucketbot.domain.entity.Task; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; + +/** + * // TODO: 12.09.2020 Добавить описание. + * + * @author upagge 12.09.2020 + */ +@Component +public class CommentToTaskConvert implements Converter { + + @Override + public Task convert(Comment source) { + final Task task = new Task(); + task.setId(source.getId()); + task.setUrl(source.getUrl()); + task.setUrlApi(source.getUrlApi()); + task.setResponsible(source.getResponsible()); + task.setStatus(TaskStatus.OPEN); + task.setPullRequestId(source.getPullRequestId()); + task.setBitbucketVersion(source.getBitbucketVersion()); + task.setCreateDate(source.getCreateDate()); + task.setDescription(source.getMessage()); + task.setAuthor(source.getAuthor()); + task.setAnswers(source.getAnswers()); + return task; + } + +} diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/TaskToCommentConvert.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/TaskToCommentConvert.java new file mode 100644 index 0000000..bf6268c --- /dev/null +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/TaskToCommentConvert.java @@ -0,0 +1,32 @@ +package org.sadtech.bot.bitbucketbot.service.converter; + +import org.sadtech.bot.bitbucketbot.domain.entity.Comment; +import org.sadtech.bot.bitbucketbot.domain.entity.Task; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; + +/** + * // TODO: 12.09.2020 Добавить описание. + * + * @author upagge 12.09.2020 + */ +@Component +public class TaskToCommentConvert implements Converter { + + @Override + public Comment convert(Task source) { + final Comment comment = new Comment(); + comment.setId(source.getId()); + comment.setUrl(source.getUrl()); + comment.setUrlApi(source.getUrlApi()); + comment.setPullRequestId(source.getPullRequestId()); + comment.setBitbucketVersion(source.getBitbucketVersion()); + comment.setCreateDate(source.getCreateDate()); + comment.setMessage(source.getDescription()); + comment.setResponsible(source.getResponsible()); + comment.setAuthor(source.getAuthor()); + comment.setAnswers(source.getAnswers()); + return comment; + } + +} diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/executor/Seeker.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/executor/Seeker.java index a23be64..e1b9010 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/executor/Seeker.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/executor/Seeker.java @@ -8,19 +8,20 @@ import java.util.Optional; import java.util.concurrent.Callable; @RequiredArgsConstructor -public class Seeker implements Callable> { +public class Seeker implements Callable> { private final DataScan dataScan; private final String token; @Override - public Optional call() { + public Optional call() { return Utils.urlToJson(dataScan.getUrlComment(), token, CommentJson.class) .map( - commentJson -> new ResultScan( - dataScan.getUrlComment(), - dataScan.getPullRequestId(), - commentJson) + commentJson -> { + commentJson.setCustomPullRequestId(dataScan.getPullRequestId()); + commentJson.setCustomCommentApiUrl(dataScan.getUrlComment()); + return commentJson; + } ); } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/CommentServiceImpl.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/CommentServiceImpl.java index a263699..60e4bba 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/CommentServiceImpl.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/CommentServiceImpl.java @@ -2,21 +2,29 @@ package org.sadtech.bot.bitbucketbot.service.impl; import lombok.NonNull; import org.sadtech.basic.core.service.AbstractSimpleManagerService; +import org.sadtech.bot.bitbucketbot.domain.Answer; +import org.sadtech.bot.bitbucketbot.domain.change.comment.AnswerCommentChange; import org.sadtech.bot.bitbucketbot.domain.change.comment.CommentChange; import org.sadtech.bot.bitbucketbot.domain.entity.Comment; +import org.sadtech.bot.bitbucketbot.domain.entity.Task; import org.sadtech.bot.bitbucketbot.exception.NotFoundException; import org.sadtech.bot.bitbucketbot.repository.CommentRepository; import org.sadtech.bot.bitbucketbot.service.ChangeService; import org.sadtech.bot.bitbucketbot.service.CommentService; import org.sadtech.bot.bitbucketbot.service.PersonService; +import org.sadtech.bot.bitbucketbot.service.TaskService; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.convert.ConversionService; import org.springframework.stereotype.Service; import java.time.LocalDateTime; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; @Service public class CommentServiceImpl extends AbstractSimpleManagerService implements CommentService { @@ -26,12 +34,23 @@ public class CommentServiceImpl extends AbstractSimpleManagerService existsById(@NonNull Set ids) { + return commentRepository.existsById(ids); + } + + private void updateAnswer(Comment oldComment, Comment newComment) { + final Set oldAnswerIds = oldComment.getAnswers(); + final Set newAnswerIds = newComment.getAnswers(); + if (!newAnswerIds.isEmpty()) { + final Set existsNewAnswersIds = commentRepository.existsById(newAnswerIds); + final List newAnswers = commentRepository.findAllById(existsNewAnswersIds).stream() + .filter(comment -> !oldAnswerIds.contains(comment.getId())) + .collect(Collectors.toList()); + oldComment.getAnswers().clear(); + oldComment.setAnswers(existsNewAnswersIds); + changeService.save( + AnswerCommentChange.builder() + .telegramIds( + personService.getAllTelegramIdByLogin(Collections.singleton(newComment.getAuthor())) + ) + .url(oldComment.getUrl()) + .youMessage(newComment.getMessage()) + .answers( + newAnswers.stream() + .map(answerComment -> Answer.of(answerComment.getAuthor(), answerComment.getMessage())) + .collect(Collectors.toList()) + ) + .build() + ); + } + } + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/ExecutorScanner.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/ExecutorScanner.java index 6705f79..68a98de 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/ExecutorScanner.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/ExecutorScanner.java @@ -4,9 +4,9 @@ import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty; +import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentJson; import org.sadtech.bot.bitbucketbot.service.executor.DataScan; import org.sadtech.bot.bitbucketbot.service.executor.Executor; -import org.sadtech.bot.bitbucketbot.service.executor.ResultScan; import org.sadtech.bot.bitbucketbot.service.executor.Seeker; import org.springframework.stereotype.Service; @@ -21,10 +21,10 @@ import java.util.stream.Collectors; @Slf4j @Service @RequiredArgsConstructor -public class ExecutorScanner implements Executor { +public class ExecutorScanner implements Executor { private final ExecutorService executorService; - private List>> resultList = new ArrayList<>(); + private List>> resultList = new ArrayList<>(); private final BitbucketProperty bitbucketProperty; @Override @@ -39,11 +39,11 @@ public class ExecutorScanner implements Executor { } @Override - public List getResult() { + public List getResult() { while (!resultList.stream().allMatch(Future::isDone)) { } - final List result = resultList.stream() + final List result = resultList.stream() .filter(Future::isDone) .map(this::getResultScan) .filter(Optional::isPresent) @@ -53,7 +53,7 @@ public class ExecutorScanner implements Executor { return result; } - private Optional getResultScan(Future> test) { + private Optional getResultScan(Future> test) { try { return test.get(); } catch (InterruptedException | ExecutionException e) { diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/TaskServiceImpl.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/TaskServiceImpl.java index 7628961..a9ff997 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/TaskServiceImpl.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/TaskServiceImpl.java @@ -3,42 +3,173 @@ package org.sadtech.bot.bitbucketbot.service.impl; import lombok.NonNull; import org.sadtech.basic.core.service.AbstractSimpleManagerService; import org.sadtech.basic.core.util.Assert; +import org.sadtech.bot.bitbucketbot.domain.Answer; +import org.sadtech.bot.bitbucketbot.domain.TaskStatus; +import org.sadtech.bot.bitbucketbot.domain.change.comment.AnswerCommentChange; +import org.sadtech.bot.bitbucketbot.domain.change.comment.CommentChange; +import org.sadtech.bot.bitbucketbot.domain.change.task.TaskCloseChange; import org.sadtech.bot.bitbucketbot.domain.change.task.TaskNewChange; +import org.sadtech.bot.bitbucketbot.domain.entity.Comment; import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest; import org.sadtech.bot.bitbucketbot.domain.entity.Task; import org.sadtech.bot.bitbucketbot.exception.NotFoundException; import org.sadtech.bot.bitbucketbot.repository.TaskRepository; import org.sadtech.bot.bitbucketbot.service.ChangeService; +import org.sadtech.bot.bitbucketbot.service.CommentService; import org.sadtech.bot.bitbucketbot.service.PersonService; import org.sadtech.bot.bitbucketbot.service.PullRequestsService; import org.sadtech.bot.bitbucketbot.service.TaskService; +import org.springframework.core.convert.ConversionService; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; @Service public class TaskServiceImpl extends AbstractSimpleManagerService implements TaskService { + private static final Pattern PATTERN = Pattern.compile("@[\\w]+"); + private final TaskRepository taskRepository; private final PullRequestsService pullRequestsService; private final ChangeService changeService; private final PersonService personService; + private final CommentService commentService; - public TaskServiceImpl(TaskRepository taskRepository, PullRequestsService pullRequestsService, ChangeService changeService, PersonService personService) { + private final ConversionService conversionService; + + public TaskServiceImpl( + TaskRepository taskRepository, + PullRequestsService pullRequestsService, + ChangeService changeService, + PersonService personService, + CommentService commentService, + ConversionService conversionService + ) { super(taskRepository); this.taskRepository = taskRepository; this.pullRequestsService = pullRequestsService; this.changeService = changeService; this.personService = personService; + this.commentService = commentService; + this.conversionService = conversionService; } @Override public Task create(@NonNull Task task) { Assert.isNotNull(task.getId(), "При создании объекта должен быть установлен идентификатор"); - task.getComments().clear(); + task.getAnswers().clear(); final Task newTask = taskRepository.save(task); + notifyNewTask(task); + notificationPersonal(task); + return newTask; + } + @Override + public Task update(@NonNull Task task) { + final Task oldTask = taskRepository.findById(task.getId()) + .orElseThrow(() -> new NotFoundException("Задача не найдена")); + + if (!task.getBitbucketVersion().equals(oldTask.getBitbucketVersion())) { + oldTask.setDescription(task.getDescription()); + oldTask.setBitbucketVersion(task.getBitbucketVersion()); + } + updateAnswer(oldTask, task); + updateStatus(oldTask, task); + oldTask.setStatus(task.getStatus()); + return taskRepository.save(oldTask); + } + + private void updateStatus(Task oldTask, Task task) { + final TaskStatus oldStatus = oldTask.getStatus(); + final TaskStatus newStatus = task.getStatus(); + if (!oldStatus.equals(newStatus)) { + switch (newStatus) { + case OPEN: + changeService.save( + TaskNewChange.builder() + .messageTask(task.getDescription()) + .authorName(task.getAuthor()) + .url(task.getUrl()) + .telegramIds( + personService.getAllTelegramIdByLogin(Collections.singleton(task.getResponsible())) + ) + .build() + ); + break; + case RESOLVED: + changeService.save( + TaskCloseChange.builder() + .messageTask(task.getDescription()) + .authorName(task.getAuthor()) + .url(task.getUrl()) + .telegramIds( + personService.getAllTelegramIdByLogin(Collections.singleton(task.getAuthor())) + ) + .build() + ); + break; + default: + throw new NotFoundException("Обработчика типа не существует"); + } + oldTask.setStatus(newStatus); + } + } + + private void updateAnswer(Task oldTask, Task task) { + final Set oldAnswerIds = oldTask.getAnswers(); + final Set newAnswerIds = task.getAnswers(); + if (!newAnswerIds.isEmpty()) { + final Set existsNewAnswersIds = commentService.existsById(newAnswerIds); + final List newAnswers = commentService.getAllById(existsNewAnswersIds).stream() + .filter(comment -> !oldAnswerIds.contains(comment.getId())) + .collect(Collectors.toList()); + oldTask.getAnswers().clear(); + oldTask.setAnswers(existsNewAnswersIds); + changeService.save( + AnswerCommentChange.builder() + .telegramIds( + personService.getAllTelegramIdByLogin(Collections.singleton(oldTask.getAuthor())) + ) + .url(task.getUrl()) + .youMessage(oldTask.getDescription()) + .answers( + newAnswers.stream() + .map(answerComment -> Answer.of(answerComment.getAuthor(), answerComment.getMessage())) + .collect(Collectors.toList()) + ) + .build() + ); + } + } + + @Override + public Long getLastTaskId() { + return taskRepository.findFirstByOrderByIdDesc().map(Task::getId).orElse(0L); + } + + @Override + public Task convert(@NonNull Comment comment) { + commentService.deleteById(comment.getId()); + final Task task = conversionService.convert(comment, Task.class); + final Task newTask = taskRepository.save(task); + notifyNewTask(newTask); + return newTask; + } + + @Override + public List getAllBetweenDate(@NonNull LocalDateTime dateFrom, @NonNull LocalDateTime dateTo) { + return taskRepository.findByCreateDateBetween(dateFrom, dateTo); + } + + private void notifyNewTask(Task task) { final PullRequest pullRequest = pullRequestsService.getById(task.getPullRequestId()) .orElseThrow(() -> new NotFoundException("ПР не найден")); @@ -54,20 +185,24 @@ public class TaskServiceImpl extends AbstractSimpleManagerService im ) .build() ); - - return newTask; } - @Override - public Task update(@NonNull Task task) { - final Task oldTask = taskRepository.findById(task.getId()).orElseThrow(() -> new NotFoundException("Задача не найдена")); - oldTask.setStatus(task.getStatus()); - return taskRepository.save(oldTask); - } - - @Override - public Long getLastTaskId() { - return taskRepository.findFirstByOrderByIdDesc().map(Task::getId).orElse(0L); + private void notificationPersonal(@NonNull Task task) { + Matcher matcher = PATTERN.matcher(task.getDescription()); + Set recipientsLogins = new HashSet<>(); + while (matcher.find()) { + final String login = matcher.group(0).replace("@", ""); + recipientsLogins.add(login); + } + final Set recipientsIds = personService.getAllTelegramIdByLogin(recipientsLogins); + changeService.save( + CommentChange.builder() + .authorName(task.getAuthor()) + .url(task.getUrl()) + .telegramIds(recipientsIds) + .message(task.getDescription()) + .build() + ); } } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/parser/CommentAndTaskParser.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/parser/CommentAndTaskParser.java index ca539cb..e012bd1 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/parser/CommentAndTaskParser.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/parser/CommentAndTaskParser.java @@ -7,8 +7,6 @@ import org.sadtech.basic.core.page.PaginationImpl; import org.sadtech.bot.bitbucketbot.config.InitProperty; import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty; import org.sadtech.bot.bitbucketbot.config.properties.CommentSchedulerProperty; -import org.sadtech.bot.bitbucketbot.domain.Answer; -import org.sadtech.bot.bitbucketbot.domain.change.comment.AnswerCommentChange; import org.sadtech.bot.bitbucketbot.domain.entity.Comment; import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest; import org.sadtech.bot.bitbucketbot.domain.entity.PullRequestMini; @@ -16,14 +14,11 @@ import org.sadtech.bot.bitbucketbot.domain.entity.Task; import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentJson; import org.sadtech.bot.bitbucketbot.dto.bitbucket.Severity; import org.sadtech.bot.bitbucketbot.exception.NotFoundException; -import org.sadtech.bot.bitbucketbot.service.ChangeService; import org.sadtech.bot.bitbucketbot.service.CommentService; -import org.sadtech.bot.bitbucketbot.service.PersonService; import org.sadtech.bot.bitbucketbot.service.PullRequestsService; import org.sadtech.bot.bitbucketbot.service.TaskService; import org.sadtech.bot.bitbucketbot.service.Utils; import org.sadtech.bot.bitbucketbot.service.executor.DataScan; -import org.sadtech.bot.bitbucketbot.service.executor.ResultScan; import org.sadtech.bot.bitbucketbot.service.impl.ExecutorScanner; import org.springframework.core.convert.ConversionService; import org.springframework.stereotype.Component; @@ -31,10 +26,8 @@ import org.springframework.stereotype.Component; import java.text.MessageFormat; import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.Set; import java.util.stream.Collectors; /** @@ -47,8 +40,6 @@ public class CommentAndTaskParser { private final CommentService commentService; private final PullRequestsService pullRequestsService; - private final PersonService personService; - private final ChangeService changeService; private final ExecutorScanner executorScanner; private final TaskService taskService; private final ConversionService conversionService; @@ -65,7 +56,7 @@ public class CommentAndTaskParser { do { final List dataScans = generatingLinksToPossibleComments(commentId); executorScanner.registration(dataScans); - final List resultScans = executorScanner.getResult(); + final List resultScans = executorScanner.getResult(); if (!resultScans.isEmpty()) { final long commentMax = commentService.createAll(getCommentsByResultScan(resultScans)).stream() .mapToLong(Comment::getId) @@ -114,23 +105,24 @@ public class CommentAndTaskParser { return commentUrls; } - private List getCommentsByResultScan(List resultScans) { - return resultScans.stream() - .filter(resultScan -> Severity.NORMAL.equals(resultScan.getCommentJson().getSeverity())) + private List getCommentsByResultScan(List commentJsons) { + return commentJsons.stream() + .filter(json -> Severity.NORMAL.equals(json.getSeverity())) .map(resultScan -> conversionService.convert(resultScan, Comment.class)) .peek( comment -> { final PullRequestMini pullRequestMini = pullRequestsService.getMiniInfo(comment.getPullRequestId()) .orElseThrow(() -> new NotFoundException("Автор ПР не найден")); comment.setUrl(generateUrl(comment.getId(), pullRequestMini.getUrl())); + comment.setResponsible(pullRequestMini.getAuthorLogin()); } ) .collect(Collectors.toList()); } - private List getTaskByResultScan(List resultScans) { - return resultScans.stream() - .filter(commentJson -> Severity.BLOCKER.equals(commentJson.getCommentJson().getSeverity())) + private List getTaskByResultScan(List commentJsons) { + return commentJsons.stream() + .filter(json -> Severity.BLOCKER.equals(json.getSeverity())) .map(resultScan -> conversionService.convert(resultScan, Task.class)) .peek( task -> { @@ -156,45 +148,50 @@ public class CommentAndTaskParser { } public void scanOldComment() { - @NonNull final List comments = commentService.getAllBetweenDate( - LocalDateTime.now().minusDays(10), LocalDateTime.now() + final List comments = commentService.getAllBetweenDate( + LocalDateTime.now().minusDays(20), LocalDateTime.now() ); for (Comment oldComment : comments) { final Optional optCommentJson = Utils.urlToJson( - oldComment.getUrl(), + oldComment.getUrlApi(), bitbucketProperty.getToken(), CommentJson.class ); - final Comment newComment = commentService.update(conversionService.convert(oldComment, Comment.class)); - if (optCommentJson.isPresent()) { - final CommentJson commentJson = optCommentJson.get(); - notifyNewCommentAnswers(oldComment, newComment); + final CommentJson json = optCommentJson.get(); + if (Severity.BLOCKER.equals(json.getSeverity())) { + taskService.convert(oldComment); + } else { + final Comment newComment = conversionService.convert(json, Comment.class); + commentService.update(newComment); + } + } else { + commentService.deleteById(oldComment.getId()); } } } - private void notifyNewCommentAnswers(Comment oldComment, Comment newComment) { - final Set oldAnswerIds = oldComment.getAnswers(); - final Set newAnswerIds = newComment.getAnswers(); - if (!newAnswerIds.isEmpty()) { - final List newAnswers = commentService.getAllById(newAnswerIds).stream() - .filter(comment -> !oldAnswerIds.contains(comment.getId())) - .collect(Collectors.toList()); - changeService.save( - AnswerCommentChange.builder() - .telegramIds( - personService.getAllTelegramIdByLogin(Collections.singleton(newComment.getAuthor())) - ) - .url(newComment.getPullRequestId().toString()) - .youMessage(newComment.getMessage()) - .answers( - newAnswers.stream() - .map(answerComment -> Answer.of(answerComment.getAuthor(), answerComment.getMessage())) - .collect(Collectors.toList()) - ) - .build() + public void scanOldTask() { + final List tasks = taskService.getAllBetweenDate( + LocalDateTime.now().minusDays(20), LocalDateTime.now() + ); + for (Task oldTask : tasks) { + final Optional optCommentJson = Utils.urlToJson( + oldTask.getUrlApi(), + bitbucketProperty.getToken(), + CommentJson.class ); + if (optCommentJson.isPresent()) { + final CommentJson json = optCommentJson.get(); + if (Severity.NORMAL.equals(json.getSeverity())) { + commentService.convert(oldTask); + } else { + final Task newTask = conversionService.convert(json, Task.class); + taskService.update(newTask); + } + } else { + taskService.deleteById(oldTask.getId()); + } } } diff --git a/src/main/resources/application-dev.yaml b/src/main/resources/application-dev.yaml index d255a75..cf64301 100644 --- a/src/main/resources/application-dev.yaml +++ b/src/main/resources/application-dev.yaml @@ -23,7 +23,7 @@ bitbucketbot: no-comment-count: 20 comment-count: 100 init: - start-comment-id: 7796 + start-comment-id: 7807 use: false server-send: url: http://188.225.35.149:8080/api/send diff --git a/src/main/resources/liquibase/v.2.0.0/2020-09-06-create-table.xml b/src/main/resources/liquibase/v.2.0.0/2020-09-06-create-table.xml index a0df8e0..1aa4394 100644 --- a/src/main/resources/liquibase/v.2.0.0/2020-09-06-create-table.xml +++ b/src/main/resources/liquibase/v.2.0.0/2020-09-06-create-table.xml @@ -101,6 +101,10 @@ + + +