Compare commits
12 Commits
develop
...
feature/is
Author | SHA1 | Date | |
---|---|---|---|
e662a96eea | |||
ee1bebb5e0 | |||
887f5a36f3 | |||
a514fcb74f | |||
35783a55e7 | |||
7396c2a2ef | |||
b5ff193b49 | |||
7e1c6c1f44 | |||
30ff49eb75 | |||
331ddd7314 | |||
b0fb70e150 | |||
f146165024 |
241
.drone.yml
241
.drone.yml
@ -3,17 +3,13 @@ kind: pipeline
|
|||||||
type: docker
|
type: docker
|
||||||
name: develop build
|
name: develop build
|
||||||
|
|
||||||
image_pull_secrets:
|
|
||||||
- DOCKER_AUTH
|
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
- develop
|
- develop
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- name: docker
|
- name: docker
|
||||||
# https://hub.docker.com/r/library/docker
|
image: docker:20.10.22-dind-alpine3.17
|
||||||
image: hub.docker.struchkov.dev/docker:27.1.2-dind-alpine3.20
|
|
||||||
privileged: true
|
privileged: true
|
||||||
volumes:
|
volumes:
|
||||||
- name: dockersock
|
- name: dockersock
|
||||||
@ -28,8 +24,7 @@ volumes:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: create jar
|
- name: create jar
|
||||||
# https://hub.docker.com/_/maven
|
image: maven:3.8.6-eclipse-temurin-17
|
||||||
image: hub.docker.struchkov.dev/maven:3.9-eclipse-temurin-22-alpine
|
|
||||||
volumes:
|
volumes:
|
||||||
- name: m2
|
- name: m2
|
||||||
path: /root/.m2/repository
|
path: /root/.m2/repository
|
||||||
@ -37,19 +32,26 @@ steps:
|
|||||||
- mvn -U clean package
|
- mvn -U clean package
|
||||||
|
|
||||||
- name: docker publish develop
|
- name: docker publish develop
|
||||||
image: docker.struchkov.dev/docker-buildx:latest
|
image: upagge/docker-buildx:latest
|
||||||
environment:
|
environment:
|
||||||
|
STRUCHKOV_DOCKER_REGISTRY_TOKEN:
|
||||||
|
from_secret: STRUCHKOV_DOCKER_REGISTRY_TOKEN
|
||||||
|
STRUCHKOV_DOCKER_IMAGE_NAME:
|
||||||
|
from_secret: STRUCHKOV_DOCKER_IMAGE_NAME
|
||||||
DOCKER_REGISTRY_TOKEN:
|
DOCKER_REGISTRY_TOKEN:
|
||||||
from_secret: DOCKER_REGISTRY_TOKEN
|
from_secret: DOCKER_REGISTRY_TOKEN
|
||||||
|
DOCKER_IMAGE_NAME:
|
||||||
|
from_secret: DOCKER_IMAGE_NAME
|
||||||
DOCKER_REGISTRY_USER:
|
DOCKER_REGISTRY_USER:
|
||||||
from_secret: DOCKER_REGISTRY_USER
|
from_secret: DOCKER_REGISTRY_USER
|
||||||
volumes:
|
volumes:
|
||||||
- name: dockersock
|
- name: dockersock
|
||||||
path: /var/run
|
path: /var/run
|
||||||
commands:
|
commands:
|
||||||
- echo "$DOCKER_REGISTRY_TOKEN" | docker login docker.struchkov.dev --username $DOCKER_REGISTRY_USER --password-stdin
|
- echo "$STRUCHKOV_DOCKER_REGISTRY_TOKEN" | docker login git.struchkov.dev --username $DOCKER_REGISTRY_USER --password-stdin
|
||||||
|
- echo "$DOCKER_REGISTRY_TOKEN" | docker login docker.io --username $DOCKER_REGISTRY_USER --password-stdin
|
||||||
- docker buildx create --use
|
- docker buildx create --use
|
||||||
- docker buildx build -f Dockerfile-develop --push --platform linux/amd64,linux/arm64/v8 -t "docker.struchkov.dev/gitlab-notify:develop" .
|
- docker buildx build -f Dockerfile-develop --push --platform linux/amd64,linux/arm64/v8 -t "$DOCKER_IMAGE_NAME:develop" -t "git.struchkov.dev/$STRUCHKOV_DOCKER_IMAGE_NAME:develop" .
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -57,17 +59,13 @@ kind: pipeline
|
|||||||
type: docker
|
type: docker
|
||||||
name: release build
|
name: release build
|
||||||
|
|
||||||
image_pull_secrets:
|
|
||||||
- DOCKER_AUTH
|
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
ref:
|
ref:
|
||||||
- refs/tags/v.*.*.*
|
- refs/tags/v.*.*.*
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- name: docker
|
- name: docker
|
||||||
# https://hub.docker.com/r/library/docker
|
image: docker:20.10.22-dind-alpine3.17
|
||||||
image: hub.docker.struchkov.dev/docker:27.1.2-dind-alpine3.20
|
|
||||||
privileged: true
|
privileged: true
|
||||||
volumes:
|
volumes:
|
||||||
- name: dockersock
|
- name: dockersock
|
||||||
@ -82,7 +80,7 @@ volumes:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: create jar
|
- name: create jar
|
||||||
image: hub.docker.struchkov.dev/maven:3.9-eclipse-temurin-22-alpine
|
image: maven:3.8.6-eclipse-temurin-17
|
||||||
volumes:
|
volumes:
|
||||||
- name: m2
|
- name: m2
|
||||||
path: /root/.m2/repository
|
path: /root/.m2/repository
|
||||||
@ -90,117 +88,122 @@ steps:
|
|||||||
- mvn -U clean package
|
- mvn -U clean package
|
||||||
|
|
||||||
- name: docker publish release
|
- name: docker publish release
|
||||||
image: docker.struchkov.dev/docker-buildx:latest
|
image: upagge/docker-buildx:latest
|
||||||
|
environment:
|
||||||
|
STRUCHKOV_DOCKER_REGISTRY_TOKEN:
|
||||||
|
from_secret: STRUCHKOV_DOCKER_REGISTRY_TOKEN
|
||||||
|
STRUCHKOV_DOCKER_IMAGE_NAME:
|
||||||
|
from_secret: STRUCHKOV_DOCKER_IMAGE_NAME
|
||||||
|
DOCKER_REGISTRY_TOKEN:
|
||||||
|
from_secret: DOCKER_REGISTRY_TOKEN
|
||||||
|
DOCKER_IMAGE_NAME:
|
||||||
|
from_secret: DOCKER_IMAGE_NAME
|
||||||
|
DOCKER_REGISTRY_USER:
|
||||||
|
from_secret: DOCKER_REGISTRY_USER
|
||||||
volumes:
|
volumes:
|
||||||
- name: dockersock
|
- name: dockersock
|
||||||
path: /var/run
|
path: /var/run
|
||||||
environment:
|
|
||||||
DOCKER_REGISTRY_TOKEN:
|
|
||||||
from_secret: DOCKER_REGISTRY_TOKEN
|
|
||||||
DOCKER_REGISTRY_USER:
|
|
||||||
from_secret: DOCKER_REGISTRY_USER
|
|
||||||
commands:
|
commands:
|
||||||
- echo "$DOCKER_REGISTRY_TOKEN" | docker login docker.struchkov.dev --username $DOCKER_REGISTRY_USER --password-stdin
|
- echo "$STRUCHKOV_DOCKER_REGISTRY_TOKEN" | docker login git.struchkov.dev --username $DOCKER_REGISTRY_USER --password-stdin
|
||||||
|
- echo "$DOCKER_REGISTRY_TOKEN" | docker login docker.io --username $DOCKER_REGISTRY_USER --password-stdin
|
||||||
- docker buildx create --use
|
- docker buildx create --use
|
||||||
- docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t "docker.struchkov.dev/gitlab-notify:latest" -t "docker.struchkov.dev/gitlab-notify:$DRONE_TAG" .
|
- docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t "$DOCKER_IMAGE_NAME:latest" -t "$DOCKER_IMAGE_NAME:$DRONE_TAG" -t "git.struchkov.dev/$STRUCHKOV_DOCKER_IMAGE_NAME:latest" -t "git.struchkov.dev/$STRUCHKOV_DOCKER_IMAGE_NAME:$DRONE_TAG" .
|
||||||
|
|
||||||
#---
|
---
|
||||||
#kind: pipeline
|
kind: pipeline
|
||||||
#type: docker
|
type: docker
|
||||||
#name: create-develop-docs-site
|
name: create-develop-docs-site
|
||||||
#
|
|
||||||
#trigger:
|
|
||||||
# branch:
|
|
||||||
# - develop
|
|
||||||
# - docs
|
|
||||||
#
|
|
||||||
#clone:
|
|
||||||
# disable: true
|
|
||||||
#
|
|
||||||
#steps:
|
|
||||||
#
|
|
||||||
# - name: build docs
|
|
||||||
# image: git.struchkov.dev/upagge/mkdocs-material-insiders:latest
|
|
||||||
# volumes:
|
|
||||||
# - name: mkdocs_cache
|
|
||||||
# path: ${DRONE_WORKSPACE}/documentation/ru/.cache
|
|
||||||
# environment:
|
|
||||||
# GIT_SSH:
|
|
||||||
# from_secret: GIT_SSH
|
|
||||||
# GIT_SSH_COMMAND: "ssh -i ~/.ssh/id_rsa -p 222"
|
|
||||||
# commands:
|
|
||||||
# - eval $(ssh-agent -s)
|
|
||||||
# - mkdir -p ~/.ssh
|
|
||||||
# - chmod 700 ~/.ssh
|
|
||||||
# - echo "$GIT_SSH" >> ~/.ssh/id_rsa
|
|
||||||
# - chmod 600 ~/.ssh/id_rsa
|
|
||||||
# - ssh-keyscan -p 222 git.struchkov.dev >> ~/.ssh/known_hosts
|
|
||||||
# - chmod 644 ~/.ssh/known_hosts
|
|
||||||
# - git config --global user.name "${DRONE_COMMIT_AUTHOR_NAME}"
|
|
||||||
# - git config --global user.email "${DRONE_COMMIT_AUTHOR_EMAIL}"
|
|
||||||
# - git clone ssh://git@git.struchkov.dev:222/Telegram-Bots/gitlab-notification.git .
|
|
||||||
# - git checkout $DRONE_COMMIT
|
|
||||||
# - cd documentation/ru
|
|
||||||
# - mike deploy --prefix gitlab-notification/ru --branch docs-deploy --push --update-aliases develop
|
|
||||||
#
|
|
||||||
#image_pull_secrets:
|
|
||||||
# - DOCKER_AUTH
|
|
||||||
#
|
|
||||||
#volumes:
|
|
||||||
# - name: mkdocs_cache
|
|
||||||
# host:
|
|
||||||
# path: /drone/volume/mkdocs_cache/gitlab_notification/ru
|
|
||||||
#
|
|
||||||
#---
|
|
||||||
#kind: pipeline
|
|
||||||
#type: docker
|
|
||||||
#name: create-release-docs-site
|
|
||||||
#
|
|
||||||
#trigger:
|
|
||||||
# ref:
|
|
||||||
# - refs/tags/v.*.*.*
|
|
||||||
#
|
|
||||||
#clone:
|
|
||||||
# disable: true
|
|
||||||
#
|
|
||||||
#steps:
|
|
||||||
#
|
|
||||||
# - name: build docs
|
|
||||||
# image: git.struchkov.dev/upagge/mkdocs-material-insiders:latest
|
|
||||||
# volumes:
|
|
||||||
# - name: mkdocs_cache
|
|
||||||
# path: ${DRONE_WORKSPACE}/documentation/ru/.cache
|
|
||||||
# environment:
|
|
||||||
# GIT_SSH:
|
|
||||||
# from_secret: GIT_SSH
|
|
||||||
# GIT_SSH_COMMAND: "ssh -i ~/.ssh/id_rsa -p 222"
|
|
||||||
# commands:
|
|
||||||
# - eval $(ssh-agent -s)
|
|
||||||
# - mkdir -p ~/.ssh
|
|
||||||
# - chmod 700 ~/.ssh
|
|
||||||
# - echo "$GIT_SSH" >> ~/.ssh/id_rsa
|
|
||||||
# - chmod 600 ~/.ssh/id_rsa
|
|
||||||
# - ssh-keyscan -p 222 git.struchkov.dev >> ~/.ssh/known_hosts
|
|
||||||
# - chmod 644 ~/.ssh/known_hosts
|
|
||||||
# - git config --global user.name "${DRONE_COMMIT_AUTHOR_NAME}"
|
|
||||||
# - git config --global user.email "${DRONE_COMMIT_AUTHOR_EMAIL}"
|
|
||||||
# - git clone ssh://git@git.struchkov.dev:222/Telegram-Bots/gitlab-notification.git .
|
|
||||||
# - git checkout $DRONE_COMMIT
|
|
||||||
# - cd documentation/ru
|
|
||||||
# - mike deploy --prefix gitlab-notification/ru --branch docs-deploy --push --update-aliases ${DRONE_TAG}
|
|
||||||
# - mike deploy --prefix gitlab-notification/ru --branch docs-deploy --push --update-aliases latest
|
|
||||||
#
|
|
||||||
#image_pull_secrets:
|
|
||||||
# - DOCKER_AUTH
|
|
||||||
#
|
|
||||||
#volumes:
|
|
||||||
# - name: mkdocs_cache
|
|
||||||
# host:
|
|
||||||
# path: /drone/volume/mkdocs_cache/gitlab_notification\
|
|
||||||
|
|
||||||
# drone sign --save Telegram-Bots/gitlab-notification
|
trigger:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- docs
|
||||||
|
|
||||||
|
clone:
|
||||||
|
disable: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: build docs
|
||||||
|
image: git.struchkov.dev/upagge/mkdocs-material-insiders:latest
|
||||||
|
volumes:
|
||||||
|
- name: mkdocs_cache
|
||||||
|
path: ${DRONE_WORKSPACE}/documentation/ru/.cache
|
||||||
|
environment:
|
||||||
|
GIT_SSH:
|
||||||
|
from_secret: GIT_SSH
|
||||||
|
GIT_SSH_COMMAND: "ssh -i ~/.ssh/id_rsa -p 222"
|
||||||
|
commands:
|
||||||
|
- eval $(ssh-agent -s)
|
||||||
|
- mkdir -p ~/.ssh
|
||||||
|
- chmod 700 ~/.ssh
|
||||||
|
- echo "$GIT_SSH" >> ~/.ssh/id_rsa
|
||||||
|
- chmod 600 ~/.ssh/id_rsa
|
||||||
|
- ssh-keyscan -p 222 git.struchkov.dev >> ~/.ssh/known_hosts
|
||||||
|
- chmod 644 ~/.ssh/known_hosts
|
||||||
|
- git config --global user.name "${DRONE_COMMIT_AUTHOR_NAME}"
|
||||||
|
- git config --global user.email "${DRONE_COMMIT_AUTHOR_EMAIL}"
|
||||||
|
- git clone ssh://git@git.struchkov.dev:222/Telegram-Bots/gitlab-notification.git .
|
||||||
|
- git checkout $DRONE_COMMIT
|
||||||
|
- cd documentation/ru
|
||||||
|
- mike deploy --prefix gitlab-notification/ru --branch docs-deploy --push --update-aliases develop
|
||||||
|
|
||||||
|
image_pull_secrets:
|
||||||
|
- DOCKER_AUTH
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- name: mkdocs_cache
|
||||||
|
host:
|
||||||
|
path: /drone/volume/mkdocs_cache/gitlab_notification/ru
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: create-release-docs-site
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
ref:
|
||||||
|
- refs/tags/v.*.*.*
|
||||||
|
|
||||||
|
clone:
|
||||||
|
disable: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: build docs
|
||||||
|
image: git.struchkov.dev/upagge/mkdocs-material-insiders:latest
|
||||||
|
volumes:
|
||||||
|
- name: mkdocs_cache
|
||||||
|
path: ${DRONE_WORKSPACE}/documentation/ru/.cache
|
||||||
|
environment:
|
||||||
|
GIT_SSH:
|
||||||
|
from_secret: GIT_SSH
|
||||||
|
GIT_SSH_COMMAND: "ssh -i ~/.ssh/id_rsa -p 222"
|
||||||
|
commands:
|
||||||
|
- eval $(ssh-agent -s)
|
||||||
|
- mkdir -p ~/.ssh
|
||||||
|
- chmod 700 ~/.ssh
|
||||||
|
- echo "$GIT_SSH" >> ~/.ssh/id_rsa
|
||||||
|
- chmod 600 ~/.ssh/id_rsa
|
||||||
|
- ssh-keyscan -p 222 git.struchkov.dev >> ~/.ssh/known_hosts
|
||||||
|
- chmod 644 ~/.ssh/known_hosts
|
||||||
|
- git config --global user.name "${DRONE_COMMIT_AUTHOR_NAME}"
|
||||||
|
- git config --global user.email "${DRONE_COMMIT_AUTHOR_EMAIL}"
|
||||||
|
- git clone ssh://git@git.struchkov.dev:222/Telegram-Bots/gitlab-notification.git .
|
||||||
|
- git checkout $DRONE_COMMIT
|
||||||
|
- cd documentation/ru
|
||||||
|
- mike deploy --prefix gitlab-notification/ru --branch docs-deploy --push --update-aliases ${DRONE_TAG}
|
||||||
|
- mike deploy --prefix gitlab-notification/ru --branch docs-deploy --push --update-aliases latest
|
||||||
|
|
||||||
|
image_pull_secrets:
|
||||||
|
- DOCKER_AUTH
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- name: mkdocs_cache
|
||||||
|
host:
|
||||||
|
path: /drone/volume/mkdocs_cache/gitlab_notification
|
||||||
---
|
---
|
||||||
kind: signature
|
kind: signature
|
||||||
hmac: b0704e1ed6c75469f2197afa7de1fb6f4a96765bb00f766be8a3da6fc4a87267
|
hmac: cf1bd0800e8f6bb49dae0a6c5f607676b87d5ee713f4203f4f1ed08a17f71f68
|
||||||
|
|
||||||
...
|
...
|
||||||
|
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -1 +1 @@
|
|||||||
custom: ["https://docs.struchkov.dev/gitlab-notification/ru/latest/support-development/"]
|
custom: ["https://docs.struchkov.dev/gitlab-notification/support-development/"]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM eclipse-temurin:17 AS app-build
|
FROM eclipse-temurin:17 as app-build
|
||||||
ENV RELEASE=17
|
ENV RELEASE=17
|
||||||
|
|
||||||
WORKDIR /opt/build
|
WORKDIR /opt/build
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM eclipse-temurin:17 AS app-build
|
FROM eclipse-temurin:17 as app-build
|
||||||
ENV RELEASE=17
|
ENV RELEASE=17
|
||||||
|
|
||||||
WORKDIR /opt/build
|
WORKDIR /opt/build
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.struchkov.bot.gitlab</groupId>
|
<groupId>dev.struchkov.bot.gitlab</groupId>
|
||||||
<artifactId>gitlab-bot</artifactId>
|
<artifactId>gitlab-bot</artifactId>
|
||||||
<version>2.0.0-SNAPSHOT</version>
|
<version>1.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>bot-context</artifactId>
|
<artifactId>bot-context</artifactId>
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.changed;
|
package dev.struchkov.bot.gitlab.context.domain;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import java.util.Optional;
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNull;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -17,18 +18,18 @@ public enum AssigneeChanged {
|
|||||||
|
|
||||||
private final boolean changed;
|
private final boolean changed;
|
||||||
|
|
||||||
public static AssigneeChanged valueOf(Long gitlabUserId, Optional<Person> oldAssignee, Optional<Person> newAssignee) {
|
public static AssigneeChanged valueOf(Long gitlabUserId, Person oldAssignee, Person newAssignee) {
|
||||||
if (oldAssignee.isEmpty() && newAssignee.isPresent() && gitlabUserId.equals(newAssignee.get().getId())) {
|
if (checkNull(oldAssignee) && checkNotNull(newAssignee) && gitlabUserId.equals(newAssignee.getId())) {
|
||||||
return AssigneeChanged.BECOME;
|
return AssigneeChanged.BECOME;
|
||||||
}
|
}
|
||||||
if (oldAssignee.isPresent() && newAssignee.isEmpty() && gitlabUserId.equals(oldAssignee.get().getId())) {
|
if (checkNotNull(oldAssignee) && checkNull(newAssignee) && gitlabUserId.equals(oldAssignee.getId())) {
|
||||||
return AssigneeChanged.DELETED;
|
return AssigneeChanged.DELETED;
|
||||||
}
|
}
|
||||||
if (oldAssignee.isPresent() && newAssignee.isPresent() && !oldAssignee.get().getId().equals(newAssignee.get().getId())) {
|
if (checkNotNull(oldAssignee) && checkNotNull(newAssignee) && !oldAssignee.getId().equals(newAssignee.getId())) {
|
||||||
if (gitlabUserId.equals(oldAssignee.get().getId())) {
|
if (gitlabUserId.equals(oldAssignee.getId())) {
|
||||||
return AssigneeChanged.DELETED;
|
return AssigneeChanged.DELETED;
|
||||||
}
|
}
|
||||||
if (gitlabUserId.equals(newAssignee.get().getId())) {
|
if (gitlabUserId.equals(newAssignee.getId())) {
|
||||||
return AssigneeChanged.BECOME;
|
return AssigneeChanged.BECOME;
|
||||||
}
|
}
|
||||||
return AssigneeChanged.NOT_AFFECT_USER;
|
return AssigneeChanged.NOT_AFFECT_USER;
|
@ -0,0 +1,50 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko [25.01.2023]
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum AssigneesChanged {
|
||||||
|
|
||||||
|
BECOME(true),
|
||||||
|
DELETED(true),
|
||||||
|
NOT_AFFECT_USER(true),
|
||||||
|
NOT_CHANGED(false);
|
||||||
|
|
||||||
|
private final boolean changed;
|
||||||
|
|
||||||
|
public static AssigneesChanged valueOf(Long gitlabUserId, List<Person> oldAssignees, List<Person> newAssignees) {
|
||||||
|
final Map<Long, Person> oldMap = oldAssignees.stream().collect(Collectors.toMap(Person::getId, p -> p));
|
||||||
|
final Map<Long, Person> newMap = newAssignees.stream().collect(Collectors.toMap(Person::getId, p -> p));
|
||||||
|
|
||||||
|
if (!oldMap.keySet().equals(newMap.keySet())) {
|
||||||
|
|
||||||
|
if (oldMap.containsKey(gitlabUserId) && !newMap.containsKey(gitlabUserId)) {
|
||||||
|
return AssigneesChanged.DELETED;
|
||||||
|
}
|
||||||
|
if (!oldMap.containsKey(gitlabUserId) && newMap.containsKey(gitlabUserId)) {
|
||||||
|
return AssigneesChanged.BECOME;
|
||||||
|
}
|
||||||
|
return AssigneesChanged.NOT_AFFECT_USER;
|
||||||
|
}
|
||||||
|
return AssigneesChanged.NOT_CHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getNewStatus(boolean oldStatus) {
|
||||||
|
return switch (this) {
|
||||||
|
case BECOME -> true;
|
||||||
|
case DELETED -> false;
|
||||||
|
case NOT_AFFECT_USER, NOT_CHANGED -> oldStatus;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmotry Sheyko [25.01.2023]
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class IdAndStatusIssue {
|
||||||
|
|
||||||
|
private long id;
|
||||||
|
private long twoId;
|
||||||
|
private long projectId;
|
||||||
|
private IssueState status;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko 21.01.2021
|
||||||
|
*/
|
||||||
|
public enum IssueState {
|
||||||
|
|
||||||
|
OPENED, CLOSED
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko 21.01.2021
|
||||||
|
*/
|
||||||
|
public enum IssueType {
|
||||||
|
|
||||||
|
ISSUE, INCIDENT
|
||||||
|
|
||||||
|
}
|
@ -1,10 +1,6 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain;
|
package dev.struchkov.bot.gitlab.context.domain;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,9 +8,6 @@ import lombok.Setter;
|
|||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
|
||||||
public class PersonInformation {
|
public class PersonInformation {
|
||||||
|
|
||||||
private String username;
|
private String username;
|
||||||
|
@ -21,7 +21,7 @@ public enum PipelineStatus {
|
|||||||
SKIPPED("\uD83D\uDD18"),
|
SKIPPED("\uD83D\uDD18"),
|
||||||
MANUAL("\uD83D\uDD79"),
|
MANUAL("\uD83D\uDD79"),
|
||||||
SCHEDULED("\uD83D\uDD52"),
|
SCHEDULED("\uD83D\uDD52"),
|
||||||
NEW("\uD83C\uDD95");
|
NULL("\uD83C\uDD95");
|
||||||
|
|
||||||
private final String icon;
|
private final String icon;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.changed;
|
package dev.struchkov.bot.gitlab.context.domain;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
@ -1,51 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.changed;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
|
||||||
public class ApprovalChanged {
|
|
||||||
|
|
||||||
private Set<Person> newApproval;
|
|
||||||
private Set<Person> dontApprove;
|
|
||||||
|
|
||||||
public static Optional<ApprovalChanged> approvalChanged(List<Person> oldApproval, List<Person> newApproval) {
|
|
||||||
// Если списки одинаковы, возвращаем пустой Optional
|
|
||||||
if (Objects.equals(oldApproval, newApproval)) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Преобразуем списки в множества для удобства вычислений
|
|
||||||
Set<Person> oldApprovalSet = new HashSet<>(oldApproval);
|
|
||||||
Set<Person> newApprovalSet = new HashSet<>(newApproval);
|
|
||||||
|
|
||||||
// Вычисляем новые одобрения: те, кто есть в новом списке, но нет в старом
|
|
||||||
final Set<Person> newApprovalSetOnly = new HashSet<>(newApprovalSet);
|
|
||||||
newApprovalSetOnly.removeAll(oldApprovalSet);
|
|
||||||
|
|
||||||
// Вычисляем тех, кто больше не одобряет: те, кто есть в старом списке, но нет в новом
|
|
||||||
final Set<Person> dontApproveSet = new HashSet<>(oldApprovalSet);
|
|
||||||
dontApproveSet.removeAll(newApprovalSet);
|
|
||||||
|
|
||||||
if (!newApprovalSetOnly.isEmpty() || !dontApproveSet.isEmpty()) {
|
|
||||||
return Optional.of(new ApprovalChanged(newApprovalSetOnly, dontApproveSet));
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -10,12 +10,8 @@ import jakarta.persistence.JoinTable;
|
|||||||
import jakarta.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
import jakarta.persistence.OneToMany;
|
import jakarta.persistence.OneToMany;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -29,10 +25,7 @@ import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Entity
|
@Entity
|
||||||
@NoArgsConstructor
|
|
||||||
@Builder(toBuilder = true)
|
|
||||||
@Table(name = "discussion")
|
@Table(name = "discussion")
|
||||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
|
||||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
public class Discussion {
|
public class Discussion {
|
||||||
|
|
||||||
|
@ -0,0 +1,145 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain.entity;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.IssueState;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.IssueType;
|
||||||
|
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 jakarta.persistence.CascadeType;
|
||||||
|
import jakarta.persistence.CollectionTable;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.ElementCollection;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.JoinTable;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.OneToMany;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сущность Issue.
|
||||||
|
*
|
||||||
|
* @author Dmitry Sheyko [17.01.2023]
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Entity
|
||||||
|
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
|
||||||
|
@Table(name = "issue")
|
||||||
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
|
public class Issue {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "id")
|
||||||
|
@EqualsAndHashCode.Include
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "two_id")
|
||||||
|
private Long twoId;
|
||||||
|
|
||||||
|
@Column(name = "project_id")
|
||||||
|
private Long projectId;
|
||||||
|
|
||||||
|
@Column(name = "title")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Column(name = "description")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Enumerated(value = EnumType.STRING)
|
||||||
|
@Column(name = "state")
|
||||||
|
private IssueState state;
|
||||||
|
|
||||||
|
@Column(name = "created_date")
|
||||||
|
private LocalDateTime createdDate;
|
||||||
|
|
||||||
|
@Column(name = "updated_date")
|
||||||
|
private LocalDateTime updatedDate;
|
||||||
|
|
||||||
|
@Column(name = "closed_at")
|
||||||
|
private LocalDateTime closeDate;
|
||||||
|
|
||||||
|
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||||
|
@JoinColumn(name = "closed_by_id")
|
||||||
|
private Person closedBy;
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@CollectionTable(name = "issue_label", joinColumns = @JoinColumn(name = "issue_id"))
|
||||||
|
@Column(name = "label")
|
||||||
|
private Set<String> labels = new HashSet<>();
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
fetch = FetchType.LAZY,
|
||||||
|
cascade = {CascadeType.PERSIST, CascadeType.MERGE}
|
||||||
|
)
|
||||||
|
@JoinTable(
|
||||||
|
name = "issue_assignees",
|
||||||
|
joinColumns = @JoinColumn(name = "issue_id", referencedColumnName = "id"),
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id")
|
||||||
|
)
|
||||||
|
private List<Person> assignees = new ArrayList<>();
|
||||||
|
|
||||||
|
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||||
|
@JoinColumn(name = "author_id")
|
||||||
|
private Person author;
|
||||||
|
|
||||||
|
@Enumerated(value = EnumType.STRING)
|
||||||
|
@Column(name = "type")
|
||||||
|
private IssueType type;
|
||||||
|
|
||||||
|
@Column(name = "user_notes_count")
|
||||||
|
private Integer userNotesCount;
|
||||||
|
|
||||||
|
@Column(name = "merge_requests_count")
|
||||||
|
private Integer mergeRequestsCount;
|
||||||
|
|
||||||
|
@Column(name = "up_votes")
|
||||||
|
private Integer upVotes;
|
||||||
|
|
||||||
|
@Column(name = "down_votes")
|
||||||
|
private Integer downVotes;
|
||||||
|
|
||||||
|
@Column(name = "due_date")
|
||||||
|
private LocalDate dueDate;
|
||||||
|
|
||||||
|
@Column(name = "confidential")
|
||||||
|
private Boolean confidential;
|
||||||
|
|
||||||
|
@Column(name = "discussion_locked")
|
||||||
|
private Integer discussionLocked;
|
||||||
|
|
||||||
|
@Column(name = "task_count")
|
||||||
|
private Integer taskCount;
|
||||||
|
|
||||||
|
@Column(name = "task_completed_count")
|
||||||
|
private Integer taskCompletedCount;
|
||||||
|
|
||||||
|
@Column(name = "web_url")
|
||||||
|
private String webUrl;
|
||||||
|
|
||||||
|
@Column(name = "blocking_issues_count")
|
||||||
|
private Integer blockingIssuesCount;
|
||||||
|
|
||||||
|
@Column(name = "has_tasks")
|
||||||
|
private Boolean hasTasks;
|
||||||
|
|
||||||
|
@Column(name = "notification")
|
||||||
|
private boolean notification;
|
||||||
|
|
||||||
|
@Column(name = "is_assignee")
|
||||||
|
private boolean userAssignee;
|
||||||
|
|
||||||
|
}
|
@ -17,14 +17,9 @@ import jakarta.persistence.JoinTable;
|
|||||||
import jakarta.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
import jakarta.persistence.OneToMany;
|
import jakarta.persistence.OneToMany;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -40,17 +35,12 @@ import java.util.Set;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Entity
|
@Entity
|
||||||
@ToString(onlyExplicitlyIncluded = true)
|
|
||||||
@NoArgsConstructor
|
|
||||||
@Builder(toBuilder = true)
|
|
||||||
@Table(name = "merge_request")
|
|
||||||
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
|
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
|
||||||
|
@Table(name = "merge_request")
|
||||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
|
||||||
public class MergeRequest {
|
public class MergeRequest {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@ToString.Include
|
|
||||||
@Column(name = "id")
|
@Column(name = "id")
|
||||||
@EqualsAndHashCode.Include
|
@EqualsAndHashCode.Include
|
||||||
private Long id;
|
private Long id;
|
||||||
@ -61,16 +51,12 @@ public class MergeRequest {
|
|||||||
@Column(name = "project_id")
|
@Column(name = "project_id")
|
||||||
private Long projectId;
|
private Long projectId;
|
||||||
|
|
||||||
@ToString.Include
|
|
||||||
@Column(name = "title")
|
@Column(name = "title")
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
@Column(name = "description")
|
@Column(name = "description")
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
@Column(name = "milestone")
|
|
||||||
private String milestone;
|
|
||||||
|
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
@Column(name = "state")
|
@Column(name = "state")
|
||||||
private MergeRequestState state;
|
private MergeRequestState state;
|
||||||
@ -121,17 +107,6 @@ public class MergeRequest {
|
|||||||
@Column(name = "is_reviewer")
|
@Column(name = "is_reviewer")
|
||||||
private boolean userReviewer;
|
private boolean userReviewer;
|
||||||
|
|
||||||
@OneToMany(
|
|
||||||
fetch = FetchType.LAZY,
|
|
||||||
cascade = {CascadeType.PERSIST, CascadeType.MERGE}
|
|
||||||
)
|
|
||||||
@JoinTable(
|
|
||||||
name = "merge_request_approvals",
|
|
||||||
joinColumns = @JoinColumn(name = "merge_request_id", referencedColumnName = "id"),
|
|
||||||
inverseJoinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id")
|
|
||||||
)
|
|
||||||
private List<Person> approvals = new ArrayList<>();
|
|
||||||
|
|
||||||
@ElementCollection
|
@ElementCollection
|
||||||
@CollectionTable(name = "merge_request_label", joinColumns = @JoinColumn(name = "merge_request_id"))
|
@CollectionTable(name = "merge_request_label", joinColumns = @JoinColumn(name = "merge_request_id"))
|
||||||
@Column(name = "label")
|
@Column(name = "label")
|
||||||
|
@ -9,7 +9,6 @@ import jakarta.persistence.Table;
|
|||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author upagge 14.01.2021
|
* @author upagge 14.01.2021
|
||||||
@ -17,10 +16,9 @@ import lombok.ToString;
|
|||||||
@Entity
|
@Entity
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@ToString
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
@Table(name = "person")
|
@Table(name = "person")
|
||||||
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
|
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
|
||||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
|
||||||
public class Person {
|
public class Person {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
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 jakarta.persistence.Column;
|
|
||||||
import jakarta.persistence.Entity;
|
|
||||||
import jakarta.persistence.Id;
|
|
||||||
import jakarta.persistence.Table;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
@Table(name = "person_telegram")
|
|
||||||
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
|
|
||||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
|
||||||
public class PersonTelegram {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@EqualsAndHashCode.Include
|
|
||||||
@Column(name = "id")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@Column(name = "telegram_username")
|
|
||||||
private String telegramUserName;
|
|
||||||
|
|
||||||
}
|
|
@ -11,12 +11,8 @@ import jakarta.persistence.Id;
|
|||||||
import jakarta.persistence.JoinColumn;
|
import jakarta.persistence.JoinColumn;
|
||||||
import jakarta.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@ -29,11 +25,8 @@ import java.time.LocalDateTime;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@FieldNames
|
@FieldNames
|
||||||
@NoArgsConstructor
|
|
||||||
@Table(name = "pipeline")
|
@Table(name = "pipeline")
|
||||||
@Builder(toBuilder = true)
|
|
||||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
|
||||||
public class Pipeline {
|
public class Pipeline {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor(staticName = "newDiscussion")
|
|
||||||
public class NewDiscussionEvent {
|
|
||||||
|
|
||||||
private Discussion discussion;
|
|
||||||
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor(staticName = "newMergeRequest")
|
|
||||||
public class NewMergeRequestEvent {
|
|
||||||
|
|
||||||
private MergeRequest mergeRequest;
|
|
||||||
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor(staticName = "newPipeline")
|
|
||||||
public class NewPipelineEvent {
|
|
||||||
|
|
||||||
private Pipeline pipeline;
|
|
||||||
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor(staticName = "newProject")
|
|
||||||
public class NewProjectEvent {
|
|
||||||
|
|
||||||
private Project project;
|
|
||||||
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor(staticName = "updateDiscussion")
|
|
||||||
public class UpdateDiscussionEvent {
|
|
||||||
|
|
||||||
private Discussion oldDiscussion;
|
|
||||||
private Discussion newDiscussion;
|
|
||||||
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.changed.ApprovalChanged;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.changed.AssigneeChanged;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.changed.ReviewerChanged;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor(staticName = "updateMergeRequest")
|
|
||||||
public class UpdateMergeRequestEvent {
|
|
||||||
|
|
||||||
private MergeRequest oldMergeRequest;
|
|
||||||
private MergeRequest newMergeRequest;
|
|
||||||
|
|
||||||
private AssigneeChanged assigneeChanged;
|
|
||||||
private ReviewerChanged reviewerChanged;
|
|
||||||
private Optional<ApprovalChanged> optApprovalChanged;
|
|
||||||
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor(staticName = "updatePipeline")
|
|
||||||
public class UpdatePipelineEvent {
|
|
||||||
|
|
||||||
private Pipeline oldPipeline;
|
|
||||||
private Pipeline newPipeline;
|
|
||||||
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify;
|
|
||||||
|
|
||||||
public interface GroupNotify extends Notify {
|
|
||||||
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify;
|
|
||||||
|
|
||||||
public interface PersonalNotify extends Notify{
|
|
||||||
|
|
||||||
}
|
|
@ -1,13 +1,13 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify.comment;
|
package dev.struchkov.bot.gitlab.context.domain.notify.comment;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
||||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@FieldNames
|
@FieldNames
|
||||||
public final class NewCommentPersonalNotify implements PersonalNotify {
|
public final class NewCommentNotify implements Notify {
|
||||||
|
|
||||||
public static final String TYPE = "NewCommentNotify";
|
public static final String TYPE = "NewCommentNotify";
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ public final class NewCommentPersonalNotify implements PersonalNotify {
|
|||||||
private final int numberNotes;
|
private final int numberNotes;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
public NewCommentPersonalNotify(
|
public NewCommentNotify(
|
||||||
String threadId,
|
String threadId,
|
||||||
String mergeRequestName,
|
String mergeRequestName,
|
||||||
String url,
|
String url,
|
@ -1,38 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify.group.mr;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify;
|
|
||||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.group.mr.ConflictMrGroupNotifyFields.CLASS_NAME;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@FieldNames
|
|
||||||
public class ConflictMrGroupNotify implements GroupNotify {
|
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
|
||||||
|
|
||||||
protected final String sourceBranch;
|
|
||||||
protected final String projectName;
|
|
||||||
protected final String title;
|
|
||||||
protected final String url;
|
|
||||||
protected final String milestone;
|
|
||||||
protected final String authorTelegramUsername;
|
|
||||||
|
|
||||||
@Builder
|
|
||||||
public ConflictMrGroupNotify(String sourceBranch, String projectName, String title, String url, String milestone, String authorTelegramUsername) {
|
|
||||||
this.sourceBranch = sourceBranch;
|
|
||||||
this.projectName = projectName;
|
|
||||||
this.title = title;
|
|
||||||
this.url = url;
|
|
||||||
this.milestone = milestone;
|
|
||||||
this.authorTelegramUsername = authorTelegramUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify.group.mr;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify;
|
|
||||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.group.mr.NewMergeRequestGroupPersonalNotifyFields.CLASS_NAME;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@FieldNames
|
|
||||||
public class NewMergeRequestGroupNotify implements GroupNotify {
|
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
|
||||||
|
|
||||||
protected final Long mrId;
|
|
||||||
protected final String projectName;
|
|
||||||
protected final String title;
|
|
||||||
protected final String url;
|
|
||||||
protected final String milestone;
|
|
||||||
protected final String description;
|
|
||||||
protected final String author;
|
|
||||||
protected final String targetBranch;
|
|
||||||
protected final String sourceBranch;
|
|
||||||
protected final Map<Long, String> reviewerTelegramUsernames;
|
|
||||||
protected final Person assignee;
|
|
||||||
|
|
||||||
@Builder
|
|
||||||
public NewMergeRequestGroupNotify(Long mrId, String projectName, String title, String url, String milestone, String description, String author, String targetBranch, String sourceBranch, Map<Long, String> reviewerTelegramUsernames, Person assignee) {
|
|
||||||
this.mrId = mrId;
|
|
||||||
this.projectName = projectName;
|
|
||||||
this.title = title;
|
|
||||||
this.url = url;
|
|
||||||
this.milestone = milestone;
|
|
||||||
this.description = description;
|
|
||||||
this.author = author;
|
|
||||||
this.targetBranch = targetBranch;
|
|
||||||
this.sourceBranch = sourceBranch;
|
|
||||||
this.reviewerTelegramUsernames = reviewerTelegramUsernames;
|
|
||||||
this.assignee = assignee;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify.group.mr;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify;
|
|
||||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@FieldNames
|
|
||||||
public class NoReviewerGroupNotify implements GroupNotify {
|
|
||||||
|
|
||||||
public static final String TYPE = "NoReviewersGroupNotify";
|
|
||||||
|
|
||||||
protected final String projectName;
|
|
||||||
protected final String title;
|
|
||||||
protected final String url;
|
|
||||||
protected final String milestone;
|
|
||||||
protected final String targetBranch;
|
|
||||||
protected final String sourceBranch;
|
|
||||||
protected final Person assignee;
|
|
||||||
protected final String ownerTelegramUsername;
|
|
||||||
|
|
||||||
@Builder
|
|
||||||
public NoReviewerGroupNotify(String projectName, String title, String url, String milestone, String targetBranch, String sourceBranch, Person assignee, String ownerTelegramUsername) {
|
|
||||||
this.projectName = projectName;
|
|
||||||
this.title = title;
|
|
||||||
this.url = url;
|
|
||||||
this.milestone = milestone;
|
|
||||||
this.targetBranch = targetBranch;
|
|
||||||
this.sourceBranch = sourceBranch;
|
|
||||||
this.assignee = assignee;
|
|
||||||
this.ownerTelegramUsername = ownerTelegramUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify.group.pipeline;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify;
|
|
||||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.group.pipeline.PipelineGroupNotifyFields.CLASS_NAME;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@FieldNames
|
|
||||||
public class PipelineGroupNotify implements GroupNotify {
|
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
|
||||||
|
|
||||||
private final String projectName;
|
|
||||||
private final String refName;
|
|
||||||
private final PipelineStatus oldStatus;
|
|
||||||
private final PipelineStatus newStatus;
|
|
||||||
private final String webUrl;
|
|
||||||
private final String ownerTelegramUsername;
|
|
||||||
|
|
||||||
@Builder
|
|
||||||
public PipelineGroupNotify(String projectName, String refName, PipelineStatus oldStatus, PipelineStatus newStatus, String webUrl, String ownerTelegramUsername) {
|
|
||||||
this.projectName = projectName;
|
|
||||||
this.refName = refName;
|
|
||||||
this.oldStatus = oldStatus;
|
|
||||||
this.newStatus = newStatus;
|
|
||||||
this.webUrl = webUrl;
|
|
||||||
this.ownerTelegramUsername = ownerTelegramUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,33 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain.notify.issue;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko 25.01.2021
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class DeleteFromAssigneesNotify extends IssueNotify {
|
||||||
|
|
||||||
|
public static final String TYPE = "DeleteFromAssigneesOfIssueNotify";
|
||||||
|
|
||||||
|
private final String updateDate;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
public DeleteFromAssigneesNotify(
|
||||||
|
String projectName,
|
||||||
|
String title,
|
||||||
|
String url,
|
||||||
|
String issueType,
|
||||||
|
String updateDate
|
||||||
|
) {
|
||||||
|
super(projectName, title, url, issueType);
|
||||||
|
this.updateDate = updateDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain.notify.issue;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko 25.01.2021
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class DescriptionIssueNotify extends IssueNotify {
|
||||||
|
|
||||||
|
public static final String TYPE = "DescriptionIssueNotify";
|
||||||
|
|
||||||
|
private final String newDescription;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
public DescriptionIssueNotify(
|
||||||
|
String projectName,
|
||||||
|
String title,
|
||||||
|
String url,
|
||||||
|
String issueType,
|
||||||
|
String newDescription
|
||||||
|
) {
|
||||||
|
super(projectName, title, url, issueType);
|
||||||
|
this.newDescription = newDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain.notify.issue;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko 25.01.2021
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class DueDateIssueNotify extends IssueNotify {
|
||||||
|
|
||||||
|
public static final String TYPE = "DueDateIssueNotify";
|
||||||
|
|
||||||
|
private final String oldDueDate;
|
||||||
|
private final String newDueDate;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
public DueDateIssueNotify(
|
||||||
|
String projectName,
|
||||||
|
String title,
|
||||||
|
String url,
|
||||||
|
String issueType,
|
||||||
|
String oldDueDate,
|
||||||
|
String newDueDate
|
||||||
|
) {
|
||||||
|
super(projectName, title, url, issueType);
|
||||||
|
this.oldDueDate = oldDueDate;
|
||||||
|
this.newDueDate = newDueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain.notify.issue;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko 23.01.2021
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public abstract class IssueNotify implements Notify {
|
||||||
|
|
||||||
|
protected final String projectName;
|
||||||
|
protected final String title;
|
||||||
|
protected final String url;
|
||||||
|
protected final String issueType;
|
||||||
|
|
||||||
|
public IssueNotify(
|
||||||
|
String projectName,
|
||||||
|
String title,
|
||||||
|
String url,
|
||||||
|
String issueType
|
||||||
|
) {
|
||||||
|
this.projectName = projectName;
|
||||||
|
this.title = title;
|
||||||
|
this.url = url;
|
||||||
|
this.issueType = issueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain.notify.issue;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko 23.01.2021
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class NewIssueNotify extends IssueNotify {
|
||||||
|
|
||||||
|
public static final String TYPE = "NewIssueNotify";
|
||||||
|
|
||||||
|
private final String author;
|
||||||
|
private final String description;
|
||||||
|
private final String dueDate;
|
||||||
|
private final Set<String> labels;
|
||||||
|
private final String confidential;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
public NewIssueNotify(
|
||||||
|
String projectName,
|
||||||
|
String title,
|
||||||
|
String url,
|
||||||
|
String issueType,
|
||||||
|
String author,
|
||||||
|
String description,
|
||||||
|
String dueDate,
|
||||||
|
Set<String> labels,
|
||||||
|
String confidential
|
||||||
|
) {
|
||||||
|
super(projectName, title, url, issueType);
|
||||||
|
this.author = author;
|
||||||
|
this.description = description;
|
||||||
|
this.dueDate = dueDate;
|
||||||
|
this.labels = labels;
|
||||||
|
this.confidential = confidential;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain.notify.issue;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.IssueState;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko 23.01.2021
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class StatusIssueNotify extends IssueNotify{
|
||||||
|
|
||||||
|
public static final String TYPE = "StatusIssueNotify";
|
||||||
|
|
||||||
|
private final IssueState oldStatus;
|
||||||
|
private final IssueState newStatus;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
private StatusIssueNotify(
|
||||||
|
String name,
|
||||||
|
String url,
|
||||||
|
String projectName,
|
||||||
|
String issueType,
|
||||||
|
IssueState oldStatus,
|
||||||
|
IssueState newStatus
|
||||||
|
) {
|
||||||
|
super(projectName, name, url, issueType);
|
||||||
|
this.oldStatus = oldStatus;
|
||||||
|
this.newStatus = newStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain.notify.issue;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko 25.01.2021
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class TitleIssueNotify extends IssueNotify {
|
||||||
|
|
||||||
|
public static final String TYPE = "TitleIssueNotify";
|
||||||
|
|
||||||
|
private final String newTitle;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
public TitleIssueNotify(
|
||||||
|
String projectName,
|
||||||
|
String title,
|
||||||
|
String url,
|
||||||
|
String issueType,
|
||||||
|
String newTitle
|
||||||
|
) {
|
||||||
|
super(projectName, title, url, issueType);
|
||||||
|
this.newTitle = newTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain.notify.issue;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.IssueType;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko 25.01.2021
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class TypeIssueNotify extends IssueNotify {
|
||||||
|
|
||||||
|
public static final String TYPE = "TypeIssueNotify";
|
||||||
|
|
||||||
|
private final IssueType oldType;
|
||||||
|
private final IssueType newType;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
public TypeIssueNotify(
|
||||||
|
String projectName,
|
||||||
|
String title,
|
||||||
|
String url,
|
||||||
|
String issueType,
|
||||||
|
IssueType oldType,
|
||||||
|
IssueType newType
|
||||||
|
) {
|
||||||
|
super(projectName, title, url, issueType);
|
||||||
|
this.oldType = oldType;
|
||||||
|
this.newType = newType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,42 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify.mergerequest;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
|
||||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ApprovalChangedMrPersonalNotifyFields.CLASS_NAME;
|
|
||||||
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@FieldNames
|
|
||||||
public class ApprovalChangedMrPersonalNotify extends MrPersonalNotify {
|
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
|
||||||
|
|
||||||
private final Set<Person> newApproval;
|
|
||||||
private final Set<Person> dontApproval;
|
|
||||||
|
|
||||||
@Builder
|
|
||||||
public ApprovalChangedMrPersonalNotify(
|
|
||||||
Long mrId,
|
|
||||||
String projectName,
|
|
||||||
String title,
|
|
||||||
String url,
|
|
||||||
String milestone,
|
|
||||||
Set<Person> newApproval,
|
|
||||||
Set<Person> dontApproval
|
|
||||||
) {
|
|
||||||
super(mrId, projectName, title, url, milestone);
|
|
||||||
this.newApproval = newApproval;
|
|
||||||
this.dontApproval = dontApproval;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -4,26 +4,25 @@ import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
|||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictMrPersonalNotifyFields.CLASS_NAME;
|
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictMrNotifyFields.CLASS_NAME;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@FieldNames
|
@FieldNames
|
||||||
public class ConflictMrPersonalNotify extends MrPersonalNotify {
|
public class ConflictMrNotify extends MrNotify {
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
public static final String TYPE = CLASS_NAME;
|
||||||
|
|
||||||
private final String sourceBranch;
|
private final String sourceBranch;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
private ConflictMrPersonalNotify(
|
private ConflictMrNotify(
|
||||||
Long mrId,
|
Long mrId,
|
||||||
String name,
|
String name,
|
||||||
String url,
|
String url,
|
||||||
String projectKey,
|
String projectKey,
|
||||||
String sourceBranch,
|
String sourceBranch
|
||||||
String milestone
|
|
||||||
) {
|
) {
|
||||||
super(mrId, projectKey, name, url, milestone);
|
super(mrId, projectKey, name, url);
|
||||||
this.sourceBranch = sourceBranch;
|
this.sourceBranch = sourceBranch;
|
||||||
}
|
}
|
||||||
|
|
@ -4,26 +4,25 @@ import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
|||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictResolveMrPersonalNotifyFields.CLASS_NAME;
|
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictResolveMrNotifyFields.CLASS_NAME;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@FieldNames
|
@FieldNames
|
||||||
public class ConflictResolveMrPersonalNotify extends MrPersonalNotify {
|
public class ConflictResolveMrNotify extends MrNotify {
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
public static final String TYPE = CLASS_NAME;
|
||||||
|
|
||||||
private final String sourceBranch;
|
private final String sourceBranch;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
private ConflictResolveMrPersonalNotify(
|
private ConflictResolveMrNotify(
|
||||||
Long mrId,
|
Long mrId,
|
||||||
String name,
|
String name,
|
||||||
String url,
|
String url,
|
||||||
String projectKey,
|
String projectKey,
|
||||||
String sourceBranch,
|
String sourceBranch
|
||||||
String milestone
|
|
||||||
) {
|
) {
|
||||||
super(mrId, projectKey, name, url, milestone);
|
super(mrId, projectKey, name, url);
|
||||||
this.sourceBranch = sourceBranch;
|
this.sourceBranch = sourceBranch;
|
||||||
}
|
}
|
||||||
|
|
@ -1,29 +1,26 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify.mergerequest;
|
package dev.struchkov.bot.gitlab.context.domain.notify.mergerequest;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public abstract class MrPersonalNotify implements PersonalNotify {
|
public abstract class MrNotify implements Notify {
|
||||||
|
|
||||||
protected final Long mrId;
|
protected final Long mrId;
|
||||||
protected final String projectName;
|
protected final String projectName;
|
||||||
protected final String title;
|
protected final String title;
|
||||||
protected final String url;
|
protected final String url;
|
||||||
protected final String milestone;
|
|
||||||
|
|
||||||
protected MrPersonalNotify(
|
protected MrNotify(
|
||||||
Long mrId,
|
Long mrId,
|
||||||
String projectName,
|
String projectName,
|
||||||
String title,
|
String title,
|
||||||
String url,
|
String url
|
||||||
String milestone
|
|
||||||
) {
|
) {
|
||||||
this.mrId = mrId;
|
this.mrId = mrId;
|
||||||
this.projectName = projectName;
|
this.projectName = projectName;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.milestone = milestone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -12,7 +12,7 @@ import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.NewMrF
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@FieldNames
|
@FieldNames
|
||||||
public class NewMrForAssignee extends NewMrPersonalNotify {
|
public class NewMrForAssignee extends NewMrNotify {
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
public static final String TYPE = CLASS_NAME;
|
||||||
|
|
||||||
@ -33,8 +33,7 @@ public class NewMrForAssignee extends NewMrPersonalNotify {
|
|||||||
Set<String> labels,
|
Set<String> labels,
|
||||||
@Singular List<String> reviewers,
|
@Singular List<String> reviewers,
|
||||||
String oldAssigneeName,
|
String oldAssigneeName,
|
||||||
String newAssigneeName,
|
String newAssigneeName
|
||||||
String milestone
|
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
mrId,
|
mrId,
|
||||||
@ -45,8 +44,7 @@ public class NewMrForAssignee extends NewMrPersonalNotify {
|
|||||||
projectName,
|
projectName,
|
||||||
targetBranch,
|
targetBranch,
|
||||||
sourceBranch,
|
sourceBranch,
|
||||||
labels,
|
labels
|
||||||
milestone
|
|
||||||
);
|
);
|
||||||
this.reviewers = reviewers;
|
this.reviewers = reviewers;
|
||||||
this.oldAssigneeName = oldAssigneeName;
|
this.oldAssigneeName = oldAssigneeName;
|
||||||
|
@ -10,7 +10,7 @@ import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.NewMrF
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@FieldNames
|
@FieldNames
|
||||||
public class NewMrForReview extends NewMrPersonalNotify {
|
public class NewMrForReview extends NewMrNotify {
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
public static final String TYPE = CLASS_NAME;
|
||||||
|
|
||||||
@ -27,8 +27,7 @@ public class NewMrForReview extends NewMrPersonalNotify {
|
|||||||
String targetBranch,
|
String targetBranch,
|
||||||
String sourceBranch,
|
String sourceBranch,
|
||||||
Set<String> labels,
|
Set<String> labels,
|
||||||
String assignee,
|
String assignee
|
||||||
String milestone
|
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
mrId,
|
mrId,
|
||||||
@ -39,8 +38,7 @@ public class NewMrForReview extends NewMrPersonalNotify {
|
|||||||
projectName,
|
projectName,
|
||||||
targetBranch,
|
targetBranch,
|
||||||
sourceBranch,
|
sourceBranch,
|
||||||
labels,
|
labels
|
||||||
milestone
|
|
||||||
);
|
);
|
||||||
this.assignee = assignee;
|
this.assignee = assignee;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import lombok.Getter;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public abstract class NewMrPersonalNotify extends MrPersonalNotify {
|
public abstract class NewMrNotify extends MrNotify {
|
||||||
|
|
||||||
protected final String description;
|
protected final String description;
|
||||||
protected final String author;
|
protected final String author;
|
||||||
@ -13,7 +13,7 @@ public abstract class NewMrPersonalNotify extends MrPersonalNotify {
|
|||||||
protected final String sourceBranch;
|
protected final String sourceBranch;
|
||||||
protected final Set<String> labels;
|
protected final Set<String> labels;
|
||||||
|
|
||||||
protected NewMrPersonalNotify(
|
protected NewMrNotify(
|
||||||
Long mrId,
|
Long mrId,
|
||||||
String title,
|
String title,
|
||||||
String url,
|
String url,
|
||||||
@ -22,10 +22,9 @@ public abstract class NewMrPersonalNotify extends MrPersonalNotify {
|
|||||||
String projectName,
|
String projectName,
|
||||||
String targetBranch,
|
String targetBranch,
|
||||||
String sourceBranch,
|
String sourceBranch,
|
||||||
Set<String> labels,
|
Set<String> labels
|
||||||
String milestone
|
|
||||||
) {
|
) {
|
||||||
super(mrId, projectName, title, url, milestone);
|
super(mrId, projectName, title, url);
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.author = author;
|
this.author = author;
|
||||||
this.targetBranch = targetBranch;
|
this.targetBranch = targetBranch;
|
@ -5,11 +5,11 @@ import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
|||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.StatusMrPersonalNotifyFields.CLASS_NAME;
|
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.StatusMrNotifyFields.CLASS_NAME;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@FieldNames
|
@FieldNames
|
||||||
public class StatusMrPersonalNotify extends MrPersonalNotify {
|
public class StatusMrNotify extends MrNotify {
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
public static final String TYPE = CLASS_NAME;
|
||||||
|
|
||||||
@ -17,16 +17,15 @@ public class StatusMrPersonalNotify extends MrPersonalNotify {
|
|||||||
private final MergeRequestState newStatus;
|
private final MergeRequestState newStatus;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
private StatusMrPersonalNotify(
|
private StatusMrNotify(
|
||||||
Long mrId,
|
Long mrId,
|
||||||
String name,
|
String name,
|
||||||
String url,
|
String url,
|
||||||
String projectName,
|
String projectName,
|
||||||
MergeRequestState oldStatus,
|
MergeRequestState oldStatus,
|
||||||
MergeRequestState newStatus,
|
MergeRequestState newStatus
|
||||||
String milestone
|
|
||||||
) {
|
) {
|
||||||
super(mrId, projectName, name, url, milestone);
|
super(mrId, projectName, name, url);
|
||||||
this.oldStatus = oldStatus;
|
this.oldStatus = oldStatus;
|
||||||
this.newStatus = newStatus;
|
this.newStatus = newStatus;
|
||||||
}
|
}
|
@ -4,11 +4,11 @@ import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
|||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.UpdateMrPersonalNotifyFields.CLASS_NAME;
|
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.UpdateMrNotifyFields.CLASS_NAME;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@FieldNames
|
@FieldNames
|
||||||
public class UpdateMrPersonalNotify extends MrPersonalNotify {
|
public class UpdateMrNotify extends MrNotify {
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
public static final String TYPE = CLASS_NAME;
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ public class UpdateMrPersonalNotify extends MrPersonalNotify {
|
|||||||
private final String comment;
|
private final String comment;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
private UpdateMrPersonalNotify(
|
private UpdateMrNotify(
|
||||||
Long mrId,
|
Long mrId,
|
||||||
String name,
|
String name,
|
||||||
String url,
|
String url,
|
||||||
@ -30,10 +30,9 @@ public class UpdateMrPersonalNotify extends MrPersonalNotify {
|
|||||||
Long allResolvedTasks,
|
Long allResolvedTasks,
|
||||||
Long personTasks,
|
Long personTasks,
|
||||||
Long personResolvedTasks,
|
Long personResolvedTasks,
|
||||||
String comment,
|
String comment
|
||||||
String milestone
|
|
||||||
) {
|
) {
|
||||||
super(mrId, projectName, name, url, milestone);
|
super(mrId, projectName, name, url);
|
||||||
this.author = author;
|
this.author = author;
|
||||||
this.allTasks = allTasks;
|
this.allTasks = allTasks;
|
||||||
this.allResolvedTasks = allResolvedTasks;
|
this.allResolvedTasks = allResolvedTasks;
|
@ -1,12 +1,12 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify.pipeline;
|
package dev.struchkov.bot.gitlab.context.domain.notify.pipeline;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
||||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.pipeline.PipelinePersonalNotifyFields.CLASS_NAME;
|
import static dev.struchkov.bot.gitlab.context.domain.notify.pipeline.PipelineNotifyFields.CLASS_NAME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author upagge 17.01.2021
|
* @author upagge 17.01.2021
|
||||||
@ -14,25 +14,28 @@ import static dev.struchkov.bot.gitlab.context.domain.notify.pipeline.PipelinePe
|
|||||||
//TODO [16.12.2022|uPagge]: Нужно реализовать заполнение projectName
|
//TODO [16.12.2022|uPagge]: Нужно реализовать заполнение projectName
|
||||||
@Getter
|
@Getter
|
||||||
@FieldNames
|
@FieldNames
|
||||||
public final class PipelinePersonalNotify implements PersonalNotify {
|
public final class PipelineNotify implements Notify {
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
public static final String TYPE = CLASS_NAME;
|
||||||
|
|
||||||
private final String projectName;
|
private final Long projectId;
|
||||||
|
private final Long pipelineId;
|
||||||
private final String refName;
|
private final String refName;
|
||||||
private final PipelineStatus oldStatus;
|
private final PipelineStatus oldStatus;
|
||||||
private final PipelineStatus newStatus;
|
private final PipelineStatus newStatus;
|
||||||
private final String webUrl;
|
private final String webUrl;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
public PipelinePersonalNotify(
|
public PipelineNotify(
|
||||||
String projectName,
|
Long projectId,
|
||||||
|
Long pipelineId,
|
||||||
String refName,
|
String refName,
|
||||||
PipelineStatus oldStatus,
|
PipelineStatus oldStatus,
|
||||||
PipelineStatus newStatus,
|
PipelineStatus newStatus,
|
||||||
String webUrl
|
String webUrl
|
||||||
) {
|
) {
|
||||||
this.projectName = projectName;
|
this.projectId = projectId;
|
||||||
|
this.pipelineId = pipelineId;
|
||||||
this.refName = refName;
|
this.refName = refName;
|
||||||
this.oldStatus = oldStatus;
|
this.oldStatus = oldStatus;
|
||||||
this.newStatus = newStatus;
|
this.newStatus = newStatus;
|
@ -1,18 +1,18 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify.project;
|
package dev.struchkov.bot.gitlab.context.domain.notify.project;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
||||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.project.NewProjectPersonalNotifyFields.CLASS_NAME;
|
import static dev.struchkov.bot.gitlab.context.domain.notify.project.NewProjectNotifyFields.CLASS_NAME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author upagge 15.01.2021
|
* @author upagge 15.01.2021
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@FieldNames
|
@FieldNames
|
||||||
public final class NewProjectPersonalNotify implements PersonalNotify {
|
public final class NewProjectNotify implements Notify {
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
public static final String TYPE = CLASS_NAME;
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ public final class NewProjectPersonalNotify implements PersonalNotify {
|
|||||||
private final String httpUrlToRepo;
|
private final String httpUrlToRepo;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
public NewProjectPersonalNotify(
|
public NewProjectNotify(
|
||||||
Long projectId,
|
Long projectId,
|
||||||
String projectName,
|
String projectName,
|
||||||
String projectUrl,
|
String projectUrl,
|
@ -8,14 +8,14 @@ import lombok.Singular;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.task.DiscussionNewPersonalNotifyFields.CLASS_NAME;
|
import static dev.struchkov.bot.gitlab.context.domain.notify.task.DiscussionNewNotifyFields.CLASS_NAME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author upagge 10.09.2020
|
* @author upagge 10.09.2020
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@FieldNames
|
@FieldNames
|
||||||
public class DiscussionNewPersonalNotify extends ThreadPersonalNotify {
|
public class DiscussionNewNotify extends ThreadNotify {
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
public static final String TYPE = CLASS_NAME;
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ public class DiscussionNewPersonalNotify extends ThreadPersonalNotify {
|
|||||||
private final List<Pair<String, String>> notes;
|
private final List<Pair<String, String>> notes;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
public DiscussionNewPersonalNotify(
|
public DiscussionNewNotify(
|
||||||
String threadId,
|
String threadId,
|
||||||
String mergeRequestName,
|
String mergeRequestName,
|
||||||
String authorName,
|
String authorName,
|
@ -4,14 +4,14 @@ import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
|||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.task.ThreadClosePersonalNotifyFields.CLASS_NAME;
|
import static dev.struchkov.bot.gitlab.context.domain.notify.task.ThreadCloseNotifyFields.CLASS_NAME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author upagge 10.09.2020
|
* @author upagge 10.09.2020
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@FieldNames
|
@FieldNames
|
||||||
public class ThreadClosePersonalNotify extends ThreadPersonalNotify {
|
public class ThreadCloseNotify extends ThreadNotify {
|
||||||
|
|
||||||
public static final String TYPE = CLASS_NAME;
|
public static final String TYPE = CLASS_NAME;
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ public class ThreadClosePersonalNotify extends ThreadPersonalNotify {
|
|||||||
private final String messageLastNote;
|
private final String messageLastNote;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
protected ThreadClosePersonalNotify(
|
protected ThreadCloseNotify(
|
||||||
String mergeRequestName,
|
String mergeRequestName,
|
||||||
String authorName,
|
String authorName,
|
||||||
String url,
|
String url,
|
@ -1,17 +1,17 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify.task;
|
package dev.struchkov.bot.gitlab.context.domain.notify.task;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public abstract class ThreadPersonalNotify implements PersonalNotify {
|
public abstract class ThreadNotify implements Notify {
|
||||||
|
|
||||||
protected final String mergeRequestName;
|
protected final String mergeRequestName;
|
||||||
protected final String authorName;
|
protected final String authorName;
|
||||||
protected final String url;
|
protected final String url;
|
||||||
protected final String messageTask;
|
protected final String messageTask;
|
||||||
|
|
||||||
protected ThreadPersonalNotify(
|
protected ThreadNotify(
|
||||||
String mergeRequestName,
|
String mergeRequestName,
|
||||||
String authorName,
|
String authorName,
|
||||||
String url,
|
String url,
|
@ -1,17 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.prop;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Основные настройки приложения.
|
|
||||||
*
|
|
||||||
* @author upagge 11.10.2020
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class AppProperty {
|
|
||||||
|
|
||||||
private String version;
|
|
||||||
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.prop;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class GroupNotifyProperty {
|
|
||||||
|
|
||||||
private Optional<String> chatId;
|
|
||||||
private Optional<Integer> threadId;
|
|
||||||
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.prop;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author upagge 15.01.2021
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class PersonProperty {
|
|
||||||
|
|
||||||
private String telegramId;
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,27 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.repository;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.IdAndStatusIssue;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.IssueState;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Issue;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko [24.01.2023]
|
||||||
|
*/
|
||||||
|
public interface IssueRepository {
|
||||||
|
|
||||||
|
Set<IdAndStatusIssue> findAllIdByStateIn(@NonNull Set<IssueState> states);
|
||||||
|
|
||||||
|
Issue save(Issue issue);
|
||||||
|
|
||||||
|
Optional<Issue> findById(Long issueId);
|
||||||
|
|
||||||
|
List<Issue> findAllById(Set<Long> mergeRequestIds);
|
||||||
|
|
||||||
|
void deleteByStates(Set<IssueState> states);
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.repository;
|
package dev.struchkov.bot.gitlab.context.repository;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.PersonTelegram;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -18,8 +17,4 @@ public interface PersonRepository {
|
|||||||
|
|
||||||
List<Person> findAllById(Set<Long> personIds);
|
List<Person> findAllById(Set<Long> personIds);
|
||||||
|
|
||||||
Optional<PersonTelegram> findTelegramInfoById(Long personId);
|
|
||||||
|
|
||||||
List<PersonTelegram> findAllTelegramInfoByIds(Set<Long> personIds);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.service;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.*;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Issue;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko [24.01.2023]
|
||||||
|
*/
|
||||||
|
public interface IssueService {
|
||||||
|
|
||||||
|
Issue create(@NonNull Issue issue);
|
||||||
|
|
||||||
|
Issue update(@NonNull Issue issue);
|
||||||
|
|
||||||
|
List<Issue> updateAll(@NonNull List<Issue> issues);
|
||||||
|
|
||||||
|
ExistContainer<Issue, Long> existsById(@NonNull Set<Long> issueIds);
|
||||||
|
|
||||||
|
List<Issue> createAll(List<Issue> issues);
|
||||||
|
|
||||||
|
Set<IdAndStatusIssue> getAllId(Set<IssueState> statuses);
|
||||||
|
|
||||||
|
void cleanOld();
|
||||||
|
|
||||||
|
}
|
@ -1,13 +1,11 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.service;
|
package dev.struchkov.bot.gitlab.context.service;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
public interface MessageSendService {
|
public interface MessageSendService {
|
||||||
|
|
||||||
void send(@NonNull PersonalNotify notify);
|
void send(@NonNull Notify notify);
|
||||||
|
|
||||||
void send(@NonNull GroupNotify notify);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.service;
|
package dev.struchkov.bot.gitlab.context.service;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Сервис по работе с изменениями в битбакете.
|
* Сервис по работе с изменениями в битбакете.
|
||||||
*
|
*
|
||||||
* @author upagge
|
* @author upagge
|
||||||
* @see PersonalNotify
|
* @see Notify
|
||||||
*/
|
*/
|
||||||
public interface NotifyService {
|
public interface NotifyService {
|
||||||
|
|
||||||
<T extends PersonalNotify> void send(T notify);
|
<T extends Notify> void send(T notify);
|
||||||
|
|
||||||
<T extends GroupNotify> void send(T notify);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@ import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
|||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,14 +14,12 @@ public interface PersonService {
|
|||||||
|
|
||||||
Person create(@NonNull Person person);
|
Person create(@NonNull Person person);
|
||||||
|
|
||||||
|
Person update(@NonNull Person person);
|
||||||
|
|
||||||
Person getByIdOrThrown(@NonNull Long personId);
|
Person getByIdOrThrown(@NonNull Long personId);
|
||||||
|
|
||||||
ExistContainer<Person, Long> existsById(Set<Long> personIds);
|
ExistContainer<Person, Long> existsById(Set<Long> personIds);
|
||||||
|
|
||||||
List<Person> createAll(List<Person> newPersons);
|
List<Person> createAll(List<Person> newPersons);
|
||||||
|
|
||||||
Optional<String> getTelegramUsernamesByPersonIds(Long personId);
|
|
||||||
|
|
||||||
Map<Long, String> getTelegramUsernamesByPersonIds(Set<Long> personIds);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,17 +19,16 @@ public class Icons {
|
|||||||
public static final String GREEN_CIRCLE = "\uD83D\uDFE2";
|
public static final String GREEN_CIRCLE = "\uD83D\uDFE2";
|
||||||
public static final String PEN = "✏️";
|
public static final String PEN = "✏️";
|
||||||
public static final String ASSIGNEE = "\uD83C\uDFA9";
|
public static final String ASSIGNEE = "\uD83C\uDFA9";
|
||||||
public static final String APPROVAL = "\uD83D\uDC4D";
|
|
||||||
public static final String BUILD = "⚙️";
|
public static final String BUILD = "⚙️";
|
||||||
public static final String LINK = "\uD83D\uDD17";
|
public static final String LINK = "\uD83D\uDD17";
|
||||||
public static final String REVIEWER = "\uD83D\uDD0E";
|
public static final String REVIEWER = "\uD83D\uDD0E";
|
||||||
public static final String MILESTONE = "\uD83C\uDFAF";
|
|
||||||
public static final String PROJECT = "\uD83C\uDFD7";
|
public static final String PROJECT = "\uD83C\uDFD7";
|
||||||
public static final String DISABLE_NOTIFY = "\uD83D\uDD15";
|
public static final String DISABLE_NOTIFY = "\uD83D\uDD15";
|
||||||
public static final String YES = "✅";
|
public static final String YES = "✅";
|
||||||
public static final String NO = "❌";
|
public static final String NO = "❌";
|
||||||
public static final String NOTIFY = "\uD83D\uDD14";
|
public static final String NOTIFY = "\uD83D\uDD14";
|
||||||
public static final String GOOD = "\uD83D\uDC4D";
|
public static final String GOOD = "\uD83D\uDC4D";
|
||||||
|
public static final String BELL ="\uD83D\uDD14";
|
||||||
|
|
||||||
private Icons() {
|
private Icons() {
|
||||||
utilityClass();
|
utilityClass();
|
||||||
@ -39,4 +38,4 @@ public class Icons {
|
|||||||
return "[" + escapeMarkdown(title) + "](" + url + ")";
|
return "[" + escapeMarkdown(title) + "](" + url + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.struchkov.bot.gitlab</groupId>
|
<groupId>dev.struchkov.bot.gitlab</groupId>
|
||||||
<artifactId>gitlab-bot</artifactId>
|
<artifactId>gitlab-bot</artifactId>
|
||||||
<version>2.0.0-SNAPSHOT</version>
|
<version>1.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>bot-core</artifactId>
|
<artifactId>bot-core</artifactId>
|
||||||
@ -34,10 +34,6 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@ -56,6 +52,11 @@
|
|||||||
<artifactId>postgresql</artifactId>
|
<artifactId>postgresql</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.struchkov.bot.gitlab</groupId>
|
||||||
|
<artifactId>gitlab-sdk</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
@ -63,12 +64,10 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>dev.struchkov.sdk.gitlab</groupId>
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
<artifactId>gitlab-sdk-spring-boot-starter</artifactId>
|
<artifactId>okhttp</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.core.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class CoreConfig {
|
||||||
|
|
||||||
|
@Bean("parserPool")
|
||||||
|
public ForkJoinPool parserPool() {
|
||||||
|
return new ForkJoinPool(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.core.config.properties;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Основные настройки приложения.
|
||||||
|
*
|
||||||
|
* @author upagge 11.10.2020
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "gitlab-bot")
|
||||||
|
public class AppProperty {
|
||||||
|
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.core.config.properties;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Данные необходимые для взаимодействия с API GitLab.
|
||||||
|
*
|
||||||
|
* @author upagge [31.01.2020]
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties("gitlab-bot.gitlab")
|
||||||
|
public class GitlabProperty {
|
||||||
|
|
||||||
|
private String baseUrl;
|
||||||
|
|
||||||
|
private String replaceUrl;
|
||||||
|
|
||||||
|
private String usersUrl;
|
||||||
|
|
||||||
|
private String userUrl;
|
||||||
|
|
||||||
|
private String projectsUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Адрес, по которому можно получить открытые MR
|
||||||
|
*/
|
||||||
|
private String openMergeRequestsUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Адрес, по которому можно получить закрытые MR
|
||||||
|
*/
|
||||||
|
private String closeMergeRequestsUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Адрес, по которому можно получить комментарии к MR
|
||||||
|
*/
|
||||||
|
private String commentsOfMergeRequestUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Адрес MR
|
||||||
|
*/
|
||||||
|
private String mergeRequestUrl;
|
||||||
|
|
||||||
|
private String projectAddUrl;
|
||||||
|
|
||||||
|
private String noteUrl;
|
||||||
|
|
||||||
|
private String notesOfMergeRequestUrl;
|
||||||
|
|
||||||
|
private String pipelinesUrl;
|
||||||
|
|
||||||
|
private String pipelineUrl;
|
||||||
|
|
||||||
|
private String lastCommitOfMergeRequestUrl;
|
||||||
|
|
||||||
|
private String newNoteUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Адрес дискуссий для MR
|
||||||
|
*/
|
||||||
|
private String discussionsUrl;
|
||||||
|
|
||||||
|
private String discussionUrl;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Адрес, по которому можно получить ISSUE
|
||||||
|
*/
|
||||||
|
private String issueUrl;
|
||||||
|
|
||||||
|
private String openIssueUrl;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.core.config.properties;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author upagge 15.01.2021
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "gitlab-bot.person")
|
||||||
|
public class PersonProperty {
|
||||||
|
|
||||||
|
private String token;
|
||||||
|
private String telegramId;
|
||||||
|
|
||||||
|
}
|
@ -1,388 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.handler;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.changed.ApprovalChanged;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.changed.AssigneeChanged;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.changed.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;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.event.NewMergeRequestEvent;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.event.UpdateMergeRequestEvent;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.group.mr.ConflictMrGroupNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.group.mr.NewMergeRequestGroupNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.group.mr.NoReviewerGroupNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ApprovalChangedMrPersonalNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictMrPersonalNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictResolveMrPersonalNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.NewMrForAssignee;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.NewMrForReview;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.StatusMrPersonalNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.UpdateMrPersonalNotify;
|
|
||||||
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.context.service.ProjectService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.context.event.EventListener;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
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 static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
|
||||||
import static java.lang.Boolean.TRUE;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class MergeRequestHandler {
|
|
||||||
|
|
||||||
private final NotifyService notifyService;
|
|
||||||
|
|
||||||
private final PersonService personService;
|
|
||||||
private final PersonInformation personInformation;
|
|
||||||
private final ProjectService projectService;
|
|
||||||
private final DiscussionService discussionService;
|
|
||||||
|
|
||||||
@EventListener
|
|
||||||
public void newMrHandle(NewMergeRequestEvent event) {
|
|
||||||
final MergeRequest mergeRequest = event.getMergeRequest();
|
|
||||||
final String projectName = projectService.getByIdOrThrow(mergeRequest.getProjectId()).getName();
|
|
||||||
|
|
||||||
final boolean userReviewer = mergeRequest.isUserReviewer();
|
|
||||||
final boolean userAssignee = mergeRequest.isUserAssignee();
|
|
||||||
if (mergeRequest.isConflict()) {
|
|
||||||
sendGroupNotifyAboutConflict(mergeRequest, projectName);
|
|
||||||
} else {
|
|
||||||
if (mergeRequest.isNotification()) {
|
|
||||||
if (userReviewer || userAssignee) {
|
|
||||||
if (userReviewer) sendNotifyNewMrReview(mergeRequest, projectName);
|
|
||||||
if (userAssignee) sendNotifyNewAssignee(mergeRequest, projectName, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sendGroupNotifyForReviewers(mergeRequest, projectName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventListener
|
|
||||||
public void updateMrHandle(UpdateMergeRequestEvent event) {
|
|
||||||
final MergeRequest oldMergeRequest = event.getOldMergeRequest();
|
|
||||||
final MergeRequest newMergeRequest = event.getNewMergeRequest();
|
|
||||||
final AssigneeChanged assigneeChanged = event.getAssigneeChanged();
|
|
||||||
final ReviewerChanged reviewerChanged = event.getReviewerChanged();
|
|
||||||
final Optional<ApprovalChanged> optApprovalChanged = event.getOptApprovalChanged();
|
|
||||||
|
|
||||||
final boolean resolveConflict = oldMergeRequest.isConflict() && !newMergeRequest.isConflict();
|
|
||||||
final boolean newConflict = !oldMergeRequest.isConflict() && newMergeRequest.isConflict();
|
|
||||||
final boolean isChangedMr = !oldMergeRequest.getUpdatedDate().equals(newMergeRequest.getUpdatedDate());
|
|
||||||
final Project project = projectService.getByIdOrThrow(newMergeRequest.getProjectId());
|
|
||||||
|
|
||||||
if (oldMergeRequest.isNotification()) {
|
|
||||||
if (newConflict) {
|
|
||||||
personalNotifyAboutNewConflict(oldMergeRequest, newMergeRequest, project);
|
|
||||||
}
|
|
||||||
if (resolveConflict) {
|
|
||||||
personalNotifyAboutResolveConflict(oldMergeRequest, newMergeRequest, project);
|
|
||||||
}
|
|
||||||
if (isChangedMr) {
|
|
||||||
personalNotifyAboutStatus(oldMergeRequest, newMergeRequest, project);
|
|
||||||
personalNotifyAboutUpdate(oldMergeRequest, newMergeRequest, project);
|
|
||||||
}
|
|
||||||
if (reviewerChanged.isChanged()) {
|
|
||||||
notifyReviewer(reviewerChanged, newMergeRequest, project);
|
|
||||||
}
|
|
||||||
if (assigneeChanged.isChanged()) {
|
|
||||||
notifyAssignee(assigneeChanged, oldMergeRequest, newMergeRequest, project);
|
|
||||||
}
|
|
||||||
if (optApprovalChanged.isPresent()) {
|
|
||||||
final ApprovalChanged approvalChanged = optApprovalChanged.get();
|
|
||||||
notifyApproval(newMergeRequest, project, approvalChanged);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//групповые уведомления
|
|
||||||
if (newConflict) {
|
|
||||||
sendGroupNotifyAboutConflict(newMergeRequest, project.getName());
|
|
||||||
}
|
|
||||||
if (reviewerChanged.isChanged()) {
|
|
||||||
sendGroupNotifyForReviewers(newMergeRequest, project.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void sendGroupNotifyAboutConflict(MergeRequest mergeRequest, String projectName) {
|
|
||||||
final Optional<String> optAuthorUserName = personService.getTelegramUsernamesByPersonIds(mergeRequest.getAuthor().getId());
|
|
||||||
if (optAuthorUserName.isPresent()) {
|
|
||||||
final String authorUserName = optAuthorUserName.get();
|
|
||||||
notifyService.send(
|
|
||||||
ConflictMrGroupNotify.builder()
|
|
||||||
.projectName(projectName)
|
|
||||||
.url(mergeRequest.getWebUrl())
|
|
||||||
.title(mergeRequest.getTitle())
|
|
||||||
.milestone(mergeRequest.getMilestone())
|
|
||||||
.sourceBranch(mergeRequest.getSourceBranch())
|
|
||||||
.authorTelegramUsername(authorUserName)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendGroupNotifyAboutNoReviewers(MergeRequest mergeRequest, String projectName) {
|
|
||||||
final Optional<String> optAuthorUserName = personService.getTelegramUsernamesByPersonIds(mergeRequest.getAuthor().getId());
|
|
||||||
if (optAuthorUserName.isPresent()) {
|
|
||||||
final String authorUsername = optAuthorUserName.get();
|
|
||||||
notifyService.send(
|
|
||||||
NoReviewerGroupNotify.builder()
|
|
||||||
.ownerTelegramUsername(authorUsername)
|
|
||||||
.title(mergeRequest.getTitle())
|
|
||||||
.url(mergeRequest.getWebUrl())
|
|
||||||
.milestone(mergeRequest.getMilestone())
|
|
||||||
.projectName(projectName)
|
|
||||||
.targetBranch(mergeRequest.getTargetBranch())
|
|
||||||
.sourceBranch(mergeRequest.getSourceBranch())
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendGroupNotifyForReviewers(MergeRequest mergeRequest, String projectName) {
|
|
||||||
if (checkNotEmpty(mergeRequest.getReviewers())) {
|
|
||||||
final Map<Long, String> reviewerTelegramUsernames = personService.getTelegramUsernamesByPersonIds(mergeRequest.getReviewers().stream().map(Person::getId).collect(Collectors.toSet()));
|
|
||||||
if (!reviewerTelegramUsernames.isEmpty()) {
|
|
||||||
notifyService.send(
|
|
||||||
NewMergeRequestGroupNotify.builder()
|
|
||||||
.mrId(mergeRequest.getId())
|
|
||||||
.title(mergeRequest.getTitle())
|
|
||||||
.url(mergeRequest.getWebUrl())
|
|
||||||
.author(mergeRequest.getAuthor().getName())
|
|
||||||
.reviewerTelegramUsernames(reviewerTelegramUsernames)
|
|
||||||
.milestone(mergeRequest.getMilestone())
|
|
||||||
.projectName(projectName)
|
|
||||||
.targetBranch(mergeRequest.getTargetBranch())
|
|
||||||
.sourceBranch(mergeRequest.getSourceBranch())
|
|
||||||
.description(mergeRequest.getDescription())
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sendGroupNotifyAboutNoReviewers(mergeRequest, projectName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void notifyApproval(MergeRequest mergeRequest, Project project, ApprovalChanged approvalChanged) {
|
|
||||||
final Set<Person> newApproval = approvalChanged.getNewApproval().stream()
|
|
||||||
.filter(approval -> !personInformation.getId().equals(approval.getId()))
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
final Set<Person> dontApproval = approvalChanged.getDontApprove().stream()
|
|
||||||
.filter(approval -> !personInformation.getId().equals(approval.getId()))
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
if (checkNotEmpty(newApproval) || checkNotEmpty(dontApproval)) {
|
|
||||||
notifyService.send(
|
|
||||||
ApprovalChangedMrPersonalNotify.builder()
|
|
||||||
.mrId(mergeRequest.getId())
|
|
||||||
.milestone(mergeRequest.getMilestone())
|
|
||||||
.projectName(project.getName())
|
|
||||||
.title(mergeRequest.getTitle())
|
|
||||||
.url(mergeRequest.getWebUrl())
|
|
||||||
.newApproval(newApproval)
|
|
||||||
.dontApproval(dontApproval)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendNotifyNewMrReview(MergeRequest mergeRequest, String projectName) {
|
|
||||||
final NewMrForReview.NewMrForReviewBuilder builder = NewMrForReview.builder()
|
|
||||||
.mrId(mergeRequest.getId())
|
|
||||||
.projectName(projectName)
|
|
||||||
.labels(mergeRequest.getLabels())
|
|
||||||
.author(mergeRequest.getAuthor().getName())
|
|
||||||
.milestone(mergeRequest.getMilestone())
|
|
||||||
.description(mergeRequest.getDescription())
|
|
||||||
.title(mergeRequest.getTitle())
|
|
||||||
.url(mergeRequest.getWebUrl())
|
|
||||||
.targetBranch(mergeRequest.getTargetBranch())
|
|
||||||
.sourceBranch(mergeRequest.getSourceBranch());
|
|
||||||
|
|
||||||
getAssignee(mergeRequest)
|
|
||||||
.map(Person::getName)
|
|
||||||
.ifPresent(builder::assignee);
|
|
||||||
|
|
||||||
notifyService.send(builder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendNotifyNewAssignee(MergeRequest mergeRequest, String projectName, String oldAssigneeName) {
|
|
||||||
final NewMrForAssignee.NewMrForAssigneeBuilder builder = NewMrForAssignee.builder()
|
|
||||||
.mrId(mergeRequest.getId())
|
|
||||||
.projectName(projectName)
|
|
||||||
.labels(mergeRequest.getLabels())
|
|
||||||
.author(mergeRequest.getAuthor().getName())
|
|
||||||
.description(mergeRequest.getDescription())
|
|
||||||
.milestone(mergeRequest.getMilestone())
|
|
||||||
.title(mergeRequest.getTitle())
|
|
||||||
.url(mergeRequest.getWebUrl())
|
|
||||||
.targetBranch(mergeRequest.getTargetBranch())
|
|
||||||
.sourceBranch(mergeRequest.getSourceBranch())
|
|
||||||
.milestone(mergeRequest.getMilestone())
|
|
||||||
.reviewers(mergeRequest.getReviewers().stream().map(Person::getName).toList());
|
|
||||||
|
|
||||||
if (checkNotNull(oldAssigneeName)) {
|
|
||||||
builder.oldAssigneeName(oldAssigneeName);
|
|
||||||
|
|
||||||
getAssignee(mergeRequest)
|
|
||||||
.map(Person::getName)
|
|
||||||
.ifPresent(builder::newAssigneeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyService.send(builder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void personalNotifyAboutUpdate(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
|
||||||
final Long botUserGitlabId = personInformation.getId();
|
|
||||||
if (
|
|
||||||
!botUserGitlabId.equals(mergeRequest.getAuthor().getId()) // Автор MR не пользователь приложения
|
|
||||||
&& !Objects.equals(oldMergeRequest.getDateLastCommit(), mergeRequest.getDateLastCommit())
|
|
||||||
&& !mergeRequest.isConflict() // MR не находится в состоянии конфликта
|
|
||||||
&& !botUserGitlabId.equals(oldMergeRequest.getAuthor().getId()) // и MR создан НЕ пользователем бота
|
|
||||||
) {
|
|
||||||
long allTask = 0;
|
|
||||||
long resolvedTask = 0;
|
|
||||||
long allYouTasks = 0;
|
|
||||||
long resolvedYouTask = 0;
|
|
||||||
|
|
||||||
final List<Discussion> discussions = discussionService.getAllByMergeRequestId(oldMergeRequest.getId());
|
|
||||||
for (Discussion discussion : discussions) {
|
|
||||||
if (checkNotNull(discussion.getResponsible())) {
|
|
||||||
final boolean isBotUserAuthorDiscussion = botUserGitlabId.equals(discussion.getFirstNote().getAuthor().getId());
|
|
||||||
allTask += 1;
|
|
||||||
if (isBotUserAuthorDiscussion) {
|
|
||||||
allYouTasks += 1;
|
|
||||||
}
|
|
||||||
if (TRUE.equals(discussion.getResolved())) {
|
|
||||||
resolvedTask += 1;
|
|
||||||
if (isBotUserAuthorDiscussion) {
|
|
||||||
resolvedYouTask += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final UpdateMrPersonalNotify.UpdateMrPersonalNotifyBuilder notifyBuilder = UpdateMrPersonalNotify.builder()
|
|
||||||
.mrId(oldMergeRequest.getId())
|
|
||||||
.author(oldMergeRequest.getAuthor().getName())
|
|
||||||
.name(oldMergeRequest.getTitle())
|
|
||||||
.projectName(project.getName())
|
|
||||||
.url(oldMergeRequest.getWebUrl())
|
|
||||||
.allTasks(allTask)
|
|
||||||
.milestone(mergeRequest.getMilestone())
|
|
||||||
.allResolvedTasks(resolvedTask)
|
|
||||||
.personTasks(allYouTasks)
|
|
||||||
.personResolvedTasks(resolvedYouTask);
|
|
||||||
|
|
||||||
if (oldMergeRequest.isConflict() && !mergeRequest.isConflict()) {
|
|
||||||
notifyBuilder.comment("The conflict has been resolved");
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyService.send(notifyBuilder.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void personalNotifyAboutNewConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
|
||||||
final Long gitlabUserId = personInformation.getId();
|
|
||||||
if (
|
|
||||||
!oldMergeRequest.isConflict() // У старого MR не было конфликта
|
|
||||||
&& mergeRequest.isConflict() // А у нового есть
|
|
||||||
&& gitlabUserId.equals(oldMergeRequest.getAuthor().getId()) // и MR создан пользователем бота
|
|
||||||
) {
|
|
||||||
notifyService.send(
|
|
||||||
ConflictMrPersonalNotify.builder()
|
|
||||||
.mrId(oldMergeRequest.getId())
|
|
||||||
.sourceBranch(oldMergeRequest.getSourceBranch())
|
|
||||||
.name(mergeRequest.getTitle())
|
|
||||||
.url(mergeRequest.getWebUrl())
|
|
||||||
.projectKey(project.getName())
|
|
||||||
.milestone(mergeRequest.getMilestone())
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void personalNotifyAboutResolveConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
|
||||||
final Long gitlabUserId = personInformation.getId();
|
|
||||||
if (oldMergeRequest.isConflict() && !mergeRequest.isConflict()) {
|
|
||||||
// проверяем даты коммитов, так как при пуше в target ветку MR у которого есть конфликт, конфликт на время пропадает. Судя по всему GitLab после пуша заново проверяет вероятность конфликта. Чаще всего конфликт никуда не девается.
|
|
||||||
if (Objects.equals(oldMergeRequest.getDateLastCommit(), mergeRequest.getDateLastCommit())) {
|
|
||||||
mergeRequest.setConflict(true);
|
|
||||||
} else {
|
|
||||||
if (gitlabUserId.equals(oldMergeRequest.getAuthor().getId())) {
|
|
||||||
notifyService.send(
|
|
||||||
ConflictResolveMrPersonalNotify.builder()
|
|
||||||
.mrId(oldMergeRequest.getId())
|
|
||||||
.sourceBranch(oldMergeRequest.getSourceBranch())
|
|
||||||
.name(mergeRequest.getTitle())
|
|
||||||
.url(mergeRequest.getWebUrl())
|
|
||||||
.projectKey(project.getName())
|
|
||||||
.milestone(mergeRequest.getMilestone())
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void personalNotifyAboutStatus(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) // статус изменился
|
|
||||||
&& gitlabUserId.equals(oldMergeRequest.getAuthor().getId()) // создатель MR является пользователем бота
|
|
||||||
) {
|
|
||||||
notifyService.send(
|
|
||||||
StatusMrPersonalNotify.builder()
|
|
||||||
.mrId(oldMergeRequest.getId())
|
|
||||||
.name(newMergeRequest.getTitle())
|
|
||||||
.url(oldMergeRequest.getWebUrl())
|
|
||||||
.projectName(project.getName())
|
|
||||||
.newStatus(newStatus)
|
|
||||||
.oldStatus(oldStatus)
|
|
||||||
.milestone(newMergeRequest.getMilestone())
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<Person> getAssignee(MergeRequest mergeRequest) {
|
|
||||||
return Optional.ofNullable(mergeRequest.getAssignee());
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление
|
|
||||||
|
|
||||||
private void notifyAssignee(AssigneeChanged assigneeChanged, MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
|
||||||
switch (assigneeChanged) {
|
|
||||||
case BECOME -> sendNotifyNewAssignee(
|
|
||||||
mergeRequest, project.getName(), getAssignee(oldMergeRequest).map(Person::getName).orElse(null)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление ревьювера
|
|
||||||
|
|
||||||
private void notifyReviewer(ReviewerChanged reviewerChanged, MergeRequest mergeRequest, Project project) {
|
|
||||||
switch (reviewerChanged) {
|
|
||||||
case BECOME -> sendNotifyNewMrReview(mergeRequest, project.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,138 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.handler;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.event.NewPipelineEvent;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.event.UpdatePipelineEvent;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.group.pipeline.PipelineGroupNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.pipeline.PipelinePersonalNotify;
|
|
||||||
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.haiti.utils.Strings;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.context.event.EventListener;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.CANCELED;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.FAILED;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SKIPPED;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SUCCESS;
|
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class PipelineHandler {
|
|
||||||
|
|
||||||
// Статусы пайплайнов, о которых нужно уведомить
|
|
||||||
private static final Set<PipelineStatus> notificationStatus = Set.of(FAILED, SUCCESS, CANCELED, SKIPPED);
|
|
||||||
|
|
||||||
private final PersonService personService;
|
|
||||||
private final PersonInformation personInformation;
|
|
||||||
private final NotifyService notifyService;
|
|
||||||
private final ProjectService projectService;
|
|
||||||
|
|
||||||
@EventListener
|
|
||||||
public void newPipelineHandle(NewPipelineEvent event) {
|
|
||||||
final Pipeline pipeline = event.getPipeline();
|
|
||||||
|
|
||||||
final Optional<String> optProjectName = projectService.getProjectNameById(pipeline.getProjectId())
|
|
||||||
.map(Strings::escapeMarkdown);
|
|
||||||
|
|
||||||
if (isNeedPersonalNotifyPipeline(pipeline)) {
|
|
||||||
final PipelinePersonalNotify.PipelinePersonalNotifyBuilder builder = PipelinePersonalNotify.builder()
|
|
||||||
.newStatus(pipeline.getStatus())
|
|
||||||
.refName(pipeline.getRef())
|
|
||||||
.webUrl(pipeline.getWebUrl())
|
|
||||||
.oldStatus(PipelineStatus.NEW);
|
|
||||||
|
|
||||||
optProjectName.ifPresent(builder::projectName);
|
|
||||||
|
|
||||||
notifyService.send(builder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNeedPersonalGroupPipeline(pipeline)) {
|
|
||||||
final Optional<String> optTelegramUsername = personService.getTelegramUsernamesByPersonIds(pipeline.getPerson().getId());
|
|
||||||
if (optTelegramUsername.isPresent()) {
|
|
||||||
final String telegramUsername = optTelegramUsername.get();
|
|
||||||
|
|
||||||
final PipelineGroupNotify.PipelineGroupNotifyBuilder builder = PipelineGroupNotify.builder()
|
|
||||||
.newStatus(pipeline.getStatus())
|
|
||||||
.refName(pipeline.getRef())
|
|
||||||
.webUrl(pipeline.getWebUrl())
|
|
||||||
.oldStatus(PipelineStatus.NEW)
|
|
||||||
.ownerTelegramUsername(telegramUsername);
|
|
||||||
|
|
||||||
optProjectName.ifPresent(builder::projectName);
|
|
||||||
|
|
||||||
notifyService.send(builder.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventListener
|
|
||||||
public void updatePipelineHandle(UpdatePipelineEvent event) {
|
|
||||||
final Pipeline oldPipeline = event.getOldPipeline();
|
|
||||||
final Pipeline newPipeline = event.getNewPipeline();
|
|
||||||
if (!Objects.equals(oldPipeline.getUpdated(), newPipeline.getUpdated())) {
|
|
||||||
final Optional<String> optProjectName = projectService.getProjectNameById(newPipeline.getProjectId())
|
|
||||||
.map(Strings::escapeMarkdown);
|
|
||||||
|
|
||||||
if (isNeedPersonalNotifyPipeline(newPipeline)) {
|
|
||||||
final PipelinePersonalNotify.PipelinePersonalNotifyBuilder builder = PipelinePersonalNotify.builder()
|
|
||||||
.newStatus(newPipeline.getStatus())
|
|
||||||
.refName(newPipeline.getRef())
|
|
||||||
.webUrl(newPipeline.getWebUrl())
|
|
||||||
.oldStatus(oldPipeline.getStatus());
|
|
||||||
|
|
||||||
optProjectName.ifPresent(builder::projectName);
|
|
||||||
|
|
||||||
notifyService.send(builder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNeedPersonalGroupPipeline(newPipeline)) {
|
|
||||||
final Optional<String> optTelegramUsername = personService.getTelegramUsernamesByPersonIds(newPipeline.getPerson().getId());
|
|
||||||
if (optTelegramUsername.isEmpty()) {
|
|
||||||
final String telegramUsername = optTelegramUsername.get();
|
|
||||||
|
|
||||||
final PipelineGroupNotify.PipelineGroupNotifyBuilder builder = PipelineGroupNotify.builder()
|
|
||||||
.newStatus(newPipeline.getStatus())
|
|
||||||
.refName(newPipeline.getRef())
|
|
||||||
.webUrl(newPipeline.getWebUrl())
|
|
||||||
.oldStatus(oldPipeline.getStatus())
|
|
||||||
.ownerTelegramUsername(telegramUsername);
|
|
||||||
|
|
||||||
optProjectName.ifPresent(builder::projectName);
|
|
||||||
|
|
||||||
notifyService.send(builder.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isNeedPersonalNotifyPipeline(@NonNull Pipeline pipeline) {
|
|
||||||
final Person personPipelineCreator = pipeline.getPerson();
|
|
||||||
return notificationStatus.contains(pipeline.getStatus()) // Пайплайн имеет статус необходимый для уведомления
|
|
||||||
&& checkNotNull(personPipelineCreator) // Создатель пайплайна не null
|
|
||||||
&& personInformation.getId().equals(personPipelineCreator.getId()) // Пользователь приложения является инициатором пайплайна
|
|
||||||
&& LocalDateTime.now().minusDays(1).isBefore(pipeline.getCreated()); // Пайплан был создан не более 24 часов назад
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isNeedPersonalGroupPipeline(@NonNull Pipeline pipeline) {
|
|
||||||
final Person personPipelineCreator = pipeline.getPerson();
|
|
||||||
return notificationStatus.contains(pipeline.getStatus()) // Пайплайн имеет статус необходимый для уведомления
|
|
||||||
&& checkNotNull(personPipelineCreator) // Создатель пайплайна не null
|
|
||||||
&& LocalDateTime.now().minusDays(1).isBefore(pipeline.getCreated()); // Пайплан был создан не более 24 часов назад
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.handler;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.event.NewProjectEvent;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.project.NewProjectPersonalNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
|
||||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.context.event.EventListener;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class ProjectHandler {
|
|
||||||
|
|
||||||
private final NotifyService notifyService;
|
|
||||||
private final PersonService personService;
|
|
||||||
|
|
||||||
@EventListener
|
|
||||||
public void handleNewProjectEvent(NewProjectEvent event) {
|
|
||||||
final Project newProject = event.getProject();
|
|
||||||
final String authorName = personService.getByIdOrThrown(newProject.getCreatorId()).getName();
|
|
||||||
notifyService.send(
|
|
||||||
NewProjectPersonalNotify.builder()
|
|
||||||
.projectId(newProject.getId())
|
|
||||||
.projectDescription(newProject.getDescription())
|
|
||||||
.projectName(newProject.getName())
|
|
||||||
.projectUrl(newProject.getWebUrl())
|
|
||||||
.sshUrlToRepo(newProject.getSshUrlToRepo())
|
|
||||||
.httpUrlToRepo(newProject.getHttpUrlToRepo())
|
|
||||||
.authorName(authorName)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.parser;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
|
||||||
import dev.struchkov.bot.gitlab.context.service.PipelineService;
|
|
||||||
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
|
||||||
import dev.struchkov.haiti.utils.container.Pair;
|
|
||||||
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
|
|
||||||
import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineShortJson;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.core.convert.ConversionService;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.CREATED;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.MANUAL;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.PENDING;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.PREPARING;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.RUNNING;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.WAITING_FOR_RESOURCE;
|
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkFalse;
|
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
|
||||||
import static java.util.stream.Collectors.toMap;
|
|
||||||
import static java.util.stream.Collectors.toSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Парсер пайплайнов.
|
|
||||||
*
|
|
||||||
* @author upagge 17.01.2021
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class PipelineParser {
|
|
||||||
|
|
||||||
private static final Set<PipelineStatus> oldSOLD_STATUSES = Set.of(
|
|
||||||
CREATED, WAITING_FOR_RESOURCE, PREPARING, PENDING, RUNNING, MANUAL
|
|
||||||
);
|
|
||||||
|
|
||||||
private final GitlabSdkManager gitlabSdkManager;
|
|
||||||
|
|
||||||
private final PipelineService pipelineService;
|
|
||||||
private final ProjectService projectService;
|
|
||||||
private final ConversionService conversionService;
|
|
||||||
|
|
||||||
private LocalDateTime lastUpdate = LocalDateTime.now();
|
|
||||||
|
|
||||||
public void scanNewPipeline() {
|
|
||||||
log.debug("Старт обработки новых пайплайнов");
|
|
||||||
final Set<Long> projectIds = projectService.getAllIdByProcessingEnable();
|
|
||||||
|
|
||||||
final Map<Long, Long> pipelineProjectMap = getPipelineShortJsons(projectIds).stream()
|
|
||||||
.collect(toMap(PipelineShortJson::getId, PipelineShortJson::getProjectId));
|
|
||||||
|
|
||||||
if (checkNotEmpty(pipelineProjectMap)) {
|
|
||||||
final ExistContainer<Pipeline, Long> existContainer = pipelineService.existsById(pipelineProjectMap.keySet());
|
|
||||||
|
|
||||||
if (checkFalse(existContainer.isAllFound())) {
|
|
||||||
final Set<Pair<Long, Long>> idsNotFound = existContainer.getIdNoFound().stream()
|
|
||||||
.map(pipelineId -> new Pair<>(pipelineProjectMap.get(pipelineId), pipelineId))
|
|
||||||
.collect(toSet());
|
|
||||||
|
|
||||||
final List<Pipeline> newPipelines = gitlabSdkManager.getAllPipelineForProject(idsNotFound).stream()
|
|
||||||
.map(json -> conversionService.convert(json, Pipeline.class))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
;
|
|
||||||
|
|
||||||
if (checkNotEmpty(newPipelines)) {
|
|
||||||
pipelineService.createAll(newPipelines);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("Конец обработки новых пайплайнов");
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<PipelineShortJson> getPipelineShortJsons(Set<Long> projectIds) {
|
|
||||||
final LocalDateTime newLastUpdate = LocalDateTime.now();
|
|
||||||
final List<PipelineShortJson> pipelineJsons = gitlabSdkManager.getAllPipeline(projectIds, lastUpdate.minusHours(12L));
|
|
||||||
lastUpdate = newLastUpdate;
|
|
||||||
return pipelineJsons;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void scanOldPipeline() {
|
|
||||||
log.debug("Старт обработки старых пайплайнов");
|
|
||||||
final List<Pipeline> pipelines = pipelineService.getAllByStatuses(oldSOLD_STATUSES);
|
|
||||||
|
|
||||||
final List<Pipeline> newPipelines = gitlabSdkManager.getAllPipelineForProject(
|
|
||||||
pipelines.stream()
|
|
||||||
.map(pipeline -> new Pair<>(pipeline.getProjectId(), pipeline.getId()))
|
|
||||||
.collect(toSet())
|
|
||||||
).stream()
|
|
||||||
.map(json -> conversionService.convert(json, Pipeline.class))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
if (checkNotEmpty(newPipelines)) {
|
|
||||||
pipelineService.updateAll(newPipelines);
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("Конец обработки старых пайплайнов");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,174 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service;
|
|
||||||
|
|
||||||
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.MergeRequestForDiscussion;
|
|
||||||
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.level.DiscussionLevel;
|
|
||||||
import dev.struchkov.bot.gitlab.context.repository.DiscussionRepository;
|
|
||||||
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
|
|
||||||
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
|
||||||
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.event.NewDiscussionEvent.newDiscussion;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.event.UpdateDiscussionEvent.updateDiscussion;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel.WITHOUT_NOTIFY;
|
|
||||||
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Сервис для работы с дискуссиями.
|
|
||||||
*
|
|
||||||
* @author upagge 11.02.2021
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class DiscussionServiceImpl implements DiscussionService {
|
|
||||||
|
|
||||||
private final DiscussionRepository repository;
|
|
||||||
|
|
||||||
private final AppSettingService settingService;
|
|
||||||
private final GitlabSdkManager gitlabSdkManager;
|
|
||||||
private final ApplicationEventPublisher eventPublisher;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public Discussion create(@NonNull Discussion discussion) {
|
|
||||||
|
|
||||||
final DiscussionLevel levelDiscussionNotify = settingService.getLevelDiscussionNotify();
|
|
||||||
if (!WITHOUT_NOTIFY.equals(levelDiscussionNotify)) {
|
|
||||||
discussion.setNotification(true);
|
|
||||||
|
|
||||||
eventPublisher.publishEvent(newDiscussion(discussion));
|
|
||||||
} else {
|
|
||||||
discussion.setNotification(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
final boolean resolved = discussion.getNotes().stream()
|
|
||||||
.allMatch(note -> note.isResolvable() && note.getResolved());
|
|
||||||
|
|
||||||
discussion.setResolved(resolved);
|
|
||||||
|
|
||||||
return repository.save(discussion);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public Discussion update(@NonNull Discussion discussion) {
|
|
||||||
final Discussion oldDiscussion = repository.findById(discussion.getId())
|
|
||||||
.orElseThrow(notFoundException("Дискуссия не найдена"));
|
|
||||||
|
|
||||||
discussion.setResponsible(oldDiscussion.getResponsible());
|
|
||||||
discussion.setMergeRequest(oldDiscussion.getMergeRequest());
|
|
||||||
discussion.setNotification(oldDiscussion.isNotification());
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final boolean resolved = discussion.getNotes().stream()
|
|
||||||
.allMatch(note -> note.isResolvable() && note.getResolved());
|
|
||||||
discussion.setResolved(resolved);
|
|
||||||
|
|
||||||
eventPublisher.publishEvent(updateDiscussion(oldDiscussion, discussion));
|
|
||||||
|
|
||||||
return repository.save(discussion);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Discussion> updateAll(@NonNull List<Discussion> discussions) {
|
|
||||||
return discussions.stream()
|
|
||||||
.map(this::update)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void answer(@NonNull String discussionId, @NonNull String text) {
|
|
||||||
final Discussion discussion = repository.findById(discussionId)
|
|
||||||
.orElseThrow(notFoundException("Дисскусия {0} не найдена", discussionId));
|
|
||||||
final MergeRequestForDiscussion mergeRequest = discussion.getMergeRequest();
|
|
||||||
final Long projectId = mergeRequest.getProjectId();
|
|
||||||
|
|
||||||
gitlabSdkManager.sendMessageToDiscussion(projectId, mergeRequest.getTwoId(), discussionId, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Discussion> getAllByMergeRequestId(@NonNull Long mergeRequestId) {
|
|
||||||
return repository.findAllByMergeRequestId(mergeRequestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExistContainer<Discussion, String> existsById(@NonNull Set<String> discussionIds) {
|
|
||||||
final List<Discussion> existsEntity = repository.findAllById(discussionIds);
|
|
||||||
final Set<String> existsIds = existsEntity.stream().map(Discussion::getId).collect(Collectors.toSet());
|
|
||||||
if (existsIds.containsAll(discussionIds)) {
|
|
||||||
return ExistContainer.allFind(existsEntity);
|
|
||||||
} else {
|
|
||||||
final Set<String> noExistsId = discussionIds.stream()
|
|
||||||
.filter(id -> !existsIds.contains(id))
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
return ExistContainer.notAllFind(existsEntity, noExistsId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Discussion> createAll(@NonNull List<Discussion> newDiscussions) {
|
|
||||||
return newDiscussions.stream()
|
|
||||||
.map(this::create)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Discussion> getAll() {
|
|
||||||
return repository.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getAllIds() {
|
|
||||||
return repository.findAllIds();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public void deleteById(@NonNull String discussionId) {
|
|
||||||
repository.deleteById(discussionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public void cleanOld() {
|
|
||||||
log.debug("Старт очистки старых дискуссий");
|
|
||||||
repository.cleanOld();
|
|
||||||
log.debug("Конец очистки старых дискуссий");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public void notification(boolean enable, String discussionId) {
|
|
||||||
repository.notification(enable, discussionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,199 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service;
|
|
||||||
|
|
||||||
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.changed.ApprovalChanged;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.changed.AssigneeChanged;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.changed.ReviewerChanged;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequestForDiscussion;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
|
||||||
import dev.struchkov.bot.gitlab.context.repository.MergeRequestRepository;
|
|
||||||
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.MergeRequestState.CLOSED;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.MergeRequestState.MERGED;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.event.NewMergeRequestEvent.newMergeRequest;
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.event.UpdateMergeRequestEvent.updateMergeRequest;
|
|
||||||
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class MergeRequestsServiceImpl implements MergeRequestsService {
|
|
||||||
|
|
||||||
public static final Set<MergeRequestState> DELETE_STATES = Set.of(MERGED, CLOSED);
|
|
||||||
|
|
||||||
private final ApplicationEventPublisher eventPublisher;
|
|
||||||
|
|
||||||
private final MergeRequestRepository repository;
|
|
||||||
|
|
||||||
private final PersonInformation personInformation;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public MergeRequest create(@NonNull MergeRequest mergeRequest) {
|
|
||||||
final boolean botUserReviewer = isBotUserReviewer(mergeRequest);
|
|
||||||
final boolean botUserAssignee = isBotUserAssigneeAndNotAuthor(mergeRequest);
|
|
||||||
final boolean botUserAuthor = personInformation.getId().equals(mergeRequest.getAuthor().getId());
|
|
||||||
|
|
||||||
mergeRequest.setNotification(botUserReviewer || botUserAssignee || botUserAuthor);
|
|
||||||
mergeRequest.setUserAssignee(botUserAssignee);
|
|
||||||
mergeRequest.setUserReviewer(botUserReviewer);
|
|
||||||
|
|
||||||
final MergeRequest savedMergeRequest = repository.save(mergeRequest);
|
|
||||||
|
|
||||||
eventPublisher.publishEvent(newMergeRequest(savedMergeRequest));
|
|
||||||
|
|
||||||
return savedMergeRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isBotUserAssigneeAndNotAuthor(MergeRequest mergeRequest) {
|
|
||||||
final Long gitlabUserId = personInformation.getId();
|
|
||||||
final Optional<Person> optAssignee = getAssignee(mergeRequest);
|
|
||||||
final Person author = mergeRequest.getAuthor();
|
|
||||||
|
|
||||||
if (optAssignee.isPresent()) {
|
|
||||||
final Person assignee = optAssignee.get();
|
|
||||||
if (gitlabUserId.equals(assignee.getId()) && !isAuthorSameAssignee(author, assignee)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Создатель MR является ответственным за этот MR
|
|
||||||
*
|
|
||||||
* @return true, если автор и ответственный один и тот же человек.
|
|
||||||
*/
|
|
||||||
private boolean isAuthorSameAssignee(Person author, Person assignee) {
|
|
||||||
return author.getId().equals(assignee.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isBotUserReviewer(MergeRequest savedMergeRequest) {
|
|
||||||
final List<Person> reviewers = savedMergeRequest.getReviewers();
|
|
||||||
final Long botUserGitlabId = personInformation.getId();
|
|
||||||
|
|
||||||
if (checkNotEmpty(reviewers)) {
|
|
||||||
for (Person reviewer : reviewers) {
|
|
||||||
if (botUserGitlabId.equals(reviewer.getId())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public MergeRequest update(@NonNull MergeRequest mergeRequest) {
|
|
||||||
final MergeRequest oldMergeRequest = repository.findById(mergeRequest.getId())
|
|
||||||
.orElseThrow(notFoundException("MergeRequest не найден"));
|
|
||||||
|
|
||||||
mergeRequest.setNotification(oldMergeRequest.isNotification());
|
|
||||||
|
|
||||||
final Long gitlabUserId = personInformation.getId();
|
|
||||||
final AssigneeChanged assigneeChanged = AssigneeChanged.valueOf(gitlabUserId, getAssignee(oldMergeRequest), getAssignee(mergeRequest));
|
|
||||||
final ReviewerChanged reviewerChanged = ReviewerChanged.valueOf(gitlabUserId, oldMergeRequest.getReviewers(), mergeRequest.getReviewers());
|
|
||||||
final Optional<ApprovalChanged> optApprovalChanged = ApprovalChanged.approvalChanged(oldMergeRequest.getApprovals(), mergeRequest.getApprovals());
|
|
||||||
|
|
||||||
mergeRequest.setUserAssignee(assigneeChanged.getNewStatus(oldMergeRequest.isUserAssignee()));
|
|
||||||
mergeRequest.setUserReviewer(reviewerChanged.getNewStatus(oldMergeRequest.isUserReviewer()));
|
|
||||||
|
|
||||||
eventPublisher.publishEvent(
|
|
||||||
updateMergeRequest(oldMergeRequest, mergeRequest, assigneeChanged, reviewerChanged, optApprovalChanged)
|
|
||||||
);
|
|
||||||
|
|
||||||
return repository.save(mergeRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public List<MergeRequest> updateAll(@NonNull List<MergeRequest> mergeRequests) {
|
|
||||||
return mergeRequests.stream()
|
|
||||||
.map(this::update)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<IdAndStatusPr> getAllId(Set<MergeRequestState> statuses) {
|
|
||||||
return repository.findAllIdByStateIn(statuses);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<MergeRequestForDiscussion> getAllForDiscussion() {
|
|
||||||
return repository.findAllForDiscussion();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExistContainer<MergeRequest, Long> existsById(@NonNull Set<Long> mergeRequestIds) {
|
|
||||||
final List<MergeRequest> existsEntity = repository.findAllById(mergeRequestIds);
|
|
||||||
final Set<Long> existsIds = existsEntity.stream().map(MergeRequest::getId).collect(Collectors.toSet());
|
|
||||||
if (existsIds.containsAll(mergeRequestIds)) {
|
|
||||||
return ExistContainer.allFind(existsEntity);
|
|
||||||
} else {
|
|
||||||
final Set<Long> noExistsId = mergeRequestIds.stream()
|
|
||||||
.filter(id -> !existsIds.contains(id))
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
return ExistContainer.notAllFind(existsEntity, noExistsId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<MergeRequest> createAll(List<MergeRequest> newMergeRequests) {
|
|
||||||
return newMergeRequests.stream()
|
|
||||||
.map(this::create)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<MergeRequest> getAllByReviewerId(@NonNull Long personId) {
|
|
||||||
return repository.findAllByReviewerId(personId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cleanOld() {
|
|
||||||
log.debug("Старт очистки старых MR");
|
|
||||||
repository.deleteByStates(DELETE_STATES);
|
|
||||||
log.debug("Конец очистки старых MR");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
public Set<Long> getAllIds() {
|
|
||||||
return repository.findAllIds();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public void notification(boolean enable, @NonNull Long mrId) {
|
|
||||||
repository.notification(enable, mrId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public void notificationByProjectId(boolean enable, @NonNull Set<Long> projectIds) {
|
|
||||||
repository.notificationByProjectId(enable, projectIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<Person> getAssignee(MergeRequest mergeRequest) {
|
|
||||||
return Optional.ofNullable(mergeRequest.getAssignee());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.convert;
|
package dev.struchkov.bot.gitlab.core.service.convert;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||||
import dev.struchkov.sdk.gitlab.schema.note.DiscussionJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.DiscussionJson;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
@ -0,0 +1,97 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.core.service.convert;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.IssueState;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.IssueType;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Issue;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
|
import dev.struchkov.bot.gitlab.sdk.domain.*;
|
||||||
|
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 Dmitry Sheyko [22.01.2023]
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class IssueJsonConverter implements Converter<IssueJson, Issue> {
|
||||||
|
|
||||||
|
private final PersonJsonConverter convertPerson;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Issue convert(IssueJson source) {
|
||||||
|
final Issue issue = new Issue();
|
||||||
|
issue.setId(source.getId());
|
||||||
|
issue.setTwoId(source.getTwoId());
|
||||||
|
issue.setProjectId(source.getProjectId());
|
||||||
|
issue.setTitle(source.getTitle());
|
||||||
|
issue.setDescription(source.getDescription());
|
||||||
|
issue.setState(convertState(source.getState()));
|
||||||
|
issue.setCreatedDate(source.getCreatedDate());
|
||||||
|
issue.setUpdatedDate(source.getUpdatedDate());
|
||||||
|
issue.setCloseDate(source.getClosedDate());
|
||||||
|
issue.setType(convertType(source.getType()));
|
||||||
|
issue.setUserNotesCount(source.getUserNotesCount());
|
||||||
|
issue.setMergeRequestsCount(source.getMergeRequestsCount());
|
||||||
|
issue.setUpVotes(source.getUpVotes());
|
||||||
|
issue.setDownVotes(source.getDownVotes());
|
||||||
|
issue.setDueDate(source.getDueDate());
|
||||||
|
issue.setConfidential(source.getConfidential());
|
||||||
|
issue.setDiscussionLocked(source.getDiscussionLocked());
|
||||||
|
issue.setTaskCount(source.getTaskCompletionStatus().getCount());
|
||||||
|
issue.setTaskCompletedCount(source.getTaskCompletionStatus().getCompletedCount());
|
||||||
|
issue.setWebUrl(source.getWebUrl());
|
||||||
|
issue.setBlockingIssuesCount(source.getBlockingIssuesCount());
|
||||||
|
issue.setHasTasks(source.getHasTasks());
|
||||||
|
|
||||||
|
convertAssignees(issue, source.getAssignees());
|
||||||
|
convertLabels(issue, source.getLabels());
|
||||||
|
|
||||||
|
if (checkNotNull(source.getClosedBy())) {
|
||||||
|
issue.setClosedBy(convertPerson.convert(source.getClosedBy()));
|
||||||
|
}
|
||||||
|
|
||||||
|
issue.setAuthor(convertPerson.convert(source.getAuthor()));
|
||||||
|
return issue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convertAssignees(Issue issue, List<PersonJson> jsonAssignees) {
|
||||||
|
if (checkNotEmpty(jsonAssignees)) {
|
||||||
|
final List<Person> assignees = jsonAssignees.stream()
|
||||||
|
.map(convertPerson::convert)
|
||||||
|
.toList();
|
||||||
|
issue.setAssignees(assignees);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convertLabels(Issue issue, Set<String> source) {
|
||||||
|
if (checkNotEmpty(source)) {
|
||||||
|
final Set<String> labels = source.stream()
|
||||||
|
.map(label -> label.replace("-", "_"))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
issue.setLabels(labels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IssueState convertState(IssueStateJson state) {
|
||||||
|
return switch (state) {
|
||||||
|
case CLOSED -> IssueState.CLOSED;
|
||||||
|
case OPENED -> IssueState.OPENED;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private IssueType convertType(IssueTypeJson type) {
|
||||||
|
return switch (type) {
|
||||||
|
case ISSUE -> IssueType.ISSUE;
|
||||||
|
case INCIDENT -> IssueType.INCIDENT;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.convert;
|
package dev.struchkov.bot.gitlab.core.service.convert;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
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.MergeRequest;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import dev.struchkov.sdk.gitlab.schema.common.PersonJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.MergeRequestJson;
|
||||||
import dev.struchkov.sdk.gitlab.schema.mergerequest.MergeRequestJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.MergeRequestStateJson;
|
||||||
import dev.struchkov.sdk.gitlab.schema.mergerequest.MergeRequestStateJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.PersonJson;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -43,10 +43,6 @@ public class MergeRequestJsonConverter implements Converter<MergeRequestJson, Me
|
|||||||
convertLabels(mergeRequest, source.getLabels());
|
convertLabels(mergeRequest, source.getLabels());
|
||||||
convertReviewers(mergeRequest, source.getReviewers());
|
convertReviewers(mergeRequest, source.getReviewers());
|
||||||
|
|
||||||
if (checkNotNull(source.getMilestone())) {
|
|
||||||
mergeRequest.setMilestone(source.getMilestone().getTitle());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkNotNull(source.getAssignee())) {
|
if (checkNotNull(source.getAssignee())) {
|
||||||
mergeRequest.setAssignee(convertPerson.convert(source.getAssignee()));
|
mergeRequest.setAssignee(convertPerson.convert(source.getAssignee()));
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.convert;
|
package dev.struchkov.bot.gitlab.core.service.convert;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||||
import dev.struchkov.sdk.gitlab.schema.note.NoteJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.NoteJson;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
@ -1,7 +1,7 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.convert;
|
package dev.struchkov.bot.gitlab.core.service.convert;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import dev.struchkov.sdk.gitlab.schema.common.PersonJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.PersonJson;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.convert;
|
package dev.struchkov.bot.gitlab.core.service.convert;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||||
import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.PipelineJson;
|
||||||
import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineStatusJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.PipelineStatusJson;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
@ -1,7 +1,7 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.convert;
|
package dev.struchkov.bot.gitlab.core.service.convert;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||||
import dev.struchkov.sdk.gitlab.schema.repository.ProjectJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.ProjectJson;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
@ -1,4 +1,4 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service;
|
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.AppSetting;
|
import dev.struchkov.bot.gitlab.context.domain.entity.AppSetting;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel;
|
import dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel;
|
@ -1,23 +1,35 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.handler;
|
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
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.Discussion;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequestForDiscussion;
|
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequestForDiscussion;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.event.NewDiscussionEvent;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.event.UpdateDiscussionEvent;
|
import dev.struchkov.bot.gitlab.context.domain.notify.comment.NewCommentNotify;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.comment.NewCommentPersonalNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel;
|
import dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.task.DiscussionNewPersonalNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.task.DiscussionNewNotify;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.task.ThreadClosePersonalNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.task.ThreadCloseNotify;
|
||||||
|
import dev.struchkov.bot.gitlab.context.repository.DiscussionRepository;
|
||||||
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
|
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
||||||
|
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;
|
||||||
import dev.struchkov.haiti.utils.container.Pair;
|
import dev.struchkov.haiti.utils.container.Pair;
|
||||||
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.context.event.EventListener;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import okhttp3.FormBody;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.MessageFormat;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -30,100 +42,95 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel.NOTIFY_WITH_CONTEXT;
|
import static dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel.NOTIFY_WITH_CONTEXT;
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel.WITHOUT_NOTIFY;
|
import static dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel.WITHOUT_NOTIFY;
|
||||||
|
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNull;
|
import static dev.struchkov.haiti.utils.Checker.checkNull;
|
||||||
import static java.lang.Boolean.FALSE;
|
import static java.lang.Boolean.FALSE;
|
||||||
import static java.lang.Boolean.TRUE;
|
import static java.lang.Boolean.TRUE;
|
||||||
|
|
||||||
@Component
|
/**
|
||||||
|
* Сервис для работы с дискуссиями.
|
||||||
|
*
|
||||||
|
* @author upagge 11.02.2021
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class DiscussionHandler {
|
public class DiscussionServiceImpl implements DiscussionService {
|
||||||
|
|
||||||
protected static final Pattern PATTERN = Pattern.compile("@[\\w]+");
|
protected static final Pattern PATTERN = Pattern.compile("@[\\w]+");
|
||||||
|
private final OkHttpClient client = new OkHttpClient();
|
||||||
|
|
||||||
private final PersonInformation personInformation;
|
private final DiscussionRepository repository;
|
||||||
private final AppSettingService settingService;
|
|
||||||
private final DiscussionService discussionService;
|
|
||||||
|
|
||||||
private final NotifyService notifyService;
|
private final NotifyService notifyService;
|
||||||
|
private final AppSettingService settingService;
|
||||||
|
|
||||||
@EventListener
|
private final PersonInformation personInformation;
|
||||||
public void newDiscussionEvent(NewDiscussionEvent event) {
|
private final GitlabProperty gitlabProperty;
|
||||||
final Discussion discussion = event.getDiscussion();
|
private final PersonProperty personProperty;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public Discussion create(@NonNull Discussion discussion) {
|
||||||
final List<Note> notes = discussion.getNotes();
|
final List<Note> notes = discussion.getNotes();
|
||||||
|
|
||||||
if (isNeedNotifyNewNote(discussion)) {
|
final DiscussionLevel levelDiscussionNotify = settingService.getLevelDiscussionNotify();
|
||||||
notifyNewThread(discussion);
|
if (!WITHOUT_NOTIFY.equals(levelDiscussionNotify)) {
|
||||||
|
discussion.setNotification(true);
|
||||||
|
|
||||||
|
if (isNeedNotifyNewNote(discussion)) {
|
||||||
|
notifyNewThread(discussion);
|
||||||
|
} else {
|
||||||
|
notes.forEach(note -> notifyAboutPersonalAnswer(discussion, note));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
notes.forEach(note -> notifyAboutPersonalAnswer(discussion, note));
|
discussion.setNotification(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean resolved = discussion.getNotes().stream()
|
||||||
|
.allMatch(note -> note.isResolvable() && note.getResolved());
|
||||||
|
|
||||||
|
discussion.setResolved(resolved);
|
||||||
|
|
||||||
|
return repository.save(discussion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventListener
|
@Override
|
||||||
public void updateDiscussionHandle(UpdateDiscussionEvent event) {
|
@Transactional
|
||||||
final Discussion oldDiscussion = event.getOldDiscussion();
|
public Discussion update(@NonNull Discussion discussion) {
|
||||||
final Discussion newDiscussion = event.getNewDiscussion();
|
final Discussion oldDiscussion = repository.findById(discussion.getId())
|
||||||
|
.orElseThrow(notFoundException("Дискуссия не найдена"));
|
||||||
|
|
||||||
|
discussion.setResponsible(oldDiscussion.getResponsible());
|
||||||
|
discussion.setMergeRequest(oldDiscussion.getMergeRequest());
|
||||||
|
discussion.setNotification(oldDiscussion.isNotification());
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean resolved = discussion.getNotes().stream()
|
||||||
|
.allMatch(note -> note.isResolvable() && note.getResolved());
|
||||||
|
discussion.setResolved(resolved);
|
||||||
|
|
||||||
if (oldDiscussion.isNotification()) {
|
if (oldDiscussion.isNotification()) {
|
||||||
final Map<Long, Note> oldNoteMap = oldDiscussion
|
notifyUpdateNote(oldDiscussion, discussion);
|
||||||
.getNotes().stream()
|
|
||||||
.collect(Collectors.toMap(Note::getId, n -> n));
|
|
||||||
|
|
||||||
// Пользователь участвовал в обсуждении
|
|
||||||
final boolean userParticipatedInDiscussion = oldDiscussion.getNotes().stream()
|
|
||||||
.anyMatch(note -> personInformation.getId().equals(note.getAuthor().getId()));
|
|
||||||
|
|
||||||
final Note threadFirstNote = newDiscussion.getFirstNote();
|
|
||||||
if (TRUE.equals(newDiscussion.getResolved())) {
|
|
||||||
notifyAboutCloseThread(threadFirstNote, oldNoteMap.get(threadFirstNote.getId()), newDiscussion.getLastNote());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Note newNote : newDiscussion.getNotes()) {
|
|
||||||
final Long newNoteId = newNote.getId();
|
|
||||||
if (!oldNoteMap.containsKey(newNoteId)) {
|
|
||||||
if (userParticipatedInDiscussion) {
|
|
||||||
notifyAboutNewAnswer(newDiscussion, newNote);
|
|
||||||
} else {
|
|
||||||
notifyAboutPersonalAnswer(newDiscussion, newNote);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Уведомляет пользователя, если появился новый комментарий</p>
|
|
||||||
*/
|
|
||||||
private void notifyNewThread(Discussion discussion) {
|
|
||||||
final DiscussionLevel discussionLevel = settingService.getLevelDiscussionNotify();
|
|
||||||
if (!WITHOUT_NOTIFY.equals(discussionLevel)) {
|
|
||||||
final Note firstNote = discussion.getFirstNote();
|
|
||||||
|
|
||||||
final MergeRequestForDiscussion mergeRequest = discussion.getMergeRequest();
|
return repository.save(discussion);
|
||||||
final DiscussionNewPersonalNotify.DiscussionNewPersonalNotifyBuilder messageBuilder = DiscussionNewPersonalNotify.builder()
|
|
||||||
.url(firstNote.getWebUrl())
|
|
||||||
.threadId(discussion.getId())
|
|
||||||
.mergeRequestName(mergeRequest.getTitle())
|
|
||||||
.authorName(firstNote.getAuthor().getName());
|
|
||||||
|
|
||||||
if (NOTIFY_WITH_CONTEXT.equals(discussionLevel)) {
|
|
||||||
final List<Note> notes = discussion.getNotes();
|
|
||||||
|
|
||||||
messageBuilder
|
|
||||||
.discussionMessage(firstNote.getBody());
|
|
||||||
|
|
||||||
if (notes.size() > 1) {
|
|
||||||
for (int i = 1; i < notes.size(); i++) {
|
|
||||||
final Note note = notes.get(i);
|
|
||||||
messageBuilder.note(
|
|
||||||
new Pair<>(note.getAuthor().getName(), note.getBody())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyService.send(messageBuilder.build());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isNeedNotifyNewNote(Discussion discussion) {
|
private boolean isNeedNotifyNewNote(Discussion discussion) {
|
||||||
@ -135,80 +142,38 @@ public class DiscussionHandler {
|
|||||||
&& FALSE.equals(firstNote.getResolved()); // Комментарий не отмечен как решенный
|
&& FALSE.equals(firstNote.getResolved()); // Комментарий не отмечен как решенный
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Уведомляет пользователя, если его никнейм упоминается в комментарии.
|
public List<Discussion> updateAll(@NonNull List<Discussion> discussions) {
|
||||||
*/
|
return discussions.stream()
|
||||||
private void notifyAboutPersonalAnswer(Discussion discussion, Note note) {
|
.map(this::update)
|
||||||
final DiscussionLevel discussionLevel = settingService.getLevelDiscussionNotify();
|
.collect(Collectors.toList());
|
||||||
if (!WITHOUT_NOTIFY.equals(discussionLevel)) {
|
|
||||||
final Matcher matcher = PATTERN.matcher(note.getBody());
|
|
||||||
final Set<String> recipientsLogins = new HashSet<>();
|
|
||||||
|
|
||||||
while (matcher.find()) {
|
|
||||||
final String login = matcher.group(0).replace("@", "");
|
|
||||||
recipientsLogins.add(login);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recipientsLogins.contains(personInformation.getUsername())) {
|
|
||||||
final NewCommentPersonalNotify.NewCommentPersonalNotifyBuilder notifyBuilder = NewCommentPersonalNotify.builder()
|
|
||||||
.threadId(discussion.getId())
|
|
||||||
.mergeRequestName(discussion.getMergeRequest().getTitle())
|
|
||||||
.url(note.getWebUrl());
|
|
||||||
|
|
||||||
if (NOTIFY_WITH_CONTEXT.equals(discussionLevel)) {
|
|
||||||
final Optional<Note> prevLastNote = discussion.getPrevLastNote();
|
|
||||||
final Note firstNote = discussion.getFirstNote();
|
|
||||||
|
|
||||||
if (!firstNote.equals(note)) {
|
|
||||||
notifyBuilder.message(note.getBody())
|
|
||||||
.authorName(note.getAuthor().getName());
|
|
||||||
}
|
|
||||||
if (prevLastNote.isPresent()) {
|
|
||||||
final Note prevNote = prevLastNote.get();
|
|
||||||
notifyBuilder.previousMessage(prevNote.getBody());
|
|
||||||
notifyBuilder.previousAuthor(prevNote.getAuthor().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyBuilder
|
|
||||||
.discussionMessage(firstNote.getBody())
|
|
||||||
.discussionAuthor(firstNote.getAuthor().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyService.send(notifyBuilder.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyAboutNewAnswer(Discussion discussion, Note note) {
|
private void notifyUpdateNote(Discussion oldDiscussion, Discussion discussion) {
|
||||||
final DiscussionLevel discussionLevel = settingService.getLevelDiscussionNotify();
|
final Map<Long, Note> oldNoteMap = oldDiscussion
|
||||||
|
.getNotes().stream()
|
||||||
|
.collect(Collectors.toMap(Note::getId, n -> n));
|
||||||
|
|
||||||
if (!WITHOUT_NOTIFY.equals(discussionLevel)
|
// Пользователь участвовал в обсуждении
|
||||||
&& !personInformation.getId().equals(note.getAuthor().getId())) {
|
final boolean userParticipatedInDiscussion = oldDiscussion.getNotes().stream()
|
||||||
final Note firstNote = discussion.getFirstNote();
|
.anyMatch(note -> personInformation.getId().equals(note.getAuthor().getId()));
|
||||||
|
|
||||||
final NewCommentPersonalNotify.NewCommentPersonalNotifyBuilder notifyBuilder = NewCommentPersonalNotify.builder()
|
final Note threadFirstNote = discussion.getFirstNote();
|
||||||
.threadId(discussion.getId())
|
if (TRUE.equals(discussion.getResolved())) {
|
||||||
.url(note.getWebUrl())
|
notifyAboutCloseThread(threadFirstNote, oldNoteMap.get(threadFirstNote.getId()), discussion.getLastNote());
|
||||||
.mergeRequestName(discussion.getMergeRequest().getTitle());
|
|
||||||
|
|
||||||
if (NOTIFY_WITH_CONTEXT.equals(discussionLevel)) {
|
|
||||||
final Optional<Note> prevLastNote = discussion.getPrevLastNote();
|
|
||||||
|
|
||||||
if (prevLastNote.isPresent()) {
|
|
||||||
final Note prevNote = prevLastNote.get();
|
|
||||||
notifyBuilder.previousMessage(prevNote.getBody());
|
|
||||||
notifyBuilder.previousAuthor(prevNote.getAuthor().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyBuilder
|
|
||||||
.discussionMessage(firstNote.getBody())
|
|
||||||
.discussionAuthor(firstNote.getAuthor().getName())
|
|
||||||
.message(note.getBody())
|
|
||||||
.authorName(note.getAuthor().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyService.send(notifyBuilder.build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Note newNote : discussion.getNotes()) {
|
||||||
|
final Long newNoteId = newNote.getId();
|
||||||
|
if (!oldNoteMap.containsKey(newNoteId)) {
|
||||||
|
if (userParticipatedInDiscussion) {
|
||||||
|
notifyAboutNewAnswer(discussion, newNote);
|
||||||
|
} else {
|
||||||
|
notifyAboutPersonalAnswer(discussion, newNote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyAboutCloseThread(Note newNote, Note oldNote, Optional<Note> lastNote) {
|
private void notifyAboutCloseThread(Note newNote, Note oldNote, Optional<Note> lastNote) {
|
||||||
@ -218,7 +183,7 @@ public class DiscussionHandler {
|
|||||||
if (isResolved(newNote, oldNote)) {
|
if (isResolved(newNote, oldNote)) {
|
||||||
final MergeRequestForDiscussion mergeRequest = oldNote.getDiscussion().getMergeRequest();
|
final MergeRequestForDiscussion mergeRequest = oldNote.getDiscussion().getMergeRequest();
|
||||||
|
|
||||||
final List<Discussion> discussions = discussionService.getAllByMergeRequestId(mergeRequest.getId())
|
final List<Discussion> discussions = getAllByMergeRequestId(mergeRequest.getId())
|
||||||
.stream()
|
.stream()
|
||||||
.filter(discussion -> Objects.nonNull(discussion.getResponsible()))
|
.filter(discussion -> Objects.nonNull(discussion.getResponsible()))
|
||||||
.toList();
|
.toList();
|
||||||
@ -229,7 +194,7 @@ public class DiscussionHandler {
|
|||||||
.filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId()) && discussion.getResolved())
|
.filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId()) && discussion.getResolved())
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
final ThreadClosePersonalNotify.ThreadClosePersonalNotifyBuilder notifyBuilder = ThreadClosePersonalNotify.builder()
|
final ThreadCloseNotify.ThreadCloseNotifyBuilder notifyBuilder = ThreadCloseNotify.builder()
|
||||||
.mergeRequestName(mergeRequest.getTitle())
|
.mergeRequestName(mergeRequest.getTitle())
|
||||||
.url(oldNote.getWebUrl())
|
.url(oldNote.getWebUrl())
|
||||||
.personTasks(allYouTasks)
|
.personTasks(allYouTasks)
|
||||||
@ -262,4 +227,195 @@ public class DiscussionHandler {
|
|||||||
&& !note.getResolvedBy().getId().equals(oldNote.getAuthor().getId()); // и решающий не является автором треда
|
&& !note.getResolvedBy().getId().equals(oldNote.getAuthor().getId()); // и решающий не является автором треда
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void answer(@NonNull String discussionId, @NonNull String text) {
|
||||||
|
final Discussion discussion = repository.findById(discussionId)
|
||||||
|
.orElseThrow(notFoundException("Дисскусия {0} не найдена", discussionId));
|
||||||
|
final MergeRequestForDiscussion mergeRequest = discussion.getMergeRequest();
|
||||||
|
final Long projectId = mergeRequest.getProjectId();
|
||||||
|
|
||||||
|
final String requestUrl = MessageFormat.format(gitlabProperty.getNewNoteUrl(), projectId, mergeRequest.getTwoId(), discussion.getId(), text);
|
||||||
|
|
||||||
|
final RequestBody formBody = new FormBody.Builder().build();
|
||||||
|
|
||||||
|
final Request request = new Request.Builder()
|
||||||
|
.post(formBody)
|
||||||
|
.header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken())
|
||||||
|
.url(requestUrl)
|
||||||
|
.build();
|
||||||
|
try {
|
||||||
|
client.newCall(request).execute();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Discussion> getAllByMergeRequestId(@NonNull Long mergeRequestId) {
|
||||||
|
return repository.findAllByMergeRequestId(mergeRequestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExistContainer<Discussion, String> existsById(@NonNull Set<String> discussionIds) {
|
||||||
|
final List<Discussion> existsEntity = repository.findAllById(discussionIds);
|
||||||
|
final Set<String> existsIds = existsEntity.stream().map(Discussion::getId).collect(Collectors.toSet());
|
||||||
|
if (existsIds.containsAll(discussionIds)) {
|
||||||
|
return ExistContainer.allFind(existsEntity);
|
||||||
|
} else {
|
||||||
|
final Set<String> noExistsId = discussionIds.stream()
|
||||||
|
.filter(id -> !existsIds.contains(id))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
return ExistContainer.notAllFind(existsEntity, noExistsId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Discussion> createAll(@NonNull List<Discussion> newDiscussions) {
|
||||||
|
return newDiscussions.stream()
|
||||||
|
.map(this::create)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Discussion> getAll() {
|
||||||
|
return repository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getAllIds() {
|
||||||
|
return repository.findAllIds();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void deleteById(@NonNull String discussionId) {
|
||||||
|
repository.deleteById(discussionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void cleanOld() {
|
||||||
|
log.debug("Старт очистки старых дискуссий");
|
||||||
|
repository.cleanOld();
|
||||||
|
log.debug("Конец очистки старых дискуссий");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void notification(boolean enable, String discussionId) {
|
||||||
|
repository.notification(enable, discussionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyAboutNewAnswer(Discussion discussion, Note note) {
|
||||||
|
final DiscussionLevel discussionLevel = settingService.getLevelDiscussionNotify();
|
||||||
|
|
||||||
|
if (!WITHOUT_NOTIFY.equals(discussionLevel)
|
||||||
|
&& !personInformation.getId().equals(note.getAuthor().getId())) {
|
||||||
|
final Note firstNote = discussion.getFirstNote();
|
||||||
|
|
||||||
|
final NewCommentNotify.NewCommentNotifyBuilder notifyBuilder = NewCommentNotify.builder()
|
||||||
|
.threadId(discussion.getId())
|
||||||
|
.url(note.getWebUrl())
|
||||||
|
.mergeRequestName(discussion.getMergeRequest().getTitle());
|
||||||
|
|
||||||
|
if (NOTIFY_WITH_CONTEXT.equals(discussionLevel)) {
|
||||||
|
final Optional<Note> prevLastNote = discussion.getPrevLastNote();
|
||||||
|
|
||||||
|
if (prevLastNote.isPresent()) {
|
||||||
|
final Note prevNote = prevLastNote.get();
|
||||||
|
notifyBuilder.previousMessage(prevNote.getBody());
|
||||||
|
notifyBuilder.previousAuthor(prevNote.getAuthor().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyBuilder
|
||||||
|
.discussionMessage(firstNote.getBody())
|
||||||
|
.discussionAuthor(firstNote.getAuthor().getName())
|
||||||
|
.message(note.getBody())
|
||||||
|
.authorName(note.getAuthor().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyService.send(notifyBuilder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Уведомляет пользователя, если его никнейм упоминается в комментарии.
|
||||||
|
*/
|
||||||
|
private void notifyAboutPersonalAnswer(Discussion discussion, Note note) {
|
||||||
|
final DiscussionLevel discussionLevel = settingService.getLevelDiscussionNotify();
|
||||||
|
if (!WITHOUT_NOTIFY.equals(discussionLevel)) {
|
||||||
|
final Matcher matcher = PATTERN.matcher(note.getBody());
|
||||||
|
final Set<String> recipientsLogins = new HashSet<>();
|
||||||
|
|
||||||
|
while (matcher.find()) {
|
||||||
|
final String login = matcher.group(0).replace("@", "");
|
||||||
|
recipientsLogins.add(login);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recipientsLogins.contains(personInformation.getUsername())) {
|
||||||
|
final NewCommentNotify.NewCommentNotifyBuilder notifyBuilder = NewCommentNotify.builder()
|
||||||
|
.threadId(discussion.getId())
|
||||||
|
.mergeRequestName(discussion.getMergeRequest().getTitle())
|
||||||
|
.url(note.getWebUrl());
|
||||||
|
|
||||||
|
if (NOTIFY_WITH_CONTEXT.equals(discussionLevel)) {
|
||||||
|
final Optional<Note> prevLastNote = discussion.getPrevLastNote();
|
||||||
|
final Note firstNote = discussion.getFirstNote();
|
||||||
|
|
||||||
|
if (!firstNote.equals(note)) {
|
||||||
|
notifyBuilder.message(note.getBody())
|
||||||
|
.authorName(note.getAuthor().getName());
|
||||||
|
}
|
||||||
|
if (prevLastNote.isPresent()) {
|
||||||
|
final Note prevNote = prevLastNote.get();
|
||||||
|
notifyBuilder.previousMessage(prevNote.getBody());
|
||||||
|
notifyBuilder.previousAuthor(prevNote.getAuthor().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyBuilder
|
||||||
|
.discussionMessage(firstNote.getBody())
|
||||||
|
.discussionAuthor(firstNote.getAuthor().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyService.send(notifyBuilder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Уведомляет пользователя, если появился новый комментарий</p>
|
||||||
|
*/
|
||||||
|
private void notifyNewThread(Discussion discussion) {
|
||||||
|
final DiscussionLevel discussionLevel = settingService.getLevelDiscussionNotify();
|
||||||
|
if (!WITHOUT_NOTIFY.equals(discussionLevel)) {
|
||||||
|
final Note firstNote = discussion.getFirstNote();
|
||||||
|
|
||||||
|
final MergeRequestForDiscussion mergeRequest = discussion.getMergeRequest();
|
||||||
|
final DiscussionNewNotify.DiscussionNewNotifyBuilder messageBuilder = DiscussionNewNotify.builder()
|
||||||
|
.url(firstNote.getWebUrl())
|
||||||
|
.threadId(discussion.getId())
|
||||||
|
.mergeRequestName(mergeRequest.getTitle())
|
||||||
|
.authorName(firstNote.getAuthor().getName());
|
||||||
|
|
||||||
|
if (NOTIFY_WITH_CONTEXT.equals(discussionLevel)) {
|
||||||
|
final List<Note> notes = discussion.getNotes();
|
||||||
|
|
||||||
|
messageBuilder
|
||||||
|
.discussionMessage(firstNote.getBody());
|
||||||
|
|
||||||
|
if (notes.size() > 1) {
|
||||||
|
for (int i = 1; i < notes.size(); i++) {
|
||||||
|
final Note note = notes.get(i);
|
||||||
|
messageBuilder.note(
|
||||||
|
new Pair<>(note.getAuthor().getName(), note.getBody())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyService.send(messageBuilder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,313 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.*;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Issue;
|
||||||
|
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.notify.issue.*;
|
||||||
|
import dev.struchkov.bot.gitlab.context.repository.IssueRepository;
|
||||||
|
import dev.struchkov.bot.gitlab.context.service.IssueService;
|
||||||
|
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
||||||
|
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static dev.struchkov.bot.gitlab.context.domain.IssueState.CLOSED;
|
||||||
|
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko [25.01.2023]
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class IssueServiceImpl implements IssueService {
|
||||||
|
|
||||||
|
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("dd.MM.yyyy");
|
||||||
|
public static final Set<IssueState> DELETE_STATES = Set.of(CLOSED);
|
||||||
|
|
||||||
|
private final PersonInformation personInformation;
|
||||||
|
private final IssueRepository repository;
|
||||||
|
private final ProjectService projectService;
|
||||||
|
private final NotifyService notifyService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public Issue create(@NonNull Issue issue) {
|
||||||
|
final boolean botUserAssignee = isBotUserAssignee(issue);
|
||||||
|
final boolean botUserAssigneeAndNotAuthor = isBotUserAssigneeAndNotAuthor(issue);
|
||||||
|
issue.setUserAssignee(botUserAssignee);
|
||||||
|
issue.setNotification(botUserAssigneeAndNotAuthor);
|
||||||
|
|
||||||
|
final Issue savedIssue = repository.save(issue);
|
||||||
|
|
||||||
|
if (botUserAssigneeAndNotAuthor) {
|
||||||
|
final String projectName = projectService.getByIdOrThrow(savedIssue.getProjectId()).getName();
|
||||||
|
sendNotifyAboutAssignee(issue, projectName);
|
||||||
|
}
|
||||||
|
return savedIssue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBotUserAssignee(Issue savedIssue) {
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
final List<Person> assignees = savedIssue.getAssignees();
|
||||||
|
|
||||||
|
if (checkNotEmpty(assignees)) {
|
||||||
|
for (Person assignee : assignees) {
|
||||||
|
if (gitlabUserId.equals(assignee.getId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBotUserAssigneeAndNotAuthor(Issue savedIssue) {
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
final boolean botUserAssignee = isBotUserAssignee(savedIssue);
|
||||||
|
|
||||||
|
if (botUserAssignee) {
|
||||||
|
return !gitlabUserId.equals(savedIssue.getAuthor().getId());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendNotifyAboutAssignee(Issue issue, String projectName) {
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
if (!gitlabUserId.equals(issue.getAuthor().getId()) // создатель Issue не является пользователем бота
|
||||||
|
)
|
||||||
|
notifyService.send(
|
||||||
|
NewIssueNotify.builder()
|
||||||
|
.projectName(projectName)
|
||||||
|
.title(issue.getTitle())
|
||||||
|
.url(issue.getWebUrl())
|
||||||
|
.issueType(issue.getType().name())
|
||||||
|
.author(issue.getAuthor().getName())
|
||||||
|
.description(issue.getDescription())
|
||||||
|
.dueDate(issue.getDueDate().format(DATE_FORMAT))
|
||||||
|
.labels(issue.getLabels())
|
||||||
|
.confidential(issue.getConfidential().toString())
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendNotifyAboutDeleteFromAssignees(Issue issue, String projectName) {
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
if (!gitlabUserId.equals(issue.getAuthor().getId()) // создатель Issue не является пользователем бота
|
||||||
|
)
|
||||||
|
notifyService.send(
|
||||||
|
DeleteFromAssigneesNotify.builder()
|
||||||
|
.projectName(projectName)
|
||||||
|
.title(issue.getTitle())
|
||||||
|
.url(issue.getWebUrl())
|
||||||
|
.issueType(issue.getType().name())
|
||||||
|
.updateDate(issue.getUpdatedDate().format(DATE_FORMAT))
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public Issue update(@NonNull Issue issue) {
|
||||||
|
final Issue oldIssue = repository.findById(issue.getId())
|
||||||
|
.orElseThrow(notFoundException("Issue не найдено"));
|
||||||
|
|
||||||
|
issue.setNotification(oldIssue.isNotification());
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* проверяем изменения списка Assignees: пользователь появился в списке или удален из него или без изменений.
|
||||||
|
*/
|
||||||
|
final AssigneesChanged assigneesChanged = AssigneesChanged.valueOf(gitlabUserId, oldIssue.getAssignees(), issue.getAssignees());
|
||||||
|
issue.setUserAssignee(assigneesChanged.getNewStatus(oldIssue.isUserAssignee()));
|
||||||
|
final boolean isChangedIssue = !oldIssue.getUpdatedDate().equals(issue.getUpdatedDate());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Удаление пользователя из assignee не всегда обновляет UpdatedDate, поэтому добавляется
|
||||||
|
* второе условие assigneesChanged.isChanged()
|
||||||
|
*/
|
||||||
|
if (isChangedIssue || assigneesChanged.isChanged()) {
|
||||||
|
|
||||||
|
if (assigneesChanged.equals(AssigneesChanged.BECOME) && !gitlabUserId.equals(issue.getAuthor().getId()))
|
||||||
|
issue.setNotification(true);
|
||||||
|
|
||||||
|
if (issue.isNotification()) {
|
||||||
|
final Project project = projectService.getByIdOrThrow(issue.getProjectId());
|
||||||
|
notifyAboutStatus(oldIssue, issue, project);
|
||||||
|
notifyAboutType(oldIssue, issue, project);
|
||||||
|
notifyAboutTitle(oldIssue, issue, project);
|
||||||
|
notifyAboutDescription(oldIssue, issue, project);
|
||||||
|
notifyAboutDueDate(oldIssue, issue, project);
|
||||||
|
notifyAboutChangeAssignees(assigneesChanged, issue, project);
|
||||||
|
}
|
||||||
|
return repository.save(issue);
|
||||||
|
}
|
||||||
|
return oldIssue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExistContainer<Issue, Long> existsById(@NonNull Set<Long> issueIds) {
|
||||||
|
final List<Issue> existsEntity = repository.findAllById(issueIds);
|
||||||
|
final Set<Long> existsIds = existsEntity.stream().map(Issue::getId).collect(Collectors.toSet());
|
||||||
|
if (existsIds.containsAll(issueIds)) {
|
||||||
|
return ExistContainer.allFind(existsEntity);
|
||||||
|
} else {
|
||||||
|
final Set<Long> noExistsId = issueIds.stream()
|
||||||
|
.filter(id -> !existsIds.contains(id))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
return ExistContainer.notAllFind(existsEntity, noExistsId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Issue> createAll(List<Issue> newIssues) {
|
||||||
|
return newIssues.stream()
|
||||||
|
.map(this::create)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public List<Issue> updateAll(@NonNull List<Issue> issues) {
|
||||||
|
return issues.stream()
|
||||||
|
.map(this::update)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<IdAndStatusIssue> getAllId(Set<IssueState> statuses) {
|
||||||
|
return repository.findAllIdByStateIn(statuses);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void notifyAboutChangeAssignees(AssigneesChanged assigneesChanged, Issue issue, Project project) {
|
||||||
|
switch (assigneesChanged) {
|
||||||
|
case BECOME -> sendNotifyAboutAssignee(issue, project.getName());
|
||||||
|
case DELETED -> {
|
||||||
|
sendNotifyAboutDeleteFromAssignees(issue, project.getName());
|
||||||
|
issue.setUserAssignee(false);
|
||||||
|
issue.setNotification(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void notifyAboutTitle(Issue oldIssue, Issue newIssue, Project project) {
|
||||||
|
final String oldTitle = oldIssue.getTitle();
|
||||||
|
final String newTitle = newIssue.getTitle();
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
if (
|
||||||
|
!oldTitle.equals(newTitle) // заголовок изменился
|
||||||
|
&& !gitlabUserId.equals(oldIssue.getAuthor().getId()) // создатель Issue не является пользователем бота
|
||||||
|
) {
|
||||||
|
notifyService.send(
|
||||||
|
TitleIssueNotify.builder()
|
||||||
|
.projectName(project.getName())
|
||||||
|
.title(oldIssue.getTitle())
|
||||||
|
.url(oldIssue.getWebUrl())
|
||||||
|
.issueType(oldIssue.getType().name())
|
||||||
|
.newTitle(newTitle)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void notifyAboutDescription(Issue oldIssue, Issue newIssue, Project project) {
|
||||||
|
final String oldDescription = oldIssue.getDescription();
|
||||||
|
final String newDescription = newIssue.getDescription();
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
if (
|
||||||
|
!oldDescription.equals(newDescription) // описание изменилось
|
||||||
|
&& !gitlabUserId.equals(oldIssue.getAuthor().getId()) // создатель Issue не является пользователем бота
|
||||||
|
) {
|
||||||
|
notifyService.send(
|
||||||
|
DescriptionIssueNotify.builder()
|
||||||
|
.projectName(project.getName())
|
||||||
|
.title(oldIssue.getTitle())
|
||||||
|
.url(oldIssue.getWebUrl())
|
||||||
|
.issueType(oldIssue.getType().name())
|
||||||
|
.newDescription(newDescription)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void notifyAboutType(Issue oldIssue, Issue newIssue, Project project) {
|
||||||
|
final IssueType oldType = oldIssue.getType();
|
||||||
|
final IssueType newType = newIssue.getType();
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
if (
|
||||||
|
!oldType.equals(newType) // тип изменился
|
||||||
|
&& !gitlabUserId.equals(oldIssue.getAuthor().getId()) // создатель Issue не является пользователем бота
|
||||||
|
) {
|
||||||
|
notifyService.send(
|
||||||
|
TypeIssueNotify.builder()
|
||||||
|
.projectName(project.getName())
|
||||||
|
.title(oldIssue.getTitle())
|
||||||
|
.url(oldIssue.getWebUrl())
|
||||||
|
.issueType(oldIssue.getType().name())
|
||||||
|
.oldType(oldType)
|
||||||
|
.newType(newType)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void notifyAboutStatus(Issue oldIssue, Issue newIssue, Project project) {
|
||||||
|
final IssueState oldStatus = oldIssue.getState();
|
||||||
|
final IssueState newStatus = newIssue.getState();
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
if (
|
||||||
|
!oldStatus.equals(newStatus) // статус изменился
|
||||||
|
&& gitlabUserId.equals(oldIssue.getAuthor().getId()) // создатель Issue является пользователем бота
|
||||||
|
) {
|
||||||
|
notifyService.send(
|
||||||
|
StatusIssueNotify.builder()
|
||||||
|
.name(newIssue.getTitle())
|
||||||
|
.url(oldIssue.getWebUrl())
|
||||||
|
.issueType(oldIssue.getType().name())
|
||||||
|
.projectName(project.getName())
|
||||||
|
.newStatus(newStatus)
|
||||||
|
.oldStatus(oldStatus)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void notifyAboutDueDate(Issue oldIssue, Issue newIssue, Project project) {
|
||||||
|
final String oldDueDate = oldIssue.getDueDate().format(DATE_FORMAT);
|
||||||
|
final String newDueDate = newIssue.getDueDate().format(DATE_FORMAT);
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
if (
|
||||||
|
(!Objects.equals(oldDueDate, newDueDate)) // дата изменилась
|
||||||
|
&& (!gitlabUserId.equals(oldIssue.getAuthor().getId())) // создатель Issue не является пользователем бота
|
||||||
|
) {
|
||||||
|
notifyService.send(
|
||||||
|
DueDateIssueNotify.builder()
|
||||||
|
.projectName(project.getName())
|
||||||
|
.title(oldIssue.getTitle())
|
||||||
|
.url(oldIssue.getWebUrl())
|
||||||
|
.issueType(oldIssue.getType().name())
|
||||||
|
.oldDueDate(oldDueDate)
|
||||||
|
.newDueDate(newDueDate)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanOld() {
|
||||||
|
log.debug("Старт очистки старых Issue");
|
||||||
|
repository.deleteByStates(DELETE_STATES);
|
||||||
|
log.debug("Конец очистки старых Issue");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,396 @@
|
|||||||
|
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.MergeRequestForDiscussion;
|
||||||
|
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.notify.mergerequest.ConflictMrNotify;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictResolveMrNotify;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.NewMrForAssignee;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.NewMrForReview;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.StatusMrNotify;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.UpdateMrNotify;
|
||||||
|
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.ProjectService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static dev.struchkov.bot.gitlab.context.domain.MergeRequestState.CLOSED;
|
||||||
|
import static dev.struchkov.bot.gitlab.context.domain.MergeRequestState.MERGED;
|
||||||
|
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 java.lang.Boolean.TRUE;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MergeRequestsServiceImpl implements MergeRequestsService {
|
||||||
|
|
||||||
|
public static final Set<MergeRequestState> DELETE_STATES = Set.of(MERGED, CLOSED);
|
||||||
|
|
||||||
|
private final MergeRequestRepository repository;
|
||||||
|
|
||||||
|
private final NotifyService notifyService;
|
||||||
|
private final ProjectService projectService;
|
||||||
|
private final DiscussionService discussionService;
|
||||||
|
|
||||||
|
private final PersonInformation personInformation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public MergeRequest create(@NonNull MergeRequest mergeRequest) {
|
||||||
|
final boolean botUserReviewer = isBotUserReviewer(mergeRequest);
|
||||||
|
final boolean botUserAssignee = isBotUserAssigneeAndNotAuthor(mergeRequest);
|
||||||
|
final boolean botUserAuthor = personInformation.getId().equals(mergeRequest.getAuthor().getId());
|
||||||
|
|
||||||
|
mergeRequest.setNotification(botUserReviewer || botUserAssignee || botUserAuthor);
|
||||||
|
mergeRequest.setUserAssignee(botUserAssignee);
|
||||||
|
mergeRequest.setUserReviewer(botUserReviewer);
|
||||||
|
|
||||||
|
final MergeRequest savedMergeRequest = repository.save(mergeRequest);
|
||||||
|
|
||||||
|
if (botUserReviewer || botUserAssignee) {
|
||||||
|
if (!mergeRequest.isConflict()) {
|
||||||
|
final String projectName = projectService.getByIdOrThrow(savedMergeRequest.getProjectId()).getName();
|
||||||
|
if (botUserReviewer) sendNotifyNewMrReview(savedMergeRequest, projectName);
|
||||||
|
if (botUserAssignee) sendNotifyNewAssignee(mergeRequest, projectName, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return savedMergeRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBotUserAssigneeAndNotAuthor(MergeRequest mergeRequest) {
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
final Person assignee = mergeRequest.getAssignee();
|
||||||
|
final Person author = mergeRequest.getAuthor();
|
||||||
|
|
||||||
|
if (checkNotNull(assignee)) {
|
||||||
|
if (gitlabUserId.equals(assignee.getId()) && !isAuthorSameAssignee(author, assignee)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создатель MR является ответственным за этот MR
|
||||||
|
*
|
||||||
|
* @return true, если автор и ответственный один и тот же человек.
|
||||||
|
*/
|
||||||
|
private boolean isAuthorSameAssignee(Person author, Person assignee) {
|
||||||
|
return author.getId().equals(assignee.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBotUserReviewer(MergeRequest savedMergeRequest) {
|
||||||
|
final List<Person> reviewers = savedMergeRequest.getReviewers();
|
||||||
|
final Long botUserGitlabId = personInformation.getId();
|
||||||
|
|
||||||
|
if (checkNotEmpty(reviewers)) {
|
||||||
|
for (Person reviewer : reviewers) {
|
||||||
|
if (botUserGitlabId.equals(reviewer.getId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendNotifyNewMrReview(MergeRequest mergeRequest, String projectName) {
|
||||||
|
notifyService.send(
|
||||||
|
NewMrForReview.builder()
|
||||||
|
.mrId(mergeRequest.getId())
|
||||||
|
.projectName(projectName)
|
||||||
|
.labels(mergeRequest.getLabels())
|
||||||
|
.author(mergeRequest.getAuthor().getName())
|
||||||
|
.description(mergeRequest.getDescription())
|
||||||
|
.title(mergeRequest.getTitle())
|
||||||
|
.url(mergeRequest.getWebUrl())
|
||||||
|
.targetBranch(mergeRequest.getTargetBranch())
|
||||||
|
.sourceBranch(mergeRequest.getSourceBranch())
|
||||||
|
.assignee(mergeRequest.getAssignee().getName())
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendNotifyNewAssignee(MergeRequest mergeRequest, String projectName, String oldAssigneeName) {
|
||||||
|
final NewMrForAssignee.NewMrForAssigneeBuilder builder = NewMrForAssignee.builder()
|
||||||
|
.mrId(mergeRequest.getId())
|
||||||
|
.projectName(projectName)
|
||||||
|
.labels(mergeRequest.getLabels())
|
||||||
|
.author(mergeRequest.getAuthor().getName())
|
||||||
|
.description(mergeRequest.getDescription())
|
||||||
|
.title(mergeRequest.getTitle())
|
||||||
|
.url(mergeRequest.getWebUrl())
|
||||||
|
.targetBranch(mergeRequest.getTargetBranch())
|
||||||
|
.sourceBranch(mergeRequest.getSourceBranch())
|
||||||
|
.reviewers(mergeRequest.getReviewers().stream().map(Person::getName).toList());
|
||||||
|
|
||||||
|
if (checkNotNull(oldAssigneeName)) {
|
||||||
|
builder.oldAssigneeName(oldAssigneeName);
|
||||||
|
|
||||||
|
if (checkNotNull(mergeRequest.getAssignee())) {
|
||||||
|
builder.newAssigneeName(mergeRequest.getAssignee().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyService.send(builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public MergeRequest update(@NonNull MergeRequest mergeRequest) {
|
||||||
|
final MergeRequest oldMergeRequest = repository.findById(mergeRequest.getId())
|
||||||
|
.orElseThrow(notFoundException("MergeRequest не найден"));
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
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) {
|
||||||
|
|
||||||
|
if (oldMergeRequest.isNotification()) {
|
||||||
|
final Project project = projectService.getByIdOrThrow(mergeRequest.getProjectId());
|
||||||
|
|
||||||
|
if (isChangedMr) {
|
||||||
|
notifyAboutStatus(oldMergeRequest, mergeRequest, project);
|
||||||
|
notifyAboutNewConflict(oldMergeRequest, mergeRequest, project);
|
||||||
|
notifyAboutResolveConflict(oldMergeRequest, mergeRequest, project);
|
||||||
|
notifyAboutUpdate(oldMergeRequest, mergeRequest, project);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isChangedLinkedEntity) {
|
||||||
|
notifyReviewer(reviewerChanged, mergeRequest, project);
|
||||||
|
notifyAssignee(assigneeChanged, oldMergeRequest, mergeRequest, project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return repository.save(mergeRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldMergeRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление
|
||||||
|
|
||||||
|
private void notifyAssignee(AssigneeChanged assigneeChanged, MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||||
|
switch (assigneeChanged) {
|
||||||
|
case BECOME ->
|
||||||
|
sendNotifyNewAssignee(mergeRequest, project.getName(), Optional.ofNullable(oldMergeRequest.getAssignee()).map(Person::getName).orElse(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление ревьювера
|
||||||
|
|
||||||
|
private void notifyReviewer(ReviewerChanged reviewerChanged, MergeRequest mergeRequest, Project project) {
|
||||||
|
switch (reviewerChanged) {
|
||||||
|
case BECOME -> sendNotifyNewMrReview(mergeRequest, project.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public List<MergeRequest> updateAll(@NonNull List<MergeRequest> mergeRequests) {
|
||||||
|
return mergeRequests.stream()
|
||||||
|
.map(this::update)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<IdAndStatusPr> getAllId(Set<MergeRequestState> statuses) {
|
||||||
|
return repository.findAllIdByStateIn(statuses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MergeRequestForDiscussion> getAllForDiscussion() {
|
||||||
|
return repository.findAllForDiscussion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExistContainer<MergeRequest, Long> existsById(@NonNull Set<Long> mergeRequestIds) {
|
||||||
|
final List<MergeRequest> existsEntity = repository.findAllById(mergeRequestIds);
|
||||||
|
final Set<Long> existsIds = existsEntity.stream().map(MergeRequest::getId).collect(Collectors.toSet());
|
||||||
|
if (existsIds.containsAll(mergeRequestIds)) {
|
||||||
|
return ExistContainer.allFind(existsEntity);
|
||||||
|
} else {
|
||||||
|
final Set<Long> noExistsId = mergeRequestIds.stream()
|
||||||
|
.filter(id -> !existsIds.contains(id))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
return ExistContainer.notAllFind(existsEntity, noExistsId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MergeRequest> createAll(List<MergeRequest> newMergeRequests) {
|
||||||
|
return newMergeRequests.stream()
|
||||||
|
.map(this::create)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MergeRequest> getAllByReviewerId(@NonNull Long personId) {
|
||||||
|
return repository.findAllByReviewerId(personId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanOld() {
|
||||||
|
log.debug("Старт очистки старых MR");
|
||||||
|
repository.deleteByStates(DELETE_STATES);
|
||||||
|
log.debug("Конец очистки старых MR");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public Set<Long> getAllIds() {
|
||||||
|
return repository.findAllIds();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void notification(boolean enable, @NonNull Long mrId) {
|
||||||
|
repository.notification(enable, mrId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void notificationByProjectId(boolean enable, @NonNull Set<Long> projectIds) {
|
||||||
|
repository.notificationByProjectId(enable, projectIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyAboutUpdate(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||||
|
final Long botUserGitlabId = personInformation.getId();
|
||||||
|
if (
|
||||||
|
!botUserGitlabId.equals(mergeRequest.getAuthor().getId()) // Автор MR не пользователь приложения
|
||||||
|
&& !oldMergeRequest.getDateLastCommit().equals(mergeRequest.getDateLastCommit()) // Изменилась дата последнего коммита
|
||||||
|
&& !mergeRequest.isConflict() // MR не находится в состоянии конфликта
|
||||||
|
&& !botUserGitlabId.equals(oldMergeRequest.getAuthor().getId()) // и MR создан НЕ пользователем бота
|
||||||
|
) {
|
||||||
|
long allTask = 0;
|
||||||
|
long resolvedTask = 0;
|
||||||
|
long allYouTasks = 0;
|
||||||
|
long resolvedYouTask = 0;
|
||||||
|
|
||||||
|
final List<Discussion> discussions = discussionService.getAllByMergeRequestId(oldMergeRequest.getId());
|
||||||
|
for (Discussion discussion : discussions) {
|
||||||
|
if (checkNotNull(discussion.getResponsible())) {
|
||||||
|
final boolean isBotUserAuthorDiscussion = botUserGitlabId.equals(discussion.getFirstNote().getAuthor().getId());
|
||||||
|
allTask += 1;
|
||||||
|
if (isBotUserAuthorDiscussion) {
|
||||||
|
allYouTasks += 1;
|
||||||
|
}
|
||||||
|
if (TRUE.equals(discussion.getResolved())) {
|
||||||
|
resolvedTask += 1;
|
||||||
|
if (isBotUserAuthorDiscussion) {
|
||||||
|
resolvedYouTask += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final UpdateMrNotify.UpdateMrNotifyBuilder notifyBuilder = UpdateMrNotify.builder()
|
||||||
|
.mrId(oldMergeRequest.getId())
|
||||||
|
.author(oldMergeRequest.getAuthor().getName())
|
||||||
|
.name(oldMergeRequest.getTitle())
|
||||||
|
.projectName(project.getName())
|
||||||
|
.url(oldMergeRequest.getWebUrl())
|
||||||
|
.allTasks(allTask)
|
||||||
|
.allResolvedTasks(resolvedTask)
|
||||||
|
.personTasks(allYouTasks)
|
||||||
|
.personResolvedTasks(resolvedYouTask);
|
||||||
|
|
||||||
|
if (oldMergeRequest.isConflict() && !mergeRequest.isConflict()) {
|
||||||
|
notifyBuilder.comment("The conflict has been resolved");
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyService.send(notifyBuilder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void notifyAboutNewConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
if (
|
||||||
|
!oldMergeRequest.isConflict() // У старого MR не было конфликта
|
||||||
|
&& mergeRequest.isConflict() // А у нового есть
|
||||||
|
&& gitlabUserId.equals(oldMergeRequest.getAuthor().getId()) // и MR создан пользователем бота
|
||||||
|
) {
|
||||||
|
notifyService.send(
|
||||||
|
ConflictMrNotify.builder()
|
||||||
|
.mrId(oldMergeRequest.getId())
|
||||||
|
.sourceBranch(oldMergeRequest.getSourceBranch())
|
||||||
|
.name(mergeRequest.getTitle())
|
||||||
|
.url(mergeRequest.getWebUrl())
|
||||||
|
.projectKey(project.getName())
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyAboutResolveConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
if (oldMergeRequest.isConflict() && !mergeRequest.isConflict()) {
|
||||||
|
// проверяем даты коммитов, так как при пуше в target ветку MR у которого есть конфликт, конфликт на время пропадает. Судя по всему GitLab после пуша заново проверяет вероятность конфликта. Чаще всего конфликт никуда не девается.
|
||||||
|
if (oldMergeRequest.getDateLastCommit().equals(mergeRequest.getDateLastCommit())) {
|
||||||
|
mergeRequest.setConflict(true);
|
||||||
|
} else {
|
||||||
|
if (gitlabUserId.equals(oldMergeRequest.getAuthor().getId())) {
|
||||||
|
notifyService.send(
|
||||||
|
ConflictResolveMrNotify.builder()
|
||||||
|
.mrId(oldMergeRequest.getId())
|
||||||
|
.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();
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
if (
|
||||||
|
!oldStatus.equals(newStatus) // статус изменился
|
||||||
|
&& gitlabUserId.equals(oldMergeRequest.getAuthor().getId()) // создатель MR является пользователем бота
|
||||||
|
) {
|
||||||
|
notifyService.send(
|
||||||
|
StatusMrNotify.builder()
|
||||||
|
.mrId(oldMergeRequest.getId())
|
||||||
|
.name(newMergeRequest.getTitle())
|
||||||
|
.url(oldMergeRequest.getWebUrl())
|
||||||
|
.projectName(project.getName())
|
||||||
|
.newStatus(newStatus)
|
||||||
|
.oldStatus(oldStatus)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,6 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service;
|
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.prop.GroupNotifyProperty;
|
|
||||||
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
|
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.MessageSendService;
|
import dev.struchkov.bot.gitlab.context.service.MessageSendService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
||||||
@ -12,33 +10,22 @@ import org.springframework.stereotype.Service;
|
|||||||
@Service
|
@Service
|
||||||
public class NotifyServiceImpl implements NotifyService {
|
public class NotifyServiceImpl implements NotifyService {
|
||||||
|
|
||||||
private final GroupNotifyProperty groupNotifyProperty;
|
|
||||||
private final MessageSendService messageSendService;
|
private final MessageSendService messageSendService;
|
||||||
private final AppSettingService settingService;
|
private final AppSettingService settingService;
|
||||||
|
|
||||||
public NotifyServiceImpl(
|
public NotifyServiceImpl(
|
||||||
GroupNotifyProperty groupNotifyProperty, @Lazy MessageSendService messageSendService,
|
@Lazy MessageSendService messageSendService,
|
||||||
AppSettingService settingService
|
AppSettingService settingService
|
||||||
) {
|
) {
|
||||||
this.groupNotifyProperty = groupNotifyProperty;
|
|
||||||
this.messageSendService = messageSendService;
|
this.messageSendService = messageSendService;
|
||||||
this.settingService = settingService;
|
this.settingService = settingService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends PersonalNotify> void send(T notify) {
|
public <T extends Notify> void send(T notify) {
|
||||||
if (settingService.isEnableAllNotify()) {
|
if (settingService.isEnableAllNotify()) {
|
||||||
messageSendService.send(notify);
|
messageSendService.send(notify);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T extends GroupNotify> void send(T notify) {
|
|
||||||
if (settingService.isEnableAllNotify()) {
|
|
||||||
if (groupNotifyProperty.getChatId().isPresent()) {
|
|
||||||
messageSendService.send(notify);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,8 +1,7 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service;
|
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.PersonTelegram;
|
|
||||||
import dev.struchkov.bot.gitlab.context.repository.PersonRepository;
|
import dev.struchkov.bot.gitlab.context.repository.PersonRepository;
|
||||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
@ -11,8 +10,6 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -32,6 +29,11 @@ public class PersonServiceImpl implements PersonService {
|
|||||||
return repository.save(person);
|
return repository.save(person);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Person update(@NonNull Person person) {
|
||||||
|
return repository.save(person);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public Person getByIdOrThrown(@NonNull Long personId) {
|
public Person getByIdOrThrown(@NonNull Long personId) {
|
||||||
@ -62,15 +64,4 @@ public class PersonServiceImpl implements PersonService {
|
|||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<String> getTelegramUsernamesByPersonIds(Long personId) {
|
|
||||||
return repository.findTelegramInfoById(personId).map(PersonTelegram::getTelegramUserName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Long, String> getTelegramUsernamesByPersonIds(Set<Long> personIds) {
|
|
||||||
return repository.findAllTelegramInfoByIds(personIds).stream()
|
|
||||||
.collect(Collectors.toMap(PersonTelegram::getId, PersonTelegram::getTelegramUserName));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,14 +1,17 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service;
|
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.notify.pipeline.PipelineNotify;
|
||||||
import dev.struchkov.bot.gitlab.context.repository.PipelineRepository;
|
import dev.struchkov.bot.gitlab.context.repository.PipelineRepository;
|
||||||
|
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.PipelineService;
|
import dev.struchkov.bot.gitlab.context.service.PipelineService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -17,9 +20,12 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.event.NewPipelineEvent.newPipeline;
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.CANCELED;
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.event.UpdatePipelineEvent.updatePipeline;
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.FAILED;
|
||||||
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SKIPPED;
|
||||||
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SUCCESS;
|
||||||
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Реализация сервиса для работы с пайплайнами.
|
* Реализация сервиса для работы с пайплайнами.
|
||||||
@ -31,15 +37,19 @@ import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundEx
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PipelineServiceImpl implements PipelineService {
|
public class PipelineServiceImpl implements PipelineService {
|
||||||
|
|
||||||
private final ApplicationEventPublisher eventPublisher;
|
// Статусы пайплайнов, о которых нужно уведомить
|
||||||
|
private static final Set<PipelineStatus> notificationStatus = Set.of(FAILED, SUCCESS, CANCELED, SKIPPED);
|
||||||
|
|
||||||
|
private final NotifyService notifyService;
|
||||||
private final PipelineRepository repository;
|
private final PipelineRepository repository;
|
||||||
|
|
||||||
|
private final PersonInformation personInformation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public Pipeline create(@NonNull Pipeline pipeline) {
|
public Pipeline create(@NonNull Pipeline pipeline) {
|
||||||
final Pipeline newPipeline = repository.save(pipeline);
|
final Pipeline newPipeline = repository.save(pipeline);
|
||||||
eventPublisher.publishEvent(newPipeline(newPipeline));
|
notifyNewPipeline(pipeline, PipelineStatus.NULL);
|
||||||
return newPipeline;
|
return newPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +61,21 @@ public class PipelineServiceImpl implements PipelineService {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void notifyNewPipeline(Pipeline pipeline, PipelineStatus oldStatus) {
|
||||||
|
if (isNeedNotifyNewPipeline(pipeline)) {
|
||||||
|
notifyService.send(
|
||||||
|
PipelineNotify.builder()
|
||||||
|
.projectId(pipeline.getProjectId())
|
||||||
|
.newStatus(pipeline.getStatus())
|
||||||
|
.pipelineId(pipeline.getId())
|
||||||
|
.refName(pipeline.getRef())
|
||||||
|
.webUrl(pipeline.getWebUrl())
|
||||||
|
.oldStatus(oldStatus)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pipeline update(@NonNull Pipeline pipeline) {
|
public Pipeline update(@NonNull Pipeline pipeline) {
|
||||||
final Pipeline oldPipeline = repository.findById(pipeline.getId())
|
final Pipeline oldPipeline = repository.findById(pipeline.getId())
|
||||||
@ -58,8 +83,12 @@ public class PipelineServiceImpl implements PipelineService {
|
|||||||
|
|
||||||
pipeline.setProjectId(oldPipeline.getProjectId());
|
pipeline.setProjectId(oldPipeline.getProjectId());
|
||||||
|
|
||||||
eventPublisher.publishEvent(updatePipeline(oldPipeline.toBuilder().build(), pipeline));
|
if (!oldPipeline.getUpdated().equals(pipeline.getUpdated())) {
|
||||||
return repository.save(pipeline);
|
notifyNewPipeline(pipeline, oldPipeline.getStatus());
|
||||||
|
return repository.save(pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -69,6 +98,13 @@ public class PipelineServiceImpl implements PipelineService {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isNeedNotifyNewPipeline(@NonNull Pipeline pipeline) {
|
||||||
|
final Person personPipelineCreator = pipeline.getPerson();
|
||||||
|
return notificationStatus.contains(pipeline.getStatus()) // Пайплайн имеет статус необходимый для уведомления
|
||||||
|
&& checkNotNull(personPipelineCreator) // Создатель пайплайна не null
|
||||||
|
&& personInformation.getId().equals(personPipelineCreator.getId()); // Пользователь приложения является инициатором пайплайна
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Pipeline> getAllByStatuses(@NonNull Set<PipelineStatus> statuses) {
|
public List<Pipeline> getAllByStatuses(@NonNull Set<PipelineStatus> statuses) {
|
||||||
return repository.findAllByStatuses(statuses);
|
return repository.findAllByStatuses(statuses);
|
||||||
@ -92,7 +128,7 @@ public class PipelineServiceImpl implements PipelineService {
|
|||||||
@Override
|
@Override
|
||||||
public void cleanOld() {
|
public void cleanOld() {
|
||||||
log.debug("Старт очистки старых пайплайнов");
|
log.debug("Старт очистки старых пайплайнов");
|
||||||
repository.deleteByCreatedBefore(LocalDateTime.now().minusDays(7L));
|
repository.deleteByCreatedBefore(LocalDateTime.now().minusDays(1L));
|
||||||
log.debug("Конец очистки старых пайплайнов");
|
log.debug("Конец очистки старых пайплайнов");
|
||||||
}
|
}
|
||||||
|
|
@ -1,12 +1,14 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service;
|
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.notify.project.NewProjectNotify;
|
||||||
import dev.struchkov.bot.gitlab.context.repository.ProjectRepository;
|
import dev.struchkov.bot.gitlab.context.repository.ProjectRepository;
|
||||||
|
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.context.service.ProjectService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -15,7 +17,6 @@ import java.util.Optional;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.event.NewProjectEvent.newProject;
|
|
||||||
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,7 +28,8 @@ public class ProjectServiceImpl implements ProjectService {
|
|||||||
|
|
||||||
private final ProjectRepository repository;
|
private final ProjectRepository repository;
|
||||||
|
|
||||||
private final ApplicationEventPublisher eventPublisher;
|
private final NotifyService notifyService;
|
||||||
|
private final PersonService personService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
@ -35,7 +37,8 @@ public class ProjectServiceImpl implements ProjectService {
|
|||||||
final Project newProject = repository.save(project);
|
final Project newProject = repository.save(project);
|
||||||
|
|
||||||
if (sendNotify) {
|
if (sendNotify) {
|
||||||
eventPublisher.publishEvent(newProject(project));
|
final String authorName = personService.getByIdOrThrown(newProject.getCreatorId()).getName();
|
||||||
|
notifyAboutNewProject(newProject, authorName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newProject;
|
return newProject;
|
||||||
@ -108,4 +111,18 @@ public class ProjectServiceImpl implements ProjectService {
|
|||||||
repository.processing(enable, projectIds);
|
repository.processing(enable, projectIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void notifyAboutNewProject(Project newProject, String authorName) {
|
||||||
|
notifyService.send(
|
||||||
|
NewProjectNotify.builder()
|
||||||
|
.projectId(newProject.getId())
|
||||||
|
.projectDescription(newProject.getDescription())
|
||||||
|
.projectName(newProject.getName())
|
||||||
|
.projectUrl(newProject.getWebUrl())
|
||||||
|
.sshUrlToRepo(newProject.getSshUrlToRepo())
|
||||||
|
.httpUrlToRepo(newProject.getHttpUrlToRepo())
|
||||||
|
.authorName(authorName)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service;
|
package dev.struchkov.bot.gitlab.core.service.impl.note;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||||
import dev.struchkov.bot.gitlab.context.repository.NoteRepository;
|
import dev.struchkov.bot.gitlab.context.repository.NoteRepository;
|
@ -1,4 +1,4 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.parser;
|
package dev.struchkov.bot.gitlab.core.service.parser;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
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.Discussion;
|
||||||
@ -7,11 +7,12 @@ 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.entity.Person;
|
||||||
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
||||||
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
|
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
||||||
import dev.struchkov.sdk.gitlab.domain.GitlabUrl;
|
import dev.struchkov.bot.gitlab.core.config.properties.PersonProperty;
|
||||||
import dev.struchkov.sdk.gitlab.schema.note.DiscussionJson;
|
import dev.struchkov.bot.gitlab.core.utils.HttpParse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import dev.struchkov.bot.gitlab.sdk.domain.DiscussionJson;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -20,11 +21,15 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static dev.struchkov.bot.gitlab.core.utils.HttpParse.ACCEPT;
|
||||||
|
import static dev.struchkov.bot.gitlab.core.utils.StringUtils.H_PRIVATE_TOKEN;
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkFalse;
|
import static dev.struchkov.haiti.utils.Checker.checkFalse;
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
@ -36,20 +41,35 @@ import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class DiscussionParser {
|
public class DiscussionParser {
|
||||||
|
|
||||||
public static final int PAGE_COUNT = 100;
|
public static final int PAGE_COUNT = 100;
|
||||||
|
|
||||||
//TODO [23.08.2024|uPagge]: Убрать
|
|
||||||
private final GitlabUrl gitlabUrl;
|
|
||||||
private final GitlabSdkManager gitlabSdkManager;
|
|
||||||
|
|
||||||
private final DiscussionService discussionService;
|
private final DiscussionService discussionService;
|
||||||
|
|
||||||
private final MergeRequestsService mergeRequestsService;
|
private final MergeRequestsService mergeRequestsService;
|
||||||
private final ConversionService conversionService;
|
private final ConversionService conversionService;
|
||||||
|
private final ForkJoinPool forkJoinPool;
|
||||||
|
|
||||||
|
private final GitlabProperty gitlabProperty;
|
||||||
|
|
||||||
|
private final PersonProperty personProperty;
|
||||||
|
|
||||||
|
public DiscussionParser(
|
||||||
|
DiscussionService discussionService,
|
||||||
|
MergeRequestsService mergeRequestsService,
|
||||||
|
ConversionService conversionService,
|
||||||
|
@Qualifier("parserPool") ForkJoinPool forkJoinPool,
|
||||||
|
GitlabProperty gitlabProperty,
|
||||||
|
PersonProperty personProperty
|
||||||
|
) {
|
||||||
|
this.discussionService = discussionService;
|
||||||
|
this.mergeRequestsService = mergeRequestsService;
|
||||||
|
this.conversionService = conversionService;
|
||||||
|
this.forkJoinPool = forkJoinPool;
|
||||||
|
this.gitlabProperty = gitlabProperty;
|
||||||
|
this.personProperty = personProperty;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поиск новых обсуждений
|
* Поиск новых обсуждений
|
||||||
@ -65,11 +85,11 @@ public class DiscussionParser {
|
|||||||
|
|
||||||
private void processingNewDiscussion(MergeRequestForDiscussion mergeRequest) {
|
private void processingNewDiscussion(MergeRequestForDiscussion mergeRequest) {
|
||||||
int page = 1;
|
int page = 1;
|
||||||
final List<DiscussionJson> discussionJson = gitlabSdkManager.getDiscussionForMergeRequest(mergeRequest.getProjectId(), mergeRequest.getTwoId(), page, PAGE_COUNT);
|
final List<DiscussionJson> discussionJson = getDiscussionJson(mergeRequest, page);
|
||||||
|
|
||||||
if (checkNotEmpty(discussionJson)) {
|
if (checkNotEmpty(discussionJson)) {
|
||||||
while (discussionJson.size() == PAGE_COUNT) {
|
while (discussionJson.size() == PAGE_COUNT) {
|
||||||
discussionJson.addAll(gitlabSdkManager.getDiscussionForMergeRequest(mergeRequest.getProjectId(), mergeRequest.getTwoId(), ++page, PAGE_COUNT));
|
discussionJson.addAll(getDiscussionJson(mergeRequest, ++page));
|
||||||
}
|
}
|
||||||
createNewDiscussion(discussionJson, mergeRequest);
|
createNewDiscussion(discussionJson, mergeRequest);
|
||||||
}
|
}
|
||||||
@ -150,12 +170,11 @@ public class DiscussionParser {
|
|||||||
|
|
||||||
final List<Discussion> newDiscussions = new ArrayList<>();
|
final List<Discussion> newDiscussions = new ArrayList<>();
|
||||||
for (Discussion discussion : discussions) {
|
for (Discussion discussion : discussions) {
|
||||||
final MergeRequestForDiscussion mergeRequest = discussion.getMergeRequest();
|
if (checkNotNull(discussion.getMergeRequest())) {
|
||||||
if (checkNotNull(mergeRequest)) {
|
getOldDiscussionJson(discussion)
|
||||||
gitlabSdkManager.getDiscussionById(mergeRequest.getProjectId(), mergeRequest.getTwoId(), discussion.getId())
|
|
||||||
.map(json -> {
|
.map(json -> {
|
||||||
final Discussion newDiscussion = conversionService.convert(json, Discussion.class);
|
final Discussion newDiscussion = conversionService.convert(json, Discussion.class);
|
||||||
newDiscussion.getNotes().forEach(createNoteLink(mergeRequest));
|
newDiscussion.getNotes().forEach(createNoteLink(discussion.getMergeRequest()));
|
||||||
return newDiscussion;
|
return newDiscussion;
|
||||||
}).ifPresent(newDiscussions::add);
|
}).ifPresent(newDiscussions::add);
|
||||||
} else {
|
} else {
|
||||||
@ -171,10 +190,33 @@ public class DiscussionParser {
|
|||||||
log.debug("Конец обработки старых дискуссий");
|
log.debug("Конец обработки старых дискуссий");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return MessageFormat.format(
|
||||||
|
gitlabProperty.getDiscussionUrl(),
|
||||||
|
discussion.getMergeRequest().getProjectId(),
|
||||||
|
discussion.getMergeRequest().getTwoId(),
|
||||||
|
discussion.getId()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<DiscussionJson> getDiscussionJson(MergeRequestForDiscussion mergeRequest, int page) {
|
||||||
|
return HttpParse.request(MessageFormat.format(gitlabProperty.getDiscussionsUrl(), mergeRequest.getProjectId(), mergeRequest.getTwoId(), page, PAGE_COUNT))
|
||||||
|
.header(ACCEPT)
|
||||||
|
.header(H_PRIVATE_TOKEN, personProperty.getToken())
|
||||||
|
.executeList(DiscussionJson.class);
|
||||||
|
}
|
||||||
|
|
||||||
private Consumer<Note> createNoteLink(MergeRequestForDiscussion mergeRequest) {
|
private Consumer<Note> createNoteLink(MergeRequestForDiscussion mergeRequest) {
|
||||||
return note -> {
|
return note -> {
|
||||||
final String url = MessageFormat.format(
|
final String url = MessageFormat.format(
|
||||||
gitlabUrl.getNote(),
|
gitlabProperty.getNoteUrl(),
|
||||||
mergeRequest.getWebUrl(),
|
mergeRequest.getWebUrl(),
|
||||||
note.getId()
|
note.getId()
|
||||||
);
|
);
|
@ -0,0 +1,166 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.core.service.parser;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.*;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Issue;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
|
import dev.struchkov.bot.gitlab.context.service.IssueService;
|
||||||
|
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
||||||
|
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
||||||
|
import dev.struchkov.bot.gitlab.core.config.properties.PersonProperty;
|
||||||
|
import dev.struchkov.bot.gitlab.core.service.parser.forktask.GetAllIssueForProjectTask;
|
||||||
|
import dev.struchkov.bot.gitlab.core.service.parser.forktask.GetSingleIssueTask;
|
||||||
|
import dev.struchkov.bot.gitlab.sdk.domain.IssueJson;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.core.convert.ConversionService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
|
import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResult;
|
||||||
|
import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResults;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmotry Sheyko [24.01.2023]
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class IssueParser {
|
||||||
|
|
||||||
|
private static final Set<IssueState> OLD_STATUSES = Set.of(IssueState.OPENED, IssueState.CLOSED);
|
||||||
|
|
||||||
|
private final GitlabProperty gitlabProperty;
|
||||||
|
private final IssueService issueService;
|
||||||
|
private final ProjectService projectService;
|
||||||
|
private final ConversionService conversionService;
|
||||||
|
private final PersonProperty personProperty;
|
||||||
|
|
||||||
|
private final ForkJoinPool forkJoinPool;
|
||||||
|
|
||||||
|
public IssueParser(
|
||||||
|
GitlabProperty gitlabProperty,
|
||||||
|
IssueService issueService,
|
||||||
|
ProjectService projectService,
|
||||||
|
ConversionService conversionService,
|
||||||
|
PersonProperty personProperty,
|
||||||
|
@Qualifier("parserPool") ForkJoinPool forkJoinPool
|
||||||
|
) {
|
||||||
|
this.gitlabProperty = gitlabProperty;
|
||||||
|
this.issueService = issueService;
|
||||||
|
this.projectService = projectService;
|
||||||
|
this.conversionService = conversionService;
|
||||||
|
this.personProperty = personProperty;
|
||||||
|
this.forkJoinPool = forkJoinPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parsingOldIssue(){
|
||||||
|
log.debug("Старт обработаки старых Issues");
|
||||||
|
final Set<IdAndStatusIssue> existIds = issueService.getAllId(OLD_STATUSES);
|
||||||
|
|
||||||
|
final List<Issue> newIssues = getOldIssues(existIds).stream()
|
||||||
|
.map(issueJson -> {
|
||||||
|
final Issue newIssue = conversionService.convert(issueJson, Issue.class);
|
||||||
|
return newIssue;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (checkNotEmpty(newIssues)) {
|
||||||
|
personMapping(newIssues);
|
||||||
|
issueService.updateAll(newIssues);
|
||||||
|
}
|
||||||
|
log.debug("Конец обработки старых Issues");
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<IssueJson> getOldIssues(Set<IdAndStatusIssue> existIds) {
|
||||||
|
final List<ForkJoinTask<Optional<IssueJson>>> tasks = existIds.stream()
|
||||||
|
.map(
|
||||||
|
existId -> new GetSingleIssueTask(
|
||||||
|
gitlabProperty.getIssueUrl(),
|
||||||
|
existId.getProjectId(),
|
||||||
|
existId.getTwoId(),
|
||||||
|
personProperty.getToken()
|
||||||
|
)
|
||||||
|
).map(forkJoinPool::submit)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return pullTaskResult(tasks).stream()
|
||||||
|
.flatMap(Optional::stream)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void parsingNewIssue() {
|
||||||
|
log.debug("Старт обработки новых Issues");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* получаем через репозиторий список id всех проектов хранящихся в нашей БД
|
||||||
|
*/
|
||||||
|
final Set<Long> projectIds = projectService.getAllIds();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* На основе id проекта, url для получения issues по id проекта и токена пользователя
|
||||||
|
* выгружаем из GitLab список всех IssueJson. Получаем в многопоточном режиме.
|
||||||
|
*/
|
||||||
|
final List<IssueJson> issueJsons = getIssues(projectIds);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Получаем id всех IssueJson загруженных из GitLab
|
||||||
|
*/
|
||||||
|
if (checkNotEmpty(issueJsons)) {
|
||||||
|
final Set<Long> jsonIds = issueJsons.stream()
|
||||||
|
.map(IssueJson::getId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
final ExistContainer<Issue, Long> existContainer = issueService.existsById(jsonIds);
|
||||||
|
log.trace("Из {} полученных Issues не найдены в хранилище {}", jsonIds.size(), existContainer.getIdNoFound().size());
|
||||||
|
if (!existContainer.isAllFound()) {
|
||||||
|
final List<Issue> newIssues = issueJsons.stream()
|
||||||
|
.filter(json -> existContainer.getIdNoFound().contains(json.getId()))
|
||||||
|
.map(json -> {
|
||||||
|
final Issue issue = conversionService.convert(json, Issue.class);
|
||||||
|
return issue;
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
log.trace("Пачка новых Issues обработана и отправлена на сохранение. Количество: {} шт.", newIssues.size());
|
||||||
|
issueService.createAll(newIssues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.debug("Конец обработки новых Issues");
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<IssueJson> getIssues(Set<Long> projectIds) {
|
||||||
|
final List<ForkJoinTask<List<IssueJson>>> tasks = projectIds.stream()
|
||||||
|
.map(projectId -> new GetAllIssueForProjectTask(projectId, gitlabProperty.getOpenIssueUrl(), personProperty.getToken()))
|
||||||
|
.map(forkJoinPool::submit)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return pullTaskResults(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void personMapping(List<Issue> newIssues) {
|
||||||
|
final Map<Long, Person> personMap = Stream.concat(
|
||||||
|
newIssues.stream()
|
||||||
|
.map(Issue::getAuthor),
|
||||||
|
newIssues.stream()
|
||||||
|
.flatMap(issue -> issue.getAssignees().stream())
|
||||||
|
).distinct()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toMap(Person::getId, p -> p));
|
||||||
|
|
||||||
|
for (Issue newIssue : newIssues) {
|
||||||
|
newIssue.setAuthor(personMap.get(newIssue.getAuthor().getId()));
|
||||||
|
|
||||||
|
newIssue.setAssignees(
|
||||||
|
newIssue.getAssignees().stream()
|
||||||
|
.map(reviewer -> personMap.get(reviewer.getId()))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,61 +1,85 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.parser;
|
package dev.struchkov.bot.gitlab.core.service.parser;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
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.MergeRequestState;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
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.Person;
|
||||||
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
||||||
import dev.struchkov.haiti.utils.container.Pair;
|
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
||||||
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
|
import dev.struchkov.bot.gitlab.core.config.properties.PersonProperty;
|
||||||
import dev.struchkov.sdk.gitlab.schema.approval.ApprovalJson;
|
import dev.struchkov.bot.gitlab.core.service.parser.forktask.GetAllMergeRequestForProjectTask;
|
||||||
import dev.struchkov.sdk.gitlab.schema.mergerequest.MergeRequestJson;
|
import dev.struchkov.bot.gitlab.core.service.parser.forktask.GetSingleMergeRequestTask;
|
||||||
import dev.struchkov.sdk.gitlab.schema.repository.CommitJson;
|
import dev.struchkov.bot.gitlab.core.utils.HttpParse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import dev.struchkov.bot.gitlab.core.utils.StringUtils;
|
||||||
|
import dev.struchkov.bot.gitlab.sdk.domain.CommitJson;
|
||||||
|
import dev.struchkov.bot.gitlab.sdk.domain.MergeRequestJson;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static dev.struchkov.bot.gitlab.core.utils.HttpParse.ACCEPT;
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
import static java.util.stream.Collectors.toList;
|
import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResult;
|
||||||
|
import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResults;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class MergeRequestParser {
|
public class MergeRequestParser {
|
||||||
|
|
||||||
private static final Set<MergeRequestState> OLD_STATUSES = Set.of(
|
private static final Set<MergeRequestState> OLD_STATUSES = Set.of(
|
||||||
MergeRequestState.MERGED, MergeRequestState.OPENED, MergeRequestState.CLOSED
|
MergeRequestState.MERGED, MergeRequestState.OPENED, MergeRequestState.CLOSED
|
||||||
);
|
);
|
||||||
|
|
||||||
private final GitlabSdkManager gitlabSdkManager;
|
private final GitlabProperty gitlabProperty;
|
||||||
|
|
||||||
private final MergeRequestsService mergeRequestsService;
|
private final MergeRequestsService mergeRequestsService;
|
||||||
private final ProjectService projectService;
|
private final ProjectService projectService;
|
||||||
private final ConversionService conversionService;
|
private final ConversionService conversionService;
|
||||||
|
private final PersonProperty personProperty;
|
||||||
|
|
||||||
|
private final ForkJoinPool forkJoinPool;
|
||||||
|
|
||||||
|
public MergeRequestParser(
|
||||||
|
GitlabProperty gitlabProperty,
|
||||||
|
MergeRequestsService mergeRequestsService,
|
||||||
|
ProjectService projectService,
|
||||||
|
ConversionService conversionService,
|
||||||
|
PersonProperty personProperty,
|
||||||
|
@Qualifier("parserPool") ForkJoinPool forkJoinPool
|
||||||
|
) {
|
||||||
|
this.gitlabProperty = gitlabProperty;
|
||||||
|
this.mergeRequestsService = mergeRequestsService;
|
||||||
|
this.projectService = projectService;
|
||||||
|
this.conversionService = conversionService;
|
||||||
|
this.personProperty = personProperty;
|
||||||
|
this.forkJoinPool = forkJoinPool;
|
||||||
|
}
|
||||||
|
|
||||||
public void parsingOldMergeRequest() {
|
public void parsingOldMergeRequest() {
|
||||||
log.debug("Старт обработки старых MR");
|
log.debug("Старт обработки старых MR");
|
||||||
final Set<Pair<Long, Long>> existIds = mergeRequestsService.getAllId(OLD_STATUSES).stream()
|
final Set<IdAndStatusPr> existIds = mergeRequestsService.getAllId(OLD_STATUSES);
|
||||||
.map(idAndStatusPr -> new Pair<>(idAndStatusPr.getProjectId(), idAndStatusPr.getTwoId()))
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
final List<MergeRequest> newMergeRequests = gitlabSdkManager.getAllMergeRequestById(existIds).stream()
|
final List<MergeRequest> newMergeRequests = getOldMergeRequests(existIds).stream()
|
||||||
.map(mergeRequestJson -> {
|
.map(mergeRequestJson -> {
|
||||||
final MergeRequest newMergeRequest = conversionService.convert(mergeRequestJson, MergeRequest.class);
|
final MergeRequest newMergeRequest = conversionService.convert(mergeRequestJson, MergeRequest.class);
|
||||||
parsingCommits(newMergeRequest);
|
parsingCommits(newMergeRequest);
|
||||||
parsingApprovals(newMergeRequest);
|
|
||||||
return newMergeRequest;
|
return newMergeRequest;
|
||||||
})
|
})
|
||||||
.collect(toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
if (checkNotEmpty(newMergeRequests)) {
|
if (checkNotEmpty(newMergeRequests)) {
|
||||||
personMapping(newMergeRequests);
|
personMapping(newMergeRequests);
|
||||||
@ -64,11 +88,28 @@ public class MergeRequestParser {
|
|||||||
log.debug("Конец обработки старых MR");
|
log.debug("Конец обработки старых MR");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<MergeRequestJson> getOldMergeRequests(Set<IdAndStatusPr> existIds) {
|
||||||
|
final List<ForkJoinTask<Optional<MergeRequestJson>>> tasks = existIds.stream()
|
||||||
|
.map(
|
||||||
|
existId -> new GetSingleMergeRequestTask(
|
||||||
|
gitlabProperty.getMergeRequestUrl(),
|
||||||
|
existId.getProjectId(),
|
||||||
|
existId.getTwoId(),
|
||||||
|
personProperty.getToken()
|
||||||
|
)
|
||||||
|
).map(forkJoinPool::submit)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return pullTaskResult(tasks).stream()
|
||||||
|
.flatMap(Optional::stream)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
public void parsingNewMergeRequest() {
|
public void parsingNewMergeRequest() {
|
||||||
log.debug("Старт обработки новых MR");
|
log.debug("Старт обработки новых MR");
|
||||||
final Set<Long> projectIds = projectService.getAllIdByProcessingEnable();
|
final Set<Long> projectIds = projectService.getAllIdByProcessingEnable();
|
||||||
|
|
||||||
final List<MergeRequestJson> mergeRequestJsons = gitlabSdkManager.getAllMergeRequestByProjectIds(projectIds);
|
final List<MergeRequestJson> mergeRequestJsons = getMergeRequests(projectIds);
|
||||||
|
|
||||||
if (checkNotEmpty(mergeRequestJsons)) {
|
if (checkNotEmpty(mergeRequestJsons)) {
|
||||||
final Set<Long> jsonIds = mergeRequestJsons.stream()
|
final Set<Long> jsonIds = mergeRequestJsons.stream()
|
||||||
@ -83,7 +124,6 @@ public class MergeRequestParser {
|
|||||||
.map(json -> {
|
.map(json -> {
|
||||||
final MergeRequest mergeRequest = conversionService.convert(json, MergeRequest.class);
|
final MergeRequest mergeRequest = conversionService.convert(json, MergeRequest.class);
|
||||||
parsingCommits(mergeRequest);
|
parsingCommits(mergeRequest);
|
||||||
parsingApprovals(mergeRequest);
|
|
||||||
return mergeRequest;
|
return mergeRequest;
|
||||||
})
|
})
|
||||||
.toList();
|
.toList();
|
||||||
@ -98,13 +138,27 @@ public class MergeRequestParser {
|
|||||||
log.debug("Конец обработки новых MR");
|
log.debug("Конец обработки новых MR");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Позволяет получить MR для переданных идентификаторов проектов.
|
||||||
|
*
|
||||||
|
* @param projectIds идентификаторы проектов
|
||||||
|
* @return полученные у GitLab MergeRequests
|
||||||
|
*/
|
||||||
|
private List<MergeRequestJson> getMergeRequests(Set<Long> projectIds) {
|
||||||
|
final List<ForkJoinTask<List<MergeRequestJson>>> tasks = projectIds.stream()
|
||||||
|
.map(projectId -> new GetAllMergeRequestForProjectTask(projectId, gitlabProperty.getOpenMergeRequestsUrl(), personProperty.getToken()))
|
||||||
|
.map(forkJoinPool::submit)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return pullTaskResults(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
private static void personMapping(List<MergeRequest> newMergeRequests) {
|
private static void personMapping(List<MergeRequest> newMergeRequests) {
|
||||||
final Map<Long, Person> personMap = Stream.concat(
|
final Map<Long, Person> personMap = Stream.concat(
|
||||||
newMergeRequests.stream()
|
newMergeRequests.stream()
|
||||||
.flatMap(mergeRequest -> Stream.of(mergeRequest.getAssignee(), mergeRequest.getAuthor())),
|
.flatMap(mergeRequest -> Stream.of(mergeRequest.getAssignee(), mergeRequest.getAuthor())),
|
||||||
newMergeRequests.stream()
|
newMergeRequests.stream()
|
||||||
.flatMap(mergeRequest -> Stream.concat(mergeRequest.getReviewers().stream(), mergeRequest.getApprovals().stream()))
|
.flatMap(mergeRequest -> mergeRequest.getReviewers().stream())
|
||||||
).distinct()
|
).distinct()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.collect(Collectors.toMap(Person::getId, p -> p));
|
.collect(Collectors.toMap(Person::getId, p -> p));
|
||||||
@ -120,35 +174,21 @@ public class MergeRequestParser {
|
|||||||
newMergeRequest.setReviewers(
|
newMergeRequest.setReviewers(
|
||||||
newMergeRequest.getReviewers().stream()
|
newMergeRequest.getReviewers().stream()
|
||||||
.map(reviewer -> personMap.get(reviewer.getId()))
|
.map(reviewer -> personMap.get(reviewer.getId()))
|
||||||
.collect(toList())
|
.collect(Collectors.toList())
|
||||||
);
|
|
||||||
|
|
||||||
newMergeRequest.setApprovals(
|
|
||||||
newMergeRequest.getApprovals().stream()
|
|
||||||
.map(approval -> personMap.get(approval.getId()))
|
|
||||||
.collect(toList())
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO [19.01.2024|uPagge]: Переделать в многопоточный режим
|
|
||||||
private void parsingCommits(MergeRequest mergeRequest) {
|
private void parsingCommits(MergeRequest mergeRequest) {
|
||||||
final List<CommitJson> commitJson = gitlabSdkManager.getAllCommitByProjectId(mergeRequest.getProjectId(), mergeRequest.getTwoId());
|
final List<CommitJson> commitJson = HttpParse.request(
|
||||||
if (checkNotEmpty(commitJson)) {
|
MessageFormat.format(gitlabProperty.getLastCommitOfMergeRequestUrl(), mergeRequest.getProjectId(), mergeRequest.getTwoId())
|
||||||
|
)
|
||||||
|
.header(ACCEPT)
|
||||||
|
.header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken())
|
||||||
|
.executeList(CommitJson.class);
|
||||||
|
if (commitJson != null && !commitJson.isEmpty()) {
|
||||||
mergeRequest.setDateLastCommit(commitJson.get(0).getCreatedDate());
|
mergeRequest.setDateLastCommit(commitJson.get(0).getCreatedDate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO [19.01.2024|uPagge]: Переделать в многопоточный режим
|
|
||||||
private void parsingApprovals(MergeRequest mergeRequest) {
|
|
||||||
final List<Person> personApprovals = gitlabSdkManager.getAllApprovalForMergeRequest(mergeRequest.getProjectId(), mergeRequest.getTwoId()).stream()
|
|
||||||
.map(ApprovalJson::getUser)
|
|
||||||
.map(personJson -> conversionService.convert(personJson, Person.class))
|
|
||||||
.collect(toList());
|
|
||||||
|
|
||||||
if (checkNotEmpty(personApprovals)) {
|
|
||||||
mergeRequest.setApprovals(personApprovals);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,166 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.core.service.parser;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||||
|
import dev.struchkov.bot.gitlab.context.service.PipelineService;
|
||||||
|
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
||||||
|
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
||||||
|
import dev.struchkov.bot.gitlab.core.config.properties.PersonProperty;
|
||||||
|
import dev.struchkov.bot.gitlab.core.service.parser.forktask.GetPipelineShortTask;
|
||||||
|
import dev.struchkov.bot.gitlab.core.service.parser.forktask.GetPipelineTask;
|
||||||
|
import dev.struchkov.bot.gitlab.sdk.domain.PipelineJson;
|
||||||
|
import dev.struchkov.bot.gitlab.sdk.domain.PipelineShortJson;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.core.convert.ConversionService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.CREATED;
|
||||||
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.MANUAL;
|
||||||
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.PENDING;
|
||||||
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.PREPARING;
|
||||||
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.RUNNING;
|
||||||
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.WAITING_FOR_RESOURCE;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkFalse;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
|
import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResult;
|
||||||
|
import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResults;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Парсер пайплайнов.
|
||||||
|
*
|
||||||
|
* @author upagge 17.01.2021
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class PipelineParser {
|
||||||
|
|
||||||
|
private static final Set<PipelineStatus> oldStatus = Set.of(
|
||||||
|
CREATED, WAITING_FOR_RESOURCE, PREPARING, PENDING, RUNNING, MANUAL
|
||||||
|
);
|
||||||
|
|
||||||
|
private final PipelineService pipelineService;
|
||||||
|
private final ProjectService projectService;
|
||||||
|
private final GitlabProperty gitlabProperty;
|
||||||
|
private final PersonProperty personProperty;
|
||||||
|
private final ConversionService conversionService;
|
||||||
|
private final ForkJoinPool forkJoinPool;
|
||||||
|
|
||||||
|
private LocalDateTime lastUpdate = LocalDateTime.now();
|
||||||
|
|
||||||
|
public PipelineParser(
|
||||||
|
PipelineService pipelineService,
|
||||||
|
ProjectService projectService,
|
||||||
|
GitlabProperty gitlabProperty,
|
||||||
|
PersonProperty personProperty,
|
||||||
|
ConversionService conversionService,
|
||||||
|
@Qualifier("parserPool") ForkJoinPool forkJoinPool
|
||||||
|
) {
|
||||||
|
this.pipelineService = pipelineService;
|
||||||
|
this.projectService = projectService;
|
||||||
|
this.gitlabProperty = gitlabProperty;
|
||||||
|
this.personProperty = personProperty;
|
||||||
|
this.conversionService = conversionService;
|
||||||
|
this.forkJoinPool = forkJoinPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void scanNewPipeline() {
|
||||||
|
log.debug("Старт обработки новых пайплайнов");
|
||||||
|
final Set<Long> projectIds = projectService.getAllIdByProcessingEnable();
|
||||||
|
|
||||||
|
final Map<Long, Long> pipelineProjectMap = getPipelineShortJsons(projectIds).stream()
|
||||||
|
.collect(Collectors.toMap(PipelineShortJson::getId, PipelineShortJson::getProjectId));
|
||||||
|
|
||||||
|
if (checkNotEmpty(pipelineProjectMap)) {
|
||||||
|
final ExistContainer<Pipeline, Long> existContainer = pipelineService.existsById(pipelineProjectMap.keySet());
|
||||||
|
|
||||||
|
if (checkFalse(existContainer.isAllFound())) {
|
||||||
|
final Set<Long> idsNotFound = existContainer.getIdNoFound();
|
||||||
|
|
||||||
|
final List<Pipeline> newPipelines = getNewPipelines(pipelineProjectMap, idsNotFound);
|
||||||
|
|
||||||
|
if (checkNotEmpty(newPipelines)) {
|
||||||
|
pipelineService.createAll(newPipelines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("Конец обработки новых пайплайнов");
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Pipeline> getNewPipelines(Map<Long, Long> pipelineProjectMap, Set<Long> idsNotFound) {
|
||||||
|
final List<ForkJoinTask<Optional<PipelineJson>>> tasks = idsNotFound.stream()
|
||||||
|
.map(pipelineId -> new GetPipelineTask(
|
||||||
|
gitlabProperty.getPipelineUrl(),
|
||||||
|
pipelineProjectMap.get(pipelineId),
|
||||||
|
pipelineId,
|
||||||
|
personProperty.getToken()
|
||||||
|
))
|
||||||
|
.map(forkJoinPool::submit)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return pullTaskResult(tasks).stream()
|
||||||
|
.flatMap(Optional::stream)
|
||||||
|
.map(json -> conversionService.convert(json, Pipeline.class))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<PipelineShortJson> getPipelineShortJsons(Set<Long> projectIds) {
|
||||||
|
LocalDateTime newLastUpdate = LocalDateTime.now();
|
||||||
|
final List<ForkJoinTask<List<PipelineShortJson>>> tasks = projectIds.stream()
|
||||||
|
.map(projectId -> new GetPipelineShortTask(
|
||||||
|
gitlabProperty.getPipelinesUrl(),
|
||||||
|
projectId,
|
||||||
|
lastUpdate,
|
||||||
|
personProperty.getToken()
|
||||||
|
))
|
||||||
|
.map(forkJoinPool::submit)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
final List<PipelineShortJson> pipelineJsons = pullTaskResults(tasks);
|
||||||
|
|
||||||
|
lastUpdate = newLastUpdate;
|
||||||
|
return pipelineJsons;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void scanOldPipeline() {
|
||||||
|
log.debug("Старт обработки старых пайплайнов");
|
||||||
|
final List<Pipeline> pipelines = pipelineService.getAllByStatuses(oldStatus);
|
||||||
|
|
||||||
|
final List<ForkJoinTask<Optional<PipelineJson>>> tasks = pipelines.stream()
|
||||||
|
.map(
|
||||||
|
pipeline -> new GetPipelineTask(
|
||||||
|
gitlabProperty.getPipelineUrl(),
|
||||||
|
pipeline.getProjectId(),
|
||||||
|
pipeline.getId(),
|
||||||
|
personProperty.getToken()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.map(forkJoinPool::submit)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
final List<Pipeline> newPipelines = pullTaskResult(tasks).stream()
|
||||||
|
.flatMap(Optional::stream)
|
||||||
|
.map(json -> conversionService.convert(json, Pipeline.class))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (checkNotEmpty(newPipelines)) {
|
||||||
|
pipelineService.updateAll(newPipelines);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("Конец обработки старых пайплайнов");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,23 +1,29 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.parser;
|
package dev.struchkov.bot.gitlab.core.service.parser;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
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.entity.Project;
|
||||||
|
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
||||||
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
|
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
||||||
import dev.struchkov.sdk.gitlab.domain.GitlabProjectParam;
|
import dev.struchkov.bot.gitlab.core.config.properties.PersonProperty;
|
||||||
import dev.struchkov.sdk.gitlab.schema.repository.ProjectJson;
|
import dev.struchkov.bot.gitlab.core.utils.HttpParse;
|
||||||
|
import dev.struchkov.bot.gitlab.core.utils.StringUtils;
|
||||||
|
import dev.struchkov.bot.gitlab.sdk.domain.PersonJson;
|
||||||
|
import dev.struchkov.bot.gitlab.sdk.domain.ProjectJson;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static dev.struchkov.bot.gitlab.core.utils.HttpParse.ACCEPT;
|
||||||
import static dev.struchkov.haiti.context.exception.ConvertException.convertException;
|
import static dev.struchkov.haiti.context.exception.ConvertException.convertException;
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
|
|
||||||
@ -31,28 +37,33 @@ import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ProjectParser {
|
public class ProjectParser {
|
||||||
|
|
||||||
private final GitlabSdkManager gitlabSdkManager;
|
public static final String OWNER = "&owned=true";
|
||||||
private final ConversionService conversionService;
|
public static final String PRIVATE = "&visibility=private";
|
||||||
|
|
||||||
|
private final MergeRequestsService mergeRequestsService;
|
||||||
private final ProjectService projectService;
|
private final ProjectService projectService;
|
||||||
private final PersonService personService;
|
private final PersonService personService;
|
||||||
|
|
||||||
|
private final ConversionService conversionService;
|
||||||
|
|
||||||
|
private final GitlabProperty gitlabProperty;
|
||||||
|
private final PersonProperty personProperty;
|
||||||
|
|
||||||
public void parseAllProjectOwner() {
|
public void parseAllProjectOwner() {
|
||||||
log.debug("Старт обработки всех проектов, где пользователь владелец");
|
log.debug("Старт обработки всех проектов, где пользователь владелец");
|
||||||
parseProjects(GitlabProjectParam.OWNER);
|
parseProjects(OWNER);
|
||||||
log.debug("Конец обработки всех проектов, где пользователь владелец");
|
log.debug("Конец обработки всех проектов, где пользователь владелец");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parseAllPrivateProject() {
|
public void parseAllPrivateProject() {
|
||||||
log.debug("Старт обработки приватных проектов");
|
log.debug("Старт обработки приватных проектов");
|
||||||
parseProjects(GitlabProjectParam.PRIVATE);
|
parseProjects(PRIVATE);
|
||||||
log.debug("Конец обработки приватных проектов");
|
log.debug("Конец обработки приватных проектов");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseProjects(GitlabProjectParam param) {
|
private void parseProjects(String param) {
|
||||||
int page = 1;
|
int page = 1;
|
||||||
List<ProjectJson> projectJsons = gitlabSdkManager.getAllProject(page, param);
|
List<ProjectJson> projectJsons = getProjectJsons(page, param);
|
||||||
|
|
||||||
while (checkNotEmpty(projectJsons)) {
|
while (checkNotEmpty(projectJsons)) {
|
||||||
|
|
||||||
@ -72,12 +83,15 @@ public class ProjectParser {
|
|||||||
projectService.createAll(newProjects);
|
projectService.createAll(newProjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
projectJsons = gitlabSdkManager.getAllProject(++page, param);
|
projectJsons = getProjectJsons(++page, param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Project parseByUrl(String projectUrl) {
|
public Project parseByUrl(String projectUrl) {
|
||||||
final ProjectJson projectJson = gitlabSdkManager.getProjectByUrl(projectUrl)
|
final ProjectJson projectJson = HttpParse.request(projectUrl)
|
||||||
|
.header(ACCEPT)
|
||||||
|
.header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken())
|
||||||
|
.execute(ProjectJson.class)
|
||||||
.orElseThrow(convertException("Error adding a repository"));
|
.orElseThrow(convertException("Error adding a repository"));
|
||||||
if (!projectService.existsById(projectJson.getId())) {
|
if (!projectService.existsById(projectJson.getId())) {
|
||||||
createNewPersons(List.of(projectJson));
|
createNewPersons(List.of(projectJson));
|
||||||
@ -100,7 +114,10 @@ public class ProjectParser {
|
|||||||
|
|
||||||
final List<Person> newPersons = notFoundId.stream()
|
final List<Person> newPersons = notFoundId.stream()
|
||||||
.map(
|
.map(
|
||||||
userId -> gitlabSdkManager.getPersonById(userId)
|
userId -> HttpParse.request(gitlabProperty.getUsersUrl() + "/" + userId)
|
||||||
|
.header(ACCEPT)
|
||||||
|
.header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken())
|
||||||
|
.execute(PersonJson.class)
|
||||||
.map(json -> conversionService.convert(json, Person.class))
|
.map(json -> conversionService.convert(json, Person.class))
|
||||||
.orElseThrow(convertException("Ошибка преобразования нового пользователя"))
|
.orElseThrow(convertException("Ошибка преобразования нового пользователя"))
|
||||||
).toList();
|
).toList();
|
||||||
@ -109,5 +126,13 @@ public class ProjectParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ProjectJson> getProjectJsons(int page, String... params) {
|
||||||
|
String param = String.join("", params);
|
||||||
|
final String url = MessageFormat.format(gitlabProperty.getProjectsUrl(), page);
|
||||||
|
return HttpParse.request(url + param)
|
||||||
|
.header(ACCEPT)
|
||||||
|
.header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken())
|
||||||
|
.executeList(ProjectJson.class);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.core.service.parser.forktask;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.core.utils.HttpParse;
|
||||||
|
import dev.struchkov.bot.gitlab.sdk.domain.DiscussionJson;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.RecursiveTask;
|
||||||
|
|
||||||
|
import static dev.struchkov.bot.gitlab.core.utils.HttpParse.ACCEPT;
|
||||||
|
import static dev.struchkov.bot.gitlab.core.utils.StringUtils.H_PRIVATE_TOKEN;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GetAllDiscussionForMergeRequestTask extends RecursiveTask<List<DiscussionJson>> {
|
||||||
|
|
||||||
|
private static final int PAGE_COUNT = 100;
|
||||||
|
|
||||||
|
private final String discussionsUrl;
|
||||||
|
private final long projectId;
|
||||||
|
private final long mergeRequestTwoId;
|
||||||
|
private final String personalGitlabToken;
|
||||||
|
private int page = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
protected List<DiscussionJson> compute() {
|
||||||
|
Thread.sleep(100);
|
||||||
|
final List<DiscussionJson> jsons = getDiscussionJson();
|
||||||
|
if (checkNotEmpty(jsons) && jsons.size() == PAGE_COUNT) {
|
||||||
|
final var newTask = new GetAllDiscussionForMergeRequestTask(discussionsUrl, projectId, mergeRequestTwoId, personalGitlabToken, page + 1);
|
||||||
|
newTask.fork();
|
||||||
|
jsons.addAll(newTask.join());
|
||||||
|
}
|
||||||
|
return jsons;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<DiscussionJson> getDiscussionJson() {
|
||||||
|
return HttpParse.request(MessageFormat.format(discussionsUrl, projectId, mergeRequestTwoId, page, PAGE_COUNT))
|
||||||
|
.header(ACCEPT)
|
||||||
|
.header(H_PRIVATE_TOKEN, personalGitlabToken)
|
||||||
|
.executeList(DiscussionJson.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.core.service.parser.forktask;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.core.utils.StringUtils;
|
||||||
|
import dev.struchkov.bot.gitlab.sdk.domain.IssueJson;
|
||||||
|
import dev.struchkov.bot.gitlab.core.utils.HttpParse;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.RecursiveTask;
|
||||||
|
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
|
import static dev.struchkov.bot.gitlab.core.utils.HttpParse.ACCEPT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitry Sheyko [24.01.2023]
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GetAllIssueForProjectTask extends RecursiveTask<List<IssueJson>> {
|
||||||
|
|
||||||
|
private static final int PAGE_COUNT = 100;
|
||||||
|
|
||||||
|
private final long projectId;
|
||||||
|
private int pageNumber = 1;
|
||||||
|
private final String urlIssueOpen;
|
||||||
|
private final String gitlabToken;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
protected List<IssueJson> compute() {
|
||||||
|
Thread.sleep(200);
|
||||||
|
final List<IssueJson> issueJson = getIssueJsons();
|
||||||
|
if (checkNotEmpty(issueJson) && issueJson.size() == PAGE_COUNT) {
|
||||||
|
final GetAllIssueForProjectTask newTask = new GetAllIssueForProjectTask(projectId, pageNumber + 1, urlIssueOpen, gitlabToken);
|
||||||
|
newTask.fork();
|
||||||
|
issueJson.addAll(newTask.join());
|
||||||
|
}
|
||||||
|
return issueJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<IssueJson> getIssueJsons() {
|
||||||
|
final List<IssueJson> jsons = HttpParse.request(MessageFormat.format(urlIssueOpen, projectId, pageNumber, PAGE_COUNT))
|
||||||
|
.header(StringUtils.H_PRIVATE_TOKEN, gitlabToken)
|
||||||
|
.header(ACCEPT)
|
||||||
|
.executeList(IssueJson.class);
|
||||||
|
log.trace("Получено {} шт потенциально новых Issue для проекта id:'{}' ", jsons.size(), projectId);
|
||||||
|
return jsons;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user