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 679235a..51adb18 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 @@ -45,7 +45,7 @@ public class Comment { @Column(name = "message") private String message; - @Column(name = "createDate") + @Column(name = "create_date") private LocalDateTime createDate; /** diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Person.java b/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Person.java index e86dfac..7c0069f 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Person.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Person.java @@ -6,8 +6,6 @@ import lombok.Setter; import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @@ -27,14 +25,7 @@ public class Person { * Логин */ @Id - @Column(name = "id") - @GeneratedValue(strategy = GenerationType.IDENTITY) @EqualsAndHashCode.Include - private Long id; - - /** - * Логин - */ @Column(name = "login") private String login; diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/PullRequest.java b/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/PullRequest.java index 74679a8..6ae8f61 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/PullRequest.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/PullRequest.java @@ -44,7 +44,7 @@ public class PullRequest { /** * Идентификатор на стороне битбакета */ - @Column(name = "bitbucket_pr_id") + @Column(name = "bitbucket_id") private Long bitbucketId; /** @@ -65,12 +65,6 @@ public class PullRequest { @Column(name = "repository_slug") private String repositorySlug; - /** - * Версия объекта для блокировок - */ - @Column(name = "version") - private Integer version; - /** * Описание пулреквеста */ @@ -133,4 +127,9 @@ public class PullRequest { @JoinColumn(name = "pull_request_id") private List reviewers; + public void setReviewers(List reviewers) { + reviewers.forEach(reviewer -> reviewer.setPullRequest(this)); + this.reviewers = reviewers; + } + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Reviewer.java b/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Reviewer.java index 4579a3a..1bc7b58 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Reviewer.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/domain/entity/Reviewer.java @@ -9,9 +9,11 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.ManyToOne; import javax.persistence.Table; /** @@ -48,4 +50,7 @@ public class Reviewer { @Column(name = "status") private ReviewerStatus status; + @ManyToOne(fetch = FetchType.LAZY) + private PullRequest pullRequest; + } 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 972e51c..10ca559 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 @@ -12,8 +12,6 @@ import javax.persistence.Enumerated; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; import javax.persistence.Table; import java.time.LocalDateTime; @@ -46,7 +44,6 @@ public class Task { @Column(name = "create_date") private LocalDateTime createDate; - @OneToMany @Column(name = "pull_request_id") private Long pullRequestId; @@ -62,8 +59,7 @@ public class Task { @Column(name = "bitbucket_version") private Integer bitbucketVersion; - @OneToMany - @JoinColumn(name = "author_login") - private Person author; + @Column(name = "author_login") + private String author; } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/ChangeRepository.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/ChangeRepository.java index 4484bb6..cb7d0b3 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/ChangeRepository.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/ChangeRepository.java @@ -7,7 +7,7 @@ import java.util.List; public interface ChangeRepository { - void add(@NonNull Change change); + T add(@NonNull T change); List getAll(); diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/PersonRepository.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/PersonRepository.java new file mode 100644 index 0000000..799cf71 --- /dev/null +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/PersonRepository.java @@ -0,0 +1,31 @@ +package org.sadtech.bot.bitbucketbot.repository; + +import lombok.NonNull; +import org.sadtech.bot.bitbucketbot.domain.entity.Person; + +import java.util.List; +import java.util.Optional; +import java.util.Set; + +/** + * // TODO: 06.09.2020 Добавить описание. + * + * @author upagge 06.09.2020 + */ +public interface PersonRepository { + + Person save(@NonNull Person person); + + boolean existsByTelegramId(Long chatId); + + boolean existsByLogin(String login); + + List findAllByTelegramIdNotNullAndTokenNotNull(); + + Long findTelegramIdByLogin(String login); + + Set findAllTelegramIdByLogin(Set logins); + + Optional findByLogin(@NonNull String login); + +} diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/PullRequestsRepository.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/PullRequestsRepository.java index bf25529..7a3e12d 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/PullRequestsRepository.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/PullRequestsRepository.java @@ -1,6 +1,7 @@ package org.sadtech.bot.bitbucketbot.repository; -import org.sadtech.basic.context.repository.BusinessLogicRepository; +import org.sadtech.basic.context.repository.SimpleManagerRepository; +import org.sadtech.basic.context.repository.simple.FilterOperation; import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr; import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus; import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus; @@ -9,7 +10,7 @@ import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest; import java.util.List; import java.util.Set; -public interface PullRequestsRepository extends BusinessLogicRepository { +public interface PullRequestsRepository extends SimpleManagerRepository, FilterOperation { List findAllByReviewerAndStatuses(String login, ReviewerStatus reviewerStatus, Set statuses); diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/ChangeRepositoryImpl.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/ChangeRepositoryImpl.java index 1b84aef..6b7b64e 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/ChangeRepositoryImpl.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/ChangeRepositoryImpl.java @@ -15,9 +15,10 @@ public class ChangeRepositoryImpl implements ChangeRepository { private long count = 0; @Override - public void add(@NonNull Change change) { + public T add(@NonNull T change) { change.setId(count++); list.add(change); + return change; } @Override diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/PersonRepositoryImpl.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/PersonRepositoryImpl.java new file mode 100644 index 0000000..2e83671 --- /dev/null +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/PersonRepositoryImpl.java @@ -0,0 +1,74 @@ +package org.sadtech.bot.bitbucketbot.repository.impl; + +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.sadtech.bot.bitbucketbot.domain.entity.Person; +import org.sadtech.bot.bitbucketbot.repository.PersonRepository; +import org.sadtech.bot.bitbucketbot.repository.jpa.PersonJpaRepository; +import org.springframework.dao.InvalidDataAccessResourceUsageException; +import org.springframework.stereotype.Repository; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +/** + * // TODO: 06.09.2020 Добавить описание. + * + * @author upagge 06.09.2020 + */ +@Slf4j +@Repository +@RequiredArgsConstructor +public class PersonRepositoryImpl implements PersonRepository { + + private final PersonJpaRepository jpaRepository; + + @Override + public Person save(@NonNull Person person) { + return jpaRepository.save(person); + } + + @Override + public boolean existsByTelegramId(Long chatId) { + return jpaRepository.existsByTelegramId(chatId); + } + + @Override + public boolean existsByLogin(String login) { + try { + return jpaRepository.existsByLogin(login); + } catch (InvalidDataAccessResourceUsageException e) { + log.error(e.getMessage()); + } + return false; + } + + @Override + public List findAllByTelegramIdNotNullAndTokenNotNull() { + try { + return jpaRepository.findAllByTelegramIdNotNullAndTokenNotNull(); + } catch (InvalidDataAccessResourceUsageException e) { + log.error(e.getMessage()); + } + return Collections.emptyList(); + } + + @Override + public Long findTelegramIdByLogin(String login) { + return jpaRepository.findTelegramIdByLogin(login); + } + + @Override + public Set findAllTelegramIdByLogin(Set logins) { + return jpaRepository.findAllTelegramIdByLogin(logins); + } + + @Override + public Optional findByLogin(@NonNull String login) { + return jpaRepository.findById(login); + } + +} diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/PullRequestsRepositoryImpl.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/PullRequestsRepositoryImpl.java index 50ac50a..271c515 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/PullRequestsRepositoryImpl.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/impl/PullRequestsRepositoryImpl.java @@ -1,6 +1,6 @@ package org.sadtech.bot.bitbucketbot.repository.impl; -import org.sadtech.basic.database.repository.AbstractBusinessLogicJpaRepository; +import org.sadtech.basic.database.repository.manager.FilterManagerRepository; import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr; import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus; import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus; @@ -13,28 +13,28 @@ import java.util.List; import java.util.Set; @Repository -public class PullRequestsRepositoryImpl extends AbstractBusinessLogicJpaRepository implements PullRequestsRepository { +public class PullRequestsRepositoryImpl extends FilterManagerRepository implements PullRequestsRepository { - private final PullRequestsRepositoryJpa pullRequestsRepositoryJpa; + private final PullRequestsRepositoryJpa repositoryJpa; - protected PullRequestsRepositoryImpl(PullRequestsRepositoryJpa pullRequestsRepositoryJpa) { - super(pullRequestsRepositoryJpa); - this.pullRequestsRepositoryJpa = pullRequestsRepositoryJpa; + public PullRequestsRepositoryImpl(PullRequestsRepositoryJpa jpaRepository) { + super(jpaRepository); + repositoryJpa = jpaRepository; } @Override public List findAllByReviewerAndStatuses(String login, ReviewerStatus reviewerStatus, Set statuses) { - return pullRequestsRepositoryJpa.findAllByReviewerAndStatuses(login, reviewerStatus, statuses); + return repositoryJpa.findAllByReviewerAndStatuses(login, reviewerStatus, statuses); } @Override public List findAllByAuthorAndReviewerStatus(String login, ReviewerStatus status) { - return pullRequestsRepositoryJpa.findAllByAuthorAndReviewerStatus(login, status); + return repositoryJpa.findAllByAuthorAndReviewerStatus(login, status); } @Override public Set findAllIdByStatusIn(Set statuses) { - return pullRequestsRepositoryJpa.findAllIdByStatusIn(statuses); + return repositoryJpa.findAllIdByStatusIn(statuses); } } 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 9bf5cb7..e1a1788 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 @@ -30,4 +30,9 @@ public class TaskRepositoryImpl implements TaskRepository { return taskRepositoryJpa.findById(id); } + @Override + public Optional findFirstByOrderByIdDesc() { + return Optional.empty(); + } + } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/CommentRepository.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/CommentRepository.java index 7ffc437..00dd203 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/CommentRepository.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/CommentRepository.java @@ -11,6 +11,6 @@ public interface CommentRepository extends JpaRepository { Optional findFirstByOrderByIdDesc(); - List findByDateBetween(LocalDateTime dateFrom, LocalDateTime dateTo); + List findByCreateDateBetween(LocalDateTime dateFrom, LocalDateTime dateTo); } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/PersonRepository.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/PersonJpaRepository.java similarity index 82% rename from src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/PersonRepository.java rename to src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/PersonJpaRepository.java index 608b4ba..06aa42f 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/PersonRepository.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/PersonJpaRepository.java @@ -6,7 +6,6 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import java.util.List; -import java.util.Optional; import java.util.Set; /** @@ -15,7 +14,7 @@ import java.util.Set; * @author upagge [30.01.2020] */ @Repository -public interface PersonRepository extends JpaRepository { +public interface PersonJpaRepository extends JpaRepository { boolean existsByTelegramId(Long chatId); @@ -29,8 +28,4 @@ public interface PersonRepository extends JpaRepository { @Query("SELECT u.telegramId FROM Person u WHERE u.login IN :logins AND u.telegramId IS NOT NULL") Set findAllTelegramIdByLogin(Set logins); - Optional findByLogin(String login); - - Person getByLogin(String login); - } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/PullRequestsRepositoryJpa.java b/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/PullRequestsRepositoryJpa.java index 6cd08cb..a9c8d63 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/PullRequestsRepositoryJpa.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/repository/jpa/PullRequestsRepositoryJpa.java @@ -8,7 +8,6 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.support.JpaRepositoryImplementation; import org.springframework.data.repository.query.Param; -import java.time.LocalDateTime; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -28,10 +27,10 @@ public interface PullRequestsRepositoryJpa extends JpaRepositoryImplementation

id); - @Query("SELECT p FROM PullRequest p LEFT JOIN p.reviewers r WHERE r.user=:reviewer AND r.status =:reviewerStatus AND p.status IN :pullRequestStatus") + @Query("SELECT p FROM PullRequest p LEFT JOIN p.reviewers r WHERE r.userLogin=:reviewer AND r.status =:reviewerStatus AND p.status IN :pullRequestStatus") List findAllByReviewerAndStatuses(@Param("reviewer") String reviewer, @Param("reviewerStatus") ReviewerStatus reviewerStatus, @Param("pullRequestStatus") Set pullRequestStatus); - @Query("SELECT p FROM PullRequest p LEFT JOIN p.reviewers r WHERE p.author.login=:author AND r.status=:reviewerStatus") + @Query("SELECT p FROM PullRequest p LEFT JOIN p.reviewers r WHERE p.authorLogin=:author AND r.status=:reviewerStatus") List findAllByAuthorAndReviewerStatus(@Param("author") String author, @Param("reviewerStatus") ReviewerStatus reviewerStatus); // @Query("SELECT new org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr(p.id, p.status) FROM PullRequest p WHERE p.status IN :statuses") @@ -40,7 +39,7 @@ public interface PullRequestsRepositoryJpa extends JpaRepositoryImplementation

findAllIds(); - @Query("SELECT p FROM PullRequest p WHERE p.author.login = :login AND p.createDate BETWEEN :dateFrom AND :dateTo") - List findAllByAuthorAndDateBetween(@Param("login") String login, @Param("dateFrom") LocalDateTime dateFrom, @Param("dateTo") LocalDateTime dateTo); +// @Query("SELECT p FROM PullRequest p WHERE p.authorLogin = :login AND p.createDate BETWEEN :dateFrom AND :dateTo") +// List findAllByAuthorAndDateBetween(@Param("login") String login, @Param("dateFrom") LocalDateTime dateFrom, @Param("dateTo") LocalDateTime dateTo); } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/SchedulerComments.java b/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/SchedulerComments.java index 807d39b..ce7d79a 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/SchedulerComments.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/SchedulerComments.java @@ -1,49 +1,9 @@ package org.sadtech.bot.bitbucketbot.scheduler; -import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -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.Pagination; -import org.sadtech.bot.bitbucketbot.domain.TaskStatus; -import org.sadtech.bot.bitbucketbot.domain.change.ChangeType; -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.TaskChange; -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.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.sadtech.bot.bitbucketbot.utils.Converter; -import org.springframework.core.convert.ConversionService; -import org.springframework.data.domain.Page; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - /** * Шедулер отвечает за работу с комментариями. Поиск новых комментариев, проверка старых. Так как таски в * битбакете реализуются через комментарии, то этот шедулер так же работает с тасками. @@ -55,210 +15,210 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class SchedulerComments { - private static final Pattern PATTERN = Pattern.compile("@[\\w]+"); - - 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; - - private final BitbucketProperty bitbucketProperty; - private final CommentSchedulerProperty commentSchedulerProperty; - - /** - * Сканирует появление новых комментариев - */ - @Scheduled(cron = "0 */3 * * * *") - public void newComments() { - long commentId = commentService.getLastCommentId() + 1; - int count = 0; - do { - final List dataScans = generatingLinksToPossibleComments(commentId); - executorScanner.registration(dataScans); - final List resultScans = executorScanner.getResult(); - if (!resultScans.isEmpty()) { - final List comments = getCommentsByResultScan(resultScans); - final List newComments = commentService.createAll(comments); - checkNewTask(newComments); - notificationPersonal(newComments); - count = 0; - } - } while (count++ < commentSchedulerProperty.getNoCommentCount()); - } - - private List getCommentsByResultScan(List resultScans) { - return resultScans.stream() - .map(result -> conversionService.convert(result, Comment.class)) - .collect(Collectors.toList()); - } - - private List generatingLinksToPossibleComments(@NonNull Long commentId) { - List commentUrls = new ArrayList<>(); - for (int i = 0; i < 5; i++) { - int page = 0; - Page pullRequestPage = pullRequestsService.getAll( - Pagination.of(page, commentSchedulerProperty.getCommentCount()) - ); - while (pullRequestPage.hasContent()) { - long finalCommentId = commentId; - commentUrls.addAll(pullRequestPage.getContent().stream() - .map( - pullRequest -> new DataScan( - getCommentUrl(finalCommentId, pullRequest), - pullRequest.getId() - ) - ) - .collect(Collectors.toList())); - pullRequestPage = pullRequestsService.getAll( - Pagination.of(++page, commentSchedulerProperty.getCommentCount()) - ); - } - commentId++; - } - return commentUrls; - } - - - private void checkNewTask(CommentJson commentJson, String urlPr, String authorLoginPr) { - if (Severity.BLOCKER.equals(commentJson.getSeverity())) { - final Task task = new Task(); - task.setStatus(Converter.taskStatus(commentJson.getState())); - task.setComment(commentService.getProxyById(commentJson.getId()).orElseThrow(() -> new NotFoundException("Неожиданная ошибка"))); - - taskService.create(task); - - if (TaskStatus.OPEN.equals(task.getStatus())) { - changeService.add( - TaskChange.builder() - .type(ChangeType.NEW_TASK) - .authorName(commentJson.getAuthor().getDisplayName()) - .messageTask(commentJson.getText()) - .telegramIds(personService.getAllTelegramIdByLogin(Collections.singleton(authorLoginPr))) - .url(urlPr) - .build() - ); - } - } - } - - - /** - * Проверяет состояние старых комментариев - */ - @Scheduled(cron = "0 */1 * * * *") - public void oldComments() { - @NonNull final List comments = commentService.getAllBetweenDate( - LocalDateTime.now().minusDays(10), LocalDateTime.now() - ); - for (Comment comment : comments) { - final Optional optCommentJson = Utils.urlToJson( - comment.getUrl(), - bitbucketProperty.getToken(), - CommentJson.class - ); - if (optCommentJson.isPresent()) { - final CommentJson commentJson = optCommentJson.get(); - checkNewAnswers(comment, commentJson); - checkOldTask(comment, commentJson); - } - } - } - - private void checkOldTask(Comment comment, CommentJson commentJson) { - final Task task = comment.getTask(); - if (task == null) { - checkNewTask(commentJson, comment.getPrUrl(), commentJson.getAuthor().getName()); - } else { - if (Severity.NORMAL.equals(commentJson.getSeverity())) { - taskService.deleteById(comment.getId()); - - changeService.add( - TaskChange.builder() - .type(ChangeType.DELETED_TASK) - .telegramIds(personService.getAllTelegramIdByLogin(Collections.singleton(commentJson.getAuthor().getName()))) - .authorName(commentJson.getAuthor().getDisplayName()) - .url(comment.getPrUrl()) - .messageTask(commentJson.getText()) - .build() - ); - } else { - final TaskStatus taskStatus = task.getStatus(); - final TaskStatus newTaskStatus = Converter.taskStatus(commentJson.getState()); - task.setStatus(newTaskStatus); - taskService.update(task); - if (!taskStatus.equals(newTaskStatus)) { - changeService.add( - TaskChange.builder() - .type(TaskStatus.RESOLVED.equals(newTaskStatus) ? ChangeType.RESOLVED_TASK : ChangeType.OPEN_TASK) - .authorName(commentJson.getAuthor().getDisplayName()) - .url(comment.getPrUrl()) - .messageTask(commentJson.getText()) - .telegramIds( - TaskStatus.RESOLVED.equals(newTaskStatus) - ? personService.getAllTelegramIdByLogin(Collections.singleton(commentJson.getAuthor().getName())) - : personService.getAllTelegramIdByLogin(Collections.singleton(commentJson.getAuthor().getName())) - ) - .build() - ); - } - } - } - } - - private void checkNewAnswers(Comment comment, CommentJson commentJson) { - final Set oldAnswerIds = comment.getAnswers(); - final List newAnswers = commentJson.getComments().stream() - .filter(answerJson -> !oldAnswerIds.contains(answerJson.getId())) - .collect(Collectors.toList()); - if (!newAnswers.isEmpty()) { - changeService.add( - AnswerCommentChange.builder() - .telegramIds( - personService.getTelegramIdByLogin(commentJson.getAuthor().getName()) - .map(Collections::singleton) - .orElse(Collections.emptySet()) - ) - .url(comment.getPrUrl()) - .youMessage(commentJson.getText()) - .answers( - newAnswers.stream() - .map(json -> Answer.of(json.getAuthor().getName(), json.getText())) - .collect(Collectors.toList()) - ) - .build() - ); - comment.getAnswers().addAll(newAnswers.stream().map(CommentJson::getId).collect(Collectors.toList())); - commentService.save(comment); - } - } - - private String getCommentUrl(long commentId, PullRequest pullRequest) { - return bitbucketProperty.getUrlPullRequestComment() - .replace("{projectKey}", pullRequest.getProjectKey()) - .replace("{repositorySlug}", pullRequest.getRepositorySlug()) - .replace("{pullRequestId}", pullRequest.getBitbucketId().toString()) - .replace("{commentId}", String.valueOf(commentId)); - } - - private void notificationPersonal(@NonNull Comment comment) { - Matcher matcher = PATTERN.matcher(comment.getMessage()); - Set recipientsLogins = new HashSet<>(); - while (matcher.find()) { - final String login = matcher.group(0).replace("@", ""); - recipientsLogins.add(login); - } - final Set recipientsIds = personService.getAllTelegramIdByLogin(recipientsLogins); - changeService.add( - CommentChange.builder() - .authorName(comment.getAuthor().getLogin()) - .url(comment.getPullRequest()) - .telegramIds(recipientsIds) - .message(comment.getMessage()) - .build() - ); - } +// private static final Pattern PATTERN = Pattern.compile("@[\\w]+"); +// +// 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; +// +// private final BitbucketProperty bitbucketProperty; +// private final CommentSchedulerProperty commentSchedulerProperty; +// +// /** +// * Сканирует появление новых комментариев +// */ +// @Scheduled(cron = "0 */3 * * * *") +// public void newComments() { +// long commentId = commentService.getLastCommentId() + 1; +// int count = 0; +// do { +// final List dataScans = generatingLinksToPossibleComments(commentId); +// executorScanner.registration(dataScans); +// final List resultScans = executorScanner.getResult(); +// if (!resultScans.isEmpty()) { +// final List comments = getCommentsByResultScan(resultScans); +// final List newComments = commentService.createAll(comments); +// checkNewTask(newComments); +// notificationPersonal(newComments); +// count = 0; +// } +// } while (count++ < commentSchedulerProperty.getNoCommentCount()); +// } +// +// private List getCommentsByResultScan(List resultScans) { +// return resultScans.stream() +// .map(result -> conversionService.convert(result, Comment.class)) +// .collect(Collectors.toList()); +// } +// +// private List generatingLinksToPossibleComments(@NonNull Long commentId) { +// List commentUrls = new ArrayList<>(); +// for (int i = 0; i < 5; i++) { +// int page = 0; +// Page pullRequestPage = pullRequestsService.getAll( +// Pagination.of(page, commentSchedulerProperty.getCommentCount()) +// ); +// while (pullRequestPage.hasContent()) { +// long finalCommentId = commentId; +// commentUrls.addAll(pullRequestPage.getContent().stream() +// .map( +// pullRequest -> new DataScan( +// getCommentUrl(finalCommentId, pullRequest), +// pullRequest.getId() +// ) +// ) +// .collect(Collectors.toList())); +// pullRequestPage = pullRequestsService.getAll( +// Pagination.of(++page, commentSchedulerProperty.getCommentCount()) +// ); +// } +// commentId++; +// } +// return commentUrls; +// } +// +// +// private void checkNewTask(CommentJson commentJson, String urlPr, String authorLoginPr) { +// if (Severity.BLOCKER.equals(commentJson.getSeverity())) { +// final Task task = new Task(); +// task.setStatus(Converter.taskStatus(commentJson.getState())); +// task.setComment(commentService.getProxyById(commentJson.getId()).orElseThrow(() -> new NotFoundException("Неожиданная ошибка"))); +// +// taskService.create(task); +// +// if (TaskStatus.OPEN.equals(task.getStatus())) { +// changeService.add( +// TaskChange.builder() +// .type(ChangeType.NEW_TASK) +// .authorName(commentJson.getAuthor().getDisplayName()) +// .messageTask(commentJson.getText()) +// .telegramIds(personService.getAllTelegramIdByLogin(Collections.singleton(authorLoginPr))) +// .url(urlPr) +// .build() +// ); +// } +// } +// } +// +// +// /** +// * Проверяет состояние старых комментариев +// */ +// @Scheduled(cron = "0 */1 * * * *") +// public void oldComments() { +// @NonNull final List comments = commentService.getAllBetweenDate( +// LocalDateTime.now().minusDays(10), LocalDateTime.now() +// ); +// for (Comment comment : comments) { +// final Optional optCommentJson = Utils.urlToJson( +// comment.getUrl(), +// bitbucketProperty.getToken(), +// CommentJson.class +// ); +// if (optCommentJson.isPresent()) { +// final CommentJson commentJson = optCommentJson.get(); +// checkNewAnswers(comment, commentJson); +// checkOldTask(comment, commentJson); +// } +// } +// } +// +// private void checkOldTask(Comment comment, CommentJson commentJson) { +// final Task task = comment.getTask(); +// if (task == null) { +// checkNewTask(commentJson, comment.getPrUrl(), commentJson.getAuthor().getName()); +// } else { +// if (Severity.NORMAL.equals(commentJson.getSeverity())) { +// taskService.deleteById(comment.getId()); +// +// changeService.add( +// TaskChange.builder() +// .type(ChangeType.DELETED_TASK) +// .telegramIds(personService.getAllTelegramIdByLogin(Collections.singleton(commentJson.getAuthor().getName()))) +// .authorName(commentJson.getAuthor().getDisplayName()) +// .url(comment.getPrUrl()) +// .messageTask(commentJson.getText()) +// .build() +// ); +// } else { +// final TaskStatus taskStatus = task.getStatus(); +// final TaskStatus newTaskStatus = Converter.taskStatus(commentJson.getState()); +// task.setStatus(newTaskStatus); +// taskService.update(task); +// if (!taskStatus.equals(newTaskStatus)) { +// changeService.add( +// TaskChange.builder() +// .type(TaskStatus.RESOLVED.equals(newTaskStatus) ? ChangeType.RESOLVED_TASK : ChangeType.OPEN_TASK) +// .authorName(commentJson.getAuthor().getDisplayName()) +// .url(comment.getPrUrl()) +// .messageTask(commentJson.getText()) +// .telegramIds( +// TaskStatus.RESOLVED.equals(newTaskStatus) +// ? personService.getAllTelegramIdByLogin(Collections.singleton(commentJson.getAuthor().getName())) +// : personService.getAllTelegramIdByLogin(Collections.singleton(commentJson.getAuthor().getName())) +// ) +// .build() +// ); +// } +// } +// } +// } +// +// private void checkNewAnswers(Comment comment, CommentJson commentJson) { +// final Set oldAnswerIds = comment.getAnswers(); +// final List newAnswers = commentJson.getComments().stream() +// .filter(answerJson -> !oldAnswerIds.contains(answerJson.getId())) +// .collect(Collectors.toList()); +// if (!newAnswers.isEmpty()) { +// changeService.add( +// AnswerCommentChange.builder() +// .telegramIds( +// personService.getTelegramIdByLogin(commentJson.getAuthor().getName()) +// .map(Collections::singleton) +// .orElse(Collections.emptySet()) +// ) +// .url(comment.getPrUrl()) +// .youMessage(commentJson.getText()) +// .answers( +// newAnswers.stream() +// .map(json -> Answer.of(json.getAuthor().getName(), json.getText())) +// .collect(Collectors.toList()) +// ) +// .build() +// ); +// comment.getAnswers().addAll(newAnswers.stream().map(CommentJson::getId).collect(Collectors.toList())); +// commentService.save(comment); +// } +// } +// +// private String getCommentUrl(long commentId, PullRequest pullRequest) { +// return bitbucketProperty.getUrlPullRequestComment() +// .replace("{projectKey}", pullRequest.getProjectKey()) +// .replace("{repositorySlug}", pullRequest.getRepositorySlug()) +// .replace("{pullRequestId}", pullRequest.getBitbucketId().toString()) +// .replace("{commentId}", String.valueOf(commentId)); +// } +// +// private void notificationPersonal(@NonNull Comment comment) { +// Matcher matcher = PATTERN.matcher(comment.getMessage()); +// Set recipientsLogins = new HashSet<>(); +// while (matcher.find()) { +// final String login = matcher.group(0).replace("@", ""); +// recipientsLogins.add(login); +// } +// final Set recipientsIds = personService.getAllTelegramIdByLogin(recipientsLogins); +// changeService.add( +// CommentChange.builder() +// .authorName(comment.getAuthor().getLogin()) +// .url(comment.getPullRequest()) +// .telegramIds(recipientsIds) +// .message(comment.getMessage()) +// .build() +// ); +// } } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/SchedulerNotification.java b/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/SchedulerNotification.java index fd1be02..12886dc 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/SchedulerNotification.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/SchedulerNotification.java @@ -9,25 +9,30 @@ import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest; import org.sadtech.bot.bitbucketbot.service.MessageSendService; import org.sadtech.bot.bitbucketbot.service.PersonService; import org.sadtech.bot.bitbucketbot.service.PullRequestsService; -import org.sadtech.bot.bitbucketbot.service.ReportService; import org.sadtech.bot.bitbucketbot.utils.Message; +import org.sadtech.bot.bitbucketbot.utils.Smile; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class SchedulerNotification { + private static final Set tksLoginNotify = new HashSet<>(Arrays.asList( + "mstruchkov", "drasskazov", "dganin", "emukhin", "ktorgaeva", "imescheryakov", "kkeglev" + )); private static final Set statuses = Collections.singleton(PullRequestStatus.OPEN); private final PersonService personService; private final PullRequestsService pullRequestsService; private final MessageSendService messageSendService; - private final ReportService reportService; // Утреннее сообщение @Scheduled(cron = "0 15 8 * * MON-FRI") @@ -49,6 +54,21 @@ public class SchedulerNotification { } } + @Scheduled(cron = "0 25 10 * * MON-FRI") + public void tks() { + List usersTks = personService.getAllRegister().stream() + .filter(user -> tksLoginNotify.contains(user.getLogin())) + .collect(Collectors.toList()); + for (Person person : usersTks) { + messageSendService.add( + MessageSend.builder() + .telegramId(person.getTelegramId()) + .message("☎️ Скоро созвон" + Smile.HR + "https://meet.google.com/czs-vigu-mte") + .build() + ); + } + } + @Scheduled(cron = "0 0 18 * * FRI") public void goodWeekEnd() { List allRegister = personService.getAllRegister(); @@ -59,7 +79,6 @@ public class SchedulerNotification { .message(Message.goodWeekEnd()) .build() ); - reportService.generateReport(user.getLogin()); } } 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 5276950..e6827cf 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 @@ -1,24 +1,22 @@ package org.sadtech.bot.bitbucketbot.scheduler.parser; import lombok.RequiredArgsConstructor; -import org.sadtech.bot.bitbucketbot.service.parser.CommentAndTaskParser; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor public class CommentAndTaskScheduler { - private final CommentAndTaskParser commentAndTaskParser; - - @Scheduled(cron = "") - public void scanNewCommentAndTask() { - commentAndTaskParser.scanNewCommentAndTask(); - } - - @Scheduled(cron = "") - public void scanOldComment() { - commentAndTaskParser.scanOldComment(); - } +// private final CommentAndTaskParser commentAndTaskParser; +// +// @Scheduled(cron = "") +// public void scanNewCommentAndTask() { +// commentAndTaskParser.scanNewCommentAndTask(); +// } +// +// @Scheduled(cron = "") +// public void scanOldComment() { +// commentAndTaskParser.scanOldComment(); +// } } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/parser/PersonScheduler.java b/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/parser/PersonScheduler.java index 07fe8a8..dc1421b 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/parser/PersonScheduler.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/parser/PersonScheduler.java @@ -1,7 +1,7 @@ package org.sadtech.bot.bitbucketbot.scheduler.parser; import lombok.RequiredArgsConstructor; -import org.sadtech.bot.bitbucketbot.service.parser.PersonParser; +import org.sadtech.bot.bitbucketbot.service.impl.parser.PersonBitbucketParser; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -9,12 +9,12 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor public class PersonScheduler { - private final PersonParser personParser; + private final PersonBitbucketParser personParser; - @Scheduled(cron = "") + // @Scheduled(cron = "0 0 0 */1 * *") + @Scheduled(cron = "0 */1 * * * *") public void scanPersons() { personParser.scanNewPerson(); } - } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/parser/PullRequestParserScheduler.java b/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/parser/PullRequestParserScheduler.java index 85dc8aa..66ef0d7 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/parser/PullRequestParserScheduler.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/scheduler/parser/PullRequestParserScheduler.java @@ -6,6 +6,11 @@ import org.sadtech.bot.bitbucketbot.service.parser.PullRequestParser; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +/** + * Позволяет задать время парсинга для ПРов. + * + * @author upagge 06.09.2020 + */ @Slf4j @Service @RequiredArgsConstructor @@ -13,12 +18,12 @@ public class PullRequestParserScheduler { private final PullRequestParser pullRequestParser; - @Scheduled(cron = "") + @Scheduled(cron = "0 */1 * * * *") public void parsingOldPullRequest() { pullRequestParser.parsingOldPullRequest(); } - @Scheduled(cron = "") + @Scheduled(cron = "0 */1 * * * *") public void parsingNewPullRequest() { pullRequestParser.parsingNewPullRequest(); } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/ChangeService.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/ChangeService.java index e5389bf..8a031ff 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/ChangeService.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/ChangeService.java @@ -2,6 +2,9 @@ package org.sadtech.bot.bitbucketbot.service; import lombok.NonNull; import org.sadtech.bot.bitbucketbot.domain.change.Change; +import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.NewPrChange; +import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.UpdatePrChange; +import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest; import java.util.List; @@ -13,12 +16,11 @@ import java.util.List; */ public interface ChangeService { - /** - * Позволяет добавить новое изменение в хранилище - * - * @param change Объект, который содержит изменения - */ - void add(@NonNull Change change); + NewPrChange create(@NonNull PullRequest newPullRequest); + + UpdatePrChange createUpdatePr(@NonNull PullRequest oldPullRequest, @NonNull PullRequest newPullRequest); + + Change createReviewersPr(@NonNull PullRequest oldPullRequest, @NonNull PullRequest newPullRequest); /** * Позволяет получить новые изменения. diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/PersonService.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/PersonService.java index a394670..eed9baf 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/PersonService.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/PersonService.java @@ -24,8 +24,6 @@ public interface PersonService { Set getAllTelegramIdByLogin(Set logins); - Optional getProxyByLogin(@NonNull String login); - Person create(@NonNull Person person); List createAll(Collection newUsers); diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/PullRequestsService.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/PullRequestsService.java index a7a8b4d..30aa382 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/PullRequestsService.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/PullRequestsService.java @@ -1,7 +1,7 @@ package org.sadtech.bot.bitbucketbot.service; import lombok.NonNull; -import org.sadtech.basic.context.service.BusinessLogicService; +import org.sadtech.basic.context.service.SimpleManagerService; import org.sadtech.basic.context.service.simple.FilterService; import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr; import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus; @@ -12,13 +12,19 @@ import org.sadtech.bot.bitbucketbot.domain.filter.PullRequestFilter; import java.util.List; import java.util.Set; -public interface PullRequestsService extends BusinessLogicService, FilterService { +public interface PullRequestsService extends SimpleManagerService, FilterService { @NonNull List getAllByReviewerAndStatuses(@NonNull String login, @NonNull ReviewerStatus reviewerStatus, @NonNull Set pullRequestStatuses); List getAllByAuthorAndReviewerStatus(@NonNull String login, @NonNull ReviewerStatus status); + /** + * Получить все идентификаторы вместе со статусами. + * + * @param statuses Статусы ПРов + * @return Объект, содержащий идентификатор и статус ПР + */ Set getAllId(Set statuses); } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/PullRequestJsonConverter.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/PullRequestJsonConverter.java index 9ad6ad2..239d1c5 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/PullRequestJsonConverter.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/PullRequestJsonConverter.java @@ -38,7 +38,7 @@ public class PullRequestJsonConverter implements Converter { final Comment comment = new Comment(); comment.setCreateDate(commentJson.getCreatedDate()); comment.setAuthor(commentJson.getAuthor().getName()); - comment.setPullRequestId(getPullRequest(resultScan.getPullRequestId())); + comment.setPullRequestId(resultScan.getPullRequestId()); comment.setMessage(commentJson.getText()); comment.setUrl(resultScan.getUrlComment()); comment.setBitbucketVersion(commentJson.getVersion()); @@ -34,16 +32,4 @@ public class ResultScanToComment implements Converter { } - private PullRequest getPullRequest(Long pullRequestId) { - final PullRequest pullRequest = new PullRequest(); - pullRequest.setId(pullRequestId); - return pullRequest; - } - - private Person getAuthor(String name) { - final Person user = new Person(); - user.setLogin(name); - return user; - } - } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/ResultScanToTaskConvert.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/ResultScanToTaskConvert.java index c48975f..27964aa 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/ResultScanToTaskConvert.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/ResultScanToTaskConvert.java @@ -1,6 +1,5 @@ package org.sadtech.bot.bitbucketbot.service.converter; -import org.sadtech.bot.bitbucketbot.domain.entity.Person; import org.sadtech.bot.bitbucketbot.domain.entity.Task; import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentJson; import org.sadtech.bot.bitbucketbot.service.executor.ResultScan; @@ -15,7 +14,7 @@ public class ResultScanToTaskConvert implements Converter { final CommentJson json = resultScan.getCommentJson(); final Task task = new Task(); task.setId(json.getId()); - task.setAuthor(getAuthor(json)); + task.setAuthor(json.getAuthor().getName()); task.setDescription(json.getText()); task.setCreateDate(json.getCreatedDate()); task.setBitbucketVersion(json.getVersion()); @@ -23,10 +22,4 @@ public class ResultScanToTaskConvert implements Converter { return task; } - private Person getAuthor(CommentJson json) { - final Person person = new Person(); - person.setLogin(json.getAuthor().getName()); - return person; - } - } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/UserDtoConverter.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/UserDtoConverter.java index 36fe79b..39619af 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/UserDtoConverter.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/UserDtoConverter.java @@ -10,11 +10,11 @@ public class UserDtoConverter implements Converter { @Override public Person convert(UserDto source) { - return Person.builder() - .login(source.getLogin()) - .token(source.getToken()) - .telegramId(source.getTelegramId()) - .build(); + final Person person = new Person(); + person.setLogin(source.getLogin()); + person.setToken(source.getToken()); + person.setTelegramId(source.getTelegramId()); + return person; } } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/UserJsonConverter.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/UserJsonConverter.java index 4685a39..87a9aee 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/UserJsonConverter.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/converter/UserJsonConverter.java @@ -3,9 +3,9 @@ package org.sadtech.bot.bitbucketbot.service.converter; import org.sadtech.bot.bitbucketbot.domain.entity.Person; import org.sadtech.bot.bitbucketbot.dto.bitbucket.UserJson; import org.springframework.core.convert.converter.Converter; -import org.springframework.stereotype.Service; +import org.springframework.stereotype.Component; -@Service +@Component public class UserJsonConverter implements Converter { @Override diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/ChangeServiceImpl.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/ChangeServiceImpl.java index b43aca9..710f288 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/ChangeServiceImpl.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/ChangeServiceImpl.java @@ -2,22 +2,100 @@ package org.sadtech.bot.bitbucketbot.service.impl; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus; import org.sadtech.bot.bitbucketbot.domain.change.Change; +import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.NewPrChange; +import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.ReviewersPrChange; +import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.UpdatePrChange; +import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest; +import org.sadtech.bot.bitbucketbot.domain.entity.Reviewer; +import org.sadtech.bot.bitbucketbot.domain.util.ReviewerChange; import org.sadtech.bot.bitbucketbot.repository.ChangeRepository; import org.sadtech.bot.bitbucketbot.service.ChangeService; +import org.sadtech.bot.bitbucketbot.service.PersonService; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class ChangeServiceImpl implements ChangeService { private final ChangeRepository changeRepository; + private final PersonService personService; @Override - public void add(@NonNull Change change) { - changeRepository.add(change); + public NewPrChange create(@NonNull PullRequest newPullRequest) { + return changeRepository.add( + NewPrChange.builder() + .author(newPullRequest.getAuthorLogin()) + .description(newPullRequest.getDescription()) + .title(newPullRequest.getTitle()) + .url(newPullRequest.getUrl()) + .telegramIds(getReviewerTelegrams(newPullRequest.getReviewers())) + .build() + ); + } + + @Override + public UpdatePrChange createUpdatePr(@NonNull PullRequest oldPullRequest, @NonNull PullRequest newPullRequest) { + return changeRepository.add( + UpdatePrChange.builder() + .author(oldPullRequest.getAuthorLogin()) + .name(newPullRequest.getTitle()) + .telegramIds(getReviewerTelegrams(newPullRequest.getReviewers())) + .url(newPullRequest.getUrl()) + .build() + ); + } + + @Override + public Change createReviewersPr(@NonNull PullRequest oldPullRequest, @NonNull PullRequest newPullRequest) { + final Map oldReviewers = oldPullRequest.getReviewers().stream() + .collect(Collectors.toMap(Reviewer::getId, reviewer -> reviewer)); + final Map newReviewers = newPullRequest.getReviewers().stream() + .collect(Collectors.toMap(Reviewer::getId, reviewer -> reviewer)); + final List reviewerChanges = new ArrayList<>(); + for (Reviewer newReviewer : newReviewers.values()) { + if (oldReviewers.containsKey(newReviewer.getId())) { + final Reviewer oldReviewer = oldReviewers.get(newReviewer.getId()); + final ReviewerStatus oldStatus = oldReviewer.getStatus(); + final ReviewerStatus newStatus = newReviewer.getStatus(); + if (!oldStatus.equals(newStatus)) { + reviewerChanges.add(ReviewerChange.ofOld(oldReviewer.getUserLogin(), oldStatus, newStatus)); + } + } else { + reviewerChanges.add(ReviewerChange.ofNew(newReviewer.getUserLogin(), newReviewer.getStatus())); + } + } + final Set oldIds = oldReviewers.keySet(); + oldIds.removeAll(newReviewers.keySet()); + reviewerChanges.addAll( + oldReviewers.entrySet().stream() + .filter(e -> oldIds.contains(e.getKey())) + .map(e -> ReviewerChange.ofDeleted(e.getValue().getUserLogin())) + .collect(Collectors.toList()) + ); + return changeRepository.add( + ReviewersPrChange.builder() + .title(newPullRequest.getTitle()) + .url(newPullRequest.getUrl()) + .telegramId(personService.getTelegramIdByLogin(newPullRequest.getAuthorLogin()).orElse(null)) + .reviewerChanges(reviewerChanges) + .build() + ); + } + + private Set getReviewerTelegrams(@NonNull List reviewers) { + return personService.getAllTelegramIdByLogin( + reviewers.stream() + .map(Reviewer::getUserLogin) + .collect(Collectors.toSet()) + ); } @Override 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 43104df..a74bdeb 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 @@ -1,100 +1,79 @@ package org.sadtech.bot.bitbucketbot.service.impl; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import org.sadtech.bot.bitbucketbot.config.InitConfig; -import org.sadtech.bot.bitbucketbot.domain.Pagination; -import org.sadtech.bot.bitbucketbot.domain.entity.Comment; -import org.sadtech.bot.bitbucketbot.exception.NotFoundException; -import org.sadtech.bot.bitbucketbot.repository.jpa.CommentRepository; -import org.sadtech.bot.bitbucketbot.service.CommentService; -import org.sadtech.bot.bitbucketbot.service.PersonService; -import org.sadtech.bot.bitbucketbot.service.PullRequestsService; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.stereotype.Service; - -import javax.transaction.Transactional; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -@Service -@RequiredArgsConstructor -public class CommentServiceImpl implements CommentService { - - private final PersonService personService; - private final CommentRepository commentRepository; - private final PullRequestsService pullRequestsService; - private final InitConfig initConfig; - - @Override - public Long getLastCommentId() { - return commentRepository.findFirstByOrderByIdDesc().map(Comment::getId).orElse(getInitCommentId()); - } - - private Long getInitCommentId() { - return initConfig.getStartCommentId() != null ? initConfig.getStartCommentId() : 0L; - } - - @Override - public Page getAll(@NonNull Pagination pagination) { - return commentRepository.findAll(PageRequest.of(pagination.getPage(), pagination.getSize())); - } - - @Override - public @NonNull List getAllBetweenDate(LocalDateTime dateFrom, LocalDateTime dateTo) { - return commentRepository.findByDateBetween(dateFrom, dateTo); - } - - @Override - public Comment create(@NonNull Comment comment) { - comment.setAuthor(personService.getProxyByLogin( - comment.getAuthor().getLogin()).orElseThrow(() -> new NotFoundException("")) - ); - comment.setPullRequest( - pullRequestsService.getProxyById(comment.getPullRequest().getId()).orElseThrow(() -> new NotFoundException("")) - ); - return commentRepository.save(comment); - } - - @Override - public void delete(@NonNull Long id) { - commentRepository.deleteById(id); - } - - @Override - public Optional getProxyById(@NonNull Long id) { - return Optional.ofNullable(commentRepository.getOne(id)); - } - - @Override - @Transactional - public List createAll(List newComments) { - return newComments.stream() - .map(this::create) - .collect(Collectors.toList()); - } - - @Override - public Comment update(Comment comment) { - final Comment oldComment = commentRepository.findById(comment.getId()) - .orElseThrow(() -> new NotFoundException("Комментарий не найден")); - - if (oldComment.getBitbucketVersion().equals(comment.getBitbucketVersion())) { - oldComment.setBitbucketVersion(comment.getBitbucketVersion()); - oldComment.setMessage(oldComment.getMessage()); - return commentRepository.save(oldComment); - } - - return oldComment; - } - - @Override - public List getAllById(@NonNull Set ids) { - return commentRepository.findAllById(ids); - } - -} +//@Service +//@RequiredArgsConstructor +//public class CommentServiceImpl implements CommentService { +// +// private final PersonService personService; +// private final CommentRepository commentRepository; +// private final PullRequestsService pullRequestsService; +// private final InitConfig initConfig; +// +// @Override +// public Long getLastCommentId() { +// return commentRepository.findFirstByOrderByIdDesc().map(Comment::getId).orElse(getInitCommentId()); +// } +// +// private Long getInitCommentId() { +// return initConfig.getStartCommentId() != null ? initConfig.getStartCommentId() : 0L; +// } +// +// @Override +// public Page getAll(@NonNull Pagination pagination) { +// return commentRepository.findAll(PageRequest.of(pagination.getPage(), pagination.getSize())); +// } +// +// @Override +// public @NonNull List getAllBetweenDate(LocalDateTime dateFrom, LocalDateTime dateTo) { +// return commentRepository.findByDateBetween(dateFrom, dateTo); +// } +// +// @Override +// public Comment create(@NonNull Comment comment) { +// comment.setAuthor(personService.getProxyByLogin( +// comment.getAuthor().getLogin()).orElseThrow(() -> new NotFoundException("")) +// ); +// comment.setPullRequest( +// pullRequestsService.getProxyById(comment.getPullRequest().getId()).orElseThrow(() -> new NotFoundException("")) +// ); +// return commentRepository.save(comment); +// } +// +// @Override +// public void delete(@NonNull Long id) { +// commentRepository.deleteById(id); +// } +// +// @Override +// public Optional getProxyById(@NonNull Long id) { +// return Optional.ofNullable(commentRepository.getOne(id)); +// } +// +// @Override +// @Transactional +// public List createAll(List newComments) { +// return newComments.stream() +// .map(this::create) +// .collect(Collectors.toList()); +// } +// +// @Override +// public Comment update(Comment comment) { +// final Comment oldComment = commentRepository.findById(comment.getId()) +// .orElseThrow(() -> new NotFoundException("Комментарий не найден")); +// +// if (oldComment.getBitbucketVersion().equals(comment.getBitbucketVersion())) { +// oldComment.setBitbucketVersion(comment.getBitbucketVersion()); +// oldComment.setMessage(oldComment.getMessage()); +// return commentRepository.save(oldComment); +// } +// +// return oldComment; +// } +// +// @Override +// public List getAllById(@NonNull Set ids) { +// return commentRepository.findAllById(ids); +// } +// +//} diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/PersonServiceImpl.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/PersonServiceImpl.java index 3d383c2..6dffc6e 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/PersonServiceImpl.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/PersonServiceImpl.java @@ -2,12 +2,13 @@ package org.sadtech.bot.bitbucketbot.service.impl; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.sadtech.basic.core.util.Assert; import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty; import org.sadtech.bot.bitbucketbot.domain.entity.Person; import org.sadtech.bot.bitbucketbot.dto.bitbucket.sheet.PullRequestSheetJson; -import org.sadtech.bot.bitbucketbot.exception.CreateException; import org.sadtech.bot.bitbucketbot.exception.RegException; -import org.sadtech.bot.bitbucketbot.repository.jpa.PersonRepository; +import org.sadtech.bot.bitbucketbot.repository.PersonRepository; import org.sadtech.bot.bitbucketbot.service.PersonService; import org.sadtech.bot.bitbucketbot.service.Utils; import org.springframework.stereotype.Service; @@ -18,6 +19,7 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +@Slf4j @Service @RequiredArgsConstructor public class PersonServiceImpl implements PersonService { @@ -27,12 +29,14 @@ public class PersonServiceImpl implements PersonService { @Override public Optional getByLogin(String login) { - return personRepository.findById(login); + return personRepository.findByLogin(login); } @Override public Set existsByLogin(@NonNull Set logins) { - return logins.stream().filter(personRepository::existsById).collect(Collectors.toSet()); + return logins.stream() + .filter(personRepository::existsByLogin) + .collect(Collectors.toSet()); } @Override @@ -75,17 +79,10 @@ public class PersonServiceImpl implements PersonService { return personRepository.findAllTelegramIdByLogin(logins); } - @Override - public Optional getProxyByLogin(@NonNull String login) { - return Optional.ofNullable(personRepository.getByLogin(login)); - } - @Override public Person create(@NonNull Person person) { - if (person.getId() == null) { - return personRepository.save(person); - } - throw new CreateException("При создании пользователя должен отсутствовать id"); + Assert.isNotNull(person.getLogin(), "При создании пользователя должен присутствовать логин"); + return personRepository.save(person); } @Override diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/PullRequestsServiceImpl.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/PullRequestsServiceImpl.java index e5ba8f1..689089b 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/PullRequestsServiceImpl.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/PullRequestsServiceImpl.java @@ -4,7 +4,8 @@ import lombok.NonNull; import org.sadtech.basic.context.page.Pagination; import org.sadtech.basic.context.page.Sheet; import org.sadtech.basic.context.service.simple.FilterService; -import org.sadtech.basic.core.service.AbstractBusinessLogicService; +import org.sadtech.basic.core.service.AbstractSimpleManagerService; +import org.sadtech.basic.core.util.Assert; import org.sadtech.basic.filter.criteria.CriteriaFilter; import org.sadtech.basic.filter.criteria.CriteriaQuery; import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr; @@ -13,12 +14,10 @@ import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus; import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest; import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest_; import org.sadtech.bot.bitbucketbot.domain.filter.PullRequestFilter; -import org.sadtech.bot.bitbucketbot.exception.CreateException; import org.sadtech.bot.bitbucketbot.exception.UpdateException; import org.sadtech.bot.bitbucketbot.repository.PullRequestsRepository; import org.sadtech.bot.bitbucketbot.service.ChangeService; import org.sadtech.bot.bitbucketbot.service.PullRequestsService; -import org.sadtech.bot.bitbucketbot.utils.ChangeGenerator; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -27,7 +26,7 @@ import java.util.Optional; import java.util.Set; @Service -public class PullRequestsServiceImpl extends AbstractBusinessLogicService implements PullRequestsService { +public class PullRequestsServiceImpl extends AbstractSimpleManagerService implements PullRequestsService { private final ChangeService changeService; private final PullRequestsRepository pullRequestsRepository; @@ -46,12 +45,13 @@ public class PullRequestsServiceImpl extends AbstractBusinessLogicService> prByDay = pullRequestsService.getAllByAuthor(login, now.minusDays(7L), now).stream() - .collect(Collectors.groupingBy(pullRequest -> pullRequest.getUpdateDate().toLocalDate())); - return generateMessage(prByDay).orElse("Кажется эту неделю ты не работал"); - } - - private Optional generateMessage(@NonNull Map> prByDay) { - if (!prByDay.isEmpty()) { - final StringBuilder message = new StringBuilder("Твой отчет на эту неделю:").append(Smile.TWO_BR); - for (Map.Entry> entry : prByDay.entrySet()) { - message.append(dayOfWeek(entry.getKey())).append(": "); - for (PullRequest pullRequest : entry.getValue()) { - message.append(" - ").append(pullRequest.getName()).append(Smile.BR) - .append(" --").append(pullRequest.getDescription()); - } - } - } - return Optional.empty(); - } - - private String dayOfWeek(LocalDate date) { - switch (date.getDayOfWeek()) { - case MONDAY: - return "Понедельник"; - case SUNDAY: - return "Воскресенье"; - case TUESDAY: - return "Вторник"; - case SATURDAY: - return "Суббота"; - case THURSDAY: - return "Четверг"; - case WEDNESDAY: - return "Среда"; - case FRIDAY: - return "Пятница"; - } - return ""; - } - -} diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/filter/PullRequestFilterService.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/filter/PullRequestFilterService.java index 90f0fcf..686832a 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/filter/PullRequestFilterService.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/filter/PullRequestFilterService.java @@ -1,10 +1,7 @@ package org.sadtech.bot.bitbucketbot.service.impl.filter; import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import org.sadtech.basic.context.page.Pagination; -import org.sadtech.basic.context.page.Sheet; -import org.sadtech.basic.context.service.simple.FilterService; +import org.sadtech.basic.core.service.AbstractFilterService; import org.sadtech.basic.filter.Filter; import org.sadtech.basic.filter.FilterQuery; import org.sadtech.basic.filter.criteria.CriteriaFilter; @@ -15,33 +12,19 @@ import org.sadtech.bot.bitbucketbot.domain.filter.PullRequestFilter; import org.sadtech.bot.bitbucketbot.repository.PullRequestsRepository; import org.springframework.stereotype.Service; -import java.util.List; -import java.util.Optional; - @Service -@RequiredArgsConstructor -public class PullRequestFilterService implements FilterService { +public class PullRequestFilterService extends AbstractFilterService { - private final PullRequestsRepository pullRequestsRepository; - - @Override - public Sheet getAll(@NonNull PullRequestFilter filter, Pagination pagination) { - return pullRequestsRepository.findAll(createFilter(filter), pagination); + public PullRequestFilterService(PullRequestsRepository filterOperation) { + super(filterOperation); } @Override - public List getAll(@NonNull PullRequestFilter filter) { - return pullRequestsRepository.findAll(createFilter(filter)); - } - - @Override - public Optional getFirst(@NonNull PullRequestFilter filter) { - return pullRequestsRepository.findFirst(createFilter(filter)); - } - - @Override - public boolean exists(@NonNull PullRequestFilter filter) { - return pullRequestsRepository.exists(createFilter(filter)); + protected Filter createFilter(@NonNull PullRequestFilter filter) { + return CriteriaFilter.create() + .and( + convertFilter(filter) + ); } private FilterQuery convertFilter(@NonNull PullRequestFilter filter) { @@ -50,11 +33,4 @@ public class PullRequestFilterService implements FilterServicecreate() - .and( - convertFilter(filter) - ); - } - } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/parser/PersonBitbucketParser.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/parser/PersonBitbucketParser.java new file mode 100644 index 0000000..352fc78 --- /dev/null +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/parser/PersonBitbucketParser.java @@ -0,0 +1,51 @@ +package org.sadtech.bot.bitbucketbot.service.impl.parser; + +import lombok.RequiredArgsConstructor; +import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty; +import org.sadtech.bot.bitbucketbot.domain.entity.Person; +import org.sadtech.bot.bitbucketbot.dto.bitbucket.UserJson; +import org.sadtech.bot.bitbucketbot.dto.bitbucket.sheet.UserSheetJson; +import org.sadtech.bot.bitbucketbot.service.PersonService; +import org.sadtech.bot.bitbucketbot.service.Utils; +import org.sadtech.bot.bitbucketbot.service.parser.PersonParser; +import org.springframework.core.convert.ConversionService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class PersonBitbucketParser implements PersonParser { + + private final PersonService personService; + private final ConversionService conversionService; + + private final BitbucketProperty bitbucketProperty; + + @Override + public void scanNewPerson() { + Optional sheetJson = Utils.urlToJson(bitbucketProperty.getUrlUsers(), bitbucketProperty.getToken(), UserSheetJson.class); + while (sheetJson.isPresent() && sheetJson.get().hasContent()) { + final UserSheetJson sheetUsers = sheetJson.get(); + final List users = sheetUsers.getValues(); + final Set logins = users.stream().map(UserJson::getName).collect(Collectors.toSet()); + final Set existsLogins = personService.existsByLogin(logins); + final Set newUsers = users.stream() + .filter(userJson -> !existsLogins.contains(userJson.getName())) + .map(userJson -> conversionService.convert(userJson, Person.class)) + .collect(Collectors.toSet()); + if (!newUsers.isEmpty()) { + personService.createAll(newUsers); + } + if (sheetUsers.getNextPageStart() != null) { + sheetJson = Utils.urlToJson(bitbucketProperty.getUrlUsers() + sheetUsers.getNextPageStart(), bitbucketProperty.getToken(), UserSheetJson.class); + } else { + break; + } + } + } + +} diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/parser/PullRequestBitbucketParser.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/parser/PullRequestBitbucketParser.java new file mode 100644 index 0000000..7f14da7 --- /dev/null +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/impl/parser/PullRequestBitbucketParser.java @@ -0,0 +1,130 @@ +package org.sadtech.bot.bitbucketbot.service.impl.parser; + +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty; +import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr; +import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus; +import org.sadtech.bot.bitbucketbot.domain.entity.Person; +import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest; +import org.sadtech.bot.bitbucketbot.domain.filter.PullRequestFilter; +import org.sadtech.bot.bitbucketbot.dto.bitbucket.PullRequestJson; +import org.sadtech.bot.bitbucketbot.dto.bitbucket.sheet.PullRequestSheetJson; +import org.sadtech.bot.bitbucketbot.service.PersonService; +import org.sadtech.bot.bitbucketbot.service.PullRequestsService; +import org.sadtech.bot.bitbucketbot.service.Utils; +import org.sadtech.bot.bitbucketbot.service.parser.PullRequestParser; +import org.sadtech.bot.bitbucketbot.utils.Pair; +import org.springframework.core.convert.ConversionService; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.DECLINED; +import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.MERGED; +import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.OPEN; + +@Slf4j +@Service +@RequiredArgsConstructor +public class PullRequestBitbucketParser implements PullRequestParser { + + private static final Set OLD_STATUSES = Stream.of(MERGED, OPEN, DECLINED).collect(Collectors.toSet()); + + private final PullRequestsService pullRequestsService; + private final PersonService personService; + private final ConversionService conversionService; + private final BitbucketProperty bitbucketProperty; + + @Override + public void parsingOldPullRequest() { + final Set existsId = pullRequestsService.getAllId(OLD_STATUSES).stream() + .map(IdAndStatusPr::getId) + .collect(Collectors.toSet()); + final Set openId = parsingPullRequest(bitbucketProperty.getUrlPullRequestOpen()); + final Set closeId = parsingPullRequest(bitbucketProperty.getUrlPullRequestClose()); + final Set newNotExistsId = existsId.stream() + .filter(id -> !openId.contains(id) && !closeId.contains(id)) + .collect(Collectors.toSet()); + log.info("Открыты: " + Arrays.toString(openId.toArray())); + log.info("Закрыты: " + Arrays.toString(closeId.toArray())); + log.info("Не найдены: " + Arrays.toString(newNotExistsId.toArray())); + if (!newNotExistsId.isEmpty()) { + pullRequestsService.deleteAllById(newNotExistsId); + } + } + + @Override + public void parsingNewPullRequest() { + final List users = personService.getAllRegister(); + for (Person user : users) { + Optional sheetJson = Utils.urlToJson(bitbucketProperty.getUrlPullRequestOpen(), user.getToken(), PullRequestSheetJson.class); + while (sheetJson.isPresent() && sheetJson.get().hasContent()) { + final PullRequestSheetJson pullRequestBitbucketSheet = sheetJson.get(); + final List newPullRequest = pullRequestBitbucketSheet.getValues().stream() + .collect(Collectors.toMap(pullRequestJson -> new Pair<>(pullRequestJson.getId(), pullRequestJson.getFromRef().getRepository().getId()), pullRequestJson -> pullRequestJson)) + .values() + .stream() + .filter(pullRequestJson -> !pullRequestsService.exists(bitbucketIdAndPullRequestId(pullRequestJson))) + .map(pullRequestJson -> conversionService.convert(pullRequestJson, PullRequest.class)) + .collect(Collectors.toList()); + + pullRequestsService.createAll(newPullRequest); + + if (pullRequestBitbucketSheet.getNextPageStart() != null) { + sheetJson = Utils.urlToJson(bitbucketProperty.getUrlPullRequestOpen() + pullRequestBitbucketSheet.getNextPageStart(), bitbucketProperty.getToken(), PullRequestSheetJson.class); + } else { + break; + } + } + } + } + + private Set parsingPullRequest(@NonNull String url) { + final List users = personService.getAllRegister(); + final Set ids = new HashSet<>(); + for (Person user : users) { + Optional sheetJson = Utils.urlToJson(url, user.getToken(), PullRequestSheetJson.class); + while (sheetJson.isPresent() && sheetJson.get().hasContent()) { + final PullRequestSheetJson jsonSheet = sheetJson.get(); + final List existsPr = getExistsPr(jsonSheet.getValues()); + + ids.addAll( + pullRequestsService.updateAll(existsPr).stream() + .map(PullRequest::getId) + .collect(Collectors.toSet()) + ); + + if (jsonSheet.getNextPageStart() != null) { + sheetJson = Utils.urlToJson(url + jsonSheet.getNextPageStart(), bitbucketProperty.getToken(), PullRequestSheetJson.class); + } else { + break; + } + } + } + return ids; + } + + private List getExistsPr(@NonNull List pullRequestJsons) { + return pullRequestJsons.stream() + .map(json -> pullRequestsService.getFirst(bitbucketIdAndPullRequestId(json))) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + } + + private PullRequestFilter bitbucketIdAndPullRequestId(PullRequestJson json) { + return PullRequestFilter.builder() + .bitbucketId(json.getId()) + .bitbucketRepositoryId(json.getFromRef().getRepository().getId()) + .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 ba0644a..2abed42 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 @@ -1,44 +1,8 @@ package org.sadtech.bot.bitbucketbot.service.parser; -import lombok.NonNull; import lombok.RequiredArgsConstructor; -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.Pagination; -import org.sadtech.bot.bitbucketbot.domain.change.ChangeType; -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.TaskChange; -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.dto.bitbucket.CommentJson; -import org.sadtech.bot.bitbucketbot.dto.bitbucket.Severity; -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.data.domain.Page; import org.springframework.stereotype.Component; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - /** *

Поиск новых комментариев и задач.

*

К несчастью, у битбакета не очень удобный API, и у них таска это то же самое что и комментарий, только с флагом

@@ -46,168 +10,168 @@ import java.util.stream.Collectors; @Component @RequiredArgsConstructor public class CommentAndTaskParser { - - private static final Pattern PATTERN = Pattern.compile("@[\\w]+"); - - 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; - - private final BitbucketProperty bitbucketProperty; - private final CommentSchedulerProperty commentSchedulerProperty; - - public void scanNewCommentAndTask() { - long commentId = getLastIdCommentOrTask() + 1; - int count = 0; - do { - final List dataScans = generatingLinksToPossibleComments(commentId); - executorScanner.registration(dataScans); - final List resultScans = executorScanner.getResult(); - if (!resultScans.isEmpty()) { - processingComments(resultScans); - processingTasks(resultScans); - count = 0; - } - } while (count++ < commentSchedulerProperty.getNoCommentCount()); - } - - private long getLastIdCommentOrTask() { - return Long.max(commentService.getLastCommentId(), taskService.getLastTaskId()); - } - - private void processingComments(List resultScans) { - final List newComments = commentService.createAll(getCommentsByResultScan(resultScans)); - newComments.forEach(this::notificationPersonal); - } - - private void processingTasks(List resultScans) { - final List newTasks = taskService.createAll(getTaskByResultScan(resultScans)); - newTasks.forEach(this::notificationNewTask); - } - - private List generatingLinksToPossibleComments(@NonNull Long commentId) { - List commentUrls = new ArrayList<>(); - for (int i = 0; i < 5; i++) { - int page = 0; - Page pullRequestPage = pullRequestsService.getAll( - Pagination.of(page, commentSchedulerProperty.getCommentCount()) - ); - while (pullRequestPage.hasContent()) { - long finalCommentId = commentId; - commentUrls.addAll(pullRequestPage.getContent().stream() - .map( - pullRequest -> new DataScan( - getCommentUrl(finalCommentId, pullRequest), - pullRequest.getId() - ) - ) - .collect(Collectors.toList())); - pullRequestPage = pullRequestsService.getAll( - Pagination.of(++page, commentSchedulerProperty.getCommentCount()) - ); - } - commentId++; - } - return commentUrls; - } - - private List getCommentsByResultScan(List resultScans) { - return resultScans.stream() - .filter(resultScan -> Severity.NORMAL.equals(resultScan.getCommentJson().getSeverity())) - .map(resultScan -> conversionService.convert(resultScan, Comment.class)) - .collect(Collectors.toList()); - } - - private List getTaskByResultScan(List resultScans) { - return resultScans.stream() - .filter(commentJson -> Severity.BLOCKER.equals(commentJson.getCommentJson().getSeverity())) - .map(resultScan -> conversionService.convert(resultScan, Task.class)) - .collect(Collectors.toList()); - } - - private String getCommentUrl(long commentId, PullRequest pullRequest) { - return bitbucketProperty.getUrlPullRequestComment() - .replace("{projectKey}", pullRequest.getProjectKey()) - .replace("{repositorySlug}", pullRequest.getRepositorySlug()) - .replace("{pullRequestId}", pullRequest.getBitbucketId().toString()) - .replace("{commentId}", String.valueOf(commentId)); - } - - private void notificationPersonal(@NonNull Comment comment) { - Matcher matcher = PATTERN.matcher(comment.getMessage()); - Set recipientsLogins = new HashSet<>(); - while (matcher.find()) { - final String login = matcher.group(0).replace("@", ""); - recipientsLogins.add(login); - } - final Set recipientsIds = personService.getAllTelegramIdByLogin(recipientsLogins); - changeService.add( - CommentChange.builder() - .authorName(comment.getAuthor().getLogin()) - .url(comment.getUrl()) - .telegramIds(recipientsIds) - .message(comment.getMessage()) - .build() - ); - } - - private void notificationNewTask(@NonNull Task task) { - changeService.add( - TaskChange.builder() - .authorName(task.getAuthor().getFullName()) - .messageTask(task.getDescription()) - .type(ChangeType.NEW_TASK) - .url(task.getUrl()) - .telegramIds(Collections.singleton(task.getPullRequest().getAuthor().getTelegramId())) - .build() - ); - } - - public void scanOldComment() { - @NonNull final List comments = commentService.getAllBetweenDate( - LocalDateTime.now().minusDays(10), LocalDateTime.now() - ); - for (Comment oldComment : comments) { - final Optional optCommentJson = Utils.urlToJson( - oldComment.getUrl(), - 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); - } - } - } - - 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.add( - AnswerCommentChange.builder() - .telegramIds( - Collections.singleton(newComment.getAuthor().getTelegramId()) - ) - .url(newComment.getPullRequest().getUrl()) - .youMessage(newComment.getMessage()) - .answers( - newAnswers.stream() - .map(comment -> Answer.of(comment.getAuthor().getFullName(), comment.getMessage())) - .collect(Collectors.toList()) - ) - .build() - ); - } - } +// +// private static final Pattern PATTERN = Pattern.compile("@[\\w]+"); +// +// 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; +// +// private final BitbucketProperty bitbucketProperty; +// private final CommentSchedulerProperty commentSchedulerProperty; +// +// public void scanNewCommentAndTask() { +// long commentId = getLastIdCommentOrTask() + 1; +// int count = 0; +// do { +// final List dataScans = generatingLinksToPossibleComments(commentId); +// executorScanner.registration(dataScans); +// final List resultScans = executorScanner.getResult(); +// if (!resultScans.isEmpty()) { +// processingComments(resultScans); +// processingTasks(resultScans); +// count = 0; +// } +// } while (count++ < commentSchedulerProperty.getNoCommentCount()); +// } +// +// private long getLastIdCommentOrTask() { +// return Long.max(commentService.getLastCommentId(), taskService.getLastTaskId()); +// } +// +// private void processingComments(List resultScans) { +// final List newComments = commentService.createAll(getCommentsByResultScan(resultScans)); +// newComments.forEach(this::notificationPersonal); +// } +// +// private void processingTasks(List resultScans) { +// final List newTasks = taskService.createAll(getTaskByResultScan(resultScans)); +// newTasks.forEach(this::notificationNewTask); +// } +// +// private List generatingLinksToPossibleComments(@NonNull Long commentId) { +// List commentUrls = new ArrayList<>(); +// for (int i = 0; i < 5; i++) { +// int page = 0; +// Page pullRequestPage = pullRequestsService.getAll( +// Pagination.of(page, commentSchedulerProperty.getCommentCount()) +// ); +// while (pullRequestPage.hasContent()) { +// long finalCommentId = commentId; +// commentUrls.addAll(pullRequestPage.getContent().stream() +// .map( +// pullRequest -> new DataScan( +// getCommentUrl(finalCommentId, pullRequest), +// pullRequest.getId() +// ) +// ) +// .collect(Collectors.toList())); +// pullRequestPage = pullRequestsService.getAll( +// Pagination.of(++page, commentSchedulerProperty.getCommentCount()) +// ); +// } +// commentId++; +// } +// return commentUrls; +// } +// +// private List getCommentsByResultScan(List resultScans) { +// return resultScans.stream() +// .filter(resultScan -> Severity.NORMAL.equals(resultScan.getCommentJson().getSeverity())) +// .map(resultScan -> conversionService.convert(resultScan, Comment.class)) +// .collect(Collectors.toList()); +// } +// +// private List getTaskByResultScan(List resultScans) { +// return resultScans.stream() +// .filter(commentJson -> Severity.BLOCKER.equals(commentJson.getCommentJson().getSeverity())) +// .map(resultScan -> conversionService.convert(resultScan, Task.class)) +// .collect(Collectors.toList()); +// } +// +// private String getCommentUrl(long commentId, PullRequest pullRequest) { +// return bitbucketProperty.getUrlPullRequestComment() +// .replace("{projectKey}", pullRequest.getProjectKey()) +// .replace("{repositorySlug}", pullRequest.getRepositorySlug()) +// .replace("{pullRequestId}", pullRequest.getBitbucketId().toString()) +// .replace("{commentId}", String.valueOf(commentId)); +// } +// +// private void notificationPersonal(@NonNull Comment comment) { +// Matcher matcher = PATTERN.matcher(comment.getMessage()); +// Set recipientsLogins = new HashSet<>(); +// while (matcher.find()) { +// final String login = matcher.group(0).replace("@", ""); +// recipientsLogins.add(login); +// } +// final Set recipientsIds = personService.getAllTelegramIdByLogin(recipientsLogins); +// changeService.add( +// CommentChange.builder() +// .authorName(comment.getAuthor().getLogin()) +// .url(comment.getUrl()) +// .telegramIds(recipientsIds) +// .message(comment.getMessage()) +// .build() +// ); +// } +// +// private void notificationNewTask(@NonNull Task task) { +// changeService.add( +// TaskChange.builder() +// .authorName(task.getAuthor().getFullName()) +// .messageTask(task.getDescription()) +// .type(ChangeType.NEW_TASK) +// .url(task.getUrl()) +// .telegramIds(Collections.singleton(task.getPullRequest().getAuthor().getTelegramId())) +// .build() +// ); +// } +// +// public void scanOldComment() { +// @NonNull final List comments = commentService.getAllBetweenDate( +// LocalDateTime.now().minusDays(10), LocalDateTime.now() +// ); +// for (Comment oldComment : comments) { +// final Optional optCommentJson = Utils.urlToJson( +// oldComment.getUrl(), +// 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); +// } +// } +// } +// +// 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.add( +// AnswerCommentChange.builder() +// .telegramIds( +// Collections.singleton(newComment.getAuthor().getTelegramId()) +// ) +// .url(newComment.getPullRequest().getUrl()) +// .youMessage(newComment.getMessage()) +// .answers( +// newAnswers.stream() +// .map(comment -> Answer.of(comment.getAuthor().getFullName(), comment.getMessage())) +// .collect(Collectors.toList()) +// ) +// .build() +// ); +// } +// } } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/parser/PersonParser.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/parser/PersonParser.java index cfcc6ef..00ad971 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/parser/PersonParser.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/parser/PersonParser.java @@ -1,49 +1,15 @@ package org.sadtech.bot.bitbucketbot.service.parser; -import lombok.RequiredArgsConstructor; -import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty; -import org.sadtech.bot.bitbucketbot.domain.entity.Person; -import org.sadtech.bot.bitbucketbot.dto.bitbucket.UserJson; -import org.sadtech.bot.bitbucketbot.dto.bitbucket.sheet.UserSheetJson; -import org.sadtech.bot.bitbucketbot.service.PersonService; -import org.sadtech.bot.bitbucketbot.service.Utils; -import org.springframework.core.convert.ConversionService; -import org.springframework.stereotype.Service; +/** + * // TODO: 06.09.2020 Добавить описание. + * + * @author upagge 06.09.2020 + */ +public interface PersonParser { -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -@Service -@RequiredArgsConstructor -public class PersonParser { - - private final PersonService personService; - private final ConversionService conversionService; - - private final BitbucketProperty bitbucketProperty; - - public void scanNewPerson() { - Optional sheetJson = Utils.urlToJson(bitbucketProperty.getUrlUsers(), bitbucketProperty.getToken(), UserSheetJson.class); - while (sheetJson.isPresent() && sheetJson.get().hasContent()) { - final UserSheetJson sheetUsers = sheetJson.get(); - final List users = sheetUsers.getValues(); - final Set logins = users.stream().map(UserJson::getName).collect(Collectors.toSet()); - final Set existsLogins = personService.existsByLogin(logins); - final Set newUsers = users.stream() - .filter(userJson -> !existsLogins.contains(userJson.getName())) - .map(userJson -> conversionService.convert(userJson, Person.class)) - .collect(Collectors.toSet()); - if (!newUsers.isEmpty()) { - personService.createAll(newUsers); - } - if (sheetUsers.getNextPageStart() != null) { - sheetJson = Utils.urlToJson(bitbucketProperty.getUrlUsers() + sheetUsers.getNextPageStart(), bitbucketProperty.getToken(), UserSheetJson.class); - } else { - break; - } - } - } + /** + * Извлечение новых пользователей SCV. + */ + void scanNewPerson(); } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/service/parser/PullRequestParser.java b/src/main/java/org/sadtech/bot/bitbucketbot/service/parser/PullRequestParser.java index 24341c4..778bd6d 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/service/parser/PullRequestParser.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/service/parser/PullRequestParser.java @@ -1,128 +1,20 @@ package org.sadtech.bot.bitbucketbot.service.parser; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty; -import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr; -import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus; -import org.sadtech.bot.bitbucketbot.domain.entity.Person; -import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest; -import org.sadtech.bot.bitbucketbot.domain.filter.PullRequestFilter; -import org.sadtech.bot.bitbucketbot.dto.bitbucket.PullRequestJson; -import org.sadtech.bot.bitbucketbot.dto.bitbucket.sheet.PullRequestSheetJson; -import org.sadtech.bot.bitbucketbot.service.PersonService; -import org.sadtech.bot.bitbucketbot.service.PullRequestsService; -import org.sadtech.bot.bitbucketbot.service.Utils; -import org.sadtech.bot.bitbucketbot.utils.Pair; -import org.springframework.core.convert.ConversionService; -import org.springframework.stereotype.Service; +/** + * // TODO: 06.09.2020 Добавить описание. + * + * @author upagge 06.09.2020 + */ +public interface PullRequestParser { -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; + /** + * Проверка старых ПР на изменение. + */ + void parsingOldPullRequest(); -import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.DECLINED; -import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.MERGED; -import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.OPEN; - -@Slf4j -@Service -@RequiredArgsConstructor -public class PullRequestParser { - - private static final Set STATUSES = Stream.of(MERGED, OPEN, DECLINED).collect(Collectors.toSet()); - - private final PullRequestsService pullRequestsService; - private final PersonService personService; - private final ConversionService conversionService; - private final BitbucketProperty bitbucketProperty; - - public void parsingOldPullRequest() { - final Set existsId = pullRequestsService.getAllId(STATUSES).stream() - .map(IdAndStatusPr::getId) - .collect(Collectors.toSet()); - final Set openId = parsingPullRequest(bitbucketProperty.getUrlPullRequestOpen()); - final Set closeId = parsingPullRequest(bitbucketProperty.getUrlPullRequestClose()); - final Set newNotExistsId = existsId.stream() - .filter(id -> !openId.contains(id) && !closeId.contains(id)) - .collect(Collectors.toSet()); - log.info("Открыты: " + Arrays.toString(openId.toArray())); - log.info("Закрыты: " + Arrays.toString(closeId.toArray())); - log.info("Не найдены: " + Arrays.toString(newNotExistsId.toArray())); - if (!newNotExistsId.isEmpty()) { - pullRequestsService.deleteAllById(newNotExistsId); - } - } - - private Set parsingPullRequest(@NonNull String url) { - final List users = personService.getAllRegister(); - final Set ids = new HashSet<>(); - for (Person user : users) { - Optional sheetJson = Utils.urlToJson(url, user.getToken(), PullRequestSheetJson.class); - while (sheetJson.isPresent() && sheetJson.get().hasContent()) { - final PullRequestSheetJson jsonSheet = sheetJson.get(); - final List existsPr = getExistsPr(jsonSheet.getValues()); - - ids.addAll( - pullRequestsService.updateAll(existsPr).stream() - .map(PullRequest::getId) - .collect(Collectors.toSet()) - ); - - if (jsonSheet.getNextPageStart() != null) { - sheetJson = Utils.urlToJson(url + jsonSheet.getNextPageStart(), bitbucketProperty.getToken(), PullRequestSheetJson.class); - } else { - break; - } - } - } - return ids; - } - - private List getExistsPr(@NonNull List pullRequestJsons) { - return pullRequestJsons.stream() - .map(json -> pullRequestsService.getByFilterQuery(bitbucketIdAndPullRequestId(json))) - .filter(Optional::isPresent) - .map(Optional::get) - .collect(Collectors.toList()); - } - - private PullRequestFilter bitbucketIdAndPullRequestId(PullRequestJson json) { - return PullRequestFilter.builder() - .bitbucketId(json.getId()) - .bitbucketRepositoryId(json.getFromRef().getRepository().getId()) - .build(); - } - - - public void parsingNewPullRequest() { - final List users = personService.getAllRegister(); - for (Person user : users) { - Optional sheetJson = Utils.urlToJson(bitbucketProperty.getUrlPullRequestOpen(), user.getToken(), PullRequestSheetJson.class); - while (sheetJson.isPresent() && sheetJson.get().hasContent()) { - final PullRequestSheetJson pullRequestBitbucketSheet = sheetJson.get(); - final List newPullRequest = pullRequestBitbucketSheet.getValues().stream() - .collect(Collectors.toMap(pullRequestJson -> new Pair<>(pullRequestJson.getId(), pullRequestJson.getFromRef().getRepository().getId()), pullRequestJson -> pullRequestJson)) - .values() - .stream() - .filter(pullRequestJson -> !pullRequestsService.existsByFilterQuery(bitbucketIdAndPullRequestId(pullRequestJson))) - .map(pullRequestJson -> conversionService.convert(pullRequestJson, PullRequest.class)) - .collect(Collectors.toList()); - - pullRequestsService.createAll(newPullRequest); - - if (pullRequestBitbucketSheet.getNextPageStart() != null) { - sheetJson = Utils.urlToJson(bitbucketProperty.getUrlPullRequestOpen() + pullRequestBitbucketSheet.getNextPageStart(), bitbucketProperty.getToken(), PullRequestSheetJson.class); - } else { - break; - } - } - } - } + /** + * Извлекает новые ПР. + */ + void parsingNewPullRequest(); } diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/utils/ChangeGenerator.java b/src/main/java/org/sadtech/bot/bitbucketbot/utils/ChangeGenerator.java deleted file mode 100644 index eee564a..0000000 --- a/src/main/java/org/sadtech/bot/bitbucketbot/utils/ChangeGenerator.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.sadtech.bot.bitbucketbot.utils; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus; -import org.sadtech.bot.bitbucketbot.domain.change.Change; -import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.NewPrChange; -import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.ReviewersPrChange; -import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.UpdatePrChange; -import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest; -import org.sadtech.bot.bitbucketbot.domain.entity.Reviewer; -import org.sadtech.bot.bitbucketbot.domain.util.ReviewerChange; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class ChangeGenerator { - - public static NewPrChange create(@NonNull PullRequest newPullRequest) { - return NewPrChange.builder() - .author(newPullRequest.getAuthor().getFullName()) - .description(newPullRequest.getDescription()) - .title(newPullRequest.getTitle()) - .url(newPullRequest.getUrl()) - .telegramIds( - newPullRequest.getReviewers().stream() - .map(reviewer -> reviewer.getUser().getTelegramId()) - .collect(Collectors.toSet()) - ) - .build(); - } - - public static UpdatePrChange createUpdatePr(@NonNull PullRequest oldPullRequest, @NonNull PullRequest newPullRequest) { - return UpdatePrChange.builder() - .author(oldPullRequest.getAuthor().getFullName()) - .name(newPullRequest.getAuthor().getFullName()) - .telegramIds( - newPullRequest.getReviewers().stream() - .map(reviewer -> reviewer.getUser().getTelegramId()) - .collect(Collectors.toSet()) - ) - .url(newPullRequest.getUrl()) - .build(); - } - - public static Change createReviewersPr(@NonNull PullRequest oldPullRequest, @NonNull PullRequest newPullRequest) { - final Map oldReviewers = oldPullRequest.getReviewers().stream() - .collect(Collectors.toMap(Reviewer::getId, reviewer -> reviewer)); - final Map newReviewers = newPullRequest.getReviewers().stream() - .collect(Collectors.toMap(Reviewer::getId, reviewer -> reviewer)); - final List reviewerChanges = new ArrayList<>(); - for (Reviewer newReviewer : newReviewers.values()) { - if (oldReviewers.containsKey(newReviewer.getId())) { - final Reviewer oldReviewer = oldReviewers.get(newReviewer.getId()); - final ReviewerStatus oldStatus = oldReviewer.getStatus(); - final ReviewerStatus newStatus = newReviewer.getStatus(); - if (!oldStatus.equals(newStatus)) { - reviewerChanges.add(ReviewerChange.ofOld(oldReviewer.getUser().getFullName(), oldStatus, newStatus)); - } - } else { - reviewerChanges.add(ReviewerChange.ofNew(newReviewer.getUser().getFullName(), newReviewer.getStatus())); - } - } - final Set oldIds = oldReviewers.keySet(); - oldIds.removeAll(newReviewers.keySet()); - reviewerChanges.addAll( - oldReviewers.entrySet().stream() - .filter(e -> oldIds.contains(e.getKey())) - .map(e -> ReviewerChange.ofDeleted(e.getValue().getUser().getFullName())) - .collect(Collectors.toList()) - ); - return ReviewersPrChange.builder() - .title(newPullRequest.getTitle()) - .url(newPullRequest.getUrl()) - .telegramId(newPullRequest.getAuthor().getTelegramId()) - .reviewerChanges(reviewerChanges) - .build(); - } -} diff --git a/src/main/java/org/sadtech/bot/bitbucketbot/utils/Message.java b/src/main/java/org/sadtech/bot/bitbucketbot/utils/Message.java index 963d0fc..691e86b 100644 --- a/src/main/java/org/sadtech/bot/bitbucketbot/utils/Message.java +++ b/src/main/java/org/sadtech/bot/bitbucketbot/utils/Message.java @@ -184,14 +184,14 @@ public class Message { pullRequestsNeedWork.stream() .limit(3) .forEach( - pullRequest -> message.append("-- ").append(link(pullRequest.getName(), pullRequest.getUrl())).append(Smile.BR) + pullRequest -> message.append("-- ").append(link(pullRequest.getTitle(), pullRequest.getUrl())).append(Smile.BR) ); return message.toString(); } private static String topPr(PullRequest pullRequest) { return Smile.statusPr(pullRequest.getUpdateDate()) + " " + - link(pullRequest.getName(), pullRequest.getUrl()) + + link(pullRequest.getTitle(), pullRequest.getUrl()) + Smile.BR; } diff --git a/src/main/resources/liquibase/change-log.xml b/src/main/resources/liquibase/change-log.xml index e5e157d..7b8a334 100644 --- a/src/main/resources/liquibase/change-log.xml +++ b/src/main/resources/liquibase/change-log.xml @@ -3,6 +3,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> - + \ No newline at end of file diff --git a/src/main/resources/liquibase/v.2.0.0/create-table.xml b/src/main/resources/liquibase/v.2.0.0/2020-09-06-create-table.xml similarity index 87% rename from src/main/resources/liquibase/v.2.0.0/create-table.xml rename to src/main/resources/liquibase/v.2.0.0/2020-09-06-create-table.xml index 3aff0c1..206d0c5 100644 --- a/src/main/resources/liquibase/v.2.0.0/create-table.xml +++ b/src/main/resources/liquibase/v.2.0.0/2020-09-06-create-table.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> - + @@ -18,7 +18,7 @@ - + @@ -60,11 +60,11 @@ - + - + @@ -83,16 +83,16 @@ - + - + - + @@ -110,14 +110,16 @@ - + - - @@ -125,7 +127,7 @@ - + diff --git a/src/main/resources/liquibase/v.2.0.0/cumulative.xml b/src/main/resources/liquibase/v.2.0.0/2020-09-06-cumulative.xml similarity index 81% rename from src/main/resources/liquibase/v.2.0.0/cumulative.xml rename to src/main/resources/liquibase/v.2.0.0/2020-09-06-cumulative.xml index 8f6afbf..5ec625e 100644 --- a/src/main/resources/liquibase/v.2.0.0/cumulative.xml +++ b/src/main/resources/liquibase/v.2.0.0/2020-09-06-cumulative.xml @@ -3,6 +3,6 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> - + \ No newline at end of file