Большой рефакторинг

This commit is contained in:
upagge 2020-04-07 10:43:54 +03:00
parent d1f3bcebb0
commit 8bc397dc8c
No known key found for this signature in database
GPG Key ID: 15CD012E46F6BA34
15 changed files with 230 additions and 106 deletions

View File

@ -7,6 +7,6 @@ package com.tsc.bitbucketbot.domain;
*/ */
public enum PullRequestStatus { public enum PullRequestStatus {
OPEN, MERGED, DECLINED OPEN, MERGED, DECLINED, DELETE
} }

View File

@ -0,0 +1,16 @@
package com.tsc.bitbucketbot.dto;
import com.tsc.bitbucketbot.domain.PullRequestStatus;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
@AllArgsConstructor
public class IdAndStatusPr {
private Long id;
private PullRequestStatus status;
}

View File

@ -1,19 +1,20 @@
package com.tsc.bitbucketbot.repository.jpa; package com.tsc.bitbucketbot.repository.jpa;
import com.tsc.bitbucketbot.domain.PullRequestStatus;
import com.tsc.bitbucketbot.domain.ReviewerStatus; import com.tsc.bitbucketbot.domain.ReviewerStatus;
import com.tsc.bitbucketbot.domain.entity.PullRequest; import com.tsc.bitbucketbot.domain.entity.PullRequest;
import com.tsc.bitbucketbot.dto.IdAndStatusPr;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
/** /**
* TODO: Добавить описание интерфейса.
*
* @author upagge [31.01.2020] * @author upagge [31.01.2020]
*/ */
public interface PullRequestsRepository extends JpaRepository<PullRequest, Long> { public interface PullRequestsRepository extends JpaRepository<PullRequest, Long> {
@ -33,7 +34,13 @@ 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") @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); List<PullRequest> findAllByAuthorAndReviewerStatus(@Param("author") String author, @Param("reviewerStatus") ReviewerStatus reviewerStatus);
@Query("SELECT new com.tsc.bitbucketbot.dto.IdAndStatusPr(p.id, p.status) FROM PullRequest p WHERE p.status IN :statuses")
Set<IdAndStatusPr> findAllIdByStatusIn(@Param("statuses") Collection<PullRequestStatus> statuses);
@Query("SELECT p.id from PullRequest p") @Query("SELECT p.id from PullRequest p")
Set<Long> getAllIds(); Set<Long> findAllIds();
@Query("SELECT p FROM PullRequest p WHERE p.author.login = :login AND p.createDate BETWEEN :dateFrom AND :dateTo")
List<PullRequest> findAllByAuthorAndDateBetween(@Param("login") String login, @Param("dateFrom") LocalDateTime dateFrom, @Param("dateTo") LocalDateTime dateTo);
} }

View File

@ -6,6 +6,7 @@ import com.tsc.bitbucketbot.domain.entity.PullRequest;
import com.tsc.bitbucketbot.domain.entity.User; import com.tsc.bitbucketbot.domain.entity.User;
import com.tsc.bitbucketbot.service.MessageSendService; import com.tsc.bitbucketbot.service.MessageSendService;
import com.tsc.bitbucketbot.service.PullRequestsService; import com.tsc.bitbucketbot.service.PullRequestsService;
import com.tsc.bitbucketbot.service.ReportService;
import com.tsc.bitbucketbot.service.UserService; import com.tsc.bitbucketbot.service.UserService;
import com.tsc.bitbucketbot.utils.Message; import com.tsc.bitbucketbot.utils.Message;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -21,6 +22,7 @@ public class SchedulerNotification {
private final UserService userService; private final UserService userService;
private final PullRequestsService pullRequestsService; private final PullRequestsService pullRequestsService;
private final MessageSendService messageSendService; private final MessageSendService messageSendService;
private final ReportService reportService;
// Утреннее сообщение // Утреннее сообщение
@Scheduled(cron = "0 15 8 * * MON-FRI") @Scheduled(cron = "0 15 8 * * MON-FRI")
@ -41,17 +43,26 @@ public class SchedulerNotification {
} }
} }
@Scheduled(cron = "0 0 18 * * FRI") // @Scheduled(cron = "0 0 18 * * FRI")
// @Scheduled(fixedRate = 30000)
public void goodWeekEnd() { public void goodWeekEnd() {
List<User> allRegister = userService.getAllRegister(); // List<User> allRegister = userService.getAllRegister();
for (User user : allRegister) { // for (User user : allRegister) {
messageSendService.add( // messageSendService.add(
MessageSend.builder() // MessageSend.builder()
.telegramId(user.getTelegramId()) // .telegramId(user.getTelegramId())
.message(Message.goodWeekEnd()) // .message(Message.goodWeekEnd())
.build() // .build()
); // );
} // reportService.generateReport(user.getLogin());
// }
final User user = userService.getByLogin("mstruchkov").get();
messageSendService.add(
MessageSend.builder()
.telegramId(user.getTelegramId())
.message(reportService.generateReport(user.getLogin()))
.build()
);
} }
} }

View File

@ -8,13 +8,11 @@ import com.tsc.bitbucketbot.domain.entity.PullRequest;
import com.tsc.bitbucketbot.domain.entity.Reviewer; import com.tsc.bitbucketbot.domain.entity.Reviewer;
import com.tsc.bitbucketbot.domain.entity.User; import com.tsc.bitbucketbot.domain.entity.User;
import com.tsc.bitbucketbot.domain.util.ReviewerChange; import com.tsc.bitbucketbot.domain.util.ReviewerChange;
import com.tsc.bitbucketbot.dto.bitbucket.PullRequestJson;
import com.tsc.bitbucketbot.dto.bitbucket.sheet.PullRequestSheetJson; import com.tsc.bitbucketbot.dto.bitbucket.sheet.PullRequestSheetJson;
import com.tsc.bitbucketbot.service.MessageSendService; import com.tsc.bitbucketbot.service.MessageSendService;
import com.tsc.bitbucketbot.service.PullRequestsService; import com.tsc.bitbucketbot.service.PullRequestsService;
import com.tsc.bitbucketbot.service.UserService; import com.tsc.bitbucketbot.service.UserService;
import com.tsc.bitbucketbot.service.Utils; import com.tsc.bitbucketbot.service.Utils;
import com.tsc.bitbucketbot.service.converter.PullRequestJsonConverter;
import com.tsc.bitbucketbot.utils.Message; import com.tsc.bitbucketbot.utils.Message;
import com.tsc.bitbucketbot.utils.Pair; import com.tsc.bitbucketbot.utils.Pair;
import com.tsc.bitbucketbot.utils.Smile; import com.tsc.bitbucketbot.utils.Smile;
@ -35,8 +33,6 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* TODO: Добавить описание класса.
*
* @author upagge [30.01.2020] * @author upagge [30.01.2020]
*/ */
@Service @Service
@ -51,53 +47,60 @@ public class SchedulerPullRequest {
@Scheduled(fixedRate = 30000) @Scheduled(fixedRate = 30000)
public void checkOldPullRequest() { public void checkOldPullRequest() {
Set<Long> existsId = pullRequestsService.getAllId(); final Set<Long> existsId = pullRequestsService.getAllId();
Set<Long> openId = checkOpenPullRequest(); final Set<Long> openId = checkOpenPullRequest();
checkClosePullRequest(); final Set<Long> closeId = checkClosePullRequest();
existsId.removeAll(openId); final Set<Long> newNotExistsId = existsId.stream()
if (!existsId.isEmpty()) { .filter(id -> !openId.contains(id) && !closeId.contains(id))
pullRequestsService.deleteAll(existsId); .collect(Collectors.toSet());
if (!newNotExistsId.isEmpty()) {
updateDeletePr(newNotExistsId);
} }
} }
private void checkClosePullRequest() { private void updateDeletePr(@NonNull Set<Long> ids) {
final Set<PullRequest> deletePr = pullRequestsService.getAllById(ids);
deletePr.stream()
.filter(pullRequest -> pullRequest.getAuthor().getTelegramId() != null)
.forEach(pullRequest -> messageSendService.add(
MessageSend.builder()
.telegramId(pullRequest.getAuthor().getTelegramId())
.message(Message.statusPullRequest(pullRequest.getName(), pullRequest.getUrl(), pullRequest.getStatus(), PullRequestStatus.DELETE))
.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 List<User> users = userService.getAllRegister();
final Set<Long> ids = new HashSet<>();
for (User user : users) { for (User user : users) {
Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestClose(), user.getToken(), PullRequestSheetJson.class); Optional<PullRequestSheetJson> sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestClose(), user.getToken(), PullRequestSheetJson.class);
while (sheetJson.isPresent() && sheetJson.get().getValues() != null && !sheetJson.get().getValues().isEmpty()) { while (sheetJson.isPresent() && sheetJson.get().getValues() != null && !sheetJson.get().getValues().isEmpty()) {
final PullRequestSheetJson bitbucketSheet = sheetJson.get(); final PullRequestSheetJson bitbucketSheet = sheetJson.get();
final List<PullRequestJson> jsonsPr = bitbucketSheet.getValues().stream() final List<PullRequest> newPrs = bitbucketSheet.getValues().stream()
.filter( .map(jsonPr -> conversionService.convert(jsonPr, PullRequest.class))
jsonPr -> pullRequestsService.existsByBitbucketIdAndReposId( .peek(pullRequest -> pullRequestsService.getIdByBitbucketIdAndReposId(pullRequest.getBitbucketId(), pullRequest.getRepositoryId()).ifPresent(pullRequest::setId))
jsonPr.getId(), .filter(pullRequest -> pullRequest.getId() != null)
jsonPr.getFromRef().getRepository().getId()
)
)
.collect(Collectors.toList()); .collect(Collectors.toList());
final Set<Long> idPr = jsonsPr.stream() for (PullRequest pullRequest : newPrs) {
.map( final User author = pullRequest.getAuthor();
jsonPr -> pullRequestsService.getIdByBitbucketIdAndReposId( final Long telegramId = author.getTelegramId();
jsonPr.getId(), if (telegramId != null) {
jsonPr.getFromRef().getRepository().getId() final String message = Message.statusPullRequest(pullRequest.getName(), pullRequest.getUrl(), PullRequestStatus.OPEN, pullRequest.getStatus());
) messageSendService.add(MessageSend.builder().telegramId(telegramId).message(message).build());
)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toSet());
for (PullRequestJson jsonPr : jsonsPr) {
final Optional<User> optUser = userService.getByLogin(jsonPr.getAuthor().getUser().getName());
if (optUser.isPresent()) {
final User author = optUser.get();
final Long telegramId = author.getTelegramId();
if (telegramId != null) {
final PullRequestStatus statusPr = PullRequestJsonConverter.convertPullRequestStatus(jsonPr.getState());
final String message = Message.statusPullRequest(jsonPr.getTitle(), jsonPr.getLinks().getSelf().get(0).getHref(), PullRequestStatus.OPEN, statusPr);
messageSendService.add(MessageSend.builder().telegramId(telegramId).message(message).build());
}
} }
} }
pullRequestsService.deleteAll(idPr); ids.addAll(
pullRequestsService.updateAll(newPrs).stream()
.map(PullRequest::getId)
.collect(Collectors.toSet())
);
if (bitbucketSheet.getNextPageStart() != null) { if (bitbucketSheet.getNextPageStart() != null) {
sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestClose() + bitbucketSheet.getNextPageStart(), bitbucketConfig.getToken(), PullRequestSheetJson.class); sheetJson = Utils.urlToJson(bitbucketConfig.getUrlPullRequestClose() + bitbucketSheet.getNextPageStart(), bitbucketConfig.getToken(), PullRequestSheetJson.class);
@ -106,6 +109,7 @@ public class SchedulerPullRequest {
} }
} }
} }
return ids;
} }
private Set<Long> checkOpenPullRequest() { private Set<Long> checkOpenPullRequest() {

View File

@ -1,15 +0,0 @@
package com.tsc.bitbucketbot.scheduler;
import com.tsc.bitbucketbot.service.ReportService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
@RequiredArgsConstructor
public class SchedulerReport {
public final ReportService reportService;
}

View File

@ -6,6 +6,7 @@ import com.tsc.bitbucketbot.domain.entity.PullRequest;
import lombok.NonNull; import lombok.NonNull;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -36,4 +37,6 @@ public interface PullRequestsService {
Page<PullRequest> getAll(@NonNull Pagination pagination); Page<PullRequest> getAll(@NonNull Pagination pagination);
List<PullRequest> getAllByAuthor(@NonNull String login, @NonNull LocalDateTime dateFrom, @NonNull LocalDateTime dateTo);
} }

View File

@ -1,4 +1,9 @@
package com.tsc.bitbucketbot.service; package com.tsc.bitbucketbot.service;
import lombok.NonNull;
public interface ReportService { public interface ReportService {
String generateReport(@NonNull String login);
} }

View File

@ -12,6 +12,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -72,7 +73,7 @@ public class PullRequestsServiceImpl implements PullRequestsService {
@Override @Override
public Set<Long> getAllId() { public Set<Long> getAllId() {
return pullRequestsRepository.getAllIds(); return pullRequestsRepository.findAllIds();
} }
@Override @Override
@ -80,4 +81,10 @@ public class PullRequestsServiceImpl implements PullRequestsService {
return pullRequestsRepository.findAll(PageRequest.of(pagination.getPage(), pagination.getSize())); return pullRequestsRepository.findAll(PageRequest.of(pagination.getPage(), pagination.getSize()));
} }
@Override
public List<PullRequest> getAllByAuthor(@NonNull String login, @NonNull LocalDateTime dateFrom, @NonNull LocalDateTime dateTo) {
return pullRequestsRepository.findAllByAuthorAndDateBetween(login, dateFrom, dateTo);
}
} }

View File

@ -1,9 +0,0 @@
package com.tsc.bitbucketbot.service.impl;
import com.tsc.bitbucketbot.service.ReportService;
import org.springframework.stereotype.Service;
@Service
public class ReportServiceImpl implements ReportService {
}

View File

@ -0,0 +1,66 @@
package com.tsc.bitbucketbot.service.impl;
import com.tsc.bitbucketbot.domain.entity.PullRequest;
import com.tsc.bitbucketbot.service.PullRequestsService;
import com.tsc.bitbucketbot.service.ReportService;
import com.tsc.bitbucketbot.utils.Smile;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class ReportServiceSimple implements ReportService {
private final PullRequestsService pullRequestsService;
@Override
public String generateReport(@NonNull String login) {
final LocalDateTime now = LocalDateTime.now();
final Map<LocalDate, List<PullRequest>> prByDay = pullRequestsService.getAllByAuthor(login, now.minusDays(7L), now).stream()
.collect(Collectors.groupingBy(pullRequest -> pullRequest.getUpdateDate().toLocalDate()));
return generateMessage(prByDay).orElse("Кажется эту неделю ты не работал");
}
private Optional<String> generateMessage(@NonNull Map<LocalDate, List<PullRequest>> prByDay) {
if (!prByDay.isEmpty()) {
final StringBuilder message = new StringBuilder("Твой отчет на эту неделю:").append(Smile.TWO_BR);
for (Map.Entry<LocalDate, List<PullRequest>> entry : prByDay.entrySet()) {
message.append(dayOfWeek(entry.getKey())).append(": ");
for (PullRequest pullRequest : entry.getValue()) {
message.append(" - ").append(pullRequest.getName()).append(Smile.BR)
.append(" --").append(pullRequest.getDescription());
}
}
}
return Optional.empty();
}
private String dayOfWeek(LocalDate date) {
switch (date.getDayOfWeek()) {
case MONDAY:
return "Понедельник";
case SUNDAY:
return "Воскресенье";
case TUESDAY:
return "Вторник";
case SATURDAY:
return "Суббота";
case THURSDAY:
return "Четверг";
case WEDNESDAY:
return "Среда";
case FRIDAY:
return "Пятница";
}
return "";
}
}

View File

@ -0,0 +1,29 @@
spring:
datasource:
url: jdbc:postgresql://localhost:5432/bitbucket_bot
username: postgres
driver-class-name: org.postgresql.Driver
password: 121314Ma
liquibase:
change-log: classpath:liquibase/change-log.xml
jpa:
show-sql: false
hibernate:
ddl-auto: none
database-platform: org.hibernate.dialect.PostgreSQLDialect
properties:
hibernate:
jdbc:
lob:
non_contextual_creation: true
bitbucketbot:
init:
start-comment-id:
server-send:
url: http://188.225.35.149:8080/api/send
bitbucket:
token: Nzg5NjUyNDQwMzk2OlA+6naQz02+GxOG0Q9li/jnsn7E
url-pull-request-open: http://192.168.236.164:7990/rest/api/1.0/dashboard/pull-requests?limit=150&state=OPEN
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

View File

@ -0,0 +1,27 @@
spring:
datasource:
url: jdbc:postgresql://localhost:5432/bitbucket_bot
username: postgres
driver-class-name: org.postgresql.Driver
password:
liquibase:
change-log: classpath:liquibase/change-log.xml
jpa:
show-sql: false
hibernate:
ddl-auto: none
database-platform: org.hibernate.dialect.PostgreSQLDialect
properties:
hibernate:
jdbc:
lob:
non_contextual_creation: true
bitbucketbot:
server-send:
url: http://188.225.35.149:8080/api/send
bitbucket:
token: Nzg5NjUyNDQwMzk2OlA+6naQz02+GxOG0Q9li/jnsn7E
url-pull-request-open: http://localhost:7990/rest/api/1.0/dashboard/pull-requests?limit=150&state=OPEN
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

View File

@ -1,29 +1,2 @@
spring:
datasource:
url: jdbc:postgresql://localhost:5432/bitbucket_bot
username: postgres
driver-class-name: org.postgresql.Driver
password:
liquibase:
change-log: classpath:liquibase/change-log.xml
jpa:
show-sql: false
hibernate:
ddl-auto: none
database-platform: org.hibernate.dialect.PostgreSQLDialect
properties:
hibernate:
jdbc:
lob:
non_contextual_creation: true
bitbucketbot:
server-send:
url: http://188.225.35.149:8080/api/send
bitbucket:
token: Nzg5NjUyNDQwMzk2OlA+6naQz02+GxOG0Q9li/jnsn7E
url-pull-request-open: http://localhost:7990/rest/api/1.0/dashboard/pull-requests?limit=150&state=OPEN
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
server: server:
port: 8018 port: 8018

View File

@ -18,7 +18,7 @@
</appender> </appender>
<root level="info"> <root level="info">
<appender-ref ref="FILE"/> <appender-ref ref="STDOUT"/>
</root> </root>
</configuration> </configuration>