Кипит работа над версией 2
This commit is contained in:
parent
117f3ca443
commit
7b9388f1a4
24
pom.xml
24
pom.xml
@ -19,6 +19,30 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.sadtech.basic.filter</groupId>
|
||||
<artifactId>criteria-filter</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.sadtech.basic</groupId>
|
||||
<artifactId>project-database</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate.orm</groupId>
|
||||
<artifactId>hibernate-jpamodelgen</artifactId>
|
||||
<version>6.0.0.Alpha5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>2.3.1.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
|
@ -9,10 +9,18 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Общий файл настройки всего приложения.
|
||||
*
|
||||
* @author upagge
|
||||
*/
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class AppConfig {
|
||||
|
||||
/**
|
||||
* Отвечает за работу шедулеров в паралельном режиме
|
||||
*/
|
||||
@Bean
|
||||
public TaskScheduler taskScheduler() {
|
||||
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
|
||||
|
@ -1,23 +0,0 @@
|
||||
package org.sadtech.bot.bitbucketbot.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* TODO: Добавить описание класса.
|
||||
*
|
||||
* @author upagge [31.01.2020]
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties("bitbucketbot.bitbucket")
|
||||
public class BitbucketConfig {
|
||||
|
||||
private String token;
|
||||
private String urlPullRequestOpen;
|
||||
private String urlPullRequestClose;
|
||||
private String urlPullRequestComment;
|
||||
private String urlPullRequest;
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package org.sadtech.bot.bitbucketbot.config.properties;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Данные необходимые для взаимодействия с API Bitbucket.
|
||||
*
|
||||
* @author upagge [31.01.2020]
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Component
|
||||
@ConfigurationProperties("bitbucketbot.bitbucket")
|
||||
public class BitbucketProperty {
|
||||
|
||||
/**
|
||||
* Токен администратора
|
||||
*/
|
||||
private String token;
|
||||
|
||||
/**
|
||||
* Адрес, по которому можно получить открытые ПР
|
||||
*/
|
||||
private String urlPullRequestOpen;
|
||||
|
||||
/**
|
||||
* Адрес, по которому можно получить закрытые ПР
|
||||
*/
|
||||
private String urlPullRequestClose;
|
||||
|
||||
/**
|
||||
* Адрес, по которому можно получить комментарии к ПР
|
||||
*/
|
||||
private String urlPullRequestComment;
|
||||
|
||||
/**
|
||||
* Адрес ПР
|
||||
*/
|
||||
private String urlPullRequest;
|
||||
|
||||
/**
|
||||
* Адрес на получение пользователей битбакет
|
||||
*/
|
||||
private String urlUsers;
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package org.sadtech.bot.bitbucketbot.config.properties;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.sadtech.bot.bitbucketbot.scheduler.SchedulerComments;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Данные для конфигурации {@link SchedulerComments}
|
||||
*
|
||||
* @author upagge
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Component
|
||||
@ConfigurationProperties("bitbucketbot.scheduler.comment.settings")
|
||||
public class CommentSchedulerProperty {
|
||||
|
||||
/**
|
||||
* Количество пустых комментариев подряд, после которого поиск останавливается
|
||||
*/
|
||||
private Integer noCommentCount;
|
||||
|
||||
/**
|
||||
* Количество комментариев в пачке сканирования
|
||||
*/
|
||||
private Integer commentCount;
|
||||
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
package org.sadtech.bot.bitbucketbot.controller;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.User;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Person;
|
||||
import org.sadtech.bot.bitbucketbot.dto.UserDto;
|
||||
import org.sadtech.bot.bitbucketbot.service.UserService;
|
||||
import org.sadtech.bot.bitbucketbot.service.PersonService;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -12,16 +12,21 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
|
||||
/**
|
||||
* Контроллер отвечат за регистрацию пользователей.
|
||||
*
|
||||
* @author upagge
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
public class UserController {
|
||||
|
||||
private final UserService userService;
|
||||
private final PersonService personService;
|
||||
private final ConversionService conversionService;
|
||||
|
||||
@PostMapping(value = "/api/user/reg", consumes = APPLICATION_JSON_VALUE)
|
||||
public HttpStatus register(@RequestBody UserDto userDto) {
|
||||
userService.reg(conversionService.convert(userDto, User.class));
|
||||
personService.reg(conversionService.convert(userDto, Person.class));
|
||||
return HttpStatus.OK;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,8 @@ package org.sadtech.bot.bitbucketbot.domain;
|
||||
*/
|
||||
public enum PullRequestStatus {
|
||||
|
||||
OPEN, MERGED, DECLINED, DELETE
|
||||
OPEN,
|
||||
MERGED,
|
||||
DECLINED
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain;
|
||||
|
||||
public enum TaskStatus {
|
||||
|
||||
OPEN,
|
||||
RESOLVED
|
||||
|
||||
}
|
@ -8,13 +8,15 @@ import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@EqualsAndHashCode(of = "id")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public abstract class Change {
|
||||
|
||||
protected final ChangeType type;
|
||||
protected final LocalDateTime localDateTime = LocalDateTime.now();
|
||||
protected final Set<Long> telegramIds;
|
||||
|
||||
@Setter
|
||||
@EqualsAndHashCode.Include
|
||||
protected Long id;
|
||||
|
||||
protected Change(ChangeType type, Set<Long> telegramIds) {
|
||||
|
@ -8,6 +8,10 @@ public enum ChangeType {
|
||||
NEW_PR,
|
||||
CONFLICT_PR,
|
||||
NEW_COMMENT,
|
||||
NEW_ANSWERS_COMMENT
|
||||
NEW_ANSWERS_COMMENT,
|
||||
NEW_TASK,
|
||||
DELETED_TASK,
|
||||
RESOLVED_TASK,
|
||||
OPEN_TASK;
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.change;
|
||||
package org.sadtech.bot.bitbucketbot.domain.change.comment;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.sadtech.bot.bitbucketbot.domain.Answer;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.Change;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ChangeType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
@ -1,8 +1,10 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.change;
|
||||
package org.sadtech.bot.bitbucketbot.domain.change.comment;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.Change;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ChangeType;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -1,7 +1,8 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.change;
|
||||
package org.sadtech.bot.bitbucketbot.domain.change.pullrequest;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ChangeType;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -1,8 +1,9 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.change;
|
||||
package org.sadtech.bot.bitbucketbot.domain.change.pullrequest;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ChangeType;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@ -16,11 +17,11 @@ public class NewPrChange extends PrChange {
|
||||
@Builder
|
||||
private NewPrChange(
|
||||
Set<Long> telegramIds,
|
||||
String name,
|
||||
String title,
|
||||
String url,
|
||||
String description,
|
||||
String author) {
|
||||
super(ChangeType.NEW_PR, telegramIds, name, url);
|
||||
super(ChangeType.NEW_PR, telegramIds, title, url);
|
||||
this.description = description;
|
||||
this.author = author;
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.change;
|
||||
package org.sadtech.bot.bitbucketbot.domain.change.pullrequest;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.Change;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ChangeType;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@ -9,12 +11,12 @@ import java.util.Set;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public abstract class PrChange extends Change {
|
||||
|
||||
private final String name;
|
||||
private final String title;
|
||||
private final String url;
|
||||
|
||||
protected PrChange(ChangeType type, Set<Long> telegramIds, String name, String url) {
|
||||
protected PrChange(ChangeType type, Set<Long> telegramIds, String title, String url) {
|
||||
super(type, telegramIds);
|
||||
this.name = name;
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.change;
|
||||
package org.sadtech.bot.bitbucketbot.domain.change.pullrequest;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ChangeType;
|
||||
import org.sadtech.bot.bitbucketbot.domain.util.ReviewerChange;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ -16,11 +17,11 @@ public class ReviewersPrChange extends PrChange {
|
||||
|
||||
@Builder
|
||||
private ReviewersPrChange(
|
||||
Set<Long> telegramIds,
|
||||
String name,
|
||||
Long telegramId,
|
||||
String title,
|
||||
String url,
|
||||
List<ReviewerChange> reviewerChanges) {
|
||||
super(ChangeType.REVIEWERS, telegramIds, name, url);
|
||||
super(ChangeType.REVIEWERS, Collections.singleton(telegramId), title, url);
|
||||
this.reviewerChanges = reviewerChanges;
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.change;
|
||||
package org.sadtech.bot.bitbucketbot.domain.change.pullrequest;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ChangeType;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -1,8 +1,9 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.change;
|
||||
package org.sadtech.bot.bitbucketbot.domain.change.pullrequest;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ChangeType;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -0,0 +1,32 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.change.task;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.Change;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ChangeType;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class TaskChange extends Change {
|
||||
|
||||
protected final String authorName;
|
||||
protected final String url;
|
||||
protected final String messageTask;
|
||||
|
||||
@Builder
|
||||
protected TaskChange(
|
||||
ChangeType type,
|
||||
Set<Long> telegramIds,
|
||||
String authorName,
|
||||
String url,
|
||||
String messageTask
|
||||
) {
|
||||
super(type, telegramIds);
|
||||
this.authorName = authorName;
|
||||
this.url = url;
|
||||
this.messageTask = messageTask;
|
||||
}
|
||||
}
|
@ -1,48 +1,58 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(of = "id")
|
||||
@ToString
|
||||
@Table(name = "pull_request_comment")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class Comment {
|
||||
|
||||
/**
|
||||
* Идентификатор
|
||||
*/
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@EqualsAndHashCode.Include
|
||||
private Long id;
|
||||
|
||||
@Column(name = "url")
|
||||
private String url;
|
||||
|
||||
@Column(name = "pr_url")
|
||||
private String prUrl;
|
||||
@Column(name = "pull_request_id")
|
||||
private Long pullRequestId;
|
||||
|
||||
@Column(name = "telegram")
|
||||
private Long telegram;
|
||||
@Column(name = "author_login")
|
||||
private String author;
|
||||
|
||||
@Column(name = "date")
|
||||
private LocalDateTime date;
|
||||
@Column(name = "message")
|
||||
private String message;
|
||||
|
||||
@Column(name = "createDate")
|
||||
private LocalDateTime createDate;
|
||||
|
||||
/**
|
||||
* Версия объекта в битбакет
|
||||
*/
|
||||
@Column(name = "bitbucket_version")
|
||||
private Integer bitbucketVersion;
|
||||
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@CollectionTable(name = "comment_tree", joinColumns = @JoinColumn(name = "parent_id"))
|
||||
|
@ -0,0 +1,59 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.entity;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* Пользователь битбакета.
|
||||
*
|
||||
* @author upagge [30.01.2020]
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "person")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class Person {
|
||||
|
||||
/**
|
||||
* Логин
|
||||
*/
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@EqualsAndHashCode.Include
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* Логин
|
||||
*/
|
||||
@Column(name = "login")
|
||||
private String login;
|
||||
|
||||
/**
|
||||
* Персональный токен из битбакета
|
||||
*/
|
||||
@Column(name = "bitbucket_token")
|
||||
private String token;
|
||||
|
||||
/**
|
||||
* Идентификатор телеграма
|
||||
*/
|
||||
@Column(name = "telegram_id")
|
||||
private Long telegramId;
|
||||
|
||||
/**
|
||||
* ФИО
|
||||
*/
|
||||
@Column(name = "full_name")
|
||||
private String fullName;
|
||||
|
||||
}
|
@ -1,12 +1,8 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
@ -19,74 +15,122 @@ import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TODO: Добавить описание класса.
|
||||
* Сущность ПуллРеквест.
|
||||
*
|
||||
* @author upagge [31.01.2020]
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(of = "id")
|
||||
@ToString
|
||||
@Table(name = "pull_request")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class PullRequest {
|
||||
|
||||
/**
|
||||
* Идентификатор
|
||||
*/
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@EqualsAndHashCode.Include
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* Идентификатор на стороне битбакета
|
||||
*/
|
||||
@Column(name = "bitbucket_pr_id")
|
||||
private Long bitbucketId;
|
||||
|
||||
/**
|
||||
* Идентификатор репозитория на стороне битбакета
|
||||
*/
|
||||
@Column(name = "repository_id")
|
||||
private Long repositoryId;
|
||||
|
||||
/**
|
||||
* Идентификатор проекта на стороне битбакета
|
||||
*/
|
||||
@Column(name = "project_key")
|
||||
private String projectKey;
|
||||
|
||||
/**
|
||||
* Символьный идентификатор на стороне битбакета
|
||||
*/
|
||||
@Column(name = "repository_slug")
|
||||
private String repositorySlug;
|
||||
|
||||
/**
|
||||
* Версия объекта для блокировок
|
||||
*/
|
||||
@Column(name = "version")
|
||||
private Integer version;
|
||||
|
||||
/**
|
||||
* Описание пулреквеста
|
||||
*/
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "author_login")
|
||||
private User author;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
|
||||
@JoinColumn(name = "pull_request_id")
|
||||
private List<Reviewer> reviewers;
|
||||
|
||||
/**
|
||||
* Адрес ПР
|
||||
*/
|
||||
@Column(name = "url")
|
||||
private String url;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
/**
|
||||
* Название ПР
|
||||
*/
|
||||
@Column(name = "title")
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* Статус ПР
|
||||
*/
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "status")
|
||||
private PullRequestStatus status;
|
||||
|
||||
/**
|
||||
* Дата создания
|
||||
*/
|
||||
@Column(name = "create_date")
|
||||
private LocalDateTime createDate;
|
||||
|
||||
/**
|
||||
* Дата обновления
|
||||
*/
|
||||
@Column(name = "update_date")
|
||||
private LocalDateTime updateDate;
|
||||
|
||||
/**
|
||||
* Флаг показывающий наличие конфликта в ПР
|
||||
*/
|
||||
@Column(name = "conflict")
|
||||
private boolean conflict;
|
||||
|
||||
/**
|
||||
* Версия объекта в битбакет
|
||||
*/
|
||||
@Column(name = "bitbucket_version")
|
||||
private Integer bitbucketVersion;
|
||||
|
||||
/**
|
||||
* Автор ПР
|
||||
*/
|
||||
@Column(name = "author_login")
|
||||
private String authorLogin;
|
||||
|
||||
/**
|
||||
* Ревьюверы
|
||||
*/
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
|
||||
@JoinColumn(name = "pull_request_id")
|
||||
private List<Reviewer> reviewers;
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus;
|
||||
|
||||
@ -17,27 +15,35 @@ import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* TODO: Добавить описание класса.
|
||||
* Ревьювер пулреквеста.
|
||||
*
|
||||
* @author upagge [01.02.2020]
|
||||
*/
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "reviewer")
|
||||
@EqualsAndHashCode(of = "id")
|
||||
@Table(name = "pull_request_reviewer")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class Reviewer {
|
||||
|
||||
/**
|
||||
* Идентификатор
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
@EqualsAndHashCode.Include
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* Пользователь
|
||||
*/
|
||||
@Column(name = "user_login")
|
||||
private String user;
|
||||
private String userLogin;
|
||||
|
||||
/**
|
||||
* Статус
|
||||
*/
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "status")
|
||||
private ReviewerStatus status;
|
||||
|
@ -0,0 +1,69 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.entity;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.sadtech.bot.bitbucketbot.domain.TaskStatus;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@Table(name = "pull_request_task")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class Task {
|
||||
|
||||
/**
|
||||
* Идентификатор
|
||||
*/
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@EqualsAndHashCode.Include
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* Описание задачи
|
||||
*/
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "status")
|
||||
private TaskStatus status;
|
||||
|
||||
@Column(name = "create_date")
|
||||
private LocalDateTime createDate;
|
||||
|
||||
@OneToMany
|
||||
@Column(name = "pull_request_id")
|
||||
private Long pullRequestId;
|
||||
|
||||
@Column(name = "url")
|
||||
private String url;
|
||||
|
||||
@Column(name = "url_api")
|
||||
private String urlApi;
|
||||
|
||||
/**
|
||||
* Версия объекта в битбакет
|
||||
*/
|
||||
@Column(name = "bitbucket_version")
|
||||
private Integer bitbucketVersion;
|
||||
|
||||
@OneToMany
|
||||
@JoinColumn(name = "author_login")
|
||||
private Person author;
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "tech_info")
|
||||
@EqualsAndHashCode(of = "surogatId")
|
||||
@ToString
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class TechInfo {
|
||||
|
||||
@Id
|
||||
@Column(name = "surogat_id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long surogatId;
|
||||
|
||||
@Column(name = "last_comment_id")
|
||||
private Long lastCommentId;
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* TODO: Добавить описание класса.
|
||||
*
|
||||
* @author upagge [30.01.2020]
|
||||
*/
|
||||
@Builder
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "`user`")
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(of = "login")
|
||||
@ToString
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
@Column(name = "login")
|
||||
private String login;
|
||||
|
||||
@Column(name = "token")
|
||||
private String token;
|
||||
|
||||
@Column(name = "telegram_id")
|
||||
private Long telegramId;
|
||||
|
||||
@Column(name = "full_name")
|
||||
private String fullName;
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package org.sadtech.bot.bitbucketbot.domain.filter;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class PullRequestFilter {
|
||||
|
||||
private Long bitbucketId;
|
||||
private Long bitbucketRepositoryId;
|
||||
|
||||
}
|
@ -11,10 +11,15 @@ import java.util.List;
|
||||
public class CommentJson {
|
||||
|
||||
private Long id;
|
||||
private Integer version;
|
||||
private String text;
|
||||
private UserJson author;
|
||||
private List<CommentJson> comments;
|
||||
|
||||
private Severity severity;
|
||||
|
||||
private CommentState state;
|
||||
|
||||
@JsonDeserialize(using = LocalDateTimeFromEpochDeserializer.class)
|
||||
private LocalDateTime createdDate;
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
package org.sadtech.bot.bitbucketbot.dto.bitbucket;
|
||||
|
||||
public enum CommentState {
|
||||
|
||||
RESOLVED,
|
||||
OPEN
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package org.sadtech.bot.bitbucketbot.dto.bitbucket;
|
||||
|
||||
public enum Severity {
|
||||
|
||||
NORMAL,
|
||||
BLOCKER
|
||||
|
||||
}
|
@ -1,9 +1,13 @@
|
||||
package org.sadtech.bot.bitbucketbot.exception;
|
||||
|
||||
class BitbucketBotException extends RuntimeException {
|
||||
abstract class BitbucketBotException extends RuntimeException {
|
||||
|
||||
public BitbucketBotException(String message) {
|
||||
protected BitbucketBotException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
protected BitbucketBotException(String message, Throwable throwable) {
|
||||
super(message, throwable);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
package org.sadtech.bot.bitbucketbot.exception;
|
||||
|
||||
public class CreateException extends BitbucketBotException {
|
||||
|
||||
public CreateException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package org.sadtech.bot.bitbucketbot.exception;
|
||||
|
||||
public class UpdateException extends BitbucketBotException {
|
||||
|
||||
public UpdateException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package org.sadtech.bot.bitbucketbot.repository;
|
||||
|
||||
import org.sadtech.basic.context.repository.BusinessLogicRepository;
|
||||
import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr;
|
||||
import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface PullRequestsRepository extends BusinessLogicRepository<PullRequest, Long> {
|
||||
|
||||
List<PullRequest> findAllByReviewerAndStatuses(String login, ReviewerStatus reviewerStatus, Set<PullRequestStatus> statuses);
|
||||
|
||||
List<PullRequest> findAllByAuthorAndReviewerStatus(String login, ReviewerStatus status);
|
||||
|
||||
Set<IdAndStatusPr> findAllIdByStatusIn(Set<PullRequestStatus> statuses);
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package org.sadtech.bot.bitbucketbot.repository;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Task;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface TaskRepository {
|
||||
|
||||
Task save(@NonNull Task task);
|
||||
|
||||
void deleteById(@NonNull Long id);
|
||||
|
||||
Optional<Task> findById(@NonNull Long id);
|
||||
|
||||
Optional<Task> findFirstByOrderByIdDesc();
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package org.sadtech.bot.bitbucketbot.repository.impl;
|
||||
|
||||
import org.sadtech.basic.database.repository.AbstractBusinessLogicJpaRepository;
|
||||
import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr;
|
||||
import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.sadtech.bot.bitbucketbot.repository.PullRequestsRepository;
|
||||
import org.sadtech.bot.bitbucketbot.repository.jpa.PullRequestsRepositoryJpa;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Repository
|
||||
public class PullRequestsRepositoryImpl extends AbstractBusinessLogicJpaRepository<PullRequest, Long> implements PullRequestsRepository {
|
||||
|
||||
private final PullRequestsRepositoryJpa pullRequestsRepositoryJpa;
|
||||
|
||||
protected PullRequestsRepositoryImpl(PullRequestsRepositoryJpa pullRequestsRepositoryJpa) {
|
||||
super(pullRequestsRepositoryJpa);
|
||||
this.pullRequestsRepositoryJpa = pullRequestsRepositoryJpa;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PullRequest> findAllByReviewerAndStatuses(String login, ReviewerStatus reviewerStatus, Set<PullRequestStatus> statuses) {
|
||||
return pullRequestsRepositoryJpa.findAllByReviewerAndStatuses(login, reviewerStatus, statuses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PullRequest> findAllByAuthorAndReviewerStatus(String login, ReviewerStatus status) {
|
||||
return pullRequestsRepositoryJpa.findAllByAuthorAndReviewerStatus(login, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<IdAndStatusPr> findAllIdByStatusIn(Set<PullRequestStatus> statuses) {
|
||||
return pullRequestsRepositoryJpa.findAllIdByStatusIn(statuses);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package org.sadtech.bot.bitbucketbot.repository.impl;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Task;
|
||||
import org.sadtech.bot.bitbucketbot.repository.TaskRepository;
|
||||
import org.sadtech.bot.bitbucketbot.repository.jpa.TaskRepositoryJpa;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class TaskRepositoryImpl implements TaskRepository {
|
||||
|
||||
private final TaskRepositoryJpa taskRepositoryJpa;
|
||||
|
||||
@Override
|
||||
public Task save(@NonNull Task task) {
|
||||
return taskRepositoryJpa.save(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(@NonNull Long id) {
|
||||
taskRepositoryJpa.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Task> findById(@NonNull Long id) {
|
||||
return taskRepositoryJpa.findById(id);
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package org.sadtech.bot.bitbucketbot.repository.jpa;
|
||||
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.User;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Person;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@ -15,20 +15,22 @@ import java.util.Set;
|
||||
* @author upagge [30.01.2020]
|
||||
*/
|
||||
@Repository
|
||||
public interface UserRepository extends JpaRepository<User, String> {
|
||||
public interface PersonRepository extends JpaRepository<Person, String> {
|
||||
|
||||
boolean existsByTelegramId(Long chatId);
|
||||
|
||||
boolean existsByLogin(String login);
|
||||
|
||||
List<User> findAllByTelegramIdNotNullAndTokenNotNull();
|
||||
List<Person> findAllByTelegramIdNotNullAndTokenNotNull();
|
||||
|
||||
@Query("SELECT u.telegramId FROM User u WHERE u.login=:login")
|
||||
@Query("SELECT u.telegramId FROM Person u WHERE u.login=:login")
|
||||
Long findTelegramIdByLogin(String login);
|
||||
|
||||
@Query("SELECT u.telegramId FROM User u WHERE u.login IN :logins AND u.telegramId IS NOT NULL")
|
||||
@Query("SELECT u.telegramId FROM Person u WHERE u.login IN :logins AND u.telegramId IS NOT NULL")
|
||||
Set<Long> findAllTelegramIdByLogin(Set<String> logins);
|
||||
|
||||
Optional<User> findByLogin(String login);
|
||||
Optional<Person> findByLogin(String login);
|
||||
|
||||
Person getByLogin(String login);
|
||||
|
||||
}
|
@ -4,8 +4,8 @@ import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr;
|
||||
import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.jpa.repository.support.JpaRepositoryImplementation;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@ -17,7 +17,7 @@ import java.util.Set;
|
||||
/**
|
||||
* @author upagge [31.01.2020]
|
||||
*/
|
||||
public interface PullRequestsRepository extends JpaRepository<PullRequest, Long> {
|
||||
public interface PullRequestsRepositoryJpa extends JpaRepositoryImplementation<PullRequest, Long> {
|
||||
|
||||
Set<PullRequest> findAllByIdIn(Set<Long> ids);
|
||||
|
||||
@ -34,7 +34,7 @@ public interface PullRequestsRepository extends JpaRepository<PullRequest, Long>
|
||||
@Query("SELECT p FROM PullRequest p LEFT JOIN p.reviewers r WHERE p.author.login=:author AND r.status=:reviewerStatus")
|
||||
List<PullRequest> findAllByAuthorAndReviewerStatus(@Param("author") String author, @Param("reviewerStatus") ReviewerStatus reviewerStatus);
|
||||
|
||||
@Query("SELECT new org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr(p.id, p.status) FROM PullRequest p WHERE p.status IN :statuses")
|
||||
// @Query("SELECT new org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr(p.id, p.status) FROM PullRequest p WHERE p.status IN :statuses")
|
||||
Set<IdAndStatusPr> findAllIdByStatusIn(@Param("statuses") Set<PullRequestStatus> statuses);
|
||||
|
||||
@Query("SELECT p.id from PullRequest p")
|
@ -0,0 +1,8 @@
|
||||
package org.sadtech.bot.bitbucketbot.repository.jpa;
|
||||
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Task;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface TaskRepositoryJpa extends JpaRepository<Task, Long> {
|
||||
|
||||
}
|
@ -3,14 +3,15 @@ package org.sadtech.bot.bitbucketbot.scheduler;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.domain.MessageSend;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.AnswerCommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.Change;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.CommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ConflictPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.NewPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ReviewersPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.StatusPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.UpdatePrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.comment.AnswerCommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.comment.CommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.ConflictPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.NewPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.ReviewersPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.StatusPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.UpdatePrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.task.TaskChange;
|
||||
import org.sadtech.bot.bitbucketbot.exception.NotFoundException;
|
||||
import org.sadtech.bot.bitbucketbot.service.ChangeService;
|
||||
import org.sadtech.bot.bitbucketbot.service.MessageSendService;
|
||||
@ -21,6 +22,12 @@ import org.springframework.stereotype.Service;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Парсер изменений. Отслеживает изменения, которые были добавлены и добавляет событие на отправку уведомления
|
||||
* пользователю.
|
||||
*
|
||||
* @author upagge
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SchedulerChangeParsing {
|
||||
@ -28,6 +35,10 @@ public class SchedulerChangeParsing {
|
||||
private final MessageSendService messageSendService;
|
||||
private final ChangeService changeService;
|
||||
|
||||
/**
|
||||
* Проверяет наличие новых изменений. Если изменения найдены, то создает новое сообщение и отправляет
|
||||
* его в сервис отправки сообщений {@link MessageSendService}
|
||||
*/
|
||||
@Scheduled(cron = "*/15 * * * * *")
|
||||
public void parsing() {
|
||||
final List<Change> newChange = changeService.getNew().stream()
|
||||
@ -46,6 +57,12 @@ public class SchedulerChangeParsing {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Создает сообщение, которое необходимо отправить в зависимости от типа изменения.
|
||||
*
|
||||
* @param change Объект изменения
|
||||
* @return Текстовое сообщение
|
||||
*/
|
||||
private String generateMessage(@NonNull Change change) {
|
||||
String message;
|
||||
switch (change.getType()) {
|
||||
@ -70,6 +87,16 @@ public class SchedulerChangeParsing {
|
||||
case NEW_ANSWERS_COMMENT:
|
||||
message = Message.generate(((AnswerCommentChange) change));
|
||||
break;
|
||||
case NEW_TASK:
|
||||
case OPEN_TASK:
|
||||
message = Message.generateNewTask(((TaskChange) change));
|
||||
break;
|
||||
case DELETED_TASK:
|
||||
message = Message.generateDeleteTask(((TaskChange) change));
|
||||
break;
|
||||
case RESOLVED_TASK:
|
||||
message = Message.generateResolveTask(((TaskChange) change));
|
||||
break;
|
||||
default:
|
||||
throw new NotFoundException("Нет обработчика для типа " + change.getType().name());
|
||||
}
|
||||
|
@ -3,22 +3,32 @@ package org.sadtech.bot.bitbucketbot.scheduler;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.sadtech.bot.bitbucketbot.config.BitbucketConfig;
|
||||
import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty;
|
||||
import org.sadtech.bot.bitbucketbot.config.properties.CommentSchedulerProperty;
|
||||
import org.sadtech.bot.bitbucketbot.domain.Answer;
|
||||
import org.sadtech.bot.bitbucketbot.domain.Pagination;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.AnswerCommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.CommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.TaskStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ChangeType;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.comment.AnswerCommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.comment.CommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.task.TaskChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Comment;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Task;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentJson;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.Severity;
|
||||
import org.sadtech.bot.bitbucketbot.exception.NotFoundException;
|
||||
import org.sadtech.bot.bitbucketbot.service.ChangeService;
|
||||
import org.sadtech.bot.bitbucketbot.service.CommentService;
|
||||
import org.sadtech.bot.bitbucketbot.service.PersonService;
|
||||
import org.sadtech.bot.bitbucketbot.service.PullRequestsService;
|
||||
import org.sadtech.bot.bitbucketbot.service.UserService;
|
||||
import org.sadtech.bot.bitbucketbot.service.TaskService;
|
||||
import org.sadtech.bot.bitbucketbot.service.Utils;
|
||||
import org.sadtech.bot.bitbucketbot.service.executor.DataScan;
|
||||
import org.sadtech.bot.bitbucketbot.service.executor.ResultScan;
|
||||
import org.sadtech.bot.bitbucketbot.service.impl.ExecutorScanner;
|
||||
import org.sadtech.bot.bitbucketbot.utils.Converter;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -34,64 +44,171 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Шедулер отвечает за работу с комментариями. Поиск новых комментариев, проверка старых. Так как таски в
|
||||
* битбакете реализуются через комментарии, то <b>этот шедулер так же работает с тасками</b>.
|
||||
*
|
||||
* @author upagge
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SchedulerComments {
|
||||
|
||||
private static final Integer COUNT = 100;
|
||||
private static final Integer NO_COMMENT = 20;
|
||||
private static final Pattern PATTERN = Pattern.compile("@[\\w]+");
|
||||
|
||||
private final CommentService commentService;
|
||||
private final PullRequestsService pullRequestsService;
|
||||
private final UserService userService;
|
||||
private final PersonService personService;
|
||||
private final ChangeService changeService;
|
||||
private final ExecutorScanner executorScanner;
|
||||
private final TaskService taskService;
|
||||
private final ConversionService conversionService;
|
||||
|
||||
private final BitbucketConfig bitbucketConfig;
|
||||
private final BitbucketProperty bitbucketProperty;
|
||||
private final CommentSchedulerProperty commentSchedulerProperty;
|
||||
|
||||
@Scheduled(cron = "0 */3 * * * MON-FRI")
|
||||
/**
|
||||
* Сканирует появление новых комментариев
|
||||
*/
|
||||
@Scheduled(cron = "0 */3 * * * *")
|
||||
public void newComments() {
|
||||
long commentId = commentService.getLastCommentId() + 1;
|
||||
int count = 0;
|
||||
do {
|
||||
final List<DataScan> dataScans = generatingLinksToPossibleComments(commentId);
|
||||
executorScanner.registration(dataScans);
|
||||
final List<ResultScan> resultScans = executorScanner.getResult();
|
||||
if (!resultScans.isEmpty()) {
|
||||
final List<Comment> comments = getCommentsByResultScan(resultScans);
|
||||
final List<Comment> newComments = commentService.createAll(comments);
|
||||
checkNewTask(newComments);
|
||||
notificationPersonal(newComments);
|
||||
count = 0;
|
||||
}
|
||||
} while (count++ < commentSchedulerProperty.getNoCommentCount());
|
||||
}
|
||||
|
||||
private List<Comment> getCommentsByResultScan(List<ResultScan> resultScans) {
|
||||
return resultScans.stream()
|
||||
.map(result -> conversionService.convert(result, Comment.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<DataScan> generatingLinksToPossibleComments(@NonNull Long commentId) {
|
||||
List<DataScan> commentUrls = new ArrayList<>();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
int page = 0;
|
||||
Page<PullRequest> pullRequestPage = pullRequestsService.getAll(Pagination.of(page, COUNT));
|
||||
Page<PullRequest> pullRequestPage = pullRequestsService.getAll(
|
||||
Pagination.of(page, commentSchedulerProperty.getCommentCount())
|
||||
);
|
||||
while (pullRequestPage.hasContent()) {
|
||||
long finalCommentId = commentId;
|
||||
commentUrls.addAll(pullRequestPage.getContent().stream()
|
||||
.map(pullRequest -> new DataScan(getCommentUrl(finalCommentId, pullRequest), pullRequest.getUrl()))
|
||||
.map(
|
||||
pullRequest -> new DataScan(
|
||||
getCommentUrl(finalCommentId, pullRequest),
|
||||
pullRequest.getId()
|
||||
)
|
||||
)
|
||||
.collect(Collectors.toList()));
|
||||
pullRequestPage = pullRequestsService.getAll(Pagination.of(++page, COUNT));
|
||||
pullRequestPage = pullRequestsService.getAll(
|
||||
Pagination.of(++page, commentSchedulerProperty.getCommentCount())
|
||||
);
|
||||
}
|
||||
commentId++;
|
||||
}
|
||||
executorScanner.registration(commentUrls);
|
||||
final List<ResultScan> result = executorScanner.getResult();
|
||||
if (!result.isEmpty()) {
|
||||
result.forEach(resultScan -> {
|
||||
notificationPersonal(resultScan.getCommentJson(), resultScan.getUrlPr());
|
||||
saveComments(resultScan.getCommentJson(), resultScan.getUrlComment(), resultScan.getUrlPr());
|
||||
});
|
||||
count = 0;
|
||||
}
|
||||
} while (count++ < NO_COMMENT);
|
||||
return commentUrls;
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 */1 * * * MON-FRI")
|
||||
|
||||
private void checkNewTask(CommentJson commentJson, String urlPr, String authorLoginPr) {
|
||||
if (Severity.BLOCKER.equals(commentJson.getSeverity())) {
|
||||
final Task task = new Task();
|
||||
task.setStatus(Converter.taskStatus(commentJson.getState()));
|
||||
task.setComment(commentService.getProxyById(commentJson.getId()).orElseThrow(() -> new NotFoundException("Неожиданная ошибка")));
|
||||
|
||||
taskService.create(task);
|
||||
|
||||
if (TaskStatus.OPEN.equals(task.getStatus())) {
|
||||
changeService.add(
|
||||
TaskChange.builder()
|
||||
.type(ChangeType.NEW_TASK)
|
||||
.authorName(commentJson.getAuthor().getDisplayName())
|
||||
.messageTask(commentJson.getText())
|
||||
.telegramIds(personService.getAllTelegramIdByLogin(Collections.singleton(authorLoginPr)))
|
||||
.url(urlPr)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Проверяет состояние старых комментариев
|
||||
*/
|
||||
@Scheduled(cron = "0 */1 * * * *")
|
||||
public void oldComments() {
|
||||
@NonNull final List<Comment> comments = commentService.getAllBetweenDate(LocalDateTime.now().minusDays(10), LocalDateTime.now());
|
||||
@NonNull final List<Comment> comments = commentService.getAllBetweenDate(
|
||||
LocalDateTime.now().minusDays(10), LocalDateTime.now()
|
||||
);
|
||||
for (Comment comment : comments) {
|
||||
final Optional<CommentJson> optCommentJson = Utils.urlToJson(
|
||||
comment.getUrl(),
|
||||
bitbucketConfig.getToken(),
|
||||
bitbucketProperty.getToken(),
|
||||
CommentJson.class
|
||||
);
|
||||
if (optCommentJson.isPresent()) {
|
||||
final CommentJson commentJson = optCommentJson.get();
|
||||
checkNewAnswers(comment, commentJson);
|
||||
checkOldTask(comment, commentJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkOldTask(Comment comment, CommentJson commentJson) {
|
||||
final Task task = comment.getTask();
|
||||
if (task == null) {
|
||||
checkNewTask(commentJson, comment.getPrUrl(), commentJson.getAuthor().getName());
|
||||
} else {
|
||||
if (Severity.NORMAL.equals(commentJson.getSeverity())) {
|
||||
taskService.deleteById(comment.getId());
|
||||
|
||||
changeService.add(
|
||||
TaskChange.builder()
|
||||
.type(ChangeType.DELETED_TASK)
|
||||
.telegramIds(personService.getAllTelegramIdByLogin(Collections.singleton(commentJson.getAuthor().getName())))
|
||||
.authorName(commentJson.getAuthor().getDisplayName())
|
||||
.url(comment.getPrUrl())
|
||||
.messageTask(commentJson.getText())
|
||||
.build()
|
||||
);
|
||||
} else {
|
||||
final TaskStatus taskStatus = task.getStatus();
|
||||
final TaskStatus newTaskStatus = Converter.taskStatus(commentJson.getState());
|
||||
task.setStatus(newTaskStatus);
|
||||
taskService.update(task);
|
||||
if (!taskStatus.equals(newTaskStatus)) {
|
||||
changeService.add(
|
||||
TaskChange.builder()
|
||||
.type(TaskStatus.RESOLVED.equals(newTaskStatus) ? ChangeType.RESOLVED_TASK : ChangeType.OPEN_TASK)
|
||||
.authorName(commentJson.getAuthor().getDisplayName())
|
||||
.url(comment.getPrUrl())
|
||||
.messageTask(commentJson.getText())
|
||||
.telegramIds(
|
||||
TaskStatus.RESOLVED.equals(newTaskStatus)
|
||||
? personService.getAllTelegramIdByLogin(Collections.singleton(commentJson.getAuthor().getName()))
|
||||
: personService.getAllTelegramIdByLogin(Collections.singleton(commentJson.getAuthor().getName()))
|
||||
)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkNewAnswers(Comment comment, CommentJson commentJson) {
|
||||
final Set<Long> oldAnswerIds = comment.getAnswers();
|
||||
final List<CommentJson> newAnswers = commentJson.getComments().stream()
|
||||
.filter(answerJson -> !oldAnswerIds.contains(answerJson.getId()))
|
||||
@ -100,7 +217,7 @@ public class SchedulerComments {
|
||||
changeService.add(
|
||||
AnswerCommentChange.builder()
|
||||
.telegramIds(
|
||||
userService.getTelegramIdByLogin(commentJson.getAuthor().getName())
|
||||
personService.getTelegramIdByLogin(commentJson.getAuthor().getName())
|
||||
.map(Collections::singleton)
|
||||
.orElse(Collections.emptySet())
|
||||
)
|
||||
@ -117,42 +234,29 @@ public class SchedulerComments {
|
||||
commentService.save(comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private void saveComments(CommentJson comment, String commentUrl, String prUrl) {
|
||||
final Comment newComment = new Comment();
|
||||
newComment.setId(comment.getId());
|
||||
newComment.setDate(LocalDateTime.now());
|
||||
newComment.setUrl(commentUrl);
|
||||
newComment.setPrUrl(prUrl);
|
||||
userService.getTelegramIdByLogin(comment.getAuthor().getName()).ifPresent(newComment::setTelegram);
|
||||
commentService.save(newComment);
|
||||
}
|
||||
|
||||
private String getCommentUrl(long commentId, PullRequest pullRequest) {
|
||||
return bitbucketConfig.getUrlPullRequestComment()
|
||||
return bitbucketProperty.getUrlPullRequestComment()
|
||||
.replace("{projectKey}", pullRequest.getProjectKey())
|
||||
.replace("{repositorySlug}", pullRequest.getRepositorySlug())
|
||||
.replace("{pullRequestId}", pullRequest.getBitbucketId().toString())
|
||||
.replace("{commentId}", String.valueOf(commentId));
|
||||
}
|
||||
|
||||
private void notificationPersonal(@NonNull CommentJson comment, @NonNull String urlPr) {
|
||||
Matcher matcher = PATTERN.matcher(comment.getText());
|
||||
private void notificationPersonal(@NonNull Comment comment) {
|
||||
Matcher matcher = PATTERN.matcher(comment.getMessage());
|
||||
Set<String> recipientsLogins = new HashSet<>();
|
||||
while (matcher.find()) {
|
||||
final String login = matcher.group(0).replace("@", "");
|
||||
recipientsLogins.add(login);
|
||||
}
|
||||
final Set<Long> recipientsIds = userService.getAllTelegramIdByLogin(recipientsLogins);
|
||||
final Set<Long> recipientsIds = personService.getAllTelegramIdByLogin(recipientsLogins);
|
||||
changeService.add(
|
||||
CommentChange.builder()
|
||||
.authorName(comment.getAuthor().getName())
|
||||
.url(urlPr)
|
||||
.authorName(comment.getAuthor().getLogin())
|
||||
.url(comment.getPullRequest())
|
||||
.telegramIds(recipientsIds)
|
||||
.message(comment.getText())
|
||||
.message(comment.getMessage())
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
package org.sadtech.bot.bitbucketbot.scheduler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.config.BitbucketConfig;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.User;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.UserJson;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.sheet.UserSheetJson;
|
||||
import org.sadtech.bot.bitbucketbot.service.UserService;
|
||||
import org.sadtech.bot.bitbucketbot.service.Utils;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* TODO: Добавить описание класса.
|
||||
*
|
||||
* @author upagge [02.02.2020]
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SchedulerNewUser {
|
||||
|
||||
private static final String URL = "http://192.168.236.164:7990/rest/api/1.0/admin/users";
|
||||
private final UserService userService;
|
||||
private final ConversionService conversionService;
|
||||
private final BitbucketConfig bitbucketConfig;
|
||||
|
||||
@Scheduled(fixedRate = 86400000)
|
||||
private void scan() {
|
||||
Optional<UserSheetJson> sheetJson = Utils.urlToJson(URL, bitbucketConfig.getToken(), UserSheetJson.class);
|
||||
while (sheetJson.isPresent() && sheetJson.get().getValues()!=null && !sheetJson.get().getValues().isEmpty()) {
|
||||
final UserSheetJson sheetUsers = sheetJson.get();
|
||||
final List<UserJson> users = sheetUsers.getValues();
|
||||
final Set<String> logins = users.stream().map(UserJson::getName).collect(Collectors.toSet());
|
||||
final Set<String> existsLogins = userService.existsByLogin(logins);
|
||||
final Set<User> newUsers = users.stream()
|
||||
.filter(userJson -> !existsLogins.contains(userJson.getName()))
|
||||
.map(userJson -> conversionService.convert(userJson, User.class))
|
||||
.collect(Collectors.toSet());
|
||||
if (!newUsers.isEmpty()) {
|
||||
userService.addAll(newUsers);
|
||||
}
|
||||
if (sheetUsers.getNextPageStart() != null) {
|
||||
sheetJson = Utils.urlToJson(URL + sheetUsers.getNextPageStart(), bitbucketConfig.getToken(), UserSheetJson.class);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -4,12 +4,12 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.domain.MessageSend;
|
||||
import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Person;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.User;
|
||||
import org.sadtech.bot.bitbucketbot.service.MessageSendService;
|
||||
import org.sadtech.bot.bitbucketbot.service.PersonService;
|
||||
import org.sadtech.bot.bitbucketbot.service.PullRequestsService;
|
||||
import org.sadtech.bot.bitbucketbot.service.ReportService;
|
||||
import org.sadtech.bot.bitbucketbot.service.UserService;
|
||||
import org.sadtech.bot.bitbucketbot.utils.Message;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -24,7 +24,7 @@ public class SchedulerNotification {
|
||||
|
||||
private static final Set<PullRequestStatus> statuses = Collections.singleton(PullRequestStatus.OPEN);
|
||||
|
||||
private final UserService userService;
|
||||
private final PersonService personService;
|
||||
private final PullRequestsService pullRequestsService;
|
||||
private final MessageSendService messageSendService;
|
||||
private final ReportService reportService;
|
||||
@ -32,8 +32,8 @@ public class SchedulerNotification {
|
||||
// Утреннее сообщение
|
||||
@Scheduled(cron = "0 15 8 * * MON-FRI")
|
||||
public void goodMorning() {
|
||||
List<User> allRegister = userService.getAllRegister();
|
||||
for (User user : allRegister) {
|
||||
List<Person> allRegister = personService.getAllRegister();
|
||||
for (Person user : allRegister) {
|
||||
List<PullRequest> pullRequestsReviews = pullRequestsService.getAllByReviewerAndStatuses(
|
||||
user.getLogin(),
|
||||
ReviewerStatus.NEEDS_WORK,
|
||||
@ -51,8 +51,8 @@ public class SchedulerNotification {
|
||||
|
||||
@Scheduled(cron = "0 0 18 * * FRI")
|
||||
public void goodWeekEnd() {
|
||||
List<User> allRegister = userService.getAllRegister();
|
||||
for (User user : allRegister) {
|
||||
List<Person> allRegister = personService.getAllRegister();
|
||||
for (Person user : allRegister) {
|
||||
messageSendService.add(
|
||||
MessageSend.builder()
|
||||
.telegramId(user.getTelegramId())
|
||||
|
@ -1,320 +0,0 @@
|
||||
package org.sadtech.bot.bitbucketbot.scheduler;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.sadtech.bot.bitbucketbot.config.BitbucketConfig;
|
||||
import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr;
|
||||
import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ConflictPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.NewPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ReviewersPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.StatusPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.UpdatePrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Reviewer;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.User;
|
||||
import org.sadtech.bot.bitbucketbot.domain.util.ReviewerChange;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.PullRequestJson;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.sheet.PullRequestSheetJson;
|
||||
import org.sadtech.bot.bitbucketbot.service.ChangeService;
|
||||
import org.sadtech.bot.bitbucketbot.service.PullRequestsService;
|
||||
import org.sadtech.bot.bitbucketbot.service.UserService;
|
||||
import org.sadtech.bot.bitbucketbot.service.Utils;
|
||||
import org.sadtech.bot.bitbucketbot.utils.NonNullUtils;
|
||||
import org.sadtech.bot.bitbucketbot.utils.Pair;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.DECLINED;
|
||||
import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.DELETE;
|
||||
import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.MERGED;
|
||||
import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.OPEN;
|
||||
|
||||
/**
|
||||
* @author upagge [30.01.2020]
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SchedulerPullRequest {
|
||||
|
||||
private static final Set<PullRequestStatus> STATUSES = Stream.of(MERGED, OPEN, DECLINED).collect(Collectors.toSet());
|
||||
|
||||
private final PullRequestsService pullRequestsService;
|
||||
private final UserService userService;
|
||||
private final ChangeService changeService;
|
||||
private final ConversionService conversionService;
|
||||
private final BitbucketConfig bitbucketConfig;
|
||||
|
||||
@Scheduled(fixedRate = 30000)
|
||||
public void checkPullRequest() {
|
||||
final Set<Long> existsId = pullRequestsService.getAllId(STATUSES).stream()
|
||||
.map(IdAndStatusPr::getId)
|
||||
.collect(Collectors.toSet());
|
||||
final Set<Long> openId = checkOpenPullRequest();
|
||||
log.info("Открыты: " + Arrays.toString(openId.toArray()));
|
||||
final Set<Long> closeId = checkClosePullRequest();
|
||||
log.info("Закрыты: " + Arrays.toString(closeId.toArray()));
|
||||
final Set<Long> newNotExistsId = existsId.stream()
|
||||
.filter(id -> !openId.contains(id) && !closeId.contains(id))
|
||||
.collect(Collectors.toSet());
|
||||
log.info("Не найдены: " + Arrays.toString(newNotExistsId.toArray()));
|
||||
if (!newNotExistsId.isEmpty()) {
|
||||
updateDeletePr(newNotExistsId);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDeletePr(@NonNull Set<Long> ids) {
|
||||
final Set<PullRequest> deletePr = pullRequestsService.getAllById(ids);
|
||||
deletePr.stream()
|
||||
.filter(pullRequest -> pullRequest.getAuthor().getTelegramId() != null)
|
||||
.forEach(pullRequest -> changeService.add(
|
||||
StatusPrChange.builder()
|
||||
.name(pullRequest.getName())
|
||||
.url(pullRequest.getUrl())
|
||||
.oldStatus(pullRequest.getStatus())
|
||||
.newStatus(DELETE)
|
||||
.telegramIds(Collections.singleton(pullRequest.getAuthor().getTelegramId()))
|
||||
.build()
|
||||
));
|
||||
pullRequestsService.updateAll(
|
||||
deletePr.stream()
|
||||
.peek(pullRequest -> pullRequest.setStatus(PullRequestStatus.DELETE))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
private Set<Long> checkClosePullRequest() {
|
||||
final List<User> users = userService.getAllRegister();
|
||||
final Set<Long> ids = new HashSet<>();
|
||||
for (User user : users) {
|
||||
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestClose(), user.getToken(), PullRequestSheetJson.class);
|
||||
while (sheetJson.isPresent() && sheetJson.get().getValues() != null && !sheetJson.get().getValues().isEmpty()) {
|
||||
final PullRequestSheetJson bitbucketSheet = sheetJson.get();
|
||||
final Map<Long, PullRequest> existsPr = getExistsPr(bitbucketSheet.getValues());
|
||||
final Set<PullRequest> pullRequests = pullRequestsService.getAllById(existsPr.keySet());
|
||||
if (!existsPr.isEmpty() && !pullRequests.isEmpty()) {
|
||||
processingUpdateClosePr(existsPr, pullRequests);
|
||||
ids.addAll(
|
||||
pullRequestsService.updateAll(existsPr.values()).stream()
|
||||
.map(PullRequest::getId)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
}
|
||||
|
||||
if (bitbucketSheet.getNextPageStart() != null) {
|
||||
sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestClose() + bitbucketSheet.getNextPageStart(), bitbucketConfig.getToken(), PullRequestSheetJson.class);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
private Set<Long> checkOpenPullRequest() {
|
||||
final List<User> users = userService.getAllRegister();
|
||||
final Set<Long> ids = new HashSet<>();
|
||||
for (User user : users) {
|
||||
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestOpen(), user.getToken(), PullRequestSheetJson.class);
|
||||
while (sheetJson.isPresent() && sheetJson.get().getValues() != null && !sheetJson.get().getValues().isEmpty()) {
|
||||
final PullRequestSheetJson jsonSheet = sheetJson.get();
|
||||
final Map<Long, PullRequest> existsPr = getExistsPr(jsonSheet.getValues());
|
||||
final Set<PullRequest> pullRequests = pullRequestsService.getAllById(existsPr.keySet());
|
||||
if (!existsPr.isEmpty() && !pullRequests.isEmpty()) {
|
||||
processingUpdateOpenPr(existsPr, pullRequests);
|
||||
ids.addAll(
|
||||
pullRequestsService.updateAll(existsPr.values()).stream()
|
||||
.map(PullRequest::getId)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
}
|
||||
|
||||
if (jsonSheet.getNextPageStart() != null) {
|
||||
sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestOpen() + jsonSheet.getNextPageStart(), bitbucketConfig.getToken(), PullRequestSheetJson.class);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
private Map<Long, PullRequest> getExistsPr(List<PullRequestJson> pullRequestJsons) {
|
||||
return pullRequestJsons.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(pullRequestJson -> conversionService.convert(pullRequestJson, PullRequest.class))
|
||||
.peek(pullRequest -> pullRequestsService.getIdByBitbucketIdAndReposId(pullRequest.getBitbucketId(), pullRequest.getRepositoryId()).ifPresent(pullRequest::setId))
|
||||
.filter(pullRequest -> pullRequest.getId() != null)
|
||||
.collect(Collectors.toMap(PullRequest::getId, pullRequest -> pullRequest));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private void processingUpdateOpenPr(Map<Long, PullRequest> newPullRequests, Set<PullRequest> pullRequests) {
|
||||
for (PullRequest pullRequest : pullRequests) {
|
||||
PullRequest newPullRequest = newPullRequests.get(pullRequest.getId());
|
||||
changeStatusPR(pullRequest, newPullRequest);
|
||||
changeReviewersPR(pullRequest, newPullRequest);
|
||||
processingReviewer(pullRequest, newPullRequest);
|
||||
conflictPr(pullRequest, newPullRequest);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private void processingUpdateClosePr(Map<Long, PullRequest> newPullRequests, Set<PullRequest> pullRequests) {
|
||||
for (PullRequest pullRequest : pullRequests) {
|
||||
PullRequest newPullRequest = newPullRequests.get(pullRequest.getId());
|
||||
changeStatusPR(pullRequest, newPullRequest);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private void conflictPr(PullRequest pullRequest, PullRequest newPullRequest) {
|
||||
if (newPullRequest.isConflict() && !pullRequest.isConflict()) {
|
||||
changeService.add(
|
||||
ConflictPrChange.builder()
|
||||
.name(pullRequest.getName())
|
||||
.url(pullRequest.getUrl())
|
||||
.telegramIds(NonNullUtils.telegramIdByUser(pullRequest.getAuthor()))
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void processingReviewer(PullRequest pullRequest, PullRequest newPullRequest) {
|
||||
if (isUpdatePr(pullRequest, newPullRequest)) {
|
||||
final Set<String> logins = newPullRequest.getReviewers().stream()
|
||||
.map(Reviewer::getUser)
|
||||
.collect(Collectors.toSet());
|
||||
final Set<Long> telegramIds = userService.getAllTelegramIdByLogin(logins);
|
||||
changeService.add(
|
||||
UpdatePrChange.builder()
|
||||
.name(newPullRequest.getName())
|
||||
.url(newPullRequest.getUrl())
|
||||
.author(newPullRequest.getAuthor().getLogin())
|
||||
.telegramIds(telegramIds)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private boolean isUpdatePr(PullRequest pullRequest, PullRequest newPullRequest) {
|
||||
LocalDateTime oldDate = pullRequest.getUpdateDate();
|
||||
LocalDateTime newDate = newPullRequest.getUpdateDate();
|
||||
return !oldDate.isEqual(newDate);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private void changeReviewersPR(PullRequest pullRequest, PullRequest newPullRequest) {
|
||||
final Map<String, Reviewer> oldReviewers = pullRequest.getReviewers().stream()
|
||||
.collect(Collectors.toMap(Reviewer::getUser, reviewer -> reviewer));
|
||||
final Map<String, Reviewer> newReviewers = newPullRequest.getReviewers().stream()
|
||||
.collect(Collectors.toMap(Reviewer::getUser, reviewer -> reviewer));
|
||||
List<ReviewerChange> reviewerChanges = new ArrayList<>();
|
||||
for (Reviewer newReviewer : newReviewers.values()) {
|
||||
if (oldReviewers.containsKey(newReviewer.getUser())) {
|
||||
final Reviewer oldReviewer = oldReviewers.get(newReviewer.getUser());
|
||||
final ReviewerStatus oldStatus = oldReviewer.getStatus();
|
||||
final ReviewerStatus newStatus = newReviewer.getStatus();
|
||||
if (!oldStatus.equals(newStatus)) {
|
||||
reviewerChanges.add(ReviewerChange.ofOld(oldReviewer.getUser(), oldStatus, newStatus));
|
||||
}
|
||||
} else {
|
||||
reviewerChanges.add(ReviewerChange.ofNew(newReviewer.getUser(), newReviewer.getStatus()));
|
||||
}
|
||||
}
|
||||
final Set<String> oldLogins = oldReviewers.keySet();
|
||||
oldLogins.removeAll(newReviewers.keySet());
|
||||
oldLogins.forEach(login -> reviewerChanges.add(ReviewerChange.ofDeleted(login)));
|
||||
if (!reviewerChanges.isEmpty()) {
|
||||
changeService.add(
|
||||
ReviewersPrChange.builder()
|
||||
.name(pullRequest.getName())
|
||||
.url(pullRequest.getUrl())
|
||||
.reviewerChanges(reviewerChanges)
|
||||
.telegramIds(NonNullUtils.telegramIdByUser(pullRequest.getAuthor()))
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
private void changeStatusPR(PullRequest pullRequest, PullRequest newPullRequest) {
|
||||
final PullRequestStatus oldStatus = pullRequest.getStatus();
|
||||
final PullRequestStatus newStatus = newPullRequest.getStatus();
|
||||
if (!oldStatus.equals(newStatus)) {
|
||||
changeService.add(
|
||||
StatusPrChange.builder()
|
||||
.name(newPullRequest.getName())
|
||||
.url(newPullRequest.getUrl())
|
||||
.oldStatus(oldStatus)
|
||||
.newStatus(newStatus)
|
||||
.telegramIds(NonNullUtils.telegramIdByUser(newPullRequest.getAuthor()))
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(fixedRate = 30000)
|
||||
public void checkNewPullRequest() {
|
||||
final List<User> users = userService.getAllRegister();
|
||||
for (User user : users) {
|
||||
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestOpen(), user.getToken(), PullRequestSheetJson.class);
|
||||
while (sheetJson.isPresent() && sheetJson.get().getValues() != null && !sheetJson.get().getValues().isEmpty()) {
|
||||
final PullRequestSheetJson pullRequestBitbucketSheet = sheetJson.get();
|
||||
final List<PullRequest> newPullRequest = pullRequestBitbucketSheet.getValues().stream()
|
||||
.collect(Collectors.toMap(pullRequestJson -> new Pair<>(pullRequestJson.getId(), pullRequestJson.getFromRef().getRepository().getId()), pullRequestJson -> pullRequestJson))
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(test -> !pullRequestsService.existsByBitbucketIdAndReposId(test.getKey().getKey(), test.getKey().getValue()))
|
||||
.map(test -> conversionService.convert(test.getValue(), PullRequest.class))
|
||||
.collect(Collectors.toList());
|
||||
final List<PullRequest> newPullRequests = pullRequestsService.addAll(newPullRequest);
|
||||
sendNotificationNewPullRequest(newPullRequests);
|
||||
if (pullRequestBitbucketSheet.getNextPageStart() != null) {
|
||||
sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestOpen() + pullRequestBitbucketSheet.getNextPageStart(), bitbucketConfig.getToken(), PullRequestSheetJson.class);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendNotificationNewPullRequest(@NonNull List<PullRequest> newPullRequests) {
|
||||
if (!newPullRequests.isEmpty()) {
|
||||
for (PullRequest newPullRequest : newPullRequests) {
|
||||
final Set<Long> reviewerTelegramIds = userService.getAllTelegramIdByLogin(newPullRequest.getReviewers().stream()
|
||||
.map(Reviewer::getUser)
|
||||
.collect(Collectors.toSet()));
|
||||
changeService.add(
|
||||
NewPrChange.builder()
|
||||
.name(newPullRequest.getName())
|
||||
.url(newPullRequest.getUrl())
|
||||
.description(newPullRequest.getDescription())
|
||||
.author(newPullRequest.getAuthor().getLogin())
|
||||
.telegramIds(reviewerTelegramIds)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -60,7 +60,9 @@ public class SchedulerPushMessageSend {
|
||||
List<MessageSend> pushMessage = messageSendService.getPushMessage();
|
||||
if (!pushMessage.isEmpty()) {
|
||||
try {
|
||||
sendMessage(objectMapper.writeValueAsString(pushMessage));
|
||||
final String json = objectMapper.writeValueAsString(pushMessage);
|
||||
// sendMessage(json);
|
||||
System.out.println(json);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package org.sadtech.bot.bitbucketbot.scheduler.parser;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.service.parser.CommentAndTaskParser;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CommentAndTaskScheduler {
|
||||
|
||||
private final CommentAndTaskParser commentAndTaskParser;
|
||||
|
||||
@Scheduled(cron = "")
|
||||
public void scanNewCommentAndTask() {
|
||||
commentAndTaskParser.scanNewCommentAndTask();
|
||||
}
|
||||
|
||||
@Scheduled(cron = "")
|
||||
public void scanOldComment() {
|
||||
commentAndTaskParser.scanOldComment();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package org.sadtech.bot.bitbucketbot.scheduler.parser;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.service.parser.PersonParser;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class PersonScheduler {
|
||||
|
||||
private final PersonParser personParser;
|
||||
|
||||
@Scheduled(cron = "")
|
||||
public void scanPersons() {
|
||||
personParser.scanNewPerson();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.sadtech.bot.bitbucketbot.scheduler.parser;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.sadtech.bot.bitbucketbot.service.parser.PullRequestParser;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PullRequestParserScheduler {
|
||||
|
||||
private final PullRequestParser pullRequestParser;
|
||||
|
||||
@Scheduled(cron = "")
|
||||
public void parsingOldPullRequest() {
|
||||
pullRequestParser.parsingOldPullRequest();
|
||||
}
|
||||
|
||||
@Scheduled(cron = "")
|
||||
public void parsingNewPullRequest() {
|
||||
pullRequestParser.parsingNewPullRequest();
|
||||
}
|
||||
|
||||
}
|
@ -5,10 +5,24 @@ import org.sadtech.bot.bitbucketbot.domain.change.Change;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Сервис по работе с изменениями в битбакете.
|
||||
*
|
||||
* @author upagge
|
||||
* @see Change
|
||||
*/
|
||||
public interface ChangeService {
|
||||
|
||||
/**
|
||||
* Позволяет добавить новое изменение в хранилище
|
||||
*
|
||||
* @param change Объект, который содержит изменения
|
||||
*/
|
||||
void add(@NonNull Change change);
|
||||
|
||||
/**
|
||||
* Позволяет получить новые изменения.
|
||||
*/
|
||||
List<Change> getNew();
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import org.springframework.data.domain.Page;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public interface CommentService {
|
||||
|
||||
@ -17,8 +19,15 @@ public interface CommentService {
|
||||
@NonNull
|
||||
List<Comment> getAllBetweenDate(LocalDateTime dateFrom, LocalDateTime dateTo);
|
||||
|
||||
void save(@NonNull Comment comment);
|
||||
Comment create(@NonNull Comment comment);
|
||||
|
||||
void delete(@NonNull Long id);
|
||||
|
||||
Optional<Comment> getProxyById(@NonNull Long id);
|
||||
|
||||
List<Comment> createAll(List<Comment> newComments);
|
||||
|
||||
Comment update(Comment comment);
|
||||
|
||||
List<Comment> getAllById(@NonNull Set<Long> ids);
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
package org.sadtech.bot.bitbucketbot.service;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Person;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public interface PersonService {
|
||||
|
||||
Optional<Person> getByLogin(String login);
|
||||
|
||||
Set<String> existsByLogin(@NonNull Set<String> logins);
|
||||
|
||||
boolean existsByLogin(@NonNull String login);
|
||||
|
||||
Person reg(@NonNull Person user);
|
||||
|
||||
List<Person> getAllRegister();
|
||||
|
||||
Optional<Long> getTelegramIdByLogin(@NonNull String login);
|
||||
|
||||
Set<Long> getAllTelegramIdByLogin(Set<String> logins);
|
||||
|
||||
Optional<Person> getProxyByLogin(@NonNull String login);
|
||||
|
||||
Person create(@NonNull Person person);
|
||||
|
||||
List<Person> createAll(Collection<Person> newUsers);
|
||||
|
||||
}
|
@ -1,46 +1,24 @@
|
||||
package org.sadtech.bot.bitbucketbot.service;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.sadtech.basic.context.service.BusinessLogicService;
|
||||
import org.sadtech.basic.context.service.simple.FilterService;
|
||||
import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr;
|
||||
import org.sadtech.bot.bitbucketbot.domain.Pagination;
|
||||
import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.sadtech.bot.bitbucketbot.domain.filter.PullRequestFilter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public interface PullRequestsService {
|
||||
|
||||
@NonNull
|
||||
boolean existsByBitbucketIdAndReposId(Long bitbucketId, Long repositoryId);
|
||||
|
||||
Set<PullRequest> getAllById(@NonNull Set<Long> pullRequestJsonId);
|
||||
|
||||
List<PullRequest> addAll(@NonNull Collection<PullRequest> pullRequests);
|
||||
|
||||
List<PullRequest> updateAll(@NonNull Collection<PullRequest> pullRequests);
|
||||
|
||||
@NonNull
|
||||
Optional<Long> getIdByBitbucketIdAndReposId(Long bitbucketId, Long repositoryId);
|
||||
|
||||
void deleteAll(@NonNull Set<Long> id);
|
||||
public interface PullRequestsService extends BusinessLogicService<PullRequest, Long>, FilterService<PullRequest, PullRequestFilter> {
|
||||
|
||||
@NonNull
|
||||
List<PullRequest> getAllByReviewerAndStatuses(@NonNull String login, @NonNull ReviewerStatus reviewerStatus, @NonNull Set<PullRequestStatus> pullRequestStatuses);
|
||||
|
||||
List<PullRequest> getAllByAuthorAndReviewerStatus(@NonNull String login, @NonNull ReviewerStatus status);
|
||||
|
||||
Set<Long> getAllId();
|
||||
|
||||
Set<IdAndStatusPr> getAllId(Set<PullRequestStatus> statuses);
|
||||
|
||||
Page<PullRequest> getAll(@NonNull Pagination pagination);
|
||||
|
||||
List<PullRequest> getAllByAuthor(@NonNull String login, @NonNull LocalDateTime dateFrom, @NonNull LocalDateTime dateTo);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package org.sadtech.bot.bitbucketbot.service;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Task;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface TaskService {
|
||||
|
||||
Task create(@NonNull Task task);
|
||||
|
||||
void deleteById(@NonNull Long id);
|
||||
|
||||
Task update(@NonNull Task task);
|
||||
|
||||
List<Task> createAll(@NonNull Collection<Task> tasks);
|
||||
|
||||
Long getLastTaskId();
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package org.sadtech.bot.bitbucketbot.service;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.User;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public interface UserService {
|
||||
|
||||
Optional<User> getByLogin(String login);
|
||||
|
||||
Set<String> existsByLogin(@NonNull Set<String> logins);
|
||||
|
||||
User reg(@NonNull User user);
|
||||
|
||||
List<User> addAll(Set<User> newUsers);
|
||||
|
||||
List<User> getAllRegister();
|
||||
|
||||
Optional<Long> getTelegramIdByLogin(@NonNull String login);
|
||||
|
||||
Set<Long> getAllTelegramIdByLogin(Set<String> logins);
|
||||
|
||||
}
|
@ -18,7 +18,7 @@ import java.util.concurrent.TimeUnit;
|
||||
@Slf4j
|
||||
public class Utils {
|
||||
|
||||
private static ObjectMapper objectMapper;
|
||||
private static final ObjectMapper objectMapper;
|
||||
|
||||
static {
|
||||
objectMapper = new ObjectMapper();
|
||||
@ -35,8 +35,7 @@ public class Utils {
|
||||
throw new IllegalStateException("Утилитарный класс");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static <T> Optional<T> urlToJson(String urlValue, String token, Class<T> classOfT) {
|
||||
public static <T> Optional<T> urlToJson(@NonNull String urlValue, @NonNull String token, @NonNull Class<T> classOfT) {
|
||||
Request request = new Request.Builder()
|
||||
.url(urlValue)
|
||||
.header("Authorization", "Bearer " + token)
|
||||
|
@ -5,15 +5,12 @@ import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Reviewer;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.User;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.Outcome;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.Properties;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.PullRequestJson;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.PullRequestState;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.UserDecisionJson;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.UserJson;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.UserPullRequestStatus;
|
||||
import org.sadtech.bot.bitbucketbot.service.UserService;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -24,27 +21,25 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
public class PullRequestJsonConverter implements Converter<PullRequestJson, PullRequest> {
|
||||
|
||||
private final UserJsonConverter userJsonConverter;
|
||||
private final UserService userService;
|
||||
|
||||
@Override
|
||||
public PullRequest convert(PullRequestJson json) {
|
||||
return PullRequest.builder()
|
||||
.bitbucketId(json.getId())
|
||||
.version(json.getVersion())
|
||||
.createDate(json.getCreatedDate())
|
||||
.updateDate(json.getUpdatedDate())
|
||||
.conflict(convertConflict(json.getProperties()))
|
||||
.description(convertDescription(json.getDescription()))
|
||||
.repositoryId(json.getFromRef().getRepository().getId())
|
||||
.author(this.convertUser(json.getAuthor().getUser()))
|
||||
.name(json.getTitle())
|
||||
.url(json.getLinks().getSelf().get(0).getHref())
|
||||
.status(convertPullRequestStatus(json.getState()))
|
||||
.projectKey(json.getFromRef().getRepository().getProject().getKey())
|
||||
.repositorySlug(json.getFromRef().getRepository().getSlug())
|
||||
.reviewers(convertReviewers(json.getReviewers()))
|
||||
.build();
|
||||
|
||||
final PullRequest pullRequest = new PullRequest();
|
||||
pullRequest.setBitbucketId(json.getId());
|
||||
pullRequest.setCreateDate(json.getCreatedDate());
|
||||
pullRequest.setUpdateDate(json.getUpdatedDate());
|
||||
pullRequest.setConflict(convertConflict(json.getProperties()));
|
||||
pullRequest.setDescription(convertDescription(json.getDescription()));
|
||||
pullRequest.setAuthorLogin(json.getAuthor().getUser().getName());
|
||||
pullRequest.setTitle(json.getTitle());
|
||||
pullRequest.setUrl(json.getLinks().getSelf().get(0).getHref());
|
||||
pullRequest.setStatus(convertPullRequestStatus(json.getState()));
|
||||
pullRequest.setProjectKey(json.getFromRef().getRepository().getProject().getKey());
|
||||
pullRequest.setRepositorySlug(json.getFromRef().getRepository().getSlug());
|
||||
pullRequest.setReviewers(convertReviewers(json.getReviewers()));
|
||||
pullRequest.setBitbucketVersion(json.getVersion());
|
||||
|
||||
return pullRequest;
|
||||
}
|
||||
|
||||
private boolean convertConflict(Properties properties) {
|
||||
@ -61,10 +56,6 @@ public class PullRequestJsonConverter implements Converter<PullRequestJson, Pull
|
||||
return null;
|
||||
}
|
||||
|
||||
private User convertUser(UserJson userJson) {
|
||||
return userService.getByLogin(userJson.getName()).orElse(userJsonConverter.convert(userJson));
|
||||
}
|
||||
|
||||
public static PullRequestStatus convertPullRequestStatus(PullRequestState state) {
|
||||
switch (state) {
|
||||
case OPEN:
|
||||
@ -82,7 +73,7 @@ public class PullRequestJsonConverter implements Converter<PullRequestJson, Pull
|
||||
.map(
|
||||
jsonReviewer -> {
|
||||
final Reviewer reviewer = new Reviewer();
|
||||
reviewer.setUser(jsonReviewer.getUser().getName());
|
||||
reviewer.setUserLogin(jsonReviewer.getUser().getName());
|
||||
reviewer.setStatus(convertStatusReviewer(jsonReviewer.getStatus()));
|
||||
return reviewer;
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
package org.sadtech.bot.bitbucketbot.service.converter;
|
||||
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Comment;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Person;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentJson;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.Severity;
|
||||
import org.sadtech.bot.bitbucketbot.service.executor.ResultScan;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class ResultScanToComment implements Converter<ResultScan, Comment> {
|
||||
|
||||
@Override
|
||||
public Comment convert(ResultScan resultScan) {
|
||||
final CommentJson commentJson = resultScan.getCommentJson();
|
||||
final Comment comment = new Comment();
|
||||
comment.setCreateDate(commentJson.getCreatedDate());
|
||||
comment.setAuthor(commentJson.getAuthor().getName());
|
||||
comment.setPullRequestId(getPullRequest(resultScan.getPullRequestId()));
|
||||
comment.setMessage(commentJson.getText());
|
||||
comment.setUrl(resultScan.getUrlComment());
|
||||
comment.setBitbucketVersion(commentJson.getVersion());
|
||||
comment.setAnswers(
|
||||
commentJson.getComments().stream()
|
||||
.filter(json -> Severity.NORMAL.equals(json.getSeverity()))
|
||||
.map(CommentJson::getId)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
return comment;
|
||||
|
||||
}
|
||||
|
||||
private PullRequest getPullRequest(Long pullRequestId) {
|
||||
final PullRequest pullRequest = new PullRequest();
|
||||
pullRequest.setId(pullRequestId);
|
||||
return pullRequest;
|
||||
}
|
||||
|
||||
private Person getAuthor(String name) {
|
||||
final Person user = new Person();
|
||||
user.setLogin(name);
|
||||
return user;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package org.sadtech.bot.bitbucketbot.service.converter;
|
||||
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Person;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Task;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentJson;
|
||||
import org.sadtech.bot.bitbucketbot.service.executor.ResultScan;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ResultScanToTaskConvert implements Converter<ResultScan, Task> {
|
||||
|
||||
@Override
|
||||
public Task convert(ResultScan resultScan) {
|
||||
final CommentJson json = resultScan.getCommentJson();
|
||||
final Task task = new Task();
|
||||
task.setId(json.getId());
|
||||
task.setAuthor(getAuthor(json));
|
||||
task.setDescription(json.getText());
|
||||
task.setCreateDate(json.getCreatedDate());
|
||||
task.setBitbucketVersion(json.getVersion());
|
||||
task.setPullRequestId(resultScan.getPullRequestId());
|
||||
return task;
|
||||
}
|
||||
|
||||
private Person getAuthor(CommentJson json) {
|
||||
final Person person = new Person();
|
||||
person.setLogin(json.getAuthor().getName());
|
||||
return person;
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
package org.sadtech.bot.bitbucketbot.service.converter;
|
||||
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.User;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Person;
|
||||
import org.sadtech.bot.bitbucketbot.dto.UserDto;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class UserDtoConverter implements Converter<UserDto, User> {
|
||||
public class UserDtoConverter implements Converter<UserDto, Person> {
|
||||
|
||||
@Override
|
||||
public User convert(UserDto source) {
|
||||
return User.builder()
|
||||
public Person convert(UserDto source) {
|
||||
return Person.builder()
|
||||
.login(source.getLogin())
|
||||
.token(source.getToken())
|
||||
.telegramId(source.getTelegramId())
|
||||
|
@ -1,19 +1,19 @@
|
||||
package org.sadtech.bot.bitbucketbot.service.converter;
|
||||
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.User;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Person;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.UserJson;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UserJsonConverter implements Converter<UserJson, User> {
|
||||
public class UserJsonConverter implements Converter<UserJson, Person> {
|
||||
|
||||
@Override
|
||||
public User convert(UserJson source) {
|
||||
return User.builder()
|
||||
.fullName(source.getDisplayName())
|
||||
.login(source.getName())
|
||||
.build();
|
||||
public Person convert(UserJson source) {
|
||||
final Person person = new Person();
|
||||
person.setFullName(source.getDisplayName());
|
||||
person.setLogin(source.getName());
|
||||
return person;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,6 @@ import lombok.Data;
|
||||
public class DataScan {
|
||||
|
||||
private final String urlComment;
|
||||
private final String urlPr;
|
||||
private final Long pullRequestId;
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
package org.sadtech.bot.bitbucketbot.service.executor;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentJson;
|
||||
|
||||
@Data
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class ResultScan {
|
||||
|
||||
private final String urlComment;
|
||||
private final String urlPr;
|
||||
private final Long pullRequestId;
|
||||
private final CommentJson commentJson;
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,12 @@ public class Seeker implements Callable<Optional<ResultScan>> {
|
||||
@Override
|
||||
public Optional<ResultScan> call() {
|
||||
return Utils.urlToJson(dataScan.getUrlComment(), token, CommentJson.class)
|
||||
.map(commentJson -> new ResultScan(dataScan.getUrlComment(), dataScan.getUrlPr(), commentJson));
|
||||
.map(
|
||||
commentJson -> new ResultScan(
|
||||
dataScan.getUrlComment(),
|
||||
dataScan.getPullRequestId(),
|
||||
commentJson)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,20 +5,29 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.config.InitConfig;
|
||||
import org.sadtech.bot.bitbucketbot.domain.Pagination;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Comment;
|
||||
import org.sadtech.bot.bitbucketbot.exception.NotFoundException;
|
||||
import org.sadtech.bot.bitbucketbot.repository.jpa.CommentRepository;
|
||||
import org.sadtech.bot.bitbucketbot.service.CommentService;
|
||||
import org.sadtech.bot.bitbucketbot.service.PersonService;
|
||||
import org.sadtech.bot.bitbucketbot.service.PullRequestsService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CommentServiceImpl implements CommentService {
|
||||
|
||||
private final PersonService personService;
|
||||
private final CommentRepository commentRepository;
|
||||
private final PullRequestsService pullRequestsService;
|
||||
private final InitConfig initConfig;
|
||||
|
||||
@Override
|
||||
@ -41,8 +50,14 @@ public class CommentServiceImpl implements CommentService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(@NonNull Comment comment) {
|
||||
commentRepository.save(comment);
|
||||
public Comment create(@NonNull Comment comment) {
|
||||
comment.setAuthor(personService.getProxyByLogin(
|
||||
comment.getAuthor().getLogin()).orElseThrow(() -> new NotFoundException(""))
|
||||
);
|
||||
comment.setPullRequest(
|
||||
pullRequestsService.getProxyById(comment.getPullRequest().getId()).orElseThrow(() -> new NotFoundException(""))
|
||||
);
|
||||
return commentRepository.save(comment);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -50,4 +65,36 @@ public class CommentServiceImpl implements CommentService {
|
||||
commentRepository.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Comment> getProxyById(@NonNull Long id) {
|
||||
return Optional.ofNullable(commentRepository.getOne(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public List<Comment> createAll(List<Comment> newComments) {
|
||||
return newComments.stream()
|
||||
.map(this::create)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comment update(Comment comment) {
|
||||
final Comment oldComment = commentRepository.findById(comment.getId())
|
||||
.orElseThrow(() -> new NotFoundException("Комментарий не найден"));
|
||||
|
||||
if (oldComment.getBitbucketVersion().equals(comment.getBitbucketVersion())) {
|
||||
oldComment.setBitbucketVersion(comment.getBitbucketVersion());
|
||||
oldComment.setMessage(oldComment.getMessage());
|
||||
return commentRepository.save(oldComment);
|
||||
}
|
||||
|
||||
return oldComment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Comment> getAllById(@NonNull Set<Long> ids) {
|
||||
return commentRepository.findAllById(ids);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package org.sadtech.bot.bitbucketbot.service.impl;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.sadtech.bot.bitbucketbot.config.BitbucketConfig;
|
||||
import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty;
|
||||
import org.sadtech.bot.bitbucketbot.service.executor.DataScan;
|
||||
import org.sadtech.bot.bitbucketbot.service.executor.Executor;
|
||||
import org.sadtech.bot.bitbucketbot.service.executor.ResultScan;
|
||||
@ -25,13 +25,13 @@ public class ExecutorScanner implements Executor<DataScan, ResultScan> {
|
||||
|
||||
private final ExecutorService executorService;
|
||||
private List<Future<Optional<ResultScan>>> resultList = new ArrayList<>();
|
||||
private final BitbucketConfig bitbucketConfig;
|
||||
private final BitbucketProperty bitbucketProperty;
|
||||
|
||||
@Override
|
||||
public boolean registration(@NonNull List<DataScan> dataScans) {
|
||||
resultList.addAll(
|
||||
dataScans.stream()
|
||||
.map(dataScan -> new Seeker(dataScan, bitbucketConfig.getToken()))
|
||||
.map(dataScan -> new Seeker(dataScan, bitbucketProperty.getToken()))
|
||||
.map(executorService::submit)
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
|
@ -0,0 +1,96 @@
|
||||
package org.sadtech.bot.bitbucketbot.service.impl;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Person;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.sheet.PullRequestSheetJson;
|
||||
import org.sadtech.bot.bitbucketbot.exception.CreateException;
|
||||
import org.sadtech.bot.bitbucketbot.exception.RegException;
|
||||
import org.sadtech.bot.bitbucketbot.repository.jpa.PersonRepository;
|
||||
import org.sadtech.bot.bitbucketbot.service.PersonService;
|
||||
import org.sadtech.bot.bitbucketbot.service.Utils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PersonServiceImpl implements PersonService {
|
||||
|
||||
private final PersonRepository personRepository;
|
||||
private final BitbucketProperty bitbucketProperty;
|
||||
|
||||
@Override
|
||||
public Optional<Person> getByLogin(String login) {
|
||||
return personRepository.findById(login);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> existsByLogin(@NonNull Set<String> logins) {
|
||||
return logins.stream().filter(personRepository::existsById).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsByLogin(@NonNull String login) {
|
||||
return personRepository.existsByLogin(login);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Person reg(@NonNull Person user) {
|
||||
final Optional<Person> optUser = personRepository.findByLogin(user.getLogin());
|
||||
if (optUser.isPresent()) {
|
||||
final Person oldUser = optUser.get();
|
||||
if (oldUser.getTelegramId() == null) {
|
||||
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(bitbucketProperty.getUrlPullRequestClose(), user.getToken(), PullRequestSheetJson.class);
|
||||
if (sheetJson.isPresent()) {
|
||||
oldUser.setTelegramId(user.getTelegramId());
|
||||
return personRepository.save(oldUser);
|
||||
} else {
|
||||
throw new RegException("Ваш токен не валиден");
|
||||
}
|
||||
} else {
|
||||
throw new RegException("Вы уже авторизованы в системе");
|
||||
}
|
||||
}
|
||||
throw new RegException("Пользователь не найден, подождите обновление базы пользователей!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Person> getAllRegister() {
|
||||
return personRepository.findAllByTelegramIdNotNullAndTokenNotNull();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Long> getTelegramIdByLogin(@NonNull String login) {
|
||||
return Optional.ofNullable(personRepository.findTelegramIdByLogin(login));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getAllTelegramIdByLogin(Set<String> logins) {
|
||||
return personRepository.findAllTelegramIdByLogin(logins);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Person> getProxyByLogin(@NonNull String login) {
|
||||
return Optional.ofNullable(personRepository.getByLogin(login));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Person create(@NonNull Person person) {
|
||||
if (person.getId() == null) {
|
||||
return personRepository.save(person);
|
||||
}
|
||||
throw new CreateException("При создании пользователя должен отсутствовать id");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Person> createAll(Collection<Person> newPersons) {
|
||||
return newPersons.stream().map(this::create).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
@ -1,65 +1,78 @@
|
||||
package org.sadtech.bot.bitbucketbot.service.impl;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.basic.context.page.Pagination;
|
||||
import org.sadtech.basic.context.page.Sheet;
|
||||
import org.sadtech.basic.core.service.AbstractBusinessLogicService;
|
||||
import org.sadtech.basic.filter.criteria.CriteriaQuery;
|
||||
import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr;
|
||||
import org.sadtech.bot.bitbucketbot.domain.Pagination;
|
||||
import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.sadtech.bot.bitbucketbot.repository.jpa.PullRequestsRepository;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest_;
|
||||
import org.sadtech.bot.bitbucketbot.domain.filter.PullRequestFilter;
|
||||
import org.sadtech.bot.bitbucketbot.exception.CreateException;
|
||||
import org.sadtech.bot.bitbucketbot.exception.UpdateException;
|
||||
import org.sadtech.bot.bitbucketbot.repository.PullRequestsRepository;
|
||||
import org.sadtech.bot.bitbucketbot.service.ChangeService;
|
||||
import org.sadtech.bot.bitbucketbot.service.PullRequestsService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.sadtech.bot.bitbucketbot.utils.ChangeGenerator;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PullRequestsServiceImpl implements PullRequestsService {
|
||||
public class PullRequestsServiceImpl extends AbstractBusinessLogicService<PullRequest, Long> implements PullRequestsService {
|
||||
|
||||
private final ChangeService changeService;
|
||||
private final PullRequestsRepository pullRequestsRepository;
|
||||
|
||||
@Override
|
||||
public boolean existsByBitbucketIdAndReposId(@NonNull Long bitbucketId, @NonNull Long repositoryId) {
|
||||
return pullRequestsRepository.existsByBitbucketIdAndRepositoryId(bitbucketId, repositoryId);
|
||||
protected PullRequestsServiceImpl(PullRequestsRepository pullRequestsRepository, ChangeService changeService) {
|
||||
super(pullRequestsRepository);
|
||||
this.changeService = changeService;
|
||||
this.pullRequestsRepository = pullRequestsRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<PullRequest> getAllById(@NonNull Set<Long> pullRequestJsonId) {
|
||||
return pullRequestsRepository.findAllByIdIn(pullRequestJsonId);
|
||||
public PullRequest create(@NonNull PullRequest pullRequest) {
|
||||
if (pullRequest.getId() == null) {
|
||||
final PullRequest newPullRequest = pullRequestsRepository.save(pullRequest);
|
||||
changeService.add(ChangeGenerator.create(newPullRequest));
|
||||
return newPullRequest;
|
||||
}
|
||||
throw new CreateException("При создании идентификатор должен быть пустым");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public List<PullRequest> addAll(@NonNull Collection<PullRequest> pullRequests) {
|
||||
return pullRequestsRepository.saveAll(pullRequests);
|
||||
public PullRequest update(@NonNull PullRequest pullRequest) {
|
||||
final PullRequest oldPullRequest = findAndFillId(pullRequest);
|
||||
|
||||
if (!oldPullRequest.getBitbucketVersion().equals(pullRequest.getBitbucketVersion())) {
|
||||
oldPullRequest.setBitbucketVersion(pullRequest.getVersion());
|
||||
oldPullRequest.setConflict(pullRequest.isConflict());
|
||||
oldPullRequest.setTitle(pullRequest.getTitle());
|
||||
oldPullRequest.setDescription(pullRequest.getDescription());
|
||||
oldPullRequest.setStatus(pullRequest.getStatus());
|
||||
oldPullRequest.setReviewers(pullRequest.getReviewers());
|
||||
|
||||
final PullRequest newPullRequest = pullRequestsRepository.save(oldPullRequest);
|
||||
|
||||
changeService.add(ChangeGenerator.createUpdatePr(pullRequest, newPullRequest));
|
||||
changeService.add(ChangeGenerator.createReviewersPr(pullRequest, newPullRequest));
|
||||
|
||||
return newPullRequest;
|
||||
}
|
||||
return oldPullRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PullRequest> updateAll(@NonNull Collection<PullRequest> pullRequests) {
|
||||
final List<PullRequest> updatePullRequests = pullRequests.stream()
|
||||
.filter(pullRequest -> pullRequestsRepository.existsById(pullRequest.getId()))
|
||||
.collect(Collectors.toList());
|
||||
return pullRequestsRepository.saveAll(updatePullRequests);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Long> getIdByBitbucketIdAndReposId(@NonNull Long bitbucketId, @NonNull Long repositoryId) {
|
||||
return pullRequestsRepository.findIdByBitbucketIdAndRepositoryId(bitbucketId, repositoryId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void deleteAll(@NonNull Set<Long> id) {
|
||||
pullRequestsRepository.deleteAllByIdIn(id);
|
||||
private PullRequest findAndFillId(@NonNull PullRequest pullRequest) {
|
||||
return pullRequestsRepository.findByFilterQuery(
|
||||
CriteriaQuery.create()
|
||||
.matchPhrase(PullRequest_.BITBUCKET_ID, pullRequest.getBitbucketId())
|
||||
.matchPhrase(PullRequest_.REPOSITORY_ID, pullRequest.getRepositoryId())
|
||||
).orElseThrow(() -> new UpdateException("ПР с таким id не существует"));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@ -73,25 +86,33 @@ public class PullRequestsServiceImpl implements PullRequestsService {
|
||||
return pullRequestsRepository.findAllByAuthorAndReviewerStatus(login, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getAllId() {
|
||||
return pullRequestsRepository.findAllIds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<IdAndStatusPr> getAllId(Set<PullRequestStatus> statuses) {
|
||||
return pullRequestsRepository.findAllIdByStatusIn(statuses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<PullRequest> getAll(@NonNull Pagination pagination) {
|
||||
return pullRequestsRepository.findAll(PageRequest.of(pagination.getPage(), pagination.getSize()));
|
||||
public Sheet<PullRequest> getAllByFilter(@NonNull PullRequestFilter filter, Pagination pagination) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PullRequest> getAllByAuthor(@NonNull String login, @NonNull LocalDateTime dateFrom, @NonNull LocalDateTime dateTo) {
|
||||
return pullRequestsRepository.findAllByAuthorAndDateBetween(login, dateFrom, dateTo);
|
||||
public Sheet<PullRequest> getALlByFilterQuery(@NonNull PullRequestFilter filter, Pagination pagination) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PullRequest> getByFilterQuery(@NonNull PullRequestFilter filterQuery) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsByFilterQuery(@NonNull PullRequestFilter filter) {
|
||||
return pullRequestsRepository.existsByFilterQuery(
|
||||
CriteriaQuery.<PullRequest>create()
|
||||
.matchPhrase(PullRequest_.BITBUCKET_ID, filter.getBitbucketId())
|
||||
.matchPhrase(PullRequest_.REPOSITORY_ID, filter.getBitbucketRepositoryId())
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
package org.sadtech.bot.bitbucketbot.service.impl;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Task;
|
||||
import org.sadtech.bot.bitbucketbot.exception.CreateException;
|
||||
import org.sadtech.bot.bitbucketbot.exception.NotFoundException;
|
||||
import org.sadtech.bot.bitbucketbot.repository.TaskRepository;
|
||||
import org.sadtech.bot.bitbucketbot.service.TaskService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TaskServiceImpl implements TaskService {
|
||||
|
||||
private final TaskRepository taskRepository;
|
||||
|
||||
@Override
|
||||
public Task create(@NonNull Task task) {
|
||||
if (task.getId() == null) {
|
||||
return taskRepository.save(task);
|
||||
}
|
||||
throw new CreateException("При создании объекта не должно быть идентификатора");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(@NonNull Long id) {
|
||||
taskRepository.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task update(@NonNull Task task) {
|
||||
final Task oldTask = taskRepository.findById(task.getId()).orElseThrow(() -> new NotFoundException("Задача не найдена"));
|
||||
oldTask.setStatus(task.getStatus());
|
||||
return taskRepository.save(oldTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Task> createAll(@NonNull Collection<Task> tasks) {
|
||||
return tasks.stream().map(this::create).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLastTaskId() {
|
||||
return taskRepository.findFirstByOrderByIdDesc().map(Task::getId).orElse(0L);
|
||||
}
|
||||
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
package org.sadtech.bot.bitbucketbot.service.impl;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.config.BitbucketConfig;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.User;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.sheet.PullRequestSheetJson;
|
||||
import org.sadtech.bot.bitbucketbot.exception.RegException;
|
||||
import org.sadtech.bot.bitbucketbot.repository.jpa.UserRepository;
|
||||
import org.sadtech.bot.bitbucketbot.service.UserService;
|
||||
import org.sadtech.bot.bitbucketbot.service.Utils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UserServiceImpl implements UserService {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final BitbucketConfig bitbucketConfig;
|
||||
|
||||
@Override
|
||||
public Optional<User> getByLogin(String login) {
|
||||
return userRepository.findById(login);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> existsByLogin(@NonNull Set<String> logins) {
|
||||
return logins.stream().filter(userRepository::existsById).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public User reg(@NonNull User user) {
|
||||
final Optional<User> optUser = userRepository.findByLogin(user.getLogin());
|
||||
if (optUser.isPresent()) {
|
||||
final User oldUser = optUser.get();
|
||||
if (oldUser.getTelegramId() == null) {
|
||||
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestClose(), user.getToken(), PullRequestSheetJson.class);
|
||||
if (sheetJson.isPresent()) {
|
||||
oldUser.setTelegramId(user.getTelegramId());
|
||||
return userRepository.save(oldUser);
|
||||
} else {
|
||||
throw new RegException("Ваш токен не валиден");
|
||||
}
|
||||
} else {
|
||||
throw new RegException("Вы уже авторизованы в системе");
|
||||
}
|
||||
}
|
||||
throw new RegException("Пользователь не найден, подождите обновление базы пользователей!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<User> addAll(Set<User> newUsers) {
|
||||
return userRepository.saveAll(newUsers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<User> getAllRegister() {
|
||||
return userRepository.findAllByTelegramIdNotNullAndTokenNotNull();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Long> getTelegramIdByLogin(@NonNull String login) {
|
||||
return Optional.ofNullable(userRepository.findTelegramIdByLogin(login));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getAllTelegramIdByLogin(Set<String> logins) {
|
||||
return userRepository.findAllTelegramIdByLogin(logins);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,213 @@
|
||||
package org.sadtech.bot.bitbucketbot.service.parser;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty;
|
||||
import org.sadtech.bot.bitbucketbot.config.properties.CommentSchedulerProperty;
|
||||
import org.sadtech.bot.bitbucketbot.domain.Answer;
|
||||
import org.sadtech.bot.bitbucketbot.domain.Pagination;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ChangeType;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.comment.AnswerCommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.comment.CommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.task.TaskChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Comment;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Task;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentJson;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.Severity;
|
||||
import org.sadtech.bot.bitbucketbot.service.ChangeService;
|
||||
import org.sadtech.bot.bitbucketbot.service.CommentService;
|
||||
import org.sadtech.bot.bitbucketbot.service.PersonService;
|
||||
import org.sadtech.bot.bitbucketbot.service.PullRequestsService;
|
||||
import org.sadtech.bot.bitbucketbot.service.TaskService;
|
||||
import org.sadtech.bot.bitbucketbot.service.Utils;
|
||||
import org.sadtech.bot.bitbucketbot.service.executor.DataScan;
|
||||
import org.sadtech.bot.bitbucketbot.service.executor.ResultScan;
|
||||
import org.sadtech.bot.bitbucketbot.service.impl.ExecutorScanner;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>Поиск новых комментариев и задач.</p>
|
||||
* <p>К несчастью, у битбакета не очень удобный API, и у них таска это то же самое что и комментарий, только с флагом</p>
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CommentAndTaskParser {
|
||||
|
||||
private static final Pattern PATTERN = Pattern.compile("@[\\w]+");
|
||||
|
||||
private final CommentService commentService;
|
||||
private final PullRequestsService pullRequestsService;
|
||||
private final PersonService personService;
|
||||
private final ChangeService changeService;
|
||||
private final ExecutorScanner executorScanner;
|
||||
private final TaskService taskService;
|
||||
private final ConversionService conversionService;
|
||||
|
||||
private final BitbucketProperty bitbucketProperty;
|
||||
private final CommentSchedulerProperty commentSchedulerProperty;
|
||||
|
||||
public void scanNewCommentAndTask() {
|
||||
long commentId = getLastIdCommentOrTask() + 1;
|
||||
int count = 0;
|
||||
do {
|
||||
final List<DataScan> dataScans = generatingLinksToPossibleComments(commentId);
|
||||
executorScanner.registration(dataScans);
|
||||
final List<ResultScan> resultScans = executorScanner.getResult();
|
||||
if (!resultScans.isEmpty()) {
|
||||
processingComments(resultScans);
|
||||
processingTasks(resultScans);
|
||||
count = 0;
|
||||
}
|
||||
} while (count++ < commentSchedulerProperty.getNoCommentCount());
|
||||
}
|
||||
|
||||
private long getLastIdCommentOrTask() {
|
||||
return Long.max(commentService.getLastCommentId(), taskService.getLastTaskId());
|
||||
}
|
||||
|
||||
private void processingComments(List<ResultScan> resultScans) {
|
||||
final List<Comment> newComments = commentService.createAll(getCommentsByResultScan(resultScans));
|
||||
newComments.forEach(this::notificationPersonal);
|
||||
}
|
||||
|
||||
private void processingTasks(List<ResultScan> resultScans) {
|
||||
final List<Task> newTasks = taskService.createAll(getTaskByResultScan(resultScans));
|
||||
newTasks.forEach(this::notificationNewTask);
|
||||
}
|
||||
|
||||
private List<DataScan> generatingLinksToPossibleComments(@NonNull Long commentId) {
|
||||
List<DataScan> commentUrls = new ArrayList<>();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
int page = 0;
|
||||
Page<PullRequest> pullRequestPage = pullRequestsService.getAll(
|
||||
Pagination.of(page, commentSchedulerProperty.getCommentCount())
|
||||
);
|
||||
while (pullRequestPage.hasContent()) {
|
||||
long finalCommentId = commentId;
|
||||
commentUrls.addAll(pullRequestPage.getContent().stream()
|
||||
.map(
|
||||
pullRequest -> new DataScan(
|
||||
getCommentUrl(finalCommentId, pullRequest),
|
||||
pullRequest.getId()
|
||||
)
|
||||
)
|
||||
.collect(Collectors.toList()));
|
||||
pullRequestPage = pullRequestsService.getAll(
|
||||
Pagination.of(++page, commentSchedulerProperty.getCommentCount())
|
||||
);
|
||||
}
|
||||
commentId++;
|
||||
}
|
||||
return commentUrls;
|
||||
}
|
||||
|
||||
private List<Comment> getCommentsByResultScan(List<ResultScan> resultScans) {
|
||||
return resultScans.stream()
|
||||
.filter(resultScan -> Severity.NORMAL.equals(resultScan.getCommentJson().getSeverity()))
|
||||
.map(resultScan -> conversionService.convert(resultScan, Comment.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<Task> getTaskByResultScan(List<ResultScan> resultScans) {
|
||||
return resultScans.stream()
|
||||
.filter(commentJson -> Severity.BLOCKER.equals(commentJson.getCommentJson().getSeverity()))
|
||||
.map(resultScan -> conversionService.convert(resultScan, Task.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String getCommentUrl(long commentId, PullRequest pullRequest) {
|
||||
return bitbucketProperty.getUrlPullRequestComment()
|
||||
.replace("{projectKey}", pullRequest.getProjectKey())
|
||||
.replace("{repositorySlug}", pullRequest.getRepositorySlug())
|
||||
.replace("{pullRequestId}", pullRequest.getBitbucketId().toString())
|
||||
.replace("{commentId}", String.valueOf(commentId));
|
||||
}
|
||||
|
||||
private void notificationPersonal(@NonNull Comment comment) {
|
||||
Matcher matcher = PATTERN.matcher(comment.getMessage());
|
||||
Set<String> recipientsLogins = new HashSet<>();
|
||||
while (matcher.find()) {
|
||||
final String login = matcher.group(0).replace("@", "");
|
||||
recipientsLogins.add(login);
|
||||
}
|
||||
final Set<Long> recipientsIds = personService.getAllTelegramIdByLogin(recipientsLogins);
|
||||
changeService.add(
|
||||
CommentChange.builder()
|
||||
.authorName(comment.getAuthor().getLogin())
|
||||
.url(comment.getUrl())
|
||||
.telegramIds(recipientsIds)
|
||||
.message(comment.getMessage())
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
private void notificationNewTask(@NonNull Task task) {
|
||||
changeService.add(
|
||||
TaskChange.builder()
|
||||
.authorName(task.getAuthor().getFullName())
|
||||
.messageTask(task.getDescription())
|
||||
.type(ChangeType.NEW_TASK)
|
||||
.url(task.getUrl())
|
||||
.telegramIds(Collections.singleton(task.getPullRequest().getAuthor().getTelegramId()))
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
public void scanOldComment() {
|
||||
@NonNull final List<Comment> comments = commentService.getAllBetweenDate(
|
||||
LocalDateTime.now().minusDays(10), LocalDateTime.now()
|
||||
);
|
||||
for (Comment oldComment : comments) {
|
||||
final Optional<CommentJson> optCommentJson = Utils.urlToJson(
|
||||
oldComment.getUrl(),
|
||||
bitbucketProperty.getToken(),
|
||||
CommentJson.class
|
||||
);
|
||||
final Comment newComment = commentService.update(conversionService.convert(oldComment, Comment.class));
|
||||
|
||||
if (optCommentJson.isPresent()) {
|
||||
final CommentJson commentJson = optCommentJson.get();
|
||||
notifyNewCommentAnswers(oldComment, newComment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyNewCommentAnswers(Comment oldComment, Comment newComment) {
|
||||
final Set<Long> oldAnswerIds = oldComment.getAnswers();
|
||||
final Set<Long> newAnswerIds = newComment.getAnswers();
|
||||
if (!newAnswerIds.isEmpty()) {
|
||||
final List<Comment> newAnswers = commentService.getAllById(newAnswerIds).stream()
|
||||
.filter(comment -> !oldAnswerIds.contains(comment.getId()))
|
||||
.collect(Collectors.toList());
|
||||
changeService.add(
|
||||
AnswerCommentChange.builder()
|
||||
.telegramIds(
|
||||
Collections.singleton(newComment.getAuthor().getTelegramId())
|
||||
)
|
||||
.url(newComment.getPullRequest().getUrl())
|
||||
.youMessage(newComment.getMessage())
|
||||
.answers(
|
||||
newAnswers.stream()
|
||||
.map(comment -> Answer.of(comment.getAuthor().getFullName(), comment.getMessage()))
|
||||
.collect(Collectors.toList())
|
||||
)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package org.sadtech.bot.bitbucketbot.service.parser;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Person;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.UserJson;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.sheet.UserSheetJson;
|
||||
import org.sadtech.bot.bitbucketbot.service.PersonService;
|
||||
import org.sadtech.bot.bitbucketbot.service.Utils;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PersonParser {
|
||||
|
||||
private final PersonService personService;
|
||||
private final ConversionService conversionService;
|
||||
|
||||
private final BitbucketProperty bitbucketProperty;
|
||||
|
||||
public void scanNewPerson() {
|
||||
Optional<UserSheetJson> sheetJson = Utils.urlToJson(bitbucketProperty.getUrlUsers(), bitbucketProperty.getToken(), UserSheetJson.class);
|
||||
while (sheetJson.isPresent() && sheetJson.get().hasContent()) {
|
||||
final UserSheetJson sheetUsers = sheetJson.get();
|
||||
final List<UserJson> users = sheetUsers.getValues();
|
||||
final Set<String> logins = users.stream().map(UserJson::getName).collect(Collectors.toSet());
|
||||
final Set<String> existsLogins = personService.existsByLogin(logins);
|
||||
final Set<Person> newUsers = users.stream()
|
||||
.filter(userJson -> !existsLogins.contains(userJson.getName()))
|
||||
.map(userJson -> conversionService.convert(userJson, Person.class))
|
||||
.collect(Collectors.toSet());
|
||||
if (!newUsers.isEmpty()) {
|
||||
personService.createAll(newUsers);
|
||||
}
|
||||
if (sheetUsers.getNextPageStart() != null) {
|
||||
sheetJson = Utils.urlToJson(bitbucketProperty.getUrlUsers() + sheetUsers.getNextPageStart(), bitbucketProperty.getToken(), UserSheetJson.class);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
package org.sadtech.bot.bitbucketbot.service.parser;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.sadtech.bot.bitbucketbot.config.properties.BitbucketProperty;
|
||||
import org.sadtech.bot.bitbucketbot.domain.IdAndStatusPr;
|
||||
import org.sadtech.bot.bitbucketbot.domain.PullRequestStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Person;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.sadtech.bot.bitbucketbot.domain.filter.PullRequestFilter;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.PullRequestJson;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.sheet.PullRequestSheetJson;
|
||||
import org.sadtech.bot.bitbucketbot.service.PersonService;
|
||||
import org.sadtech.bot.bitbucketbot.service.PullRequestsService;
|
||||
import org.sadtech.bot.bitbucketbot.service.Utils;
|
||||
import org.sadtech.bot.bitbucketbot.utils.Pair;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.DECLINED;
|
||||
import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.MERGED;
|
||||
import static org.sadtech.bot.bitbucketbot.domain.PullRequestStatus.OPEN;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PullRequestParser {
|
||||
|
||||
private static final Set<PullRequestStatus> STATUSES = Stream.of(MERGED, OPEN, DECLINED).collect(Collectors.toSet());
|
||||
|
||||
private final PullRequestsService pullRequestsService;
|
||||
private final PersonService personService;
|
||||
private final ConversionService conversionService;
|
||||
private final BitbucketProperty bitbucketProperty;
|
||||
|
||||
public void parsingOldPullRequest() {
|
||||
final Set<Long> existsId = pullRequestsService.getAllId(STATUSES).stream()
|
||||
.map(IdAndStatusPr::getId)
|
||||
.collect(Collectors.toSet());
|
||||
final Set<Long> openId = parsingPullRequest(bitbucketProperty.getUrlPullRequestOpen());
|
||||
final Set<Long> closeId = parsingPullRequest(bitbucketProperty.getUrlPullRequestClose());
|
||||
final Set<Long> newNotExistsId = existsId.stream()
|
||||
.filter(id -> !openId.contains(id) && !closeId.contains(id))
|
||||
.collect(Collectors.toSet());
|
||||
log.info("Открыты: " + Arrays.toString(openId.toArray()));
|
||||
log.info("Закрыты: " + Arrays.toString(closeId.toArray()));
|
||||
log.info("Не найдены: " + Arrays.toString(newNotExistsId.toArray()));
|
||||
if (!newNotExistsId.isEmpty()) {
|
||||
pullRequestsService.deleteAll(newNotExistsId);
|
||||
}
|
||||
}
|
||||
|
||||
private Set<Long> parsingPullRequest(@NonNull String url) {
|
||||
final List<Person> users = personService.getAllRegister();
|
||||
final Set<Long> ids = new HashSet<>();
|
||||
for (Person user : users) {
|
||||
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(url, user.getToken(), PullRequestSheetJson.class);
|
||||
while (sheetJson.isPresent() && sheetJson.get().hasContent()) {
|
||||
final PullRequestSheetJson jsonSheet = sheetJson.get();
|
||||
final List<PullRequest> existsPr = getExistsPr(jsonSheet.getValues());
|
||||
|
||||
ids.addAll(
|
||||
pullRequestsService.updateAll(existsPr).stream()
|
||||
.map(PullRequest::getId)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
|
||||
if (jsonSheet.getNextPageStart() != null) {
|
||||
sheetJson = Utils.urlToJson(url + jsonSheet.getNextPageStart(), bitbucketProperty.getToken(), PullRequestSheetJson.class);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
private List<PullRequest> getExistsPr(@NonNull List<PullRequestJson> pullRequestJsons) {
|
||||
return pullRequestJsons.stream()
|
||||
.filter(json -> pullRequestsService.existsByFilterQuery(bitbucketIdAndPullRequestId(json)))
|
||||
.map(pullRequestJson -> conversionService.convert(pullRequestJson, PullRequest.class))
|
||||
.peek(pullRequest -> pullRequestsService.getIdByBitbucketIdAndReposId(pullRequest.getBitbucketId(), pullRequest.getRepositoryId()).ifPresent(pullRequest::setId))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private PullRequestFilter bitbucketIdAndPullRequestId(PullRequestJson json) {
|
||||
return PullRequestFilter.builder()
|
||||
.bitbucketId(json.getId())
|
||||
.bitbucketRepositoryId(json.getFromRef().getRepository().getId())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
public void parsingNewPullRequest() {
|
||||
final List<Person> users = personService.getAllRegister();
|
||||
for (Person user : users) {
|
||||
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(bitbucketProperty.getUrlPullRequestOpen(), user.getToken(), PullRequestSheetJson.class);
|
||||
while (sheetJson.isPresent() && sheetJson.get().hasContent()) {
|
||||
final PullRequestSheetJson pullRequestBitbucketSheet = sheetJson.get();
|
||||
final List<PullRequest> newPullRequest = pullRequestBitbucketSheet.getValues().stream()
|
||||
.collect(Collectors.toMap(pullRequestJson -> new Pair<>(pullRequestJson.getId(), pullRequestJson.getFromRef().getRepository().getId()), pullRequestJson -> pullRequestJson))
|
||||
.values()
|
||||
.stream()
|
||||
.filter(pullRequestJson -> !pullRequestsService.existsByFilterQuery(bitbucketIdAndPullRequestId(pullRequestJson)))
|
||||
.map(pullRequestJson -> conversionService.convert(pullRequestJson, PullRequest.class))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
pullRequestsService.createAll(newPullRequest);
|
||||
|
||||
if (pullRequestBitbucketSheet.getNextPageStart() != null) {
|
||||
sheetJson = Utils.urlToJson(bitbucketProperty.getUrlPullRequestOpen() + pullRequestBitbucketSheet.getNextPageStart(), bitbucketProperty.getToken(), PullRequestSheetJson.class);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package org.sadtech.bot.bitbucketbot.utils;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import org.sadtech.bot.bitbucketbot.domain.ReviewerStatus;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.Change;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.NewPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.ReviewersPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.UpdatePrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Reviewer;
|
||||
import org.sadtech.bot.bitbucketbot.domain.util.ReviewerChange;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class ChangeGenerator {
|
||||
|
||||
public static NewPrChange create(@NonNull PullRequest newPullRequest) {
|
||||
return NewPrChange.builder()
|
||||
.author(newPullRequest.getAuthor().getFullName())
|
||||
.description(newPullRequest.getDescription())
|
||||
.title(newPullRequest.getTitle())
|
||||
.url(newPullRequest.getUrl())
|
||||
.telegramIds(
|
||||
newPullRequest.getReviewers().stream()
|
||||
.map(reviewer -> reviewer.getUser().getTelegramId())
|
||||
.collect(Collectors.toSet())
|
||||
)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static UpdatePrChange createUpdatePr(@NonNull PullRequest oldPullRequest, @NonNull PullRequest newPullRequest) {
|
||||
return UpdatePrChange.builder()
|
||||
.author(oldPullRequest.getAuthor().getFullName())
|
||||
.name(newPullRequest.getAuthor().getFullName())
|
||||
.telegramIds(
|
||||
newPullRequest.getReviewers().stream()
|
||||
.map(reviewer -> reviewer.getUser().getTelegramId())
|
||||
.collect(Collectors.toSet())
|
||||
)
|
||||
.url(newPullRequest.getUrl())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Change createReviewersPr(@NonNull PullRequest oldPullRequest, @NonNull PullRequest newPullRequest) {
|
||||
final Map<Long, Reviewer> oldReviewers = oldPullRequest.getReviewers().stream()
|
||||
.collect(Collectors.toMap(Reviewer::getId, reviewer -> reviewer));
|
||||
final Map<Long, Reviewer> newReviewers = newPullRequest.getReviewers().stream()
|
||||
.collect(Collectors.toMap(Reviewer::getId, reviewer -> reviewer));
|
||||
final List<ReviewerChange> reviewerChanges = new ArrayList<>();
|
||||
for (Reviewer newReviewer : newReviewers.values()) {
|
||||
if (oldReviewers.containsKey(newReviewer.getId())) {
|
||||
final Reviewer oldReviewer = oldReviewers.get(newReviewer.getId());
|
||||
final ReviewerStatus oldStatus = oldReviewer.getStatus();
|
||||
final ReviewerStatus newStatus = newReviewer.getStatus();
|
||||
if (!oldStatus.equals(newStatus)) {
|
||||
reviewerChanges.add(ReviewerChange.ofOld(oldReviewer.getUser().getFullName(), oldStatus, newStatus));
|
||||
}
|
||||
} else {
|
||||
reviewerChanges.add(ReviewerChange.ofNew(newReviewer.getUser().getFullName(), newReviewer.getStatus()));
|
||||
}
|
||||
}
|
||||
final Set<Long> oldIds = oldReviewers.keySet();
|
||||
oldIds.removeAll(newReviewers.keySet());
|
||||
reviewerChanges.addAll(
|
||||
oldReviewers.entrySet().stream()
|
||||
.filter(e -> oldIds.contains(e.getKey()))
|
||||
.map(e -> ReviewerChange.ofDeleted(e.getValue().getUser().getFullName()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
return ReviewersPrChange.builder()
|
||||
.title(newPullRequest.getTitle())
|
||||
.url(newPullRequest.getUrl())
|
||||
.telegramId(newPullRequest.getAuthor().getTelegramId())
|
||||
.reviewerChanges(reviewerChanges)
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package org.sadtech.bot.bitbucketbot.utils;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.sadtech.bot.bitbucketbot.domain.TaskStatus;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentState;
|
||||
import org.sadtech.bot.bitbucketbot.exception.NotFoundException;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class Converter {
|
||||
|
||||
public static TaskStatus taskStatus(CommentState commentState) {
|
||||
switch (commentState) {
|
||||
case OPEN:
|
||||
return TaskStatus.OPEN;
|
||||
case RESOLVED:
|
||||
return TaskStatus.RESOLVED;
|
||||
default:
|
||||
throw new NotFoundException("Неизвестный статус задачи");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,13 +1,14 @@
|
||||
package org.sadtech.bot.bitbucketbot.utils;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.AnswerCommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.CommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ConflictPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.NewPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.ReviewersPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.StatusPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.UpdatePrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.comment.AnswerCommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.comment.CommentChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.ConflictPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.NewPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.ReviewersPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.StatusPrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.pullrequest.UpdatePrChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.change.task.TaskChange;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.PullRequest;
|
||||
import org.sadtech.bot.bitbucketbot.domain.util.ReviewerChange;
|
||||
import org.sadtech.bot.bitbucketbot.dto.bitbucket.CommentJson;
|
||||
@ -40,7 +41,7 @@ public class Message {
|
||||
@NonNull
|
||||
public static String generate(NewPrChange newPrChange) {
|
||||
String message = Smile.FUN + " *Новый Pull Request*" + Smile.BR +
|
||||
link(newPrChange.getName(), newPrChange.getUrl()) +
|
||||
link(newPrChange.getTitle(), newPrChange.getUrl()) +
|
||||
Smile.HR;
|
||||
if (newPrChange.getDescription() != null && !"".equals(newPrChange.getDescription())) {
|
||||
message += newPrChange.getDescription() + Smile.HR;
|
||||
@ -51,7 +52,7 @@ public class Message {
|
||||
|
||||
public static String generate(@NonNull StatusPrChange change) {
|
||||
return Smile.PEN + " *Изменился статус вашего ПР*" + Smile.HR +
|
||||
link(change.getName(), change.getUrl()) + Smile.BR +
|
||||
link(change.getTitle(), change.getUrl()) + Smile.BR +
|
||||
change.getOldStatus().name() + " -> " + change.getNewStatus().name() +
|
||||
Smile.TWO_BR;
|
||||
}
|
||||
@ -89,13 +90,13 @@ public class Message {
|
||||
final String createMessage = stringBuilder.toString();
|
||||
return Smile.PEN + " *Изменения ревьюверов вашего ПР*" +
|
||||
Smile.HR +
|
||||
link(reviewersChange.getName(), reviewersChange.getUrl()) + Smile.BR +
|
||||
link(reviewersChange.getTitle(), reviewersChange.getUrl()) + Smile.BR +
|
||||
createMessage;
|
||||
}
|
||||
|
||||
public static String generate(@NonNull UpdatePrChange change) {
|
||||
return Smile.UPDATE + " *Обновление Pull Request*" + Smile.BR +
|
||||
link(change.getName(), change.getUrl()) +
|
||||
link(change.getTitle(), change.getUrl()) +
|
||||
Smile.HR +
|
||||
Smile.AUTHOR + ": " + change.getAuthor() +
|
||||
Smile.TWO_BR;
|
||||
@ -103,7 +104,7 @@ public class Message {
|
||||
|
||||
public static String generate(@NonNull ConflictPrChange change) {
|
||||
return Smile.DANGEROUS + "*Внимание конфликт в ПР*" + Smile.HR +
|
||||
link(change.getName(), change.getUrl()) + Smile.TWO_BR;
|
||||
link(change.getTitle(), change.getUrl()) + Smile.TWO_BR;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@ -132,7 +133,6 @@ public class Message {
|
||||
.append(Smile.BR);
|
||||
}
|
||||
message
|
||||
.append(Smile.BR)
|
||||
.append("Удачного дня ").append(Smile.FLOWER).append(Smile.TWO_BR);
|
||||
return message.toString();
|
||||
}
|
||||
@ -164,6 +164,21 @@ public class Message {
|
||||
return message.toString();
|
||||
}
|
||||
|
||||
public static String generateNewTask(@NonNull TaskChange newTaskChange) {
|
||||
return Smile.TASK + "*Назначена новая задача* | " + link("ПР", newTaskChange.getUrl()) + Smile.HR +
|
||||
newTaskChange.getAuthorName() + ": " + newTaskChange.getMessageTask();
|
||||
}
|
||||
|
||||
public static String generateDeleteTask(@NonNull TaskChange deletedTaskChange) {
|
||||
return Smile.TASK + "*Задача была удалена* | " + link("ПР", deletedTaskChange.getUrl()) + Smile.HR +
|
||||
deletedTaskChange.getAuthorName() + ": " + deletedTaskChange.getMessageTask();
|
||||
}
|
||||
|
||||
public static String generateResolveTask(@NonNull TaskChange deletedTaskChange) {
|
||||
return Smile.TASK + "*Задача выполнена* | " + link("ПР", deletedTaskChange.getUrl()) + Smile.HR +
|
||||
deletedTaskChange.getAuthorName() + ": " + deletedTaskChange.getMessageTask();
|
||||
}
|
||||
|
||||
private static String needWorkPr(@NonNull List<PullRequest> pullRequestsNeedWork) {
|
||||
final StringBuilder message = new StringBuilder();
|
||||
pullRequestsNeedWork.stream()
|
||||
|
@ -1,7 +1,7 @@
|
||||
package org.sadtech.bot.bitbucketbot.utils;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.User;
|
||||
import org.sadtech.bot.bitbucketbot.domain.entity.Person;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
@ -12,7 +12,7 @@ public class NonNullUtils {
|
||||
throw new IllegalStateException("Утилитный класс");
|
||||
}
|
||||
|
||||
public static Set<Long> telegramIdByUser(@NonNull User user) {
|
||||
public static Set<Long> telegramIdByUser(@NonNull Person user) {
|
||||
return user.getTelegramId() != null ? Collections.singleton(user.getTelegramId()) : Collections.emptySet();
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ public enum Smile {
|
||||
DAY_3("\uD83C\uDF18"),
|
||||
DAY_4("\uD83C\uDF11"),
|
||||
DAY_5("\uD83C\uDF1A"),
|
||||
TASK("\uD83E\uDD39\uD83C\uDFFB\u200D♂️"),
|
||||
MEGA_FUN("\uD83D\uDE02"),
|
||||
DANGEROUS("⚠️"),
|
||||
BELL("\uD83D\uDECE"),
|
||||
|
@ -17,8 +17,13 @@ spring:
|
||||
lob:
|
||||
non_contextual_creation: true
|
||||
bitbucketbot:
|
||||
scheduler:
|
||||
comment:
|
||||
settings:
|
||||
no-comment-count: 20
|
||||
comment-count: 100
|
||||
init:
|
||||
start-comment-id:
|
||||
start-comment-id: 5947
|
||||
server-send:
|
||||
url: http://188.225.35.149:8080/api/send
|
||||
bitbucket:
|
||||
@ -27,3 +32,4 @@ bitbucketbot:
|
||||
url-pull-request-close: http://192.168.236.164:7990/rest/api/1.0/dashboard/pull-requests?limit=150&closedSince=86400
|
||||
url-pull-request-comment: http://192.168.236.164:7990/rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
|
||||
url-pull-request: http://192.168.236.164:7990/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/overview
|
||||
url-users: http://192.168.236.164:7990/rest/api/1.0/admin/users
|
@ -27,3 +27,4 @@ bitbucketbot:
|
||||
url-pull-request-close: http://localhost:7990/rest/api/1.0/dashboard/pull-requests?limit=150&closedSince=86400
|
||||
url-pull-request-comment: http://localhost:7990/rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
|
||||
url-pull-request: http://localhost:7990/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/overview
|
||||
url-users: http://localhost:7990/rest/api/1.0/admin/users
|
@ -3,10 +3,6 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||
|
||||
<include file="liquibase/change-set/create-table.xml"/>
|
||||
<include file="liquibase/change-set/v1.2.0.xml"/>
|
||||
<include file="liquibase/change-set/v1.3.0.xml"/>
|
||||
<include file="liquibase/change-set/v1.4.0.xml"/>
|
||||
<include file="liquibase/change-set/v2.0.0.xml"/>
|
||||
<include file="liquibase/v.2.0.0/cumulative.xml"/>
|
||||
|
||||
</databaseChangeLog>
|
@ -1,55 +0,0 @@
|
||||
<databaseChangeLog
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||
|
||||
<changeSet id="create-table" author="upagge">
|
||||
<createTable tableName="user">
|
||||
<column name="login" type="varchar(50)">
|
||||
<constraints primaryKey="true"/>
|
||||
</column>
|
||||
<column name="token" type="varchar(200)"/>
|
||||
<column name="telegram_id" type="integer">
|
||||
<constraints unique="true"/>
|
||||
</column>
|
||||
</createTable>
|
||||
|
||||
<createTable tableName="pull_request">
|
||||
<column name="id" type="integer" autoIncrement="true">
|
||||
<constraints primaryKey="true"/>
|
||||
</column>
|
||||
<column name="bitbucket_pr_id" type="integer"/>
|
||||
<column name="repository_id" type="integer"/>
|
||||
<column name="author_login" type="varchar(100)">
|
||||
<constraints nullable="false"
|
||||
foreignKeyName="login"
|
||||
references="user(login)"/>
|
||||
</column>
|
||||
<column name="status" type="varchar(50)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="url" type="varchar(500)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="name" type="varchar(100)"/>
|
||||
</createTable>
|
||||
<addUniqueConstraint tableName="pull_request" columnNames="bitbucket_pr_id, repository_id"/>
|
||||
|
||||
<createTable tableName="reviewer">
|
||||
<column name="id" type="integer" autoIncrement="true">
|
||||
<constraints primaryKey="true"/>
|
||||
</column>
|
||||
<column name="pull_request_id" type="integer">
|
||||
<constraints foreignKeyName="fk_pull_request_id" references="pull_request(id)" deleteCascade="true"/>
|
||||
</column>
|
||||
<column name="user_login" type="varchar(100)">
|
||||
<constraints nullable="false"
|
||||
foreignKeyName="fk_user_login"
|
||||
references="user(login)"/>
|
||||
</column>
|
||||
<column name="status" type="varchar(50)"/>
|
||||
</createTable>
|
||||
<addUniqueConstraint tableName="reviewer" columnNames="pull_request_id, user_login"/>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
@ -1,34 +0,0 @@
|
||||
<databaseChangeLog
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||
|
||||
<changeSet id="v1.2.0-add-atribute-pr" author="upagge">
|
||||
<addColumn tableName="pull_request" schemaName="public" catalogName="pg_catalog">
|
||||
<column name="version" type="integer"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="default-version" author="upagge">
|
||||
<update tableName="pull_request" schemaName="public" catalogName="pg_catalog">
|
||||
<column name="version" value="0" type="integer"/>
|
||||
</update>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="date-update-pr" author="upagge">
|
||||
<addColumn tableName="pull_request" schemaName="public" catalogName="pg_catalog">
|
||||
<column name="create_date" type="date"/>
|
||||
</addColumn>
|
||||
|
||||
<addColumn tableName="pull_request" schemaName="public" catalogName="pg_catalog">
|
||||
<column name="update_date" type="date"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="user-fullname" author="upagge">
|
||||
<addColumn tableName="user" schemaName="public" catalogName="pg_catalog">
|
||||
<column name="full_name" type="varchar(50)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
@ -1,34 +0,0 @@
|
||||
<databaseChangeLog
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||
|
||||
<changeSet id="v1.3.0-add-column-pr" author="upagge">
|
||||
<addColumn tableName="pull_request" schemaName="public" catalogName="pg_catalog">
|
||||
<column name="project_key" type="varchar(50)"/>
|
||||
</addColumn>
|
||||
|
||||
<addColumn tableName="pull_request" schemaName="public" catalogName="pg_catalog">
|
||||
<column name="repository_slug" type="varchar(50)"/>
|
||||
</addColumn>
|
||||
|
||||
<createTable tableName="tech_info">
|
||||
<column name="surogat_id" type="int">
|
||||
<constraints primaryKey="true"/>
|
||||
</column>
|
||||
<column name="last_comment_id" type="int"/>
|
||||
</createTable>
|
||||
|
||||
<insert tableName="tech_info" schemaName="public" catalogName="pg_catalog">
|
||||
<column name="surogat_id" value="1"/>
|
||||
<column name="last_comment_id" value="4500"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="v1.3.0-add-pr-description" author="upagge">
|
||||
<addColumn tableName="pull_request" schemaName="public" catalogName="pg_catalog">
|
||||
<column name="description" type="varchar(200)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
@ -1,54 +0,0 @@
|
||||
<databaseChangeLog
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||
|
||||
<changeSet id="create-table-comments" author="upagge">
|
||||
<createTable tableName="comment">
|
||||
<column name="id" type="int" autoIncrement="true">
|
||||
<constraints primaryKey="true"/>
|
||||
</column>
|
||||
<column name="url" type="varchar(300)"/>
|
||||
<column name="telegram" type="integer"/>
|
||||
<column name="date" type="datetime"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="create-table-comment-tree" author="upagge">
|
||||
<createTable tableName="comment_tree">
|
||||
<column name="parent_id" type="int">
|
||||
<constraints foreignKeyName="fk_parent_id_from_comment_id" references="comment(id)" nullable="false"/>
|
||||
</column>
|
||||
<column name="child_id" type="int">
|
||||
<constraints foreignKeyName="fk_child_id_from_comment_id" references="comment(id)" nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<addPrimaryKey tableName="comment_tree" columnNames="parent_id, child_id"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="drop-table" author="upagge">
|
||||
<dropTable tableName="tech_info"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="dropForeignKeyConstraint-comment" author="upagge">
|
||||
<dropForeignKeyConstraint baseTableName="comment_tree" constraintName="fk_child_id_from_comment_id"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="modifyDataType-date-up-pr" author="upagge">
|
||||
<modifyDataType catalogName="pg_catalog"
|
||||
columnName="create_date"
|
||||
newDataType="datetime"
|
||||
schemaName="public"
|
||||
tableName="pull_request"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="modifyDataType-date-create-pr" author="upagge">
|
||||
<modifyDataType catalogName="pg_catalog"
|
||||
columnName="update_date"
|
||||
newDataType="datetime"
|
||||
schemaName="public"
|
||||
tableName="pull_request"/>
|
||||
</changeSet>
|
||||
|
||||
|
||||
</databaseChangeLog>
|
@ -1,24 +0,0 @@
|
||||
<databaseChangeLog
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||
|
||||
<changeSet id="add-column-pr-conflict" author="upagge">
|
||||
<addColumn tableName="pull_request" schemaName="public" catalogName="pg_catalog">
|
||||
<column name="conflict" type="boolean"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="default-pr-conflict" author="upagge">
|
||||
<update tableName="pull_request" schemaName="public" catalogName="pg_catalog">
|
||||
<column name="conflict" value="false" type="boolean"/>
|
||||
</update>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="add-column-comment-pr_url" author="upagge">
|
||||
<addColumn tableName="comment" schemaName="public" catalogName="pg_catalog">
|
||||
<column name="pr_url" type="varchar(300)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
162
src/main/resources/liquibase/v.2.0.0/create-table.xml
Normal file
162
src/main/resources/liquibase/v.2.0.0/create-table.xml
Normal file
@ -0,0 +1,162 @@
|
||||
<databaseChangeLog
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||
|
||||
<changeSet id="create-table-person" author="upagge">
|
||||
<createTable tableName="person">
|
||||
<column name="login" type="varchar(64)">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
<column name="full_name" type="varchar(100)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="bitbucket_token" type="varchar(200)"/>
|
||||
<column name="telegram_id" type="integer">
|
||||
<constraints unique="true"/>
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="create-table-pull-request" author="upagge">
|
||||
<createTable tableName="pull_request">
|
||||
<column name="id" type="integer" autoIncrement="true">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
<column name="bitbucket_id" type="integer">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="repository_id" type="integer"/>
|
||||
<column name="project_key" type="varchar(100)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="repository_slug" type="varchar(100)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="title" type="varchar(100)"/>
|
||||
<column name="description" type="varchar(300)"/>
|
||||
<column name="author_login" type="varchar(64)">
|
||||
<constraints nullable="false"
|
||||
foreignKeyName="pull_request_author_login_person_login"
|
||||
references="person(login)" deleteCascade="true"/>
|
||||
</column>
|
||||
<column name="status" type="varchar(50)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="url" type="varchar(500)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="conflict" type="boolean">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="bitbucket_version" type="int">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="create_date" type="datetime">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="update_date" type="datetime">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
|
||||
<addUniqueConstraint tableName="pull_request" columnNames="bitbucket_pr_id, repository_id"/>
|
||||
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="create-table-pull-request-reviewer" author="upagge">
|
||||
<createTable tableName="pull_request_reviewer">
|
||||
<column name="id" type="integer" autoIncrement="true">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
<column name="pull_request_id" type="integer">
|
||||
<constraints nullable="false" foreignKeyName="pull_request_reviewer_pull_request_id_pull_request_id"
|
||||
references="pull_request(id)" deleteCascade="true"/>
|
||||
</column>
|
||||
<column name="user_login" type="varchar(64)">
|
||||
<constraints nullable="false"
|
||||
foreignKeyName="pull_request_reviewer_user_id_user_login"
|
||||
references="person(login)" deleteCascade="true"/>
|
||||
</column>
|
||||
<column name="status" type="varchar(50)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
|
||||
<addUniqueConstraint tableName="reviewer" columnNames="pull_request_id, user_login"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="create-table-comments" author="upagge">
|
||||
<createTable tableName="pull_request_comment">
|
||||
<column name="id" type="int">
|
||||
<constraints primaryKey="true"/>
|
||||
</column>
|
||||
<column name="url" type="varchar(300)"/>
|
||||
<column name="author_login" type="integer">
|
||||
<constraints nullable="false" foreignKeyName="pull_request_task_author_login_person_login"
|
||||
references="person(login)" deleteCascade="true"/>
|
||||
</column>
|
||||
<column name="pull_request_id" type="integer">
|
||||
<constraints nullable="false" foreignKeyName="pull_request_comment_pull_request_id_pull_request_id"
|
||||
references="pull_request(id)" deleteCascade="true"/>
|
||||
</column>
|
||||
<column name="message" type="varchar(500)"/>
|
||||
<column name="create_date" type="datetime">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="bitbucket_version" type="int">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="create-table-comment-tree" author="upagge">
|
||||
<createTable tableName="comment_tree">
|
||||
<column name="parent_id" type="int">
|
||||
<constraints foreignKeyName="fk_parent_id_from_comment_id" references="comment(id)" nullable="false"
|
||||
deleteCascade="true"/>
|
||||
</column>
|
||||
<column name="child_id" type="int">
|
||||
<constraints foreignKeyName="fk_child_id_from_comment_id" references="comment(id)" nullable="false"
|
||||
deleteCascade="true"/>
|
||||
</column>
|
||||
</createTable>
|
||||
|
||||
<addPrimaryKey tableName="comment_tree" columnNames="parent_id, child_id"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="create-table-task" author="upagge">
|
||||
<createTable tableName="pull_request_task">
|
||||
<column name="id" type="integer" autoIncrement="true">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
<column name="description" type="varchar(500)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="status" type="varchar(64)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="url" type="varchar(300)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="url_api" type="varchar(300)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="author_login" type="varchar(64)">
|
||||
<constraints nullable="false" foreignKeyName="pull_request_task_author_login_person_login"
|
||||
references="person(login)" deleteCascade="true"/>
|
||||
</column>
|
||||
<column name="pull_request_id" type="int">
|
||||
<constraints nullable="true" foreignKeyName="pull_request_task_pull_request_id_pull_request_id"
|
||||
references="pull_request(id)" deleteCascade="true"/>
|
||||
</column>
|
||||
<column name="create_date" type="datetime">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="bitbucket_version" type="int">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
8
src/main/resources/liquibase/v.2.0.0/cumulative.xml
Normal file
8
src/main/resources/liquibase/v.2.0.0/cumulative.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<databaseChangeLog
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||
|
||||
<include file="liquibase/v.2.0.0/create-table.xml"/>
|
||||
|
||||
</databaseChangeLog>
|
@ -18,7 +18,7 @@
|
||||
</appender>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="FILE"/>
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
Loading…
Reference in New Issue
Block a user