Переход на gitlab-sdk

This commit is contained in:
Struchkov Mark 2024-08-23 23:37:36 +03:00
parent 58fed44e04
commit fb8a7e8a53
No known key found for this signature in database
GPG Key ID: A3F0AC3F0FA52F3C
47 changed files with 68 additions and 1377 deletions

View File

@ -56,17 +56,17 @@
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>dev.struchkov.bot.gitlab</groupId>
<artifactId>gitlab-sdk</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>dev.struchkov.sdk.gitlab</groupId>
<artifactId>gitlab-sdk-spring-boot-starter</artifactId>
</dependency>
<dependency>

View File

@ -1,7 +1,7 @@
package dev.struchkov.bot.gitlab.core.convert;
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
import dev.struchkov.bot.gitlab.sdk.domain.json.DiscussionJson;
import dev.struchkov.sdk.gitlab.schema.note.DiscussionJson;
import lombok.RequiredArgsConstructor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

View File

@ -3,9 +3,9 @@ package dev.struchkov.bot.gitlab.core.convert;
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
import dev.struchkov.bot.gitlab.sdk.domain.json.MergeRequestJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.MergeRequestStateJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.PersonJson;
import dev.struchkov.sdk.gitlab.schema.common.PersonJson;
import dev.struchkov.sdk.gitlab.schema.mergerequest.MergeRequestJson;
import dev.struchkov.sdk.gitlab.schema.mergerequest.MergeRequestStateJson;
import lombok.RequiredArgsConstructor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

View File

@ -1,7 +1,7 @@
package dev.struchkov.bot.gitlab.core.convert;
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
import dev.struchkov.bot.gitlab.sdk.domain.json.NoteJson;
import dev.struchkov.sdk.gitlab.schema.note.NoteJson;
import lombok.RequiredArgsConstructor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

View File

@ -1,7 +1,7 @@
package dev.struchkov.bot.gitlab.core.convert;
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
import dev.struchkov.bot.gitlab.sdk.domain.json.PersonJson;
import dev.struchkov.sdk.gitlab.schema.common.PersonJson;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

View File

@ -2,8 +2,8 @@ package dev.struchkov.bot.gitlab.core.convert;
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
import dev.struchkov.bot.gitlab.sdk.domain.json.PipelineJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.PipelineStatusJson;
import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineJson;
import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineStatusJson;
import lombok.RequiredArgsConstructor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

View File

@ -1,7 +1,7 @@
package dev.struchkov.bot.gitlab.core.convert;
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
import dev.struchkov.bot.gitlab.sdk.domain.json.ProjectJson;
import dev.struchkov.sdk.gitlab.schema.repository.ProjectJson;
import lombok.RequiredArgsConstructor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

View File

@ -7,9 +7,9 @@ import dev.struchkov.bot.gitlab.context.domain.entity.Note;
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
import dev.struchkov.bot.gitlab.sdk.GitlabSdkManager;
import dev.struchkov.bot.gitlab.sdk.config.GitlabUrl;
import dev.struchkov.bot.gitlab.sdk.domain.json.DiscussionJson;
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
import dev.struchkov.sdk.gitlab.domain.GitlabUrl;
import dev.struchkov.sdk.gitlab.schema.note.DiscussionJson;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.ConversionService;

View File

@ -6,11 +6,11 @@ import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
import dev.struchkov.bot.gitlab.context.service.ProjectService;
import dev.struchkov.bot.gitlab.sdk.GitlabSdkManager;
import dev.struchkov.bot.gitlab.sdk.domain.json.ApprovalJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.CommitJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.MergeRequestJson;
import dev.struchkov.haiti.utils.container.Pair;
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
import dev.struchkov.sdk.gitlab.schema.approval.ApprovalJson;
import dev.struchkov.sdk.gitlab.schema.mergerequest.MergeRequestJson;
import dev.struchkov.sdk.gitlab.schema.repository.CommitJson;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.ConversionService;

View File

@ -5,9 +5,9 @@ import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
import dev.struchkov.bot.gitlab.context.service.PipelineService;
import dev.struchkov.bot.gitlab.context.service.ProjectService;
import dev.struchkov.bot.gitlab.sdk.GitlabSdkManager;
import dev.struchkov.bot.gitlab.sdk.domain.json.PipelineShortJson;
import dev.struchkov.haiti.utils.container.Pair;
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineShortJson;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.ConversionService;

View File

@ -5,9 +5,9 @@ import dev.struchkov.bot.gitlab.context.domain.entity.Person;
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
import dev.struchkov.bot.gitlab.context.service.PersonService;
import dev.struchkov.bot.gitlab.context.service.ProjectService;
import dev.struchkov.bot.gitlab.sdk.GitlabSdkManager;
import dev.struchkov.bot.gitlab.sdk.domain.GitlabProjectParam;
import dev.struchkov.bot.gitlab.sdk.domain.json.ProjectJson;
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
import dev.struchkov.sdk.gitlab.domain.GitlabProjectParam;
import dev.struchkov.sdk.gitlab.schema.repository.ProjectJson;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.ConversionService;

View File

@ -14,8 +14,8 @@ import dev.struchkov.bot.gitlab.context.repository.DiscussionRepository;
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
import dev.struchkov.bot.gitlab.context.service.NotifyService;
import dev.struchkov.bot.gitlab.sdk.GitlabSdkManager;
import dev.struchkov.haiti.utils.container.Pair;
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

View File

@ -30,8 +30,9 @@
</dependency>
<dependency>
<groupId>dev.struchkov.bot.gitlab</groupId>
<artifactId>gitlab-sdk</artifactId>
<groupId>dev.struchkov.sdk.gitlab</groupId>
<artifactId>gitlab-sdk-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>

View File

@ -3,16 +3,20 @@ package dev.struchkov.bot.gitlab.config;
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
import dev.struchkov.bot.gitlab.context.prop.AppProperty;
import dev.struchkov.bot.gitlab.context.prop.PersonProperty;
import dev.struchkov.bot.gitlab.sdk.GitlabSdkManager;
import dev.struchkov.bot.gitlab.sdk.config.GitlabProperty;
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
import jakarta.persistence.EntityManagerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.scheduling.annotation.EnableScheduling;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.ForkJoinPool;
@ -37,15 +41,25 @@ public class AppConfig {
// }
@Bean
@ConfigurationProperties(prefix = "gitlab-bot")
public AppProperty appProperty() {
return new AppProperty();
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("dev.struchkov.bot.gitlab");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
// Explicitly set the EntityManagerFactory interface to avoid conflict between
// the EntityManagerFactory interfaces used by Spring and Hibernate.
em.setEntityManagerFactoryInterface(EntityManagerFactory.class);
return em;
}
@Bean
@ConfigurationProperties("gitlab-bot.gitlab")
public GitlabProperty gitlabProperty() {
return new GitlabProperty();
@ConfigurationProperties(prefix = "gitlab-bot")
public AppProperty appProperty() {
return new AppProperty();
}
@Bean

View File

@ -8,9 +8,9 @@ spring:
change-log: classpath:liquibase/changelog.xml
jpa:
show-sql: false
open-in-view: false
hibernate:
ddl-auto: none
database-platform: org.hibernate.dialect.PostgreSQLDialect
properties:
hibernate:
jdbc:
@ -45,10 +45,10 @@ gitlab-bot:
new-merge-request: ${CRON_NEW_MR:0 */15 * * * *}
person:
telegram-id: ${TELEGRAM_PERSON_ID}
gitlab:
access-token: ${GITLAB_PERSONAL_TOKEN}
base-url: ${GITLAB_URL}
replaceUrl: ${GITLAB_REPLACE_URL}
gitlab-sdk:
access-token: ${GITLAB_PERSONAL_TOKEN}
base-url: ${GITLAB_URL}
replace-url: ${GITLAB_REPLACE_URL}
---
spring:

View File

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>dev.struchkov.bot.gitlab</groupId>
<artifactId>gitlab-bot</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>
<artifactId>gitlab-sdk</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>dev.struchkov.haiti</groupId>
<artifactId>haiti-utils</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,219 +0,0 @@
package dev.struchkov.bot.gitlab.sdk;
import dev.struchkov.bot.gitlab.sdk.client.HttpParse;
import dev.struchkov.bot.gitlab.sdk.client.StringUtils;
import dev.struchkov.bot.gitlab.sdk.config.GitlabProperty;
import dev.struchkov.bot.gitlab.sdk.config.GitlabUrl;
import dev.struchkov.bot.gitlab.sdk.domain.GitlabProjectParam;
import dev.struchkov.bot.gitlab.sdk.domain.json.ApprovalContainerJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.ApprovalJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.CommitJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.DiscussionJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.MergeRequestJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.PersonJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.PipelineJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.PipelineShortJson;
import dev.struchkov.bot.gitlab.sdk.domain.json.ProjectJson;
import dev.struchkov.bot.gitlab.sdk.forktask.GetAllMergeRequestForProjectTask;
import dev.struchkov.bot.gitlab.sdk.forktask.GetPipelineShortTask;
import dev.struchkov.bot.gitlab.sdk.forktask.GetPipelineTask;
import dev.struchkov.bot.gitlab.sdk.forktask.GetSingleMergeRequestTask;
import dev.struchkov.haiti.utils.container.Pair;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.FormBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.Collectors;
import static dev.struchkov.bot.gitlab.sdk.client.HttpParse.ACCEPT;
import static dev.struchkov.bot.gitlab.sdk.client.StringUtils.H_PRIVATE_TOKEN;
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResult;
import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResults;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
@Slf4j
@Service
@RequiredArgsConstructor
public class GitlabSdkManager {
private final ForkJoinPool forkJoinPool;
private final GitlabUrl gitlabUrl;
private final GitlabProperty gitlabProperty;
public PersonJson getAuthPerson() {
return HttpParse.request(gitlabUrl.getUser())
.header(ACCEPT)
.header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken())
.execute(PersonJson.class)
.orElseThrow(notFoundException("Пользователь не найден"));
}
public Optional<PersonJson> getPersonById(Long userId) {
return HttpParse.request(gitlabUrl.getUsers() + "/" + userId)
.header(ACCEPT)
.header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken())
.execute(PersonJson.class);
}
public List<ProjectJson> getAllProject(int pageNumber, GitlabProjectParam... params) {
String param = Arrays.stream(params)
.map(GitlabProjectParam::getUrl)
.collect(Collectors.joining());
final String url = MessageFormat.format(gitlabUrl.getProjects(), pageNumber);
return HttpParse.request(url + param)
.header(ACCEPT)
.header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken())
.executeList(ProjectJson.class);
}
public Optional<ProjectJson> getProjectByUrl(String projectUrl) {
return HttpParse.request(projectUrl)
.header(ACCEPT)
.header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken())
.execute(ProjectJson.class);
}
/**
* Позволяет получить MR для переданных идентификаторов проектов.
*
* @param projectIds идентификаторы проектов
* @return полученные у GitLab MergeRequests
*/
public List<MergeRequestJson> getAllMergeRequestByProjectIds(Set<Long> projectIds) {
final List<ForkJoinTask<List<MergeRequestJson>>> tasks = projectIds.stream()
.map(projectId -> new GetAllMergeRequestForProjectTask(projectId, gitlabUrl.getOpenMergeRequests(), gitlabProperty.getAccessToken()))
.map(forkJoinPool::submit)
.collect(Collectors.toList());
return pullTaskResults(tasks);
}
public List<CommitJson> getAllCommitByProjectId(Long projectId, Long mergeRequestIdForProject) {
return HttpParse.request(
MessageFormat.format(gitlabUrl.getLastCommitOfMergeRequest(), projectId, mergeRequestIdForProject)
)
.header(ACCEPT)
.header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken())
.executeList(CommitJson.class);
}
public List<ApprovalJson> getAllApprovalForMergeRequest(Long projectId, Long mergeRequestIdForProject) {
return HttpParse.request(
MessageFormat.format(gitlabUrl.getMergeRequestApproval(), projectId, mergeRequestIdForProject)
)
.header(ACCEPT)
.header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken())
.execute(ApprovalContainerJson.class)
.map(ApprovalContainerJson::getApprovals)
.orElse(emptyList());
}
/**
* projectId + mrTwoId
*/
public List<MergeRequestJson> getAllMergeRequestById(Collection<Pair<Long, Long>> projectIdAndMrIdForProject) {
final List<ForkJoinTask<Optional<MergeRequestJson>>> tasks = projectIdAndMrIdForProject.stream()
.map(
pair -> new GetSingleMergeRequestTask(
gitlabUrl.getMergeRequest(),
pair.getKey(),
pair.getValue(),
gitlabProperty.getAccessToken()
)
).map(forkJoinPool::submit)
.collect(toList());
return pullTaskResult(tasks).stream()
.flatMap(Optional::stream)
.collect(toList());
}
public List<PipelineJson> getAllPipelineForProject(Collection<Pair<Long, Long>> projectIdAndPipelineId) {
final List<ForkJoinTask<Optional<PipelineJson>>> tasks = projectIdAndPipelineId.stream()
.map(
pair -> GetPipelineTask.builder()
.pipelineId(pair.getValue())
.projectId(pair.getKey())
.urlPipeline(gitlabUrl.getPipeline())
.gitlabToken(gitlabProperty.getAccessToken())
.build()
)
.map(forkJoinPool::submit)
.collect(Collectors.toList());
return pullTaskResult(tasks).stream()
.flatMap(Optional::stream)
.collect(toList());
}
public List<PipelineShortJson> getAllPipeline(Collection<Long> projectIds, LocalDateTime updatedAfter) {
final List<ForkJoinTask<List<PipelineShortJson>>> tasks = projectIds.stream()
.map(projectId -> new GetPipelineShortTask(
gitlabUrl.getPipelines(),
projectId,
updatedAfter,
gitlabProperty.getAccessToken()
))
.map(forkJoinPool::submit)
.collect(Collectors.toList());
return pullTaskResults(tasks);
}
public List<DiscussionJson> getDiscussionForMergeRequest(Long projectId, Long mergeRequestIdForProject, int pageNumber) {
return HttpParse.request(MessageFormat.format(gitlabUrl.getDiscussions(), projectId, mergeRequestIdForProject, pageNumber, pageNumber))
.header(ACCEPT)
.header(H_PRIVATE_TOKEN, gitlabProperty.getAccessToken())
.executeList(DiscussionJson.class);
}
public Optional<DiscussionJson> getDiscussionById(Long projectId, Long mergeRequestIdForProject, String discussionId) {
return HttpParse.request(createLinkOldDiscussion(projectId, mergeRequestIdForProject, discussionId))
.header(ACCEPT)
.header(H_PRIVATE_TOKEN, gitlabProperty.getAccessToken())
.execute(DiscussionJson.class);
}
private String createLinkOldDiscussion(Long projectId, Long mergeRequestIdForProject, String discussionId) {
return MessageFormat.format(
gitlabUrl.getDiscussion(),
projectId,
mergeRequestIdForProject,
discussionId
);
}
public void sendMessageToDiscussion(Long projectId, Long mergeRequestIdForProject, String discussionId, String message) {
final String requestUrl = MessageFormat.format(gitlabUrl.getNewNote(), projectId, mergeRequestIdForProject, discussionId, message);
final RequestBody formBody = new FormBody.Builder().build();
final Request request = new Request.Builder()
.post(formBody)
.header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken())
.url(requestUrl)
.build();
try {
HttpParse.getNewClient().newCall(request).execute();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}

View File

@ -1,33 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.client;
import dev.struchkov.haiti.utils.Inspector;
/**
* Утилитарная сущность для {@link HttpParse}. Упрощает сохранения в константы заголовков для запроса.
*
* @author upagge 23.12.2020
*/
public class HttpHeader {
private final String name;
private final String value;
private HttpHeader(String name, String value) {
this.name = name;
this.value = value;
}
public static HttpHeader of(String name, String value) {
Inspector.isNotNull(name, value);
return new HttpHeader(name, value);
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
}

View File

@ -1,121 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.client;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.struchkov.haiti.utils.Checker;
import dev.struchkov.haiti.utils.Inspector;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
/**
* Утилитарный класс для работы с web.
*
* @author upagge 30.09.2020
*/
public class HttpParse {
private static final Logger log = LoggerFactory.getLogger(HttpParse.class);
public static final HttpHeader ACCEPT = HttpHeader.of("Accept", "text/html,application/xhtml+xml,application/json");
private static final ObjectMapper objectMapper;
private final Request.Builder requestBuilder = new Request.Builder();
private final HttpUrl.Builder httpUrlBuilder;
static {
objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
public HttpParse(String url) {
Inspector.isNotNull(url);
httpUrlBuilder = HttpUrl.parse(url).newBuilder();
}
public static HttpParse request(String url) {
Inspector.isNotNull(url);
return new HttpParse(url);
}
public HttpParse header(String name, String value) {
Inspector.isNotNull(name);
if (value != null) {
requestBuilder.header(name, value);
}
return this;
}
public HttpParse header(HttpHeader header) {
Inspector.isNotNull(header);
requestBuilder.header(header.getName(), header.getValue());
return this;
}
public HttpParse getParameter(String name, String value) {
Inspector.isNotNull(name);
if (value != null) {
httpUrlBuilder.addQueryParameter(name, value);
}
return this;
}
public <T> Optional<T> execute(Class<T> classOfT) {
Inspector.isNotNull(classOfT);
final HttpUrl url = httpUrlBuilder.build();
final Request request = requestBuilder.url(url).build();
log.trace("Выполняется okhttp3 запрос | {}", url);
final OkHttpClient httpClient = getNewClient();
try (final Response execute = httpClient.newCall(request).execute()) {
log.trace("Запрос выполнен | {}", url);
if (execute.isSuccessful() && Checker.checkNotNull(execute.body())) {
final String string = execute.body().string();
return Optional.ofNullable(objectMapper.readValue(string, classOfT));
}
} catch (IOException e) {
log.error("Ошибка выполнения okhttp3", e);
}
return Optional.empty();
}
//TODO [16.01.2023|uPagge]: Okhttp Client создается на каждый запрос, что не рационально по потреблению ресурсов и производительности, но позволяет обойти ограничение со стороны гитлаба, при котором один и тот же клиент отбрасывался спустя 1000 запросов. Возможно стоит заменить OkHttp на что-то другое, например, RestTemplate
public <T> List<T> executeList(Class<T> classOfT) {
Inspector.isNotNull(classOfT);
final HttpUrl url = httpUrlBuilder.build();
final Request request = requestBuilder.url(url).build();
log.trace("Выполняется okhttp3 запрос | {}", url);
final OkHttpClient httpClient = getNewClient();
try (Response execute = httpClient.newCall(request).execute()) {
log.trace("Запрос выполнен | {}", url);
ResponseBody body = execute.body();
if (execute.isSuccessful() && Checker.checkNotNull(body)) {
final String stringBody = body.string();
final List<T> list = objectMapper.readValue(stringBody, objectMapper.getTypeFactory().constructCollectionType(List.class, classOfT));
return (list == null || list.isEmpty()) ? Collections.emptyList() : list;
}
} catch (IOException e) {
log.error("Ошибка выполнения okhttp3", e);
}
return Collections.emptyList();
}
public static OkHttpClient getNewClient() {
return new OkHttpClient().newBuilder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
}
}

View File

@ -1,100 +0,0 @@
//package dev.struchkov.bot.gitlab.core.utils;
//
//import com.fasterxml.jackson.databind.DeserializationFeature;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.http.HttpEntity;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.HttpMethod;
//import org.springframework.http.ResponseEntity;
//import org.springframework.stereotype.Component;
//import org.springframework.web.client.RestTemplate;
//import org.springframework.web.util.UriComponentsBuilder;
//
//import java.io.IOException;
//import java.util.Collections;
//import java.util.List;
//import java.util.Optional;
//
//@Component
//public class HttpParse {
//
// private static final Logger log = LoggerFactory.getLogger(HttpParse.class);
// private static final ObjectMapper objectMapper;
//
// static {
// objectMapper = new ObjectMapper();
// objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// }
//
// private final RestTemplate restTemplate;
// private final HttpHeaders headers = new HttpHeaders();
// private UriComponentsBuilder uriBuilder;
//
// public HttpParse(RestTemplate restTemplate) {
// this.restTemplate = restTemplate;
// }
//
// public HttpParse url(String url) {
// this.uriBuilder = UriComponentsBuilder.fromHttpUrl(url);
// return this;
// }
//
// public HttpParse header(String name, String value) {
// if (name != null && value != null) {
// headers.add(name, value);
// }
// return this;
// }
//
// public HttpParse header(HttpHeader header) {
// if (header != null) {
// headers.add(header.getName(), header.getValue());
// }
// return this;
// }
//
// public HttpParse getParameter(String name, String value) {
// if (name != null && value != null) {
// uriBuilder.queryParam(name, value);
// }
// return this;
// }
//
// public <T> Optional<T> execute(Class<T> classOfT) {
// try {
// String url = uriBuilder.toUriString();
// log.trace("Выполняется RestTemplate запрос | {}", url);
// HttpEntity<String> entity = new HttpEntity<>(headers);
// ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
// log.trace("Запрос выполнен | {}", url);
// if (response.getStatusCode().is2xxSuccessful() && response.hasBody()) {
// String body = response.getBody();
// return Optional.ofNullable(objectMapper.readValue(body, classOfT));
// }
// } catch (IOException e) {
// log.error("Ошибка выполнения RestTemplate", e);
// }
// return Optional.empty();
// }
//
// public <T> List<T> executeList(Class<T> classOfT) {
// try {
// String url = uriBuilder.toUriString();
// log.trace("Выполняется RestTemplate запрос | {}", url);
// HttpEntity<String> entity = new HttpEntity<>(headers);
// ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
// log.trace("Запрос выполнен | {}", url);
// if (response.getStatusCode().is2xxSuccessful() && response.hasBody()) {
// String body = response.getBody();
// return objectMapper.readValue(body, objectMapper.getTypeFactory().constructCollectionType(List.class, classOfT));
// }
// } catch (IOException e) {
// log.error("Ошибка выполнения RestTemplate", e);
// }
// return Collections.emptyList();
// }
//
//}

View File

@ -1,60 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.client;
import dev.struchkov.haiti.utils.Exceptions;
import okhttp3.OkHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class OkHttpUtil {
private static final Logger log = LoggerFactory.getLogger(OkHttpUtil.class);
public OkHttpUtil() {
Exceptions.utilityClass();
}
public static void ignoreCertificate(OkHttpClient.Builder builder) {
log.info("Initialising httpUtil with default configuration");
configureToIgnoreCertificate(builder);
}
//Setting testMode configuration. If set as testMode, the connection will skip certification check
private static void configureToIgnoreCertificate(OkHttpClient.Builder builder) {
log.warn("Ignore Ssl Certificate");
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
builder.hostnameVerifier((hostname, session) -> true);
} catch (Exception e) {
log.warn("Exception while configuring IgnoreSslCertificate" + e, e);
}
}
}

View File

@ -1,16 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.client;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
/**
* Утилитарный класс для работы со сторками.
*
* @author upagge 29.09.2020
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class StringUtils {
public static final String H_PRIVATE_TOKEN = "PRIVATE-TOKEN";
}

View File

@ -1,21 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.config;
import lombok.Getter;
import lombok.Setter;
/**
* Данные необходимые для взаимодействия с API GitLab.
*
* @author upagge [31.01.2020]
*/
@Getter
@Setter
public class GitlabProperty {
private String baseUrl;
private String accessToken;
private String replaceUrl;
}

View File

@ -1,49 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.config;
import lombok.Getter;
import org.springframework.stereotype.Component;
@Getter
@Component
public class GitlabUrl {
private final String users;
private final String user;
private final String projects;
private final String openMergeRequests;
private final String closeMergeRequests;
private final String commentsOfMergeRequest;
private final String mergeRequest;
private final String mergeRequestApproval;
private final String projectAdd;
private final String note;
private final String noteOfMergeRequest;
private final String pipelines;
private final String pipeline;
private final String lastCommitOfMergeRequest;
private final String newNote;
private final String discussions;
private final String discussion;
public GitlabUrl(GitlabProperty gitlabProperty) {
final String baseUrl = gitlabProperty.getBaseUrl();
this.users = baseUrl + "/api/v4/users";
this.user = baseUrl + "/api/v4/user";
this.projects = baseUrl + "/api/v4/projects?page={0, number, integer}&per_page=100";
this.openMergeRequests = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests?state=opened&page={1, number, integer}&per_page={2, number, integer}";
this.closeMergeRequests = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests?state=closed&page={1, number, integer}&per_page=100";
this.commentsOfMergeRequest = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/notes?&page={2,number,#}&per_page=100";
this.mergeRequest = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}";
this.mergeRequestApproval = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/approvals";
this.projectAdd = baseUrl + "/api/v4/projects/";
this.note = baseUrl + "{0}#note_{1,number,#}";
this.noteOfMergeRequest = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/notes/{2,number,#}";
this.pipelines = baseUrl + "/api/v4/projects/{0,number,#}/pipelines?&page={1,number,#}&per_page={2,number,#}";
this.pipeline = baseUrl + "/api/v4/projects/{0,number,#}/pipelines/{1,number,#}";
this.lastCommitOfMergeRequest = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/commits?&page=1&per_page=1";
this.newNote = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/discussions/{2}/notes?body={3}";
this.discussions = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/discussions?&page={2,number,#}&per_page={3,number,#}";
this.discussion = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/discussions/{2}";
}
}

View File

@ -1,14 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum GitlabProjectParam {
OWNER("&owned=true"),
PRIVATE("&visibility=private");
private final String url;
}

View File

@ -1,14 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
@Data
public class ApprovalContainerJson {
@JsonProperty("approved_by")
private List<ApprovalJson> approvals;
}

View File

@ -1,10 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import lombok.Data;
@Data
public class ApprovalJson {
private PersonJson user;
}

View File

@ -1,25 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author upagge 19.01.2021
*/
@Data
public class CommitJson {
private String id;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("created_at")
private LocalDateTime createdDate;
}

View File

@ -1,18 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* @author upagge 11.02.2021
*/
@Getter
@Setter
public class DiscussionJson {
private String id;
private List<NoteJson> notes;
}

View File

@ -1,61 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
/**
* @author upagge [30.01.2020]
*/
@Data
public class MergeRequestJson {
private Long id;
@JsonProperty("iid")
private Long twoId;
@JsonProperty("project_id")
private Long projectId;
private String title;
private String description;
private MergeRequestStateJson state;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("created_at")
private LocalDateTime createdDate;
@JsonProperty("updated_at")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime updatedDate;
private PersonJson author;
private PersonJson assignee;
private MilestoneJson milestone;
private List<PersonJson> reviewers;
@JsonProperty("web_url")
private String webUrl;
@JsonProperty("has_conflicts")
private boolean conflicts;
@JsonProperty("target_branch")
private String targetBranch;
@JsonProperty("source_branch")
private String sourceBranch;
private Set<String> labels;
}

View File

@ -1,19 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* @author upagge [01.02.2020]
*/
public enum MergeRequestStateJson {
@JsonProperty("opened")
OPENED,
@JsonProperty("closed")
CLOSED,
@JsonProperty("locked")
LOCKED,
@JsonProperty("merged")
MERGED
}

View File

@ -1,9 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import lombok.Data;
@Data
public class MilestoneJson {
private Long id;
private String title;
}

View File

@ -1,49 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class NoteJson {
private Long id;
private String type;
private String body;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("created_at")
private LocalDateTime created;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("updated_at")
private LocalDateTime updated;
private PersonJson author;
private boolean system;
@JsonProperty("noteable_id")
private Long noteableId;
@JsonProperty("noteable_type")
private String noteableType;
private boolean resolvable;
private Boolean resolved;
@JsonProperty("resolved_by")
private PersonJson resolvedBy;
@JsonProperty("noteable_iid")
private Long noteableIid;
}

View File

@ -1,19 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* @author upagge [31.01.2020]
*/
@Data
public class PersonJson {
private Long id;
private String name;
private String username;
@JsonProperty("web_url")
private String webUrl;
}

View File

@ -1,43 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author upagge 17.01.2021
*/
@Data
public class PipelineJson {
private Long id;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("created_at")
private LocalDateTime created;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("updated_at")
private LocalDateTime updated;
private PipelineStatusJson status;
private String ref;
private PersonJson user;
@JsonProperty("web_url")
private String webUrl;
// Поля ниже не отдаются гитлабом, а заполняются вручную
private Long projectId;
}

View File

@ -1,41 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author upagge 17.01.2021
*/
@Data
public class PipelineShortJson {
private Long id;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("created_at")
private LocalDateTime created;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("updated_at")
private LocalDateTime updated;
private PipelineStatusJson status;
private String ref;
@JsonProperty("web_url")
private String webUrl;
// Поля ниже не отдаются гитлабом, а заполняются вручную
private Long projectId;
}

View File

@ -1,43 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* @author upagge 17.01.2021
*/
public enum PipelineStatusJson {
@JsonProperty("created")
CREATED,
@JsonProperty("waiting_for_resource")
WAITING_FOR_RESOURCE,
@JsonProperty("preparing")
PREPARING,
@JsonProperty("pending")
PENDING,
@JsonProperty("running")
RUNNING,
@JsonProperty("success")
SUCCESS,
@JsonProperty("failed")
FAILED,
@JsonProperty("canceled")
CANCELED,
@JsonProperty("skipped")
SKIPPED,
@JsonProperty("manual")
MANUAL,
@JsonProperty("scheduled")
SCHEDULED
}

View File

@ -1,39 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author upagge 14.01.2021
*/
@Data
public class ProjectJson {
private Long id;
private String name;
private String description;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("created_at")
private LocalDateTime createdDate;
@JsonProperty("web_url")
private String webUrl;
@JsonProperty("ssh_url_to_repo")
private String sshUrlToRepo;
@JsonProperty("http_url_to_repo")
private String httpUrlToRepo;
@JsonProperty("creator_id")
private Long creatorId;
}

View File

@ -1,14 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.domain.json;
import lombok.Data;
/**
* @author upagge [31.01.2020]
*/
@Data
public class UserJson {
private String name;
private String displayName;
}

View File

@ -1,49 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.forktask;
import dev.struchkov.bot.gitlab.sdk.client.HttpParse;
import dev.struchkov.bot.gitlab.sdk.domain.json.DiscussionJson;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import java.text.MessageFormat;
import java.util.List;
import java.util.concurrent.RecursiveTask;
import static dev.struchkov.bot.gitlab.sdk.client.HttpParse.ACCEPT;
import static dev.struchkov.bot.gitlab.sdk.client.StringUtils.H_PRIVATE_TOKEN;
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
@AllArgsConstructor
@RequiredArgsConstructor
public class GetAllDiscussionForMergeRequestTask extends RecursiveTask<List<DiscussionJson>> {
private static final int PAGE_COUNT = 100;
private final String discussionsUrl;
private final long projectId;
private final long mergeRequestTwoId;
private final String personalGitlabToken;
private int page = 1;
@Override
@SneakyThrows
protected List<DiscussionJson> compute() {
Thread.sleep(100);
final List<DiscussionJson> jsons = getDiscussionJson();
if (checkNotEmpty(jsons) && jsons.size() == PAGE_COUNT) {
final var newTask = new GetAllDiscussionForMergeRequestTask(discussionsUrl, projectId, mergeRequestTwoId, personalGitlabToken, page + 1);
newTask.fork();
jsons.addAll(newTask.join());
}
return jsons;
}
private List<DiscussionJson> getDiscussionJson() {
return HttpParse.request(MessageFormat.format(discussionsUrl, projectId, mergeRequestTwoId, page, PAGE_COUNT))
.header(ACCEPT)
.header(H_PRIVATE_TOKEN, personalGitlabToken)
.executeList(DiscussionJson.class);
}
}

View File

@ -1,52 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.forktask;
import dev.struchkov.bot.gitlab.sdk.client.HttpParse;
import dev.struchkov.bot.gitlab.sdk.client.StringUtils;
import dev.struchkov.bot.gitlab.sdk.domain.json.MergeRequestJson;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.List;
import java.util.concurrent.RecursiveTask;
import static dev.struchkov.bot.gitlab.sdk.client.HttpParse.ACCEPT;
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
@Slf4j
@AllArgsConstructor
@RequiredArgsConstructor
public class GetAllMergeRequestForProjectTask extends RecursiveTask<List<MergeRequestJson>> {
private static final int PAGE_COUNT = 100;
private final long projectId;
private int pageNumber = 1;
private final String urlMrOpen;
private final String gitlabToken;
@Override
@SneakyThrows
protected List<MergeRequestJson> compute() {
Thread.sleep(100);
final List<MergeRequestJson> mergeRequestJsons = getMergeRequestJsons();
if (checkNotEmpty(mergeRequestJsons) && mergeRequestJsons.size() == PAGE_COUNT) {
final GetAllMergeRequestForProjectTask newTask = new GetAllMergeRequestForProjectTask(projectId, pageNumber + 1, urlMrOpen, gitlabToken);
newTask.fork();
mergeRequestJsons.addAll(newTask.join());
}
return mergeRequestJsons;
}
private List<MergeRequestJson> getMergeRequestJsons() {
final List<MergeRequestJson> jsons = HttpParse.request(MessageFormat.format(urlMrOpen, projectId, pageNumber, PAGE_COUNT))
.header(StringUtils.H_PRIVATE_TOKEN, gitlabToken)
.header(ACCEPT)
.executeList(MergeRequestJson.class);
log.trace("Получено {} шт потенциально новых MR для проекта id:'{}' ", jsons.size(), projectId);
return jsons;
}
}

View File

@ -1,55 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.forktask;
import dev.struchkov.bot.gitlab.sdk.client.HttpParse;
import dev.struchkov.bot.gitlab.sdk.client.StringUtils;
import dev.struchkov.bot.gitlab.sdk.domain.json.PipelineShortJson;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.RecursiveTask;
import static dev.struchkov.bot.gitlab.sdk.client.HttpParse.ACCEPT;
@Slf4j
@AllArgsConstructor
@RequiredArgsConstructor
public class GetPipelineShortTask extends RecursiveTask<List<PipelineShortJson>> {
private static final int PAGE_COUNT = 100;
private final String urlPipelines;
private final long projectId;
private int pageNumber = 1;
private final LocalDateTime lastUpdate;
private final String gitlabToken;
@Override
@SneakyThrows
protected List<PipelineShortJson> compute() {
Thread.sleep(100);
final List<PipelineShortJson> jsons = getPipelineJsons();
if (jsons.size() == PAGE_COUNT) {
final GetPipelineShortTask newTask = new GetPipelineShortTask(urlPipelines, projectId, pageNumber + 1, lastUpdate, gitlabToken);
newTask.fork();
jsons.addAll(newTask.join());
}
jsons.forEach(pipelineJson -> pipelineJson.setProjectId(projectId));
return jsons;
}
private List<PipelineShortJson> getPipelineJsons() {
final List<PipelineShortJson> jsons = HttpParse.request(MessageFormat.format(urlPipelines, projectId, pageNumber, PAGE_COUNT))
.header(ACCEPT)
.header(StringUtils.H_PRIVATE_TOKEN, gitlabToken)
.getParameter("updated_after", lastUpdate.toString())
.executeList(PipelineShortJson.class);
log.trace("Получено {} шт потенциально новых пайплайнов для проекта id:'{}' ", jsons.size(), projectId);
return jsons;
}
}

View File

@ -1,45 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.forktask;
import dev.struchkov.bot.gitlab.sdk.client.HttpParse;
import dev.struchkov.bot.gitlab.sdk.client.StringUtils;
import dev.struchkov.bot.gitlab.sdk.domain.json.PipelineJson;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.Optional;
import java.util.concurrent.RecursiveTask;
import static dev.struchkov.bot.gitlab.sdk.client.HttpParse.ACCEPT;
@Slf4j
@Builder
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class GetPipelineTask extends RecursiveTask<Optional<PipelineJson>> {
private String urlPipeline;
private long projectId;
private long pipelineId;
private String gitlabToken;
@Override
@SneakyThrows
protected Optional<PipelineJson> compute() {
Thread.sleep(100);
return HttpParse.request(MessageFormat.format(urlPipeline, projectId, pipelineId))
.header(ACCEPT)
.header(StringUtils.H_PRIVATE_TOKEN, gitlabToken)
.execute(PipelineJson.class)
.map(json -> {
json.setProjectId(projectId);
return json;
});
}
}

View File

@ -1,37 +0,0 @@
package dev.struchkov.bot.gitlab.sdk.forktask;
import dev.struchkov.bot.gitlab.sdk.client.HttpParse;
import dev.struchkov.bot.gitlab.sdk.client.StringUtils;
import dev.struchkov.bot.gitlab.sdk.domain.json.MergeRequestJson;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.Optional;
import java.util.concurrent.RecursiveTask;
import static dev.struchkov.bot.gitlab.sdk.client.HttpParse.ACCEPT;
@Slf4j
@RequiredArgsConstructor
public class GetSingleMergeRequestTask extends RecursiveTask<Optional<MergeRequestJson>> {
private final String urlMr;
private final long projectId;
private final long mrTwoId;
private final String gitlabToken;
@Override
@SneakyThrows
protected Optional<MergeRequestJson> compute() {
Thread.sleep(100);
final String mrUrl = MessageFormat.format(urlMr, projectId, mrTwoId);
return HttpParse.request(mrUrl)
.header(ACCEPT)
.header(StringUtils.H_PRIVATE_TOKEN, gitlabToken)
.execute(MergeRequestJson.class);
}
}

23
pom.xml
View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.1</version>
<version>3.3.3</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
@ -16,7 +16,6 @@
<modules>
<module>bot-context</module>
<module>telegram-bot</module>
<module>gitlab-sdk</module>
<module>bot-core</module>
<module>gitlab-app</module>
<module>bot-data</module>
@ -37,7 +36,7 @@
</issueManagement>
<properties>
<java.version>17</java.version>
<java.version>21</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -88,12 +87,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>dev.struchkov.bot.gitlab</groupId>
<artifactId>gitlab-sdk</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>dev.struchkov.bot.gitlab</groupId>
<artifactId>bot-data</artifactId>
@ -133,6 +126,12 @@
<version>${godfather.telegram.version}</version>
</dependency>
<dependency>
<groupId>dev.struchkov.sdk.gitlab</groupId>
<artifactId>gitlab-sdk-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- /SADTECH -->
<!-- БД -->
@ -142,12 +141,6 @@
<version>${postgresql.version}</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>${jakarta.persistance.version}</version>
</dependency>
<!-- /БД -->
<!-- утилиты -->

View File

@ -1,8 +1,8 @@
package dev.struchkov.bot.gitlab.telegram.service;
import dev.struchkov.bot.gitlab.sdk.config.GitlabProperty;
import dev.struchkov.godfather.simple.domain.BoxAnswer;
import dev.struchkov.godfather.simple.domain.action.PreSendProcessing;
import dev.struchkov.sdk.gitlab.domain.GitlabProperty;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

View File

@ -9,8 +9,6 @@ import dev.struchkov.bot.gitlab.context.service.NoteService;
import dev.struchkov.bot.gitlab.context.service.ProjectService;
import dev.struchkov.bot.gitlab.context.utils.Icons;
import dev.struchkov.bot.gitlab.core.parser.ProjectParser;
import dev.struchkov.bot.gitlab.sdk.config.GitlabProperty;
import dev.struchkov.bot.gitlab.sdk.config.GitlabUrl;
import dev.struchkov.bot.gitlab.telegram.utils.UnitName;
import dev.struchkov.godfather.main.domain.annotation.Unit;
import dev.struchkov.godfather.main.domain.content.Mail;
@ -23,6 +21,8 @@ import dev.struchkov.godfather.telegram.main.context.MailPayload;
import dev.struchkov.godfather.telegram.main.core.util.Attachments;
import dev.struchkov.godfather.telegram.starter.PersonUnitConfiguration;
import dev.struchkov.haiti.utils.Checker;
import dev.struchkov.sdk.gitlab.domain.GitlabProperty;
import dev.struchkov.sdk.gitlab.domain.GitlabUrl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;