Skip to content

Commit

Permalink
feat(graphql): Add graphql endpoint for analyzerstatus (#863)
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinWitt authored Jul 18, 2023
1 parent 3850fc2 commit fc89ddf
Show file tree
Hide file tree
Showing 16 changed files with 176 additions and 83 deletions.
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
package io.github.martinwitt.laughing_train.domain.entity;

import java.io.Serializable;
import java.time.LocalDateTime;

public class AnalyzerStatus implements Serializable {

private String analyzerName;
private Status status;
private int numberOfIssues;
private String commitHash;
private LocalDateTime localDateTime;

AnalyzerStatus(String analyzerName, Status status, int numberOfIssues) {
AnalyzerStatus(
String analyzerName, Status status, int numberOfIssues, String commitHash, LocalDateTime localDateTime) {
this.analyzerName = analyzerName;
this.status = status;
this.numberOfIssues = numberOfIssues;
this.commitHash = commitHash;
this.localDateTime = localDateTime;
}

public static AnalyzerStatus success(String analyzerName, int numberOfIssues) {
return new AnalyzerStatus(analyzerName, Status.SUCCESS, numberOfIssues);
public static AnalyzerStatus success(String analyzerName, int numberOfIssues, String commitHash) {
return new AnalyzerStatus(analyzerName, Status.SUCCESS, numberOfIssues, commitHash, LocalDateTime.now());
}

public static AnalyzerStatus failure(String analyzerName, int numberOfIssues) {
return new AnalyzerStatus(analyzerName, Status.FAILURE, numberOfIssues);
public static AnalyzerStatus failure(String analyzerName, int numberOfIssues, String commitHash) {
return new AnalyzerStatus(analyzerName, Status.FAILURE, numberOfIssues, commitHash, LocalDateTime.now());
}

enum Status {
Expand Down Expand Up @@ -68,4 +74,31 @@ public int getNumberOfIssues() {
public void setNumberOfIssues(int numberOfIssues) {
this.numberOfIssues = numberOfIssues;
}

/**
* @return the commitHash
*/
public String getCommitHash() {
return commitHash;
}
/**
* @param commitHash the commitHash to set
*/
public void setCommitHash(String commitHash) {
this.commitHash = commitHash;
}

/**
* @return the localDateTime
*/
public LocalDateTime getLocalDateTime() {
return localDateTime;
}

/**
* @param localDateTime the localDateTime to set
*/
public void setLocalDateTime(LocalDateTime localDateTime) {
this.localDateTime = localDateTime;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ public void setAnalyzerStatuses(List<AnalyzerStatus> analyzerStatuses) {
}

public void addAnalyzerStatus(AnalyzerStatus analyzerStatus) {
this.analyzerStatuses.add(analyzerStatus);
analyzerStatuses.stream()
.filter(v -> v.getCommitHash().equals(analyzerStatus.getCommitHash()))
.filter(v -> v.getAnalyzerName().equals(analyzerStatus.getAnalyzerName()))
.findFirst()
.ifPresentOrElse(
v -> {
analyzerStatuses.remove(v);
analyzerStatuses.add(analyzerStatus);
},
() -> {
analyzerStatuses.add(analyzerStatus);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
import java.util.List;
import java.util.Objects;

public class Project implements Serializable {
public class RemoteProject implements Serializable {

private String projectName;
private String projectUrl;
private List<String> commitHashes;
private List<GitHubCommit> commits;

public Project(String projectName, String projectUrl) {
public RemoteProject(String projectName, String projectUrl) {
this.projectName = Objects.requireNonNull(projectName);
this.projectUrl = Objects.requireNonNull(projectUrl);
commitHashes = new ArrayList<>();
Expand Down Expand Up @@ -80,15 +80,15 @@ public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Project project) {
if (obj instanceof RemoteProject project) {
return Objects.equals(projectName, project.projectName)
&& Objects.equals(projectUrl, project.projectUrl)
&& Objects.equals(commitHashes, project.commitHashes);
}
return false;
}

public Project withProjectUrl(String projectUrl) {
return new Project(projectName, projectUrl);
public RemoteProject withProjectUrl(String projectUrl) {
return new RemoteProject(projectName, projectUrl);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.martinwitt.laughing_train.api.graphql.dto;

import io.github.martinwitt.laughing_train.domain.entity.Project;
import io.github.martinwitt.laughing_train.domain.entity.GitHubCommit;
import io.github.martinwitt.laughing_train.domain.entity.RemoteProject;
import java.util.List;
import org.eclipse.microprofile.graphql.Name;

Expand All @@ -10,14 +11,16 @@ public class ProjectGraphQLDto {
private String projectName;
private String projectUrl;
private List<String> commitHashes;
private List<GitHubCommit> commits;

@SuppressWarnings("NullAway")
public ProjectGraphQLDto() {}

public ProjectGraphQLDto(Project project) {
public ProjectGraphQLDto(RemoteProject project) {
this.projectName = project.getProjectName();
this.projectUrl = project.getProjectUrl();
this.commitHashes = project.getCommitHashes();
this.commits = project.getCommits();
}

public String getProjectName() {
Expand All @@ -43,4 +46,18 @@ public List<String> getCommitHashes() {
public void setCommitHashes(List<String> commitHashes) {
this.commitHashes = commitHashes;
}

/**
* @return the commits
*/
public List<GitHubCommit> getCommits() {
return commits;
}

/**
* @param commits the commits to set
*/
public void setCommits(List<GitHubCommit> commits) {
this.commits = commits;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import io.github.martinwitt.laughing_train.api.graphql.dto.ProjectConfigGraphQLDto;
import io.github.martinwitt.laughing_train.api.graphql.dto.ProjectConfigGraphQLDtoInput;
import io.github.martinwitt.laughing_train.api.graphql.dto.ProjectGraphQLDto;
import io.github.martinwitt.laughing_train.domain.entity.Project;
import io.github.martinwitt.laughing_train.domain.entity.GitHubCommit;
import io.github.martinwitt.laughing_train.domain.entity.ProjectConfig;
import io.github.martinwitt.laughing_train.domain.entity.RemoteProject;
import io.github.martinwitt.laughing_train.mining.QodanaPeriodicMiner;
import io.github.martinwitt.laughing_train.persistence.repository.ProjectConfigRepository;
import io.github.martinwitt.laughing_train.persistence.repository.ProjectRepository;
Expand Down Expand Up @@ -62,7 +63,16 @@ public ProjectGraphQLDto getProject(String projectName) {
public List<String> getHashesForProject(String projectName) {
return projectRepository.findByProjectName(projectName).stream()
.findFirst()
.map(Project::getCommitHashes)
.map(RemoteProject::getCommitHashes)
.orElseThrow();
}

@Query("getGitHubCommitsForProject")
@Description("Returns all github commits for a project from the database")
public List<GitHubCommit> getGitHubCommitsForProject(String projectName) {
return projectRepository.findByProjectName(projectName).stream()
.findFirst()
.map(RemoteProject::getCommits)
.orElseThrow();
}

Expand All @@ -73,7 +83,7 @@ public ProjectGraphQLDto addProject(String projectUrl, String projectName) {
logger.atInfo().log("Adding project %s with url %s", projectName, projectUrl);
if (!projectRepository.existsByProjectUrl(projectUrl)) {
logger.atInfo().log("Project does not exist yet, creating it");
Project project = new Project(projectUrl, projectName);
RemoteProject project = new RemoteProject(projectUrl, projectName);
return mapToDto(projectRepository.create(project));
} else {
logger.atInfo().log("Project %s already exists", projectName);
Expand All @@ -85,7 +95,7 @@ public ProjectGraphQLDto addProject(String projectUrl, String projectName) {
@Authenticated
@Description("Deletes a project from the database")
public List<ProjectGraphQLDto> removeProjectByName(String projectName) {
List<Project> projects = projectRepository.findByProjectName(projectName);
List<RemoteProject> projects = projectRepository.findByProjectName(projectName);
projectRepository.deleteByProjectName(projectName);
return projects.stream().map(this::mapToDto).toList();
}
Expand Down Expand Up @@ -130,7 +140,7 @@ private ProjectConfig createConfigFromInput(ProjectConfigGraphQLDtoInput project
return config;
}

private ProjectGraphQLDto mapToDto(Project project) {
private ProjectGraphQLDto mapToDto(RemoteProject project) {
return new ProjectGraphQLDto(project);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.github.martinwitt.laughing_train.data.result.CodeAnalyzerResult;
import io.github.martinwitt.laughing_train.domain.entity.AnalyzerStatus;
import io.github.martinwitt.laughing_train.domain.entity.GitHubCommit;
import io.github.martinwitt.laughing_train.domain.entity.RemoteProject;
import io.github.martinwitt.laughing_train.mining.requests.StoreResults;
import io.github.martinwitt.laughing_train.persistence.repository.ProjectRepository;
import io.vertx.core.AbstractVerticle;
Expand Down Expand Up @@ -43,33 +44,29 @@ void persistResults(StoreResults storeResults) {
}
}

private AnalyzerStatus getAnalyzerStatus(CodeAnalyzerResult spoonResult, String name) {
private AnalyzerStatus getAnalyzerStatus(CodeAnalyzerResult spoonResult, String name, String commitHash) {
AnalyzerStatus analyzerStatus = null;
if (spoonResult instanceof CodeAnalyzerResult.Success success) {
analyzerStatus = AnalyzerStatus.success(name, success.results().size());
analyzerStatus = AnalyzerStatus.success(name, success.results().size(), commitHash);
} else if (spoonResult instanceof CodeAnalyzerResult.Failure failure) {
analyzerStatus = AnalyzerStatus.failure(name, 0);
analyzerStatus = AnalyzerStatus.failure(name, 0, commitHash);
}
return analyzerStatus;
}

private void addOrUpdateCommitHash(Project project, CodeAnalyzerResult spoonResult, String analyzerName) {
String name = project.name();
String commitHash = project.commitHash();
List<io.github.martinwitt.laughing_train.domain.entity.Project> list =
projectRepository.findByProjectUrl(project.url());
AnalyzerStatus analyzerStatus = getAnalyzerStatus(spoonResult, analyzerName);
List<RemoteProject> list = projectRepository.findByProjectUrl(project.url());
AnalyzerStatus analyzerStatus = getAnalyzerStatus(spoonResult, analyzerName, commitHash);
if (list.isEmpty()) {
io.github.martinwitt.laughing_train.domain.entity.Project newProject =
new io.github.martinwitt.laughing_train.domain.entity.Project(name, project.url());
RemoteProject newProject = new RemoteProject(name, project.url());
newProject.addCommitHash(commitHash);
var commits = newProject.getCommits();
List<GitHubCommit> commits = newProject.getCommits();
commits.stream()
.filter(v -> v.getCommitHash().equals(commitHash))
.findFirst()
.ifPresent(v -> {
v.addAnalyzerStatus(analyzerStatus);
});
.ifPresent(v -> v.addAnalyzerStatus(analyzerStatus));
projectRepository.create(newProject);
} else {
logger.atInfo().log("Updating commit hash for %s", name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import io.github.martinwitt.laughing_train.data.ProjectRequest;
import io.github.martinwitt.laughing_train.data.ProjectResult;
import io.github.martinwitt.laughing_train.domain.entity.Project;
import io.github.martinwitt.laughing_train.domain.entity.RemoteProject;
import io.github.martinwitt.laughing_train.mining.requests.GetProject;
import io.github.martinwitt.laughing_train.persistence.repository.ProjectRepository;
import io.github.martinwitt.laughing_train.services.ProjectService;
Expand Down Expand Up @@ -48,7 +48,7 @@ public void start() throws Exception {

void supplyProject(Message<GetProject> getProject) {
try {
Project project = getRandomProject();
RemoteProject project = getRandomProject();
ProjectResult checkoutProject = checkoutProject(project);
Log.info("Project %s checked out".formatted(project.getProjectUrl()));
getProject.reply(checkoutProject);
Expand All @@ -57,19 +57,19 @@ void supplyProject(Message<GetProject> getProject) {
}
}

private ProjectResult checkoutProject(Project project) throws IOException {
private ProjectResult checkoutProject(RemoteProject project) throws IOException {
return projectService.handleProjectRequest(new ProjectRequest.WithUrl(project.getProjectUrl()));
}

private Project getRandomProject() throws IOException {
private RemoteProject getRandomProject() throws IOException {
if (random.nextBoolean()) {
return searchProjectService.searchProjectOnGithub();
} else {
return getKnownProject();
}
}

private Project getKnownProject() {
private RemoteProject getKnownProject() {
var list = projectRepository.getAll();
return list.get(random.nextInt(list.size()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package io.github.martinwitt.laughing_train.mining;

import com.google.common.flogger.FluentLogger;
import io.github.martinwitt.laughing_train.domain.entity.Project;
import io.github.martinwitt.laughing_train.domain.entity.ProjectConfig;
import io.github.martinwitt.laughing_train.domain.entity.RemoteProject;
import io.github.martinwitt.laughing_train.persistence.repository.ProjectConfigRepository;
import io.github.martinwitt.laughing_train.persistence.repository.ProjectRepository;
import io.quarkus.logging.Log;
Expand Down Expand Up @@ -45,12 +45,12 @@ public SearchProjectService(
}

/**
* Searches for a random project on github and returns it as a {@link Project}.
* Searches for a random project on github and returns it as a {@link RemoteProject}.
* Only projects from the config property {@code mining.github.search.orgs} are considered.
* @return a random project from github as a {@link Project}
* @return a random project from github as a {@link RemoteProject}
* @throws IOException
*/
public Project searchProjectOnGithub() throws IOException {
public RemoteProject searchProjectOnGithub() throws IOException {
var repo = findRandomRepositoryOnGithub();
if (repo == null) {
throw new IOException("No project found on github");
Expand All @@ -65,7 +65,7 @@ public Project searchProjectOnGithub() throws IOException {
* @param ghRepo the repository to search for
* @return the repository if it exists, null otherwise
*/
private Project getProject(GHRepository ghRepo) {
private RemoteProject getProject(GHRepository ghRepo) {
var list = projectRepository.findByProjectUrl(ghRepo.getHtmlUrl().toString());
if (list.isEmpty()) {
return projectRepository.create(toProject(ghRepo));
Expand All @@ -78,7 +78,7 @@ private Project getProject(GHRepository ghRepo) {
* @param project the project to persist
* @return the persisted project or the project from the database if it already existed
*/
private Project persistProject(Project project) {
private RemoteProject persistProject(RemoteProject project) {
var list = projectRepository.findByProjectUrl(project.getProjectUrl());
if (list.isEmpty()) {
return projectRepository.create(project);
Expand All @@ -87,7 +87,7 @@ private Project persistProject(Project project) {
}
}

private void persistProjectConfigIfMissing(Project project) {
private void persistProjectConfigIfMissing(RemoteProject project) {
String projectUrl = project.getProjectUrl();
var projectConfig = projectConfigRepository.findByProjectUrl(projectUrl);
if (projectConfig.isEmpty()) {
Expand Down Expand Up @@ -120,9 +120,9 @@ private String getRandomOrgName() {
return org;
}

private Project toProject(GHRepository ghRepo) {
private RemoteProject toProject(GHRepository ghRepo) {
String ghRepoUrl = ghRepo.getHtmlUrl().toString();
return new Project(ghRepo.getName(), ghRepoUrl);
return new RemoteProject(ghRepo.getName(), ghRepoUrl);
}

@Readiness
Expand Down
Loading

0 comments on commit fc89ddf

Please sign in to comment.