Skip to content

Commit dd48c84

Browse files
Adrià Maneromikededo
authored andcommitted
feat: FetchReviewsFromPullRequest use case
1 parent ca1edf2 commit dd48c84

File tree

8 files changed

+202
-35
lines changed

8 files changed

+202
-35
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package io.pakland.mdas.githubstats.application.dto;
2+
3+
public interface UserReviewDTO {
4+
Integer getId();
5+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package io.pakland.mdas.githubstats.application.external;
2+
3+
import io.pakland.mdas.githubstats.application.exceptions.HttpException;
4+
import io.pakland.mdas.githubstats.domain.entity.PullRequest;
5+
import io.pakland.mdas.githubstats.domain.entity.Repository;
6+
import io.pakland.mdas.githubstats.domain.entity.UserReview;
7+
import io.pakland.mdas.githubstats.domain.repository.ReviewExternalRepository;
8+
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
12+
public class FetchReviewsFromPullRequest {
13+
private final ReviewExternalRepository reviewExternalRepository;
14+
15+
public FetchReviewsFromPullRequest(ReviewExternalRepository reviewExternalRepository) {
16+
this.reviewExternalRepository = reviewExternalRepository;
17+
}
18+
19+
public List<UserReview> execute(PullRequest pullRequest)
20+
throws HttpException {
21+
int page = 1;
22+
List<UserReview> reviewList = new ArrayList<>();
23+
int responseResults;
24+
Repository repository = pullRequest.getRepository();
25+
do {
26+
ReviewExternalRepository.FetchReviewsFromPullRequestRequest request = ReviewExternalRepository.FetchReviewsFromPullRequestRequest.builder()
27+
.repositoryOwner(repository.getOwnerLogin())
28+
.repositoryName(repository.getName())
29+
.pullRequestNumber(pullRequest.getNumber())
30+
.page(page)
31+
.perPage(100)
32+
.build();
33+
List<UserReview> apiResults = this.reviewExternalRepository.fetchReviewsFromPullRequest(request);
34+
reviewList.addAll(apiResults);
35+
responseResults = apiResults.size();
36+
page++;
37+
} while (responseResults > 0);
38+
39+
return reviewList;
40+
}
41+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.pakland.mdas.githubstats.application.mappers;
2+
3+
import io.pakland.mdas.githubstats.application.dto.UserReviewDTO;
4+
import io.pakland.mdas.githubstats.domain.entity.UserReview;
5+
6+
public class ReviewMapper {
7+
public static UserReview dtoToEntity(UserReviewDTO dto) {
8+
return UserReview.builder()
9+
.id(dto.getId())
10+
.build();
11+
}
12+
}

src/main/java/io/pakland/mdas/githubstats/domain/entity/UserReview.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
package io.pakland.mdas.githubstats.domain.entity;
22

3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
35
import lombok.Data;
46
import lombok.NoArgsConstructor;
5-
import lombok.ToString;
67

7-
import javax.persistence.*;
88
import java.util.ArrayList;
99
import java.util.List;
1010

1111
@Data
1212
@NoArgsConstructor
13-
@ToString
13+
@AllArgsConstructor
14+
@Builder
1415
public class UserReview {
1516

16-
private Integer id;
17+
private Integer id;
1718

18-
private User user;
19+
private User user;
1920

20-
private PullRequest pullRequest;
21+
private PullRequest pullRequest;
2122

22-
private List<Comment> comments = new ArrayList<>();
23+
private List<Comment> comments = new ArrayList<>();
2324

2425
public int sumCommentLength() {
2526
return comments.stream().mapToInt(Comment::getLength).sum();
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.pakland.mdas.githubstats.domain.repository;
2+
3+
import io.pakland.mdas.githubstats.application.exceptions.HttpException;
4+
import io.pakland.mdas.githubstats.domain.entity.UserReview;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Builder;
7+
import lombok.Getter;
8+
import lombok.NoArgsConstructor;
9+
10+
import java.util.List;
11+
12+
public interface ReviewExternalRepository {
13+
14+
public List<UserReview> fetchReviewsFromPullRequest(FetchReviewsFromPullRequestRequest request) throws HttpException;
15+
16+
@NoArgsConstructor
17+
@AllArgsConstructor
18+
@Builder
19+
@Getter
20+
public static class FetchReviewsFromPullRequestRequest {
21+
private String repositoryOwner;
22+
private String repositoryName;
23+
private Integer pullRequestNumber;
24+
private Integer page;
25+
private Integer perPage;
26+
}
27+
}

src/main/java/io/pakland/mdas/githubstats/infrastructure/github/controller/GitHubUserController.java

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
import io.pakland.mdas.githubstats.domain.repository.*;
77
import io.pakland.mdas.githubstats.infrastructure.github.model.GitHubUserOptionRequest;
88
import io.pakland.mdas.githubstats.infrastructure.github.repository.*;
9-
import java.util.List;
109
import lombok.NoArgsConstructor;
1110
import org.slf4j.Logger;
1211
import org.slf4j.LoggerFactory;
1312
import org.springframework.stereotype.Component;
1413

14+
import java.util.List;
15+
1516
@Component
1617
@NoArgsConstructor
1718
public class GitHubUserController {
@@ -23,38 +24,39 @@ public class GitHubUserController {
2324
private RepositoryExternalRepository repositoryExternalRepository;
2425
private PullRequestExternalRepository pullRequestExternalRepository;
2526
private CommitExternalRepository commitExternalRepository;
27+
private ReviewExternalRepository reviewExternalRepository;
2628
private CommentExternalRepository commentExternalRepository;
2729

2830

2931
public GitHubUserController(GitHubUserOptionRequest userOptionRequest) {
3032
WebClientConfiguration webClientConfiguration = new WebClientConfiguration(
31-
"https://api.github.com", userOptionRequest.getApiKey());
33+
"https://api.github.com", userOptionRequest.getApiKey());
3234
this.organizationExternalRepository = new OrganizationGitHubRepository(
33-
webClientConfiguration);
35+
webClientConfiguration);
3436
this.teamExternalRepository = new TeamGitHubRepository(webClientConfiguration);
3537
this.userExternalRepository = new UserGitHubRepository(webClientConfiguration);
3638
this.repositoryExternalRepository = new RepositoryGitHubRepository(webClientConfiguration);
3739
this.pullRequestExternalRepository = new PullRequestGitHubRepository(
38-
webClientConfiguration);
40+
webClientConfiguration);
3941
this.organizationExternalRepository = new OrganizationGitHubRepository(
40-
webClientConfiguration);
42+
webClientConfiguration);
4143
this.teamExternalRepository = new TeamGitHubRepository(webClientConfiguration);
4244
this.userExternalRepository = new UserGitHubRepository(webClientConfiguration);
4345
this.repositoryExternalRepository = new RepositoryGitHubRepository(webClientConfiguration);
4446
this.pullRequestExternalRepository = new PullRequestGitHubRepository(
45-
webClientConfiguration);
47+
webClientConfiguration);
4648
this.commitExternalRepository = new CommitGitHubRepository(webClientConfiguration);
49+
this.reviewExternalRepository = new ReviewGitHubRepository(webClientConfiguration);
4750
this.commentExternalRepository = new CommentGitHubRepository(webClientConfiguration);
48-
4951
}
5052

5153
public void execute() {
5254
try {
5355
// TODO: If the execution succeeds, we should make an entry to the historic_queries table.
5456
// Fetch the API key's available organizations.
5557
List<Organization> organizationList = new FetchAvailableOrganizations(
56-
this.organizationExternalRepository)
57-
.execute();
58+
this.organizationExternalRepository)
59+
.execute();
5860
organizationList.forEach(this::fetchTeamsFromOrganization);
5961
} catch (HttpException e) {
6062
throw new RuntimeException(e);
@@ -64,7 +66,7 @@ public void execute() {
6466
private void fetchTeamsFromOrganization(Organization organization) {
6567
try {
6668
List<Team> teamList = new FetchTeamsFromOrganization(teamExternalRepository)
67-
.execute(organization);
69+
.execute(organization);
6870
teamList.forEach(team -> {
6971
this.fetchRepositoriesFromTeam(team);
7072
this.fetchUsersFromTeam(team);
@@ -78,7 +80,7 @@ private void fetchRepositoriesFromTeam(Team team) {
7880
try {
7981
// Fetch the repositories for each team.
8082
List<Repository> repositoryList = new FetchRepositoriesFromTeam(
81-
repositoryExternalRepository).execute(team);
83+
repositoryExternalRepository).execute(team);
8284
// Add the team to the repository
8385
repositoryList.forEach(this::fetchPullRequestsFromRepository);
8486
} catch (HttpException e) {
@@ -99,33 +101,44 @@ private void fetchPullRequestsFromRepository(Repository repository) {
99101
try {
100102
// Fetch pull requests from each team.
101103
List<PullRequest> pullRequestList = new FetchPullRequestsFromRepository(
102-
pullRequestExternalRepository)
103-
.execute(repository);
104+
pullRequestExternalRepository)
105+
.execute(repository);
104106

105-
pullRequestList.forEach(this::fetchCommitsFromPullRequest);
107+
pullRequestList.forEach(pullRequest -> {
108+
this.fetchCommitsFromPullRequest(pullRequest);
109+
this.fetchReviewsFromPullRequest(pullRequest);
110+
this.fetchCommentsFromPullRequest(pullRequest);
111+
});
106112
} catch (HttpException e) {
107113
throw new RuntimeException(e);
108114
}
109115
}
110116

111117
private void fetchCommitsFromPullRequest(PullRequest pullRequest) {
112-
/*
113-
TODO: if the user of the PR belongs to the team, increment the prs executed inside the team
114-
TODO: else increment the prs executed outside the team
115-
TODO: Save for later calculate the additions, deletions and commit num. from PR aggregation
116-
*/
117-
//
118118
try {
119-
List<Commit> commitList = new FetchCommitsFromPullRequest(
120-
commitExternalRepository)
121-
.execute(pullRequest);
122-
//TODO: Fetch PR Reviews.
119+
// Fetch Commits from each Pull Request.
120+
List<Commit> commitList = new FetchCommitsFromPullRequest(commitExternalRepository)
121+
.execute(pullRequest);
122+
} catch (HttpException e) {
123+
throw new RuntimeException(e);
124+
}
125+
}
123126

124-
Repository repository = pullRequest.getRepository();
125-
List<Comment> commentList = new FetchCommentsFromPullRequest(
126-
commentExternalRepository).execute(repository.getOwnerLogin(), repository.getName(),
127-
pullRequest.getNumber());
127+
private void fetchReviewsFromPullRequest(PullRequest pullRequest) {
128+
try {
129+
// Fetch Reviews from each Pull Request.
130+
List<UserReview> reviewList = new FetchReviewsFromPullRequest(reviewExternalRepository)
131+
.execute(pullRequest);
132+
} catch (HttpException e) {
133+
throw new RuntimeException(e);
134+
}
135+
}
128136

137+
private void fetchCommentsFromPullRequest(PullRequest pullRequest) {
138+
try {
139+
// Fetch Comments from each Pull Request.
140+
List<Comment> commentList = new FetchCommentsFromPullRequest(commentExternalRepository)
141+
.execute(pullRequest);
129142
} catch (HttpException e) {
130143
throw new RuntimeException(e);
131144
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.pakland.mdas.githubstats.infrastructure.github.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import io.pakland.mdas.githubstats.application.dto.UserReviewDTO;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Data;
7+
import lombok.NoArgsConstructor;
8+
9+
@Data
10+
@NoArgsConstructor
11+
@AllArgsConstructor
12+
public class GitHubReviewDTO implements UserReviewDTO {
13+
@JsonProperty("id")
14+
private Integer id;
15+
16+
@Override
17+
public Integer getId() {
18+
return this.id;
19+
}
20+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package io.pakland.mdas.githubstats.infrastructure.github.repository;
2+
3+
import io.pakland.mdas.githubstats.application.exceptions.HttpException;
4+
import io.pakland.mdas.githubstats.application.mappers.ReviewMapper;
5+
import io.pakland.mdas.githubstats.domain.entity.UserReview;
6+
import io.pakland.mdas.githubstats.domain.repository.ReviewExternalRepository;
7+
import io.pakland.mdas.githubstats.infrastructure.github.model.GitHubReviewDTO;
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
import org.springframework.web.reactive.function.client.WebClientResponseException;
11+
12+
import java.util.List;
13+
14+
public class ReviewGitHubRepository implements ReviewExternalRepository {
15+
private final WebClientConfiguration webClientConfiguration;
16+
private final Logger logger = LoggerFactory.getLogger(ReviewGitHubRepository.class);
17+
18+
public ReviewGitHubRepository(WebClientConfiguration webClientConfiguration) {
19+
this.webClientConfiguration = webClientConfiguration;
20+
}
21+
22+
@Override
23+
public List<UserReview> fetchReviewsFromPullRequest(FetchReviewsFromPullRequestRequest request) throws HttpException {
24+
try {
25+
26+
return this.webClientConfiguration.getWebClient().get()
27+
.uri(String.format("/repos/%s/%s/pulls/%s/reviews?%s",
28+
request.getRepositoryOwner(),
29+
request.getRepositoryName(),
30+
request.getPullRequestNumber(),
31+
getRequestParams(request.getPage(), request.getPerPage())
32+
))
33+
.retrieve()
34+
.bodyToFlux(GitHubReviewDTO.class)
35+
.map(ReviewMapper::dtoToEntity)
36+
.collectList()
37+
.block();
38+
39+
} catch (WebClientResponseException ex) {
40+
logger.error(ex.toString());
41+
throw new HttpException(ex.getRawStatusCode(), ex.getMessage());
42+
}
43+
}
44+
45+
private String getRequestParams(Integer page, Integer perPage) {
46+
return String.format("per_page=%d&page=%d", perPage, page < 0 ? 1 : page);
47+
}
48+
}

0 commit comments

Comments
 (0)