diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/MergeRequest.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/MergeRequest.java index 92038d9..8ec97e5 100644 --- a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/MergeRequest.java +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/MergeRequest.java @@ -2,22 +2,29 @@ package dev.struchkov.bot.gitlab.context.domain.entity; import dev.struchkov.bot.gitlab.context.domain.MergeRequestState; import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames; +import dev.struchkov.haiti.utils.fieldconstants.domain.Mode; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; +import javax.persistence.CascadeType; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; import javax.persistence.Table; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -28,7 +35,7 @@ import java.util.Set; @Getter @Setter @Entity -@FieldNames +@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE}) @Table(name = "merge_request") @EqualsAndHashCode(onlyExplicitlyIncluded = true) public class MergeRequest { @@ -66,14 +73,26 @@ public class MergeRequest { @Column(name = "conflict") private boolean conflict; - @ManyToOne + @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}) @JoinColumn(name = "author_id") private Person author; - @ManyToOne + @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}) @JoinColumn(name = "assignee_id") private Person assignee; + @OneToMany( + fetch = FetchType.LAZY, + cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}, + orphanRemoval = true + ) + @JoinTable( + name = "merge_request_reviewer", + joinColumns = @JoinColumn(name = "merge_request_id", referencedColumnName = "id"), + inverseJoinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id") + ) + private List reviewers = new ArrayList<>(); + @Column(name = "target_branch") private String targetBranch; diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/Person.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/Person.java index 21ba442..6f5878b 100644 --- a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/Person.java +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/entity/Person.java @@ -1,5 +1,8 @@ package dev.struchkov.bot.gitlab.context.domain.entity; +import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames; +import dev.struchkov.haiti.utils.fieldconstants.domain.Mode; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -14,10 +17,13 @@ import javax.persistence.Table; @Entity @Getter @Setter +@EqualsAndHashCode(onlyExplicitlyIncluded = true) @Table(name = "person") +@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE}) public class Person { @Id + @EqualsAndHashCode.Include @Column(name = "id") private Long id; diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/pullrequest/NewPrNotify.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/pullrequest/NewPrNotify.java index 5fbd1b2..2c14d94 100644 --- a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/pullrequest/NewPrNotify.java +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/domain/notify/pullrequest/NewPrNotify.java @@ -48,7 +48,7 @@ public class NewPrNotify extends PrNotify { labelText = "\n\n" + labelText; } return MessageFormat.format( - "{0} *New MergeRequest | {1}*{2}[{3}]({4}){5}{2}{9}: {10} {12} {11}", + "{0} *New merge request for review | {1}*{2}[{3}]({4}){5}{2}{9}: {10} {12} {11}\n{7}: {8}", Smile.FUN.getValue(), projectName, Smile.HR.getValue(), diff --git a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/service/MergeRequestsService.java b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/service/MergeRequestsService.java index 91172bc..d7a22e2 100644 --- a/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/service/MergeRequestsService.java +++ b/bot-context/src/main/java/dev/struchkov/bot/gitlab/context/service/MergeRequestsService.java @@ -18,6 +18,8 @@ public interface MergeRequestsService { MergeRequest update(@NonNull MergeRequest mergeRequest); + List updateAll(@NonNull List mergeRequests); + /** * Получить все идентификаторы вместе со статусами. * diff --git a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/convert/MergeRequestJsonConverter.java b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/convert/MergeRequestJsonConverter.java index 820ffdb..243b531 100644 --- a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/convert/MergeRequestJsonConverter.java +++ b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/convert/MergeRequestJsonConverter.java @@ -2,16 +2,20 @@ package dev.struchkov.bot.gitlab.core.service.convert; import dev.struchkov.bot.gitlab.context.domain.MergeRequestState; import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest; +import dev.struchkov.bot.gitlab.context.domain.entity.Person; import dev.struchkov.bot.gitlab.sdk.domain.MergeRequestJson; import dev.struchkov.bot.gitlab.sdk.domain.MergeRequestStateJson; +import dev.struchkov.bot.gitlab.sdk.domain.PersonJson; import lombok.RequiredArgsConstructor; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; import static dev.struchkov.haiti.utils.Checker.checkNotEmpty; +import static dev.struchkov.haiti.utils.Checker.checkNotNull; /** * @author upagge 15.01.2021 @@ -35,23 +39,36 @@ public class MergeRequestJsonConverter implements Converter convertLabels(Set source) { - if (checkNotEmpty(source)) { - return source.stream() - .map(label -> label.replaceAll("-", "_")) - .collect(Collectors.toSet()); + private void convertReviewers(MergeRequest mergeRequest, List jsonReviewers) { + if (checkNotEmpty(jsonReviewers)) { + final List reviewers = jsonReviewers.stream() + .map(convertPerson::convert) + .toList(); + mergeRequest.setReviewers(reviewers); + } + } + + private static void convertLabels(MergeRequest mergeRequest, Set source) { + if (checkNotEmpty(source)) { + final Set labels = source.stream() + .map(label -> label.replace("-", "_")) + .collect(Collectors.toSet()); + mergeRequest.setLabels(labels); } - return null; } private MergeRequestState convertState(MergeRequestStateJson state) { diff --git a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/convert/ProjectJsonConverter.java b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/convert/ProjectJsonConverter.java index 585968b..c2db30b 100644 --- a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/convert/ProjectJsonConverter.java +++ b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/convert/ProjectJsonConverter.java @@ -2,6 +2,7 @@ package dev.struchkov.bot.gitlab.core.service.convert; import dev.struchkov.bot.gitlab.context.domain.entity.Project; import dev.struchkov.bot.gitlab.sdk.domain.ProjectJson; +import lombok.RequiredArgsConstructor; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; @@ -9,6 +10,7 @@ import org.springframework.stereotype.Component; * @author upagge 14.01.2021 */ @Component +@RequiredArgsConstructor public class ProjectJsonConverter implements Converter { @Override diff --git a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/MergeRequestsServiceImpl.java b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/MergeRequestsServiceImpl.java index a3c0f6b..eeb8051 100644 --- a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/MergeRequestsServiceImpl.java +++ b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/MergeRequestsServiceImpl.java @@ -6,6 +6,7 @@ import dev.struchkov.bot.gitlab.context.domain.MergeRequestState; 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.Person; import dev.struchkov.bot.gitlab.context.domain.entity.Project; import dev.struchkov.bot.gitlab.context.domain.filter.MergeRequestFilter; import dev.struchkov.bot.gitlab.context.domain.notify.pullrequest.ConflictPrNotify; @@ -16,7 +17,6 @@ import dev.struchkov.bot.gitlab.context.repository.MergeRequestRepository; import dev.struchkov.bot.gitlab.context.service.DiscussionService; import dev.struchkov.bot.gitlab.context.service.MergeRequestsService; import dev.struchkov.bot.gitlab.context.service.NotifyService; -import dev.struchkov.bot.gitlab.context.service.PersonService; import dev.struchkov.bot.gitlab.context.service.ProjectService; import dev.struchkov.bot.gitlab.core.service.impl.filter.MergeRequestFilterService; import lombok.NonNull; @@ -24,6 +24,7 @@ import lombok.RequiredArgsConstructor; 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.util.List; import java.util.Objects; @@ -31,6 +32,9 @@ import java.util.Set; import java.util.stream.Collectors; import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException; +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 java.lang.Boolean.TRUE; @Service @@ -39,7 +43,6 @@ public class MergeRequestsServiceImpl implements MergeRequestsService { private final NotifyService notifyService; private final MergeRequestRepository repository; - private final PersonService personService; private final MergeRequestFilterService filterService; private final ProjectService projectService; private final DiscussionService discussionService; @@ -47,63 +50,109 @@ public class MergeRequestsServiceImpl implements MergeRequestsService { private final PersonInformation personInformation; @Override + @Transactional public MergeRequest create(@NonNull MergeRequest mergeRequest) { - if (mergeRequest.getAssignee() != null) { - personService.create(mergeRequest.getAssignee()); - } - personService.create(mergeRequest.getAuthor()); - mergeRequest.setNotification(true); final MergeRequest newMergeRequest = repository.save(mergeRequest); - notifyNewPr(newMergeRequest); + notifyNewMergeRequest(newMergeRequest); return newMergeRequest; } - private void notifyNewPr(MergeRequest newMergeRequest) { - if (!personInformation.getId().equals(newMergeRequest.getAuthor().getId())) { + /** + * Уведомление о новом MergeRequest. + * + * @param savedMergeRequest сохраненный в базу новый MergeRequest. + */ + private void notifyNewMergeRequest(MergeRequest savedMergeRequest) { + notifyUserAboutNewPullRequestIfHeIsReviewer(savedMergeRequest); + notifyUserAboutNewPullRequestIfHeIsAssignee(savedMergeRequest); + } - final String projectName = projectService.getByIdOrThrow(newMergeRequest.getProjectId()).getName(); - if (!newMergeRequest.isConflict()) { - notifyService.send( - NewPrNotify.builder() - .projectName(projectName) - .labels(newMergeRequest.getLabels()) - .author(newMergeRequest.getAuthor().getName()) - .description(newMergeRequest.getDescription()) - .title(newMergeRequest.getTitle()) - .url(newMergeRequest.getWebUrl()) - .targetBranch(newMergeRequest.getTargetBranch()) - .sourceBranch(newMergeRequest.getSourceBranch()) - .build() - ); + private void notifyUserAboutNewPullRequestIfHeIsAssignee(MergeRequest savedMergeRequest) { + final Long gitlabUserId = personInformation.getId(); + final Person assignee = savedMergeRequest.getAssignee(); + final Person author = savedMergeRequest.getAuthor(); + + if (checkNotNull(assignee)) { + if (gitlabUserId.equals(assignee.getId()) && !isAuthorSameAssignee(author, assignee)) { + final String projectName = projectService.getByIdOrThrow(savedMergeRequest.getProjectId()).getName(); + if (!savedMergeRequest.isConflict()) { + //TODO [05.12.2022|uPagge]: Заменить уведомление. Нужно создать новое уведомление, если пользователя назначали ответственным + notifyService.send( + NewPrNotify.builder() + .projectName(projectName) + .labels(savedMergeRequest.getLabels()) + .author(author.getName()) + .description(savedMergeRequest.getDescription()) + .title(savedMergeRequest.getTitle()) + .url(savedMergeRequest.getWebUrl()) + .targetBranch(savedMergeRequest.getTargetBranch()) + .sourceBranch(savedMergeRequest.getSourceBranch()) + .build() + ); + } } + } + } + /** + * Создатель MR является ответственным за этот MR + * + * @return true, если автор и ответственный один и тот же человек. + */ + private boolean isAuthorSameAssignee(Person author, Person assignee) { + return author.getId().equals(assignee.getId()); + } + + private void notifyUserAboutNewPullRequestIfHeIsReviewer(MergeRequest savedMergeRequest) { + final List reviewers = savedMergeRequest.getReviewers(); + final Long gitlabUserId = personInformation.getId(); + + if (checkNotEmpty(reviewers)) { + final boolean isUserInReviewers = reviewers.stream() + .anyMatch(reviewer -> gitlabUserId.equals(reviewer.getId())); + if (isUserInReviewers) { + final String projectName = projectService.getByIdOrThrow(savedMergeRequest.getProjectId()).getName(); + if (!savedMergeRequest.isConflict()) { + notifyService.send( + NewPrNotify.builder() + .projectName(projectName) + .labels(savedMergeRequest.getLabels()) + .author(savedMergeRequest.getAuthor().getName()) + .description(savedMergeRequest.getDescription()) + .title(savedMergeRequest.getTitle()) + .url(savedMergeRequest.getWebUrl()) + .targetBranch(savedMergeRequest.getTargetBranch()) + .sourceBranch(savedMergeRequest.getSourceBranch()) + .build() + ); + } + } } } @Override public MergeRequest update(@NonNull MergeRequest mergeRequest) { - if (mergeRequest.getAssignee() != null) { - personService.create(mergeRequest.getAssignee()); - } - personService.create(mergeRequest.getAuthor()); - final MergeRequest oldMergeRequest = repository.findById(mergeRequest.getId()) - .orElseThrow(notFoundException("МержРеквест не найден")); + .orElseThrow(notFoundException("MergeRequest не найден")); - if (mergeRequest.getNotification() == null) { + final Boolean notification = mergeRequest.getNotification(); + if (checkNull(notification)) { mergeRequest.setNotification(oldMergeRequest.getNotification()); } - if (!oldMergeRequest.getUpdatedDate().equals(mergeRequest.getUpdatedDate()) || oldMergeRequest.isConflict() != mergeRequest.isConflict()) { + if ( + !oldMergeRequest.getUpdatedDate().equals(mergeRequest.getUpdatedDate()) + || oldMergeRequest.isConflict() != mergeRequest.isConflict() + ) { final Project project = projectService.getByIdOrThrow(mergeRequest.getProjectId()); if (TRUE.equals(oldMergeRequest.getNotification())) { - notifyStatus(oldMergeRequest, mergeRequest, project); - notifyConflict(oldMergeRequest, mergeRequest, project); + notifyAboutStatus(oldMergeRequest, mergeRequest, project); + notifyAboutConflict(oldMergeRequest, mergeRequest, project); notifyUpdate(oldMergeRequest, mergeRequest, project); } @@ -112,76 +161,11 @@ public class MergeRequestsServiceImpl implements MergeRequestsService { return oldMergeRequest; } - private void notifyUpdate(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) { - if ( - !personInformation.getId().equals(mergeRequest.getAuthor().getId()) - && !oldMergeRequest.getDateLastCommit().equals(mergeRequest.getDateLastCommit()) - && !mergeRequest.isConflict() - ) { - final List discussions = discussionService.getAllByMergeRequestId(oldMergeRequest.getId()) - .stream() - .filter(discussion -> Objects.nonNull(discussion.getResponsible())) - .toList(); - final long allTask = discussions.size(); - final long resolvedTask = discussions.stream() - .filter(Discussion::getResolved) - .count(); - final long allYouTasks = discussions.stream() - .filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId())) - .count(); - final long resolvedYouTask = discussions.stream() - .filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId()) && discussion.getResolved()) - .count(); - notifyService.send( - UpdatePrNotify.builder() - .author(oldMergeRequest.getAuthor().getName()) - .name(oldMergeRequest.getTitle()) - .projectKey(project.getName()) - .url(oldMergeRequest.getWebUrl()) - .allTasks(allTask) - .allResolvedTasks(resolvedTask) - .personTasks(allYouTasks) - .personResolvedTasks(resolvedYouTask) - .build() - ); - } - } - - protected void notifyConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) { - if ( - !oldMergeRequest.isConflict() - && mergeRequest.isConflict() - && personInformation.getId().equals(oldMergeRequest.getAuthor().getId()) - ) { - notifyService.send( - ConflictPrNotify.builder() - .sourceBranch(oldMergeRequest.getSourceBranch()) - .name(mergeRequest.getTitle()) - .url(mergeRequest.getWebUrl()) - .projectKey(project.getName()) - .build() - ); - } - } - - protected void notifyStatus(MergeRequest oldMergeRequest, MergeRequest newMergeRequest, Project project) { - final MergeRequestState oldStatus = oldMergeRequest.getState(); - final MergeRequestState newStatus = newMergeRequest.getState(); - if ( - !oldStatus.equals(newStatus) - && oldMergeRequest.getAuthor().getId().equals(personInformation.getId()) - ) { - - notifyService.send( - StatusPrNotify.builder() - .name(newMergeRequest.getTitle()) - .url(oldMergeRequest.getWebUrl()) - .projectName(project.getName()) - .newStatus(newStatus) - .oldStatus(oldStatus) - .build() - ); - } + @Override + public List updateAll(@NonNull List mergeRequests) { + return mergeRequests.stream() + .map(this::update) + .collect(Collectors.toList()); } @Override @@ -225,4 +209,75 @@ public class MergeRequestsServiceImpl implements MergeRequestsService { repository.deleteByIds(mergeRequestIds); } + private void notifyUpdate(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) { + if ( + !personInformation.getId().equals(mergeRequest.getAuthor().getId()) + && !oldMergeRequest.getDateLastCommit().equals(mergeRequest.getDateLastCommit()) + && !mergeRequest.isConflict() + ) { + final List discussions = discussionService.getAllByMergeRequestId(oldMergeRequest.getId()) + .stream() + .filter(discussion -> Objects.nonNull(discussion.getResponsible())) + .toList(); + final long allTask = discussions.size(); + final long resolvedTask = discussions.stream() + .filter(Discussion::getResolved) + .count(); + final long allYouTasks = discussions.stream() + .filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId())) + .count(); + final long resolvedYouTask = discussions.stream() + .filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId()) && discussion.getResolved()) + .count(); + notifyService.send( + UpdatePrNotify.builder() + .author(oldMergeRequest.getAuthor().getName()) + .name(oldMergeRequest.getTitle()) + .projectKey(project.getName()) + .url(oldMergeRequest.getWebUrl()) + .allTasks(allTask) + .allResolvedTasks(resolvedTask) + .personTasks(allYouTasks) + .personResolvedTasks(resolvedYouTask) + .build() + ); + } + } + + protected void notifyAboutConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) { + if ( + !oldMergeRequest.isConflict() + && mergeRequest.isConflict() + && personInformation.getId().equals(oldMergeRequest.getAuthor().getId()) + ) { + notifyService.send( + ConflictPrNotify.builder() + .sourceBranch(oldMergeRequest.getSourceBranch()) + .name(mergeRequest.getTitle()) + .url(mergeRequest.getWebUrl()) + .projectKey(project.getName()) + .build() + ); + } + } + + protected void notifyAboutStatus(MergeRequest oldMergeRequest, MergeRequest newMergeRequest, Project project) { + final MergeRequestState oldStatus = oldMergeRequest.getState(); + final MergeRequestState newStatus = newMergeRequest.getState(); + if ( + !oldStatus.equals(newStatus) + && oldMergeRequest.getAuthor().getId().equals(personInformation.getId()) + ) { + notifyService.send( + StatusPrNotify.builder() + .name(newMergeRequest.getTitle()) + .url(oldMergeRequest.getWebUrl()) + .projectName(project.getName()) + .newStatus(newStatus) + .oldStatus(oldStatus) + .build() + ); + } + } + } diff --git a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/ProjectServiceImpl.java b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/ProjectServiceImpl.java index 6633af1..cedd686 100644 --- a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/ProjectServiceImpl.java +++ b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/impl/ProjectServiceImpl.java @@ -13,6 +13,7 @@ import lombok.RequiredArgsConstructor; 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.util.List; import java.util.Set; @@ -34,12 +35,15 @@ public class ProjectServiceImpl implements ProjectService { private final PersonInformation personInformation; @Override + @Transactional public Project create(@NonNull Project project) { final Project newProject = repository.save(project); - if (!personInformation.getId().equals(newProject.getCreatorId())) { + final Long gitlabUserId = personInformation.getId(); + + if (!gitlabUserId.equals(newProject.getCreatorId())) { final String authorName = personService.getByIdOrThrown(newProject.getCreatorId()).getName(); - sendNotifyNewProject(newProject, authorName); + notifyAboutNewProject(newProject, authorName); } return newProject; @@ -87,7 +91,7 @@ public class ProjectServiceImpl implements ProjectService { } } - private void sendNotifyNewProject(Project newProject, String authorName) { + private void notifyAboutNewProject(Project newProject, String authorName) { notifyService.send( NewProjectNotify.builder() .projectDescription(newProject.getDescription()) diff --git a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/parser/MergeRequestParser.java b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/parser/MergeRequestParser.java index fef4cca..31a9aa4 100644 --- a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/parser/MergeRequestParser.java +++ b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/parser/MergeRequestParser.java @@ -4,6 +4,7 @@ import dev.struchkov.bot.gitlab.context.domain.ExistsContainer; import dev.struchkov.bot.gitlab.context.domain.IdAndStatusPr; import dev.struchkov.bot.gitlab.context.domain.MergeRequestState; import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest; +import dev.struchkov.bot.gitlab.context.domain.entity.Person; import dev.struchkov.bot.gitlab.context.domain.entity.Project; import dev.struchkov.bot.gitlab.context.service.MergeRequestsService; import dev.struchkov.bot.gitlab.context.service.ProjectService; @@ -22,10 +23,15 @@ import org.springframework.stereotype.Service; import java.text.MessageFormat; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; +import static dev.struchkov.haiti.utils.Checker.checkNotEmpty; +import static dev.struchkov.haiti.utils.Checker.checkNotNull; import static dev.struchkov.haiti.utils.network.HttpParse.ACCEPT; @Slf4j @@ -47,19 +53,20 @@ public class MergeRequestParser { public void parsingOldMergeRequest() { final Set existIds = mergeRequestsService.getAllId(OLD_STATUSES); - for (IdAndStatusPr existId : existIds) { - final String mrUrl = MessageFormat.format(gitlabProperty.getUrlPullRequest(), existId.getProjectId(), existId.getTwoId()); - final Optional json = HttpParse.request(mrUrl) - .header(ACCEPT) - .header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken()) - .execute(MergeRequestJson.class); - final Optional mergeRequest = json - .map(mergeRequestJson -> { - final MergeRequest newMergeRequest = conversionService.convert(mergeRequestJson, MergeRequest.class); - parsingCommits(newMergeRequest); - return newMergeRequest; - }); - mergeRequest.ifPresent(mergeRequestsService::update); + final List mergeRequests = existIds.stream() + .map(this::getMergeRequest) + .filter(Optional::isPresent) + .map(Optional::get) + .map(mergeRequestJson -> { + final MergeRequest newMergeRequest = conversionService.convert(mergeRequestJson, MergeRequest.class); + parsingCommits(newMergeRequest); + return newMergeRequest; + }) + .collect(Collectors.toList()); + + if (checkNotEmpty(mergeRequests)) { + personMapping(mergeRequests); + mergeRequestsService.updateAll(mergeRequests); } } @@ -83,7 +90,7 @@ public class MergeRequestParser { int page = 1; List mergeRequestJsons = getMergeRequestJsons(project, page); - while (!mergeRequestJsons.isEmpty()) { + while (checkNotEmpty(mergeRequestJsons)) { final Set jsonIds = mergeRequestJsons.stream() .map(MergeRequestJson::getId) @@ -99,6 +106,9 @@ public class MergeRequestParser { return mergeRequest; }) .toList(); + + personMapping(newMergeRequests); + mergeRequestsService.createAll(newMergeRequests); } @@ -106,6 +116,32 @@ public class MergeRequestParser { } } + private static void personMapping(List newMergeRequests) { + final Map personMap = Stream.concat( + newMergeRequests.stream() + .flatMap(mergeRequest -> Stream.of(mergeRequest.getAssignee(), mergeRequest.getAuthor())), + newMergeRequests.stream() + .flatMap(mergeRequest -> mergeRequest.getReviewers().stream()) + ).distinct() + .filter(Objects::nonNull) + .collect(Collectors.toMap(Person::getId, p -> p)); + + for (MergeRequest newMergeRequest : newMergeRequests) { + newMergeRequest.setAuthor(personMap.get(newMergeRequest.getAuthor().getId())); + + final Person assignee = newMergeRequest.getAssignee(); + if (checkNotNull(assignee)) { + newMergeRequest.setAssignee(personMap.get(assignee.getId())); + } + + newMergeRequest.setReviewers( + newMergeRequest.getReviewers().stream() + .map(reviewer -> personMap.get(reviewer.getId())) + .collect(Collectors.toList()) + ); + } + } + private void parsingCommits(MergeRequest mergeRequest) { final List commitJson = HttpParse.request( MessageFormat.format(gitlabProperty.getUrlCommit(), mergeRequest.getProjectId(), mergeRequest.getTwoId()) @@ -125,4 +161,12 @@ public class MergeRequestParser { .executeList(MergeRequestJson.class); } + private Optional getMergeRequest(IdAndStatusPr existId) { + final String mrUrl = MessageFormat.format(gitlabProperty.getUrlPullRequest(), existId.getProjectId(), existId.getTwoId()); + return HttpParse.request(mrUrl) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken()) + .execute(MergeRequestJson.class); + } + } diff --git a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/parser/ProjectParser.java b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/parser/ProjectParser.java index ed4ba01..6ff3738 100644 --- a/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/parser/ProjectParser.java +++ b/bot-core/src/main/java/dev/struchkov/bot/gitlab/core/service/parser/ProjectParser.java @@ -15,6 +15,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.convert.ConversionService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.text.MessageFormat; import java.util.Collection; @@ -46,10 +47,12 @@ public class ProjectParser { private final GitlabProperty gitlabProperty; private final PersonProperty personProperty; + @Transactional public void parseAllPrivateProject() { parseProjects(PRIVATE); } + @Transactional public void parseAllProjectOwner() { parseProjects(OWNER); } @@ -80,6 +83,20 @@ public class ProjectParser { } } + public void parseByUrl(String projectUrl) { + final ProjectJson projectJson = HttpParse.request(projectUrl) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken()) + .execute(ProjectJson.class) + .orElseThrow(convertException("Ошибка получения проекта")); + if (!projectService.existsById(projectJson.getId())) { + createNewPersons(List.of(projectJson)); + + final Project newProject = conversionService.convert(projectJson, Project.class); + projectService.create(newProject); + } + } + private void createNewPersons(List projectJsons) { final Set personCreatorId = projectJsons.stream() .map(ProjectJson::getCreatorId) @@ -113,16 +130,4 @@ public class ProjectParser { .executeList(ProjectJson.class); } - public void parseByUrl(String projectUrl) { - final Project project = HttpParse.request(projectUrl) - .header(ACCEPT) - .header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken()) - .execute(ProjectJson.class) - .map(json -> conversionService.convert(json, Project.class)) - .orElseThrow(convertException("Ошибка получения проекта")); - if (!projectService.existsById(project.getId())) { - projectService.create(project); - } - } - } diff --git a/gitlab-app/src/main/resources/application.yml b/gitlab-app/src/main/resources/application.yml index f991e5d..4e6527a 100644 --- a/gitlab-app/src/main/resources/application.yml +++ b/gitlab-app/src/main/resources/application.yml @@ -32,7 +32,7 @@ gitlab-bot: url-pull-request-close: "${GITLAB_URL}/api/v4/projects/{0,number,#}/merge_requests?state=closed&page={1, number, integer}&per_page=100" url-pull-request-comment: "${GITLAB_URL}/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/notes?&page={2,number,#}&per_page=100" url-pull-request: "${GITLAB_URL}/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}" - url-merge-request-add: ${GITLAB_URL}/api/v4/projects/{0}%2F{1} + url-merge-request-add: "${GITLAB_URL}/api/v4/projects/" user-url: ${GITLAB_URL}/api/v4/user users-url: ${GITLAB_URL}/api/v4/users url-note: "{0}#note_{1,number,#}" diff --git a/gitlab-app/src/main/resources/liquibase/changelog.xml b/gitlab-app/src/main/resources/liquibase/changelog.xml index be68aec..0bfedec 100644 --- a/gitlab-app/src/main/resources/liquibase/changelog.xml +++ b/gitlab-app/src/main/resources/liquibase/changelog.xml @@ -1,8 +1,9 @@ + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.17.xsd"> + \ No newline at end of file diff --git a/gitlab-app/src/main/resources/liquibase/v.1.0.0/2022-12-03-insert.xml b/gitlab-app/src/main/resources/liquibase/v.1.0.0/2022-12-03-insert.xml index 63f1126..8ff6ba7 100644 --- a/gitlab-app/src/main/resources/liquibase/v.1.0.0/2022-12-03-insert.xml +++ b/gitlab-app/src/main/resources/liquibase/v.1.0.0/2022-12-03-insert.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.17.xsd"> diff --git a/gitlab-app/src/main/resources/liquibase/v.1.0.0/changelog.xml b/gitlab-app/src/main/resources/liquibase/v.1.0.0/changelog.xml index 9d00dee..31d0925 100644 --- a/gitlab-app/src/main/resources/liquibase/v.1.0.0/changelog.xml +++ b/gitlab-app/src/main/resources/liquibase/v.1.0.0/changelog.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.17.xsd"> diff --git a/gitlab-app/src/main/resources/liquibase/v.1.1.3/2022-12-05-add-reviewers.xml b/gitlab-app/src/main/resources/liquibase/v.1.1.3/2022-12-05-add-reviewers.xml new file mode 100644 index 0000000..0ad16f5 --- /dev/null +++ b/gitlab-app/src/main/resources/liquibase/v.1.1.3/2022-12-05-add-reviewers.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gitlab-app/src/main/resources/liquibase/v.1.1.3/changelog.xml b/gitlab-app/src/main/resources/liquibase/v.1.1.3/changelog.xml new file mode 100644 index 0000000..c2b406f --- /dev/null +++ b/gitlab-app/src/main/resources/liquibase/v.1.1.3/changelog.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/gitlab-sdk/src/main/java/dev/struchkov/bot/gitlab/sdk/domain/MergeRequestJson.java b/gitlab-sdk/src/main/java/dev/struchkov/bot/gitlab/sdk/domain/MergeRequestJson.java index 3bb7670..73b125f 100644 --- a/gitlab-sdk/src/main/java/dev/struchkov/bot/gitlab/sdk/domain/MergeRequestJson.java +++ b/gitlab-sdk/src/main/java/dev/struchkov/bot/gitlab/sdk/domain/MergeRequestJson.java @@ -8,6 +8,7 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import lombok.Data; import java.time.LocalDateTime; +import java.util.List; import java.util.Set; /** @@ -40,6 +41,8 @@ public class MergeRequestJson { private PersonJson author; private PersonJson assignee; + private List reviewers; + @JsonProperty("web_url") private String webUrl; diff --git a/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/unit/MenuConfig.java b/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/unit/MenuConfig.java index 1bffaf6..2bd93b3 100644 --- a/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/unit/MenuConfig.java +++ b/telegram-bot/src/main/java/dev/struchkov/bot/gitlab/telegram/unit/MenuConfig.java @@ -19,7 +19,6 @@ import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Component; import java.text.MessageFormat; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -92,9 +91,10 @@ public class MenuConfig { public AnswerText addNewProject() { return AnswerText.builder() .answer(mail -> { - final List urlList = Arrays.stream(mail.getText().split("/")).toList(); - int lastElement = urlList.size() - 1; - final String projectUrl = MessageFormat.format(gitlabProperty.getUrlMergeRequestAdd(), urlList.get(lastElement - 1), urlList.get(lastElement)); + final String mailText = mail.getText(); + final String projectUrl = gitlabProperty.getUrlMergeRequestAdd() + mailText.replace(gitlabProperty.getBaseUrl(), "") + .substring(1) + .replace("/", "%2F"); projectParser.parseByUrl(projectUrl); return boxAnswer("Project added successfully"); })