Большой рефакторинг
This commit is contained in:
parent
0d57bee785
commit
a6dce07b3f
@ -0,0 +1,40 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNull;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum AssigneeChanged {
|
||||
|
||||
BECOME(true),
|
||||
DELETED(true),
|
||||
NOT_AFFECT_USER(true),
|
||||
NOT_CHANGED(false);
|
||||
|
||||
private final boolean changed;
|
||||
|
||||
public static AssigneeChanged valueOf(Long gitlabUserId, Person oldAssignee, Person newAssignee) {
|
||||
if (checkNull(oldAssignee) && checkNotNull(newAssignee) && gitlabUserId.equals(newAssignee.getId())) {
|
||||
return AssigneeChanged.BECOME;
|
||||
}
|
||||
if (checkNotNull(oldAssignee) && checkNull(newAssignee) && gitlabUserId.equals(oldAssignee.getId())) {
|
||||
return AssigneeChanged.DELETED;
|
||||
}
|
||||
if (checkNotNull(oldAssignee) && checkNotNull(newAssignee) && !oldAssignee.getId().equals(newAssignee.getId())) {
|
||||
if (gitlabUserId.equals(oldAssignee.getId())) {
|
||||
return AssigneeChanged.DELETED;
|
||||
}
|
||||
if (gitlabUserId.equals(newAssignee.getId())) {
|
||||
return AssigneeChanged.BECOME;
|
||||
}
|
||||
return AssigneeChanged.NOT_AFFECT_USER;
|
||||
}
|
||||
return AssigneeChanged.NOT_CHANGED;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum ReviewerChanged {
|
||||
|
||||
BECOME(true),
|
||||
DELETED(true),
|
||||
NOT_AFFECT_USER(true),
|
||||
NOT_CHANGED(false);
|
||||
|
||||
private final boolean changed;
|
||||
|
||||
public static ReviewerChanged valueOf(Long gitlabUserId, List<Person> oldReviewers, List<Person> newReviewers) {
|
||||
final Map<Long, Person> oldMap = oldReviewers.stream().collect(Collectors.toMap(Person::getId, p -> p));
|
||||
final Map<Long, Person> newMap = newReviewers.stream().collect(Collectors.toMap(Person::getId, p -> p));
|
||||
|
||||
if (!oldMap.keySet().equals(newMap.keySet())) {
|
||||
if (oldMap.containsKey(gitlabUserId) && !newMap.containsKey(gitlabUserId)) {
|
||||
return ReviewerChanged.DELETED;
|
||||
}
|
||||
if (!oldMap.containsKey(gitlabUserId) && newMap.containsKey(gitlabUserId)) {
|
||||
return ReviewerChanged.BECOME;
|
||||
}
|
||||
return ReviewerChanged.NOT_AFFECT_USER;
|
||||
}
|
||||
return ReviewerChanged.NOT_CHANGED;
|
||||
}
|
||||
|
||||
}
|
@ -30,14 +30,14 @@ public class Discussion {
|
||||
@Column(name = "id")
|
||||
private String id;
|
||||
|
||||
@ManyToOne
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
|
||||
@JoinColumn(name = "responsible_id")
|
||||
private Person responsible;
|
||||
|
||||
@Column(name = "resolved")
|
||||
private Boolean resolved;
|
||||
|
||||
@ManyToOne()
|
||||
@ManyToOne
|
||||
@JoinTable(
|
||||
name = "discussion_merge_request",
|
||||
joinColumns = @JoinColumn(name = "discussion_id"),
|
||||
@ -50,7 +50,8 @@ public class Discussion {
|
||||
fetch = FetchType.EAGER,
|
||||
cascade = {
|
||||
CascadeType.PERSIST,
|
||||
CascadeType.MERGE
|
||||
CascadeType.MERGE,
|
||||
CascadeType.REFRESH
|
||||
}
|
||||
)
|
||||
private List<Note> notes;
|
||||
|
@ -73,18 +73,17 @@ public class MergeRequest {
|
||||
@Column(name = "conflict")
|
||||
private boolean conflict;
|
||||
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@JoinColumn(name = "author_id")
|
||||
private Person author;
|
||||
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@JoinColumn(name = "assignee_id")
|
||||
private Person assignee;
|
||||
|
||||
@OneToMany(
|
||||
fetch = FetchType.LAZY,
|
||||
cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE},
|
||||
orphanRemoval = true
|
||||
cascade = {CascadeType.PERSIST, CascadeType.MERGE}
|
||||
)
|
||||
@JoinTable(
|
||||
name = "merge_request_reviewer",
|
||||
|
@ -12,6 +12,9 @@ import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static javax.persistence.CascadeType.MERGE;
|
||||
import static javax.persistence.CascadeType.PERSIST;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@ -20,7 +23,8 @@ import java.time.LocalDateTime;
|
||||
public class Note {
|
||||
|
||||
@Id
|
||||
@Column
|
||||
@Column(name = "id")
|
||||
@EqualsAndHashCode.Include
|
||||
private Long id;
|
||||
|
||||
@Column(name = "type")
|
||||
@ -35,7 +39,7 @@ public class Note {
|
||||
@Column(name = "updated_date")
|
||||
private LocalDateTime updated;
|
||||
|
||||
@ManyToOne
|
||||
@ManyToOne(cascade = {PERSIST, MERGE})
|
||||
@JoinColumn(name = "author_id")
|
||||
private Person author;
|
||||
|
||||
@ -57,7 +61,7 @@ public class Note {
|
||||
@Column(name = "resolved")
|
||||
private Boolean resolved;
|
||||
|
||||
@ManyToOne
|
||||
@ManyToOne(cascade = {PERSIST, MERGE})
|
||||
@JoinColumn(name = "resolved_id")
|
||||
private Person resolvedBy;
|
||||
|
||||
|
@ -18,6 +18,8 @@ public interface DiscussionService {
|
||||
|
||||
Discussion update(@NonNull Discussion discussion);
|
||||
|
||||
List<Discussion> updateAll(@NonNull List<Discussion> discussions);
|
||||
|
||||
/**
|
||||
* Метод отправляющий коментарий в дискуссию.
|
||||
*
|
||||
|
@ -5,13 +5,13 @@ import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.comment.CommentNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.task.TaskCloseNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.task.TaskNewNotify;
|
||||
import dev.struchkov.bot.gitlab.context.repository.DiscussionRepository;
|
||||
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
||||
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
||||
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
||||
import dev.struchkov.bot.gitlab.core.config.properties.PersonProperty;
|
||||
import dev.struchkov.bot.gitlab.core.utils.StringUtils;
|
||||
@ -25,6 +25,7 @@ import okhttp3.RequestBody;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
@ -38,6 +39,7 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||
import static java.lang.Boolean.FALSE;
|
||||
|
||||
/**
|
||||
@ -52,7 +54,6 @@ public class DiscussionServiceImpl implements DiscussionService {
|
||||
|
||||
protected static final Pattern PATTERN = Pattern.compile("@[\\w]+");
|
||||
|
||||
private final PersonService personService;
|
||||
private final DiscussionRepository repository;
|
||||
private final PersonInformation personInformation;
|
||||
|
||||
@ -62,14 +63,18 @@ public class DiscussionServiceImpl implements DiscussionService {
|
||||
private final NotifyService notifyService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Discussion create(@NonNull Discussion discussion) {
|
||||
discussion.getNotes().forEach(note -> personService.create(note.getAuthor()));
|
||||
discussion.getNotes().forEach(this::notificationPersonal);
|
||||
discussion.getNotes().forEach(note -> notifyNewNote(note, discussion));
|
||||
final List<Note> notes = discussion.getNotes();
|
||||
|
||||
notes.forEach(this::notificationPersonal);
|
||||
notes.forEach(note -> notifyNewNote(note, discussion));
|
||||
|
||||
final boolean resolved = discussion.getNotes().stream()
|
||||
.allMatch(note -> note.isResolvable() && note.getResolved());
|
||||
|
||||
discussion.setResolved(resolved);
|
||||
|
||||
return repository.save(discussion);
|
||||
}
|
||||
|
||||
@ -89,10 +94,10 @@ public class DiscussionServiceImpl implements DiscussionService {
|
||||
}
|
||||
|
||||
private boolean isNeedNotifyNewNote(Note note, Discussion discussion) {
|
||||
final Long personId = personInformation.getId();
|
||||
final Long gitlabUserId = personInformation.getId();
|
||||
return note.isResolvable() // Тип комментария требует решения (Задачи)
|
||||
&& personId.equals(discussion.getResponsible().getId()) // Создатель дискуссии пользователь приложения
|
||||
&& !personId.equals(note.getAuthor().getId()) // Создатель комментария не пользователь системы
|
||||
&& gitlabUserId.equals(discussion.getResponsible().getId()) // Создатель дискуссии пользователь приложения
|
||||
&& !gitlabUserId.equals(note.getAuthor().getId()) // Создатель комментария не пользователь системы
|
||||
&& FALSE.equals(note.getResolved()); // Комментарий не отмечен как решенный
|
||||
}
|
||||
|
||||
@ -100,42 +105,70 @@ public class DiscussionServiceImpl implements DiscussionService {
|
||||
public Discussion update(@NonNull Discussion discussion) {
|
||||
final Discussion oldDiscussion = repository.findById(discussion.getId())
|
||||
.orElseThrow(notFoundException("Дискуссия не найдена"));
|
||||
final Map<Long, Note> idAndNoteMap = oldDiscussion
|
||||
.getNotes().stream()
|
||||
.collect(Collectors.toMap(Note::getId, note -> note));
|
||||
|
||||
// Пользователь участвовал в обсуждении
|
||||
final boolean userParticipatedInDiscussion = discussion.getNotes().stream()
|
||||
.anyMatch(note -> personInformation.getId().equals(note.getAuthor().getId()));
|
||||
|
||||
discussion.setMergeRequest(oldDiscussion.getMergeRequest());
|
||||
discussion.setResponsible(oldDiscussion.getResponsible());
|
||||
discussion.getNotes().forEach(note -> updateNote(note, idAndNoteMap, userParticipatedInDiscussion));
|
||||
discussion.setMergeRequest(oldDiscussion.getMergeRequest());
|
||||
|
||||
final Person responsiblePerson = discussion.getResponsible();
|
||||
if (checkNotNull(responsiblePerson)) {
|
||||
for (Note note : discussion.getNotes()) {
|
||||
if (responsiblePerson.getId().equals(note.getAuthor().getId())) {
|
||||
note.setAuthor(responsiblePerson);
|
||||
}
|
||||
final Person resolvedBy = note.getResolvedBy();
|
||||
if (checkNotNull(resolvedBy)) {
|
||||
if (responsiblePerson.getId().equals(resolvedBy.getId())) {
|
||||
note.setResolvedBy(responsiblePerson);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
notifyUpdateNote(oldDiscussion, discussion);
|
||||
|
||||
final boolean resolved = discussion.getNotes().stream()
|
||||
.allMatch(note -> note.isResolvable() && note.getResolved());
|
||||
|
||||
discussion.setResolved(resolved);
|
||||
|
||||
return repository.save(discussion);
|
||||
}
|
||||
|
||||
private void updateNote(Note note, Map<Long, Note> noteMap, boolean inDiscussion) {
|
||||
if (noteMap.containsKey(note.getId())) {
|
||||
final Note oldNote = noteMap.get(note.getId());
|
||||
@Override
|
||||
public List<Discussion> updateAll(@NonNull List<Discussion> discussions) {
|
||||
return discussions.stream()
|
||||
.map(this::update)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
if (note.isResolvable()) {
|
||||
updateTask(note, oldNote);
|
||||
private void notifyUpdateNote(Discussion oldDiscussion, Discussion discussion) {
|
||||
final Map<Long, Note> noteMap = oldDiscussion
|
||||
.getNotes().stream()
|
||||
.collect(Collectors.toMap(Note::getId, n -> n));
|
||||
|
||||
// Пользователь участвовал в обсуждении
|
||||
final boolean userParticipatedInDiscussion = oldDiscussion.getNotes().stream()
|
||||
.anyMatch(note -> personInformation.getId().equals(note.getAuthor().getId()));
|
||||
|
||||
for (Note newNote : discussion.getNotes()) {
|
||||
final Long newNoteId = newNote.getId();
|
||||
if (noteMap.containsKey(newNoteId)) {
|
||||
final Note oldNote = noteMap.get(newNoteId);
|
||||
|
||||
if (newNote.isResolvable()) {
|
||||
updateTask(newNote, oldNote);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (inDiscussion) {
|
||||
notifyNewAnswer(note);
|
||||
if (userParticipatedInDiscussion) {
|
||||
notifyNewAnswer(newNote);
|
||||
} else {
|
||||
notificationPersonal(note);
|
||||
notificationPersonal(newNote);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void notifyNewAnswer(Note note) {
|
||||
if (!personInformation.getId().equals(note.getAuthor().getId())) {
|
||||
notifyService.send(
|
||||
|
@ -1,9 +1,11 @@
|
||||
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.AssigneeChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||
import dev.struchkov.bot.gitlab.context.domain.IdAndStatusPr;
|
||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||
import dev.struchkov.bot.gitlab.context.domain.ReviewerChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
@ -117,6 +119,13 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
|
||||
if (isUserInReviewers) {
|
||||
final String projectName = projectService.getByIdOrThrow(savedMergeRequest.getProjectId()).getName();
|
||||
if (!savedMergeRequest.isConflict()) {
|
||||
sendNotifyAboutNewMr(savedMergeRequest, projectName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendNotifyAboutNewMr(MergeRequest savedMergeRequest, String projectName) {
|
||||
notifyService.send(
|
||||
NewPrNotify.builder()
|
||||
.projectName(projectName)
|
||||
@ -130,11 +139,9 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public MergeRequest update(@NonNull MergeRequest mergeRequest) {
|
||||
final MergeRequest oldMergeRequest = repository.findById(mergeRequest.getId())
|
||||
.orElseThrow(notFoundException("MergeRequest не найден"));
|
||||
@ -144,24 +151,53 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
|
||||
mergeRequest.setNotification(oldMergeRequest.getNotification());
|
||||
}
|
||||
|
||||
if (
|
||||
final Long gitlabUserId = personInformation.getId();
|
||||
final AssigneeChanged assigneeChanged = AssigneeChanged.valueOf(gitlabUserId, oldMergeRequest.getAssignee(), mergeRequest.getAssignee());
|
||||
final ReviewerChanged reviewerChanged = ReviewerChanged.valueOf(gitlabUserId, oldMergeRequest.getReviewers(), mergeRequest.getReviewers());
|
||||
|
||||
final boolean isChangedMr =
|
||||
!oldMergeRequest.getUpdatedDate().equals(mergeRequest.getUpdatedDate())
|
||||
|| oldMergeRequest.isConflict() != mergeRequest.isConflict()
|
||||
) {
|
||||
|| oldMergeRequest.isConflict() != mergeRequest.isConflict();
|
||||
final boolean isChangedLinkedEntity = reviewerChanged.isChanged() || assigneeChanged.isChanged();
|
||||
|
||||
if (isChangedMr || isChangedLinkedEntity) {
|
||||
final Project project = projectService.getByIdOrThrow(mergeRequest.getProjectId());
|
||||
|
||||
if (TRUE.equals(oldMergeRequest.getNotification())) {
|
||||
if (TRUE.equals(notification) && isChangedMr) {
|
||||
notifyAboutStatus(oldMergeRequest, mergeRequest, project);
|
||||
notifyAboutConflict(oldMergeRequest, mergeRequest, project);
|
||||
notifyUpdate(oldMergeRequest, mergeRequest, project);
|
||||
notifyAboutUpdate(oldMergeRequest, mergeRequest, project);
|
||||
}
|
||||
|
||||
if (TRUE.equals(notification) && isChangedLinkedEntity) {
|
||||
notifyReviewer(reviewerChanged, mergeRequest, project);
|
||||
notifyAssignee(assigneeChanged, mergeRequest, project);
|
||||
}
|
||||
|
||||
return repository.save(mergeRequest);
|
||||
}
|
||||
|
||||
return oldMergeRequest;
|
||||
}
|
||||
|
||||
|
||||
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление
|
||||
private void notifyAssignee(AssigneeChanged assigneeChanged, MergeRequest mergeRequest, Project project) {
|
||||
switch (assigneeChanged) {
|
||||
case BECOME -> sendNotifyAboutNewMr(mergeRequest, project.getName());
|
||||
}
|
||||
}
|
||||
|
||||
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление ревьювера
|
||||
//TODO [05.12.2022|uPagge]: Заменить тип уведомления на самостоятельный
|
||||
private void notifyReviewer(ReviewerChanged reviewerChanged, MergeRequest mergeRequest, Project project) {
|
||||
switch (reviewerChanged) {
|
||||
case BECOME -> sendNotifyAboutNewMr(mergeRequest, project.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public List<MergeRequest> updateAll(@NonNull List<MergeRequest> mergeRequests) {
|
||||
return mergeRequests.stream()
|
||||
.map(this::update)
|
||||
@ -214,11 +250,13 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
|
||||
return repository.findAllByReviewerId(personId);
|
||||
}
|
||||
|
||||
private void notifyUpdate(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||
private void notifyAboutUpdate(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||
final Long gitlabUserId = personInformation.getId();
|
||||
|
||||
if (
|
||||
!personInformation.getId().equals(mergeRequest.getAuthor().getId())
|
||||
&& !oldMergeRequest.getDateLastCommit().equals(mergeRequest.getDateLastCommit())
|
||||
&& !mergeRequest.isConflict()
|
||||
!gitlabUserId.equals(mergeRequest.getAuthor().getId()) // Автор MR не пользователь приложения
|
||||
&& !oldMergeRequest.getDateLastCommit().equals(mergeRequest.getDateLastCommit()) // Изменилась дата последнего коммита
|
||||
&& !mergeRequest.isConflict() // MR не находится в состоянии конфликта
|
||||
) {
|
||||
final List<Discussion> discussions = discussionService.getAllByMergeRequestId(oldMergeRequest.getId())
|
||||
.stream()
|
||||
@ -229,10 +267,10 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
|
||||
.filter(Discussion::getResolved)
|
||||
.count();
|
||||
final long allYouTasks = discussions.stream()
|
||||
.filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId()))
|
||||
.filter(discussion -> gitlabUserId.equals(discussion.getFirstNote().getAuthor().getId()))
|
||||
.count();
|
||||
final long resolvedYouTask = discussions.stream()
|
||||
.filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId()) && discussion.getResolved())
|
||||
.filter(discussion -> gitlabUserId.equals(discussion.getFirstNote().getAuthor().getId()) && discussion.getResolved())
|
||||
.count();
|
||||
notifyService.send(
|
||||
UpdatePrNotify.builder()
|
||||
@ -250,10 +288,11 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
|
||||
}
|
||||
|
||||
protected void notifyAboutConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||
final Long gitlabUserId = personInformation.getId();
|
||||
if (
|
||||
!oldMergeRequest.isConflict()
|
||||
&& mergeRequest.isConflict()
|
||||
&& personInformation.getId().equals(oldMergeRequest.getAuthor().getId())
|
||||
!oldMergeRequest.isConflict() // У старого MR не было конфликта
|
||||
&& mergeRequest.isConflict() // А у нового есть
|
||||
&& gitlabUserId.equals(oldMergeRequest.getAuthor().getId()) // и MR создан пользователем бота
|
||||
) {
|
||||
notifyService.send(
|
||||
ConflictPrNotify.builder()
|
||||
@ -269,9 +308,10 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
|
||||
protected void notifyAboutStatus(MergeRequest oldMergeRequest, MergeRequest newMergeRequest, Project project) {
|
||||
final MergeRequestState oldStatus = oldMergeRequest.getState();
|
||||
final MergeRequestState newStatus = newMergeRequest.getState();
|
||||
final Long gitlabUserId = personInformation.getId();
|
||||
if (
|
||||
!oldStatus.equals(newStatus)
|
||||
&& oldMergeRequest.getAuthor().getId().equals(personInformation.getId())
|
||||
!oldStatus.equals(newStatus) // статус изменился
|
||||
&& gitlabUserId.equals(oldMergeRequest.getAuthor().getId()) // создатель MR является пользователем бота
|
||||
) {
|
||||
notifyService.send(
|
||||
StatusPrNotify.builder()
|
||||
|
@ -4,6 +4,7 @@ import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
||||
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
||||
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
||||
@ -17,13 +18,20 @@ import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.core.utils.StringUtils.H_PRIVATE_TOKEN;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNull;
|
||||
import static dev.struchkov.haiti.utils.network.HttpParse.ACCEPT;
|
||||
|
||||
/**
|
||||
@ -52,8 +60,12 @@ public class DiscussionParser {
|
||||
Page<MergeRequest> mergeRequestSheet = mergeRequestsService.getAll(PageRequest.of(page, COUNT));
|
||||
|
||||
while (mergeRequestSheet.hasContent()) {
|
||||
mergeRequestSheet.getContent()
|
||||
.forEach(this::processingMergeRequest);
|
||||
final List<MergeRequest> mergeRequests = mergeRequestSheet.getContent();
|
||||
|
||||
for (MergeRequest mergeRequest : mergeRequests) {
|
||||
processingMergeRequest(mergeRequest);
|
||||
}
|
||||
|
||||
mergeRequestSheet = mergeRequestsService.getAll(PageRequest.of(++page, COUNT));
|
||||
}
|
||||
}
|
||||
@ -86,10 +98,53 @@ public class DiscussionParser {
|
||||
discussion.getNotes().forEach(createNoteLink(mergeRequest));
|
||||
return discussion;
|
||||
})
|
||||
.filter(discussion -> discussion.getNotes() != null && !discussion.getNotes().isEmpty())
|
||||
// Фильтрация специально стоит после map(). Таким образом отбрасываются системные уведомления
|
||||
.filter(discussion -> checkNotEmpty(discussion.getNotes()))
|
||||
.toList();
|
||||
|
||||
if (checkNotEmpty(newDiscussions)) {
|
||||
personMapping(newDiscussions);
|
||||
discussionService.createAll(newDiscussions);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void personMapping(List<Discussion> newDiscussions) {
|
||||
final Stream<Person> firstStream = Stream.concat(
|
||||
newDiscussions.stream()
|
||||
.flatMap(discussion -> discussion.getNotes().stream())
|
||||
.map(Note::getResolvedBy)
|
||||
.filter(Objects::nonNull),
|
||||
newDiscussions.stream()
|
||||
.flatMap(discussion -> discussion.getNotes().stream())
|
||||
.map(Note::getAuthor)
|
||||
.filter(Objects::nonNull)
|
||||
);
|
||||
|
||||
final Map<Long, Person> personMap = Stream.concat(
|
||||
firstStream,
|
||||
newDiscussions.stream()
|
||||
.map(Discussion::getResponsible)
|
||||
.filter(Objects::nonNull)
|
||||
).distinct()
|
||||
.collect(Collectors.toMap(Person::getId, p -> p));
|
||||
|
||||
for (Discussion newDiscussion : newDiscussions) {
|
||||
final Person responsible = newDiscussion.getResponsible();
|
||||
if (checkNotNull(responsible)) {
|
||||
newDiscussion.setResponsible(personMap.get(responsible.getId()));
|
||||
}
|
||||
|
||||
for (Note note : newDiscussion.getNotes()) {
|
||||
note.setAuthor(personMap.get(note.getAuthor().getId()));
|
||||
|
||||
final Person resolvedBy = note.getResolvedBy();
|
||||
if (checkNotNull(resolvedBy)) {
|
||||
note.setResolvedBy(personMap.get(resolvedBy.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,31 +152,45 @@ public class DiscussionParser {
|
||||
*/
|
||||
public void scanOldDiscussions() {
|
||||
int page = 0;
|
||||
Page<Discussion> discussionSheet = discussionService.getAll(PageRequest.of(page, COUNT));
|
||||
Page<Discussion> discussionPage = discussionService.getAll(PageRequest.of(page, COUNT));
|
||||
|
||||
while (discussionSheet.hasContent()) {
|
||||
final List<Discussion> discussions = discussionSheet.getContent();
|
||||
while (discussionPage.hasContent()) {
|
||||
final List<Discussion> discussions = discussionPage.getContent();
|
||||
|
||||
// Удаляем обсуждения, которые потеряли свои MR
|
||||
//TODO [05.12.2022|uPagge]: Проверить целесообразность этого действия
|
||||
discussions.stream()
|
||||
.filter(discussion -> checkNull(discussion.getMergeRequest()))
|
||||
.map(Discussion::getId)
|
||||
.forEach(discussionService::deleteById);
|
||||
|
||||
final List<Discussion> newDiscussions = new ArrayList<>();
|
||||
for (Discussion discussion : discussions) {
|
||||
if (discussion.getMergeRequest() != null) {
|
||||
final Optional<Discussion> optNewDiscussion = HttpParse.request(createLinkOldDiscussion(discussion))
|
||||
.header(ACCEPT)
|
||||
.header(H_PRIVATE_TOKEN, personProperty.getToken())
|
||||
.execute(DiscussionJson.class)
|
||||
if (checkNotNull(discussion.getMergeRequest())) {
|
||||
getOldDiscussionJson(discussion)
|
||||
.map(json -> {
|
||||
final Discussion newDiscussion = conversionService.convert(json, Discussion.class);
|
||||
newDiscussion.getNotes().forEach(createNoteLink(discussion.getMergeRequest()));
|
||||
return newDiscussion;
|
||||
});
|
||||
optNewDiscussion.ifPresent(discussionService::update);
|
||||
} else {
|
||||
discussionService.deleteById(discussion.getId());
|
||||
}).ifPresent(newDiscussions::add);
|
||||
}
|
||||
}
|
||||
|
||||
discussionSheet = discussionService.getAll(PageRequest.of(++page, COUNT));
|
||||
if (checkNotEmpty(newDiscussions)) {
|
||||
personMapping(newDiscussions);
|
||||
discussionService.updateAll(newDiscussions);
|
||||
}
|
||||
|
||||
discussionPage = discussionService.getAll(PageRequest.of(++page, COUNT));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Optional<DiscussionJson> getOldDiscussionJson(Discussion discussion) {
|
||||
return HttpParse.request(createLinkOldDiscussion(discussion))
|
||||
.header(ACCEPT)
|
||||
.header(H_PRIVATE_TOKEN, personProperty.getToken())
|
||||
.execute(DiscussionJson.class);
|
||||
}
|
||||
|
||||
private String createLinkOldDiscussion(Discussion discussion) {
|
||||
@ -142,7 +211,11 @@ public class DiscussionParser {
|
||||
|
||||
private Consumer<Note> createNoteLink(MergeRequest mergeRequest) {
|
||||
return note -> {
|
||||
final String url = MessageFormat.format(gitlabProperty.getUrlNote(), mergeRequest.getWebUrl(), note.getId());
|
||||
final String url = MessageFormat.format(
|
||||
gitlabProperty.getUrlNote(),
|
||||
mergeRequest.getWebUrl(),
|
||||
note.getId()
|
||||
);
|
||||
note.setWebUrl(url);
|
||||
};
|
||||
}
|
||||
|
@ -21,8 +21,8 @@
|
||||
<artifactId>bot-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jpa</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.liquibase</groupId>
|
||||
|
@ -5,6 +5,7 @@ import dev.struchkov.bot.gitlab.context.repository.DiscussionRepository;
|
||||
import dev.struchkov.bot.gitlab.data.jpa.DiscussionJpaRepository;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@ -16,6 +17,7 @@ import java.util.Set;
|
||||
/**
|
||||
* @author upagge 11.02.2021
|
||||
*/
|
||||
@Slf4j
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class DiscussionRepositoryImpl implements DiscussionRepository {
|
||||
|
@ -7,7 +7,7 @@ spring:
|
||||
liquibase:
|
||||
change-log: classpath:liquibase/changelog.xml
|
||||
jpa:
|
||||
show-sql: false
|
||||
show-sql: true
|
||||
hibernate:
|
||||
ddl-auto: none
|
||||
database-platform: org.hibernate.dialect.PostgreSQLDialect
|
||||
|
Loading…
Reference in New Issue
Block a user