Рефакторинг старта приложения.

This commit is contained in:
Struchkov Mark 2022-12-09 21:50:37 +03:00
parent b87e516fc0
commit 695a4703dc
17 changed files with 161 additions and 121 deletions

View File

@ -37,4 +37,12 @@ public enum AssigneeChanged {
return AssigneeChanged.NOT_CHANGED;
}
public boolean getNewStatus(boolean oldStatus) {
return switch (this) {
case BECOME -> true;
case DELETED -> false;
case NOT_CHANGED, NOT_AFFECT_USER -> oldStatus;
};
}
}

View File

@ -35,4 +35,12 @@ public enum ReviewerChanged {
return ReviewerChanged.NOT_CHANGED;
}
public boolean getNewStatus(boolean oldStatus) {
return switch (this) {
case BECOME -> true;
case DELETED -> false;
case NOT_AFFECT_USER, NOT_CHANGED -> oldStatus;
};
}
}

View File

@ -99,7 +99,13 @@ public class MergeRequest {
private String sourceBranch;
@Column(name = "notification")
private Boolean notification;
private boolean notification;
@Column(name = "is_assignee")
private boolean userAssignee;
@Column(name = "is_reviewer")
private boolean userReviewer;
@ElementCollection
@CollectionTable(name = "merge_request_label", joinColumns = @JoinColumn(name = "merge_request_id"))

View File

@ -12,4 +12,8 @@ public interface NotifyService {
<T extends Notify> void send(T notify);
void enableAllNotify();
void disableAllNotify();
}

View File

@ -52,50 +52,37 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
@Override
@Transactional
public MergeRequest create(@NonNull MergeRequest mergeRequest) {
mergeRequest.setNotification(true);
final boolean botUserReviewer = isBotUserReviewer(mergeRequest);
final boolean botUserAssignee = isBotUserAssigneeAndNotAuthor(mergeRequest);
final MergeRequest newMergeRequest = repository.save(mergeRequest);
mergeRequest.setNotification(botUserReviewer || botUserAssignee);
mergeRequest.setUserAssignee(botUserAssignee);
mergeRequest.setUserReviewer(botUserReviewer);
notifyNewMergeRequest(newMergeRequest);
final MergeRequest savedMergeRequest = repository.save(mergeRequest);
return newMergeRequest;
if (botUserReviewer || botUserAssignee) {
if (!mergeRequest.isConflict()) {
final String projectName = projectService.getByIdOrThrow(savedMergeRequest.getProjectId()).getName();
if (botUserReviewer) sendNotifyAboutNewMr(savedMergeRequest, projectName);
if (botUserAssignee) sendNotifyAboutAssignee(mergeRequest, projectName);
}
}
return savedMergeRequest;
}
/**
* Уведомление о новом MergeRequest.
*
* @param savedMergeRequest сохраненный в базу новый MergeRequest.
*/
private void notifyNewMergeRequest(MergeRequest savedMergeRequest) {
notifyUserAboutNewPullRequestIfHeIsReviewer(savedMergeRequest);
notifyUserAboutNewPullRequestIfHeIsAssignee(savedMergeRequest);
}
private void notifyUserAboutNewPullRequestIfHeIsAssignee(MergeRequest savedMergeRequest) {
private boolean isBotUserAssigneeAndNotAuthor(MergeRequest mergeRequest) {
final Long gitlabUserId = personInformation.getId();
final Person assignee = savedMergeRequest.getAssignee();
final Person author = savedMergeRequest.getAuthor();
final Person assignee = mergeRequest.getAssignee();
final Person author = mergeRequest.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()
);
}
return true;
}
}
return false;
}
/**
@ -107,33 +94,46 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
return author.getId().equals(assignee.getId());
}
private void notifyUserAboutNewPullRequestIfHeIsReviewer(MergeRequest savedMergeRequest) {
private boolean isBotUserReviewer(MergeRequest savedMergeRequest) {
final List<Person> reviewers = savedMergeRequest.getReviewers();
final Long gitlabUserId = personInformation.getId();
final Long botUserGitlabId = 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()) {
sendNotifyAboutNewMr(savedMergeRequest, projectName);
for (Person reviewer : reviewers) {
if (botUserGitlabId.equals(reviewer.getId())) {
return true;
}
}
}
return false;
}
private void sendNotifyAboutNewMr(MergeRequest savedMergeRequest, String projectName) {
private void sendNotifyAboutNewMr(MergeRequest mergeRequest, String projectName) {
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())
.labels(mergeRequest.getLabels())
.author(mergeRequest.getAuthor().getName())
.description(mergeRequest.getDescription())
.title(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl())
.targetBranch(mergeRequest.getTargetBranch())
.sourceBranch(mergeRequest.getSourceBranch())
.build()
);
}
private void sendNotifyAboutAssignee(MergeRequest mergeRequest, String projectName) {
notifyService.send(
NewPrNotify.builder()
.projectName(projectName)
.labels(mergeRequest.getLabels())
.author(mergeRequest.getAuthor().getName())
.description(mergeRequest.getDescription())
.title(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl())
.targetBranch(mergeRequest.getTargetBranch())
.sourceBranch(mergeRequest.getSourceBranch())
.build()
);
}
@ -144,35 +144,37 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
final MergeRequest oldMergeRequest = repository.findById(mergeRequest.getId())
.orElseThrow(notFoundException("MergeRequest не найден"));
final Boolean notification = oldMergeRequest.getNotification();
if (checkNotNull(notification)) {
mergeRequest.setNotification(oldMergeRequest.getNotification());
}
mergeRequest.setNotification(oldMergeRequest.isNotification());
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();
mergeRequest.setUserAssignee(assigneeChanged.getNewStatus(oldMergeRequest.isUserAssignee()));
mergeRequest.setUserReviewer(reviewerChanged.getNewStatus(oldMergeRequest.isUserReviewer()));
final boolean isChangedMr = !oldMergeRequest.getUpdatedDate().equals(mergeRequest.getUpdatedDate())
|| oldMergeRequest.isConflict() != mergeRequest.isConflict();
final boolean isChangedLinkedEntity = reviewerChanged.isChanged() || assigneeChanged.isChanged();
if (isChangedMr || isChangedLinkedEntity) {
final Project project = projectService.getByIdOrThrow(mergeRequest.getProjectId());
final MergeRequest savedMergeRequest = repository.save(mergeRequest);
if (TRUE.equals(notification) && isChangedMr) {
notifyAboutStatus(oldMergeRequest, mergeRequest, project);
notifyAboutConflict(oldMergeRequest, mergeRequest, project);
notifyAboutUpdate(oldMergeRequest, mergeRequest, project);
if (oldMergeRequest.isNotification()) {
final Project project = projectService.getByIdOrThrow(mergeRequest.getProjectId());
if (isChangedMr) {
notifyAboutStatus(oldMergeRequest, savedMergeRequest, project);
notifyAboutConflict(oldMergeRequest, savedMergeRequest, project);
notifyAboutUpdate(oldMergeRequest, savedMergeRequest, project);
}
if (isChangedLinkedEntity) {
notifyReviewer(reviewerChanged, savedMergeRequest, project);
notifyAssignee(assigneeChanged, savedMergeRequest, project);
}
}
if (TRUE.equals(notification) && isChangedLinkedEntity) {
notifyReviewer(reviewerChanged, mergeRequest, project);
notifyAssignee(assigneeChanged, mergeRequest, project);
}
return repository.save(mergeRequest);
return savedMergeRequest;
}
return oldMergeRequest;

View File

@ -10,11 +10,24 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor
public class NotifyServiceImpl implements NotifyService {
private boolean enableAllNotify = true;
private final MessageSendService messageSendService;
@Override
public <T extends Notify> void send(T notify) {
messageSendService.send(notify);
if (enableAllNotify) {
messageSendService.send(notify);
}
}
@Override
public void enableAllNotify() {
enableAllNotify = true;
}
@Override
public void disableAllNotify() {
enableAllNotify = false;
}
}

View File

@ -7,6 +7,7 @@ import dev.struchkov.bot.gitlab.context.service.PersonService;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Set;
@ -34,12 +35,14 @@ public class PersonServiceImpl implements PersonService {
}
@Override
@Transactional(readOnly = true)
public Person getByIdOrThrown(@NonNull Long personId) {
return repository.findById(personId)
.orElseThrow(notFoundException("Пользователь не найден"));
}
@Override
@Transactional(readOnly = true)
public ExistContainer<Person, Long> existsById(Set<Long> personIds) {
final List<Person> existsEntity = repository.findAllById(personIds);
final Set<Long> existsIds = existsEntity.stream().map(Person::getId).collect(Collectors.toSet());
@ -54,6 +57,7 @@ public class PersonServiceImpl implements PersonService {
}
@Override
@Transactional
public List<Person> createAll(List<Person> newPersons) {
return newPersons.stream()
.map(this::create)

View File

@ -66,6 +66,7 @@ public class ProjectServiceImpl implements ProjectService {
}
@Override
@Transactional
public List<Project> createAll(List<Project> newProjects) {
return newProjects.stream()
.map(this::create)
@ -78,6 +79,7 @@ public class ProjectServiceImpl implements ProjectService {
}
@Override
@Transactional(readOnly = true)
public ExistContainer<Project, Long> existsById(Set<Long> projectIds) {
final List<Project> existsEntity = repository.findAllById(projectIds);
final Set<Long> existsIds = existsEntity.stream().map(Project::getId).collect(Collectors.toSet());

View File

@ -15,7 +15,6 @@ 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;
@ -47,12 +46,10 @@ public class ProjectParser {
private final GitlabProperty gitlabProperty;
private final PersonProperty personProperty;
@Transactional
public void parseAllPrivateProject() {
parseProjects(PRIVATE);
}
@Transactional
public void parseAllProjectOwner() {
parseProjects(OWNER);
}

View File

@ -3,7 +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-4.17.xsd">
<include file="v.1.0.0/changelog.xml" relativeToChangelogFile="true"/>
<include file="v.1.1.3/changelog.xml" relativeToChangelogFile="true"/>
<include file="v.2.0.0/changelog.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
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-4.17.xsd">
<changeSet id="2022-12-05-create-table-reviewers" author="uPagge">
<createTable tableName="merge_request_reviewer">
<column name="merge_request_id" type="int">
<constraints nullable="false" foreignKeyName="fk_merge_request_reviewer_merge_request_id"
references="merge_request(id)" deleteCascade="true"/>
</column>
<column name="person_id" type="int">
<constraints nullable="false" foreignKeyName="fk_merge_request_reviewer_person_id"
references="person(id)" deleteCascade="true"/>
</column>
</createTable>
<addPrimaryKey tableName="merge_request_reviewer" columnNames="merge_request_id, person_id"/>
</changeSet>
</databaseChangeLog>

View File

@ -1,12 +0,0 @@
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
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-4.17.xsd">
<changeSet id="2022-12-05-add-tab-v-1-0-0" author="uPagge">
<tagDatabase tag="v.1.1.3"/>
</changeSet>
<include file="2022-12-05-add-reviewers.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@ -96,10 +96,15 @@
<column name="notification" type="boolean">
<constraints nullable="false"/>
</column>
<column name="is_assignee" type="boolean">
<constraints nullable="false"/>
</column>
<column name="is_reviewer" type="boolean">
<constraints nullable="false"/>
</column>
<column name="date_last_commit" type="datetime"/>
</createTable>
<createIndex tableName="merge_request" indexName="i_merge_request_project_id">
<column name="project_id"/>
</createIndex>
@ -112,12 +117,7 @@
</changeSet>
<changeSet id="2022-12-03-create-table-labels" author="uPagge">
<createSequence sequenceName="seq_merge_request" startValue="1" incrementBy="1" cacheSize="20"/>
<createTable tableName="merge_request_label">
<column name="id" type="int" defaultValueSequenceNext="seq_merge_request">
<constraints nullable="false" primaryKey="true"/>
</column>
<column name="merge_request_id" type="int">
<constraints nullable="false" foreignKeyName="merge_request_label_merge_request_id"
references="merge_request(id)" deleteCascade="true"/>
@ -236,4 +236,19 @@
</createIndex>
</changeSet>
<changeSet id="2022-12-05-create-table-reviewers" author="uPagge">
<createTable tableName="merge_request_reviewer">
<column name="merge_request_id" type="int">
<constraints nullable="false" foreignKeyName="fk_merge_request_reviewer_merge_request_id"
references="merge_request(id)" deleteCascade="true"/>
</column>
<column name="person_id" type="int">
<constraints nullable="false" foreignKeyName="fk_merge_request_reviewer_person_id"
references="person(id)" deleteCascade="true"/>
</column>
</createTable>
<addPrimaryKey tableName="merge_request_reviewer" columnNames="merge_request_id, person_id"/>
</changeSet>
</databaseChangeLog>

View File

@ -19,9 +19,11 @@ import dev.struchkov.godfather.telegram.domain.config.TelegramConnectConfig;
import dev.struchkov.godfather.telegram.main.context.TelegramConnect;
import dev.struchkov.godfather.telegram.simple.consumer.EventDistributorService;
import dev.struchkov.godfather.telegram.simple.context.service.EventDistributor;
import dev.struchkov.godfather.telegram.simple.context.service.SenderStorageService;
import dev.struchkov.godfather.telegram.simple.context.service.TelegramSending;
import dev.struchkov.godfather.telegram.simple.core.MailAutoresponderTelegram;
import dev.struchkov.godfather.telegram.simple.core.TelegramConnectBot;
import dev.struchkov.godfather.telegram.simple.core.service.SenderMapStorageService;
import dev.struchkov.godfather.telegram.simple.sender.TelegramSender;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
@ -76,13 +78,20 @@ public class TelegramBotConfig {
return autoresponder;
}
@Bean
public SenderStorageService senderStorageService() {
return new SenderMapStorageService();
}
@Bean
public TelegramSending sending(
TelegramConnect telegramConnect,
SenderStorageService senderStorageService,
ReplaceUrlLocalhost replaceUrlLocalhost
) {
final TelegramSender telegramSender = new TelegramSender(telegramConnect);
telegramSender.setSendPreProcessing(replaceUrlLocalhost);
telegramSender.setSenderRepository(senderStorageService);
return telegramSender;
}

View File

@ -4,6 +4,7 @@ import dev.struchkov.bot.gitlab.context.domain.entity.Note;
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
import dev.struchkov.bot.gitlab.context.service.NoteService;
import dev.struchkov.bot.gitlab.context.service.NotifyService;
import dev.struchkov.bot.gitlab.core.service.parser.ProjectParser;
import dev.struchkov.godfather.main.core.unit.UnitActiveType;
import dev.struchkov.godfather.main.domain.BoxAnswer;
@ -36,6 +37,7 @@ import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.PARSE_OWNER_PROJE
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.TEXT_PARSER_PRIVATE_PROJECT;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.TEXT_PARSE_OWNER_PROJECT;
import static dev.struchkov.godfather.main.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.main.domain.BoxAnswer.replaceBoxAnswer;
import static dev.struchkov.godfather.main.domain.keyboard.button.SimpleButton.simpleButton;
import static dev.struchkov.godfather.main.domain.keyboard.simple.SimpleKeyBoardLine.simpleLine;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard;
@ -54,6 +56,8 @@ public class UnitConfig {
private final AppSettingService settingService;
private final NoteService noteService;
private final DiscussionService discussionService;
private final NotifyService notifyService;
private final ProjectParser projectParser;
@Unit(value = CHECK_FIRST_START, main = true)
@ -109,7 +113,7 @@ public class UnitConfig {
}
}
}
return boxAnswer("Ошибка");
return boxAnswer("Error");
}
)
.build();
@ -120,8 +124,7 @@ public class UnitConfig {
@Unit(CHECK_PARSER_PRIVATE_PROJECT) MainUnit<Mail> checkParserPrivateProject
) {
return AnswerText.<Mail>builder()
.answer(
boxAnswer(
.answer(() -> boxAnswer(
"Start tracking private projects?",
inlineKeyBoard(
simpleLine(
@ -143,6 +146,7 @@ public class UnitConfig {
) {
return AnswerCheck.<Mail>builder()
.check(mail -> "YES".equalsIgnoreCase(mail.getText()))
.intermediateAnswerIfTrue(replaceBoxAnswer("Scanning of private projects has begun. Wait..."))
.unitTrue(parserPrivateProject)
.unitFalse(textParseOwnerProject)
.build();
@ -154,8 +158,9 @@ public class UnitConfig {
) {
return AnswerText.<Mail>builder()
.answer(() -> {
notifyService.disableAllNotify();
projectParser.parseAllPrivateProject();
return boxAnswer("Projects have been successfully added to tracking");
return replaceBoxAnswer("Projects have been successfully added to tracking");
})
.next(textParseOwnerProject)
.build();
@ -189,6 +194,7 @@ public class UnitConfig {
) {
return AnswerCheck.<Mail>builder()
.check(message -> "YES".equalsIgnoreCase(message.getText()))
.intermediateAnswerIfTrue(replaceBoxAnswer("Scanning of public projects has begun. Wait..."))
.unitTrue(parseOwnerProject)
.unitFalse(endSetting)
.build();
@ -201,7 +207,7 @@ public class UnitConfig {
return AnswerText.<Mail>builder()
.answer(() -> {
projectParser.parseAllProjectOwner();
return boxAnswer("Projects have been successfully added to tracking");
return replaceBoxAnswer("Projects have been successfully added to tracking");
})
.next(endSetting)
.build();
@ -213,7 +219,8 @@ public class UnitConfig {
.answer(
() -> {
settingService.disableFirstStart();
return boxAnswer("""
notifyService.enableAllNotify();
return replaceBoxAnswer("""
Configuration completed successfully
Developer: [uPagge](https://mark.struchkov.dev)
""");