Skip to content

Commit

Permalink
Merge branch 'main' into ADM-727
Browse files Browse the repository at this point in the history
  • Loading branch information
Lei010 authored Jan 10, 2024
2 parents 00b3a7f + dff3aad commit 7cab7c3
Show file tree
Hide file tree
Showing 60 changed files with 1,729 additions and 382 deletions.
10 changes: 10 additions & 0 deletions backend/src/main/java/heartbeat/client/GitHubFeignClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,26 @@
@FeignClient(name = "githubFeignClient", url = "${github.url}", configuration = GitHubFeignClientDecoder.class)
public interface GitHubFeignClient {

@GetMapping(path = "/octocat")
void verifyToken(@RequestHeader("Authorization") String token);

@GetMapping(path = "/repos/{repository}/branches/{branchName}")
void verifyCanReadTargetBranch(@PathVariable String repository, @PathVariable String branchName,
@RequestHeader("Authorization") String token);

@GetMapping(path = "/user/orgs")
@ResponseStatus(HttpStatus.OK)
@Deprecated
List<GitHubOrganizationsInfo> getGithubOrganizationsInfo(@RequestHeader("Authorization") String token);

@GetMapping(path = "/user/repos")
@ResponseStatus(HttpStatus.OK)
@Deprecated
List<GitHubRepo> getAllRepos(@RequestHeader("Authorization") String token);

@GetMapping(path = "/orgs/{organizationName}/repos")
@ResponseStatus(HttpStatus.OK)
@Deprecated
List<GitHubRepo> getReposByOrganizationName(@PathVariable String organizationName,
@RequestHeader("Authorization") String token);

Expand Down
17 changes: 13 additions & 4 deletions backend/src/main/java/heartbeat/client/JiraFeignClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import heartbeat.client.dto.board.jira.CardHistoryResponseDTO;
import heartbeat.client.dto.board.jira.FieldResponseDTO;
import heartbeat.client.dto.board.jira.JiraBoardConfigDTO;
import heartbeat.client.dto.board.jira.JiraBoardProject;
import heartbeat.client.dto.board.jira.JiraBoardVerifyDTO;
import heartbeat.client.dto.board.jira.StatusSelfDTO;
import heartbeat.decoder.JiraFeignClientDecoder;
import org.springframework.cache.annotation.Cacheable;
Expand Down Expand Up @@ -30,13 +32,20 @@ StatusSelfDTO getColumnStatusCategory(URI baseUrl, @PathVariable String statusNu
String getJiraCards(URI baseUrl, @PathVariable String boardId, @PathVariable int queryCount,
@PathVariable int startAt, @PathVariable String jql, @RequestHeader String authorization);

@Cacheable(cacheNames = "jiraActivityFeed", key = "#jiraCardKey")
@GetMapping(path = "/rest/internal/2/issue/{jiraCardKey}/activityfeed")
CardHistoryResponseDTO getJiraCardHistory(URI baseUrl, @PathVariable String jiraCardKey,
@RequestHeader String authorization);
@GetMapping(path = "/rest/internal/2/issue/{jiraCardKey}/activityfeed?startAt={startAt}&maxResults={queryCount}")
CardHistoryResponseDTO getJiraCardHistoryByCount(URI baseUrl, @PathVariable String jiraCardKey,
@PathVariable int startAt, @PathVariable int queryCount, @RequestHeader String authorization);

@Cacheable(cacheNames = "targetField", key = "#projectKey")
@GetMapping(path = "/rest/api/2/issue/createmeta?projectKeys={projectKey}&expand=projects.issuetypes.fields")
FieldResponseDTO getTargetField(URI baseUrl, @PathVariable String projectKey, @RequestHeader String authorization);

@Cacheable(cacheNames = "boardVerification", key = "#boardId")
@GetMapping(path = "/rest/agile/1.0/board/{boardId}")
JiraBoardVerifyDTO getBoard(URI baseUrl, @PathVariable String boardId, @RequestHeader String authorization);

@Cacheable(cacheNames = "boardProject", key = "#projectIdOrKey")
@GetMapping(path = "rest/api/2/project/{projectIdOrKey}")
JiraBoardProject getProject(URI baseUrl, @PathVariable String projectIdOrKey, @RequestHeader String authorization);

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
@AllArgsConstructor
public class CardHistoryResponseDTO implements Serializable {

private Boolean isLast;

private List<HistoryDetail> items;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package heartbeat.client.dto.board.jira;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@Data
@Builder
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class JiraBoardProject {

private String style;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package heartbeat.client.dto.board.jira;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class JiraBoardVerifyDTO implements Serializable {

private String id;

private String name;

private String type;

private Location location;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package heartbeat.client.dto.board.jira;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Location implements Serializable {

private String projectKey;

}
4 changes: 4 additions & 0 deletions backend/src/main/java/heartbeat/config/CacheConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import heartbeat.client.dto.board.jira.CardHistoryResponseDTO;
import heartbeat.client.dto.board.jira.FieldResponseDTO;
import heartbeat.client.dto.board.jira.JiraBoardConfigDTO;
import heartbeat.client.dto.board.jira.JiraBoardProject;
import heartbeat.client.dto.board.jira.JiraBoardVerifyDTO;
import heartbeat.client.dto.board.jira.StatusSelfDTO;
import java.time.Duration;
import javax.cache.CacheManager;
Expand Down Expand Up @@ -31,6 +33,8 @@ public CacheManager ehCacheManager() {
cacheManager.createCache("jiraStatusCategory", getCacheConfiguration(StatusSelfDTO.class));
cacheManager.createCache("jiraActivityFeed", getCacheConfiguration(CardHistoryResponseDTO.class));
cacheManager.createCache("targetField", getCacheConfiguration(FieldResponseDTO.class));
cacheManager.createCache("boardVerification", getCacheConfiguration(JiraBoardVerifyDTO.class));
cacheManager.createCache("boardProject", getCacheConfiguration(JiraBoardProject.class));
return cacheManager;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import heartbeat.controller.board.dto.request.BoardRequestParam;
import heartbeat.controller.board.dto.request.BoardType;
import heartbeat.controller.board.dto.request.BoardVerifyRequestParam;
import heartbeat.controller.board.dto.response.BoardConfigDTO;
import heartbeat.controller.board.dto.response.JiraVerifyResponse;
import heartbeat.service.board.jira.JiraService;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
Expand All @@ -26,4 +28,17 @@ public BoardConfigDTO getBoard(@PathVariable @NotBlank BoardType boardType,
return jiraService.getJiraConfiguration(boardType, boardRequestParam);
}

@PostMapping("/{boardType}/verify")
public JiraVerifyResponse verify(@PathVariable @NotBlank BoardType boardType,
@Valid @RequestBody BoardVerifyRequestParam boardRequestParam) {
String projectKey = jiraService.verify(boardType, boardRequestParam);
return JiraVerifyResponse.builder().projectKey(projectKey).build();
}

@PostMapping("/{boardType}/info")
public BoardConfigDTO getInfo(@PathVariable @NotBlank BoardType boardType,
@Valid @RequestBody BoardRequestParam boardRequestParam) {
return jiraService.getInfo(boardType, boardRequestParam);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package heartbeat.controller.board.dto.request;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BoardVerifyRequestParam {

@NotBlank(message = "Board Id cannot be empty.")
private String boardId;

@NotBlank(message = "Site cannot be empty.")
private String site;

@Valid
@NotBlank(message = "Token cannot be empty.")
private String token;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package heartbeat.controller.board.dto.response;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class JiraVerifyResponse {

private String projectKey;

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@

import heartbeat.controller.source.dto.GitHubResponse;
import heartbeat.controller.source.dto.SourceControlDTO;
import heartbeat.controller.source.dto.VerifyBranchRequest;
import heartbeat.exception.BadRequestException;
import heartbeat.service.source.github.GitHubService;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
Expand All @@ -23,10 +28,13 @@
@Log4j2
public class GithubController {

public static final String TOKEN_PATTER = "^(ghp|gho|ghu|ghs|ghr)_([a-zA-Z0-9]{36})$";

private final GitHubService gitHubService;

@PostMapping
@CrossOrigin
@Deprecated(since = "frontend completed")
@ResponseStatus(HttpStatus.OK)
public GitHubResponse getRepos(@RequestBody @Valid SourceControlDTO sourceControlDTO) {
log.info("Start to get repos by token");
Expand All @@ -36,4 +44,38 @@ public GitHubResponse getRepos(@RequestBody @Valid SourceControlDTO sourceContro

}

@PostMapping("/{sourceType}/verify")
public ResponseEntity<Void> verifyToken(@PathVariable @NotBlank String sourceType,
@RequestBody @Valid SourceControlDTO sourceControlDTO) {
log.info("Start to verify source type: {} token.", sourceType);
switch (SourceType.matchSourceType(sourceType)) {
case GITHUB -> {
gitHubService.verifyTokenV2(sourceControlDTO.getToken());
log.info("Successfully verify source type: {} token.", sourceType);
}
default -> {
log.error("Failed to verify source type: {} token.", sourceType);
throw new BadRequestException("Source type is incorrect.");
}
}
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}

@PostMapping("/{sourceType}/repos/branches/{branch}/verify")
public ResponseEntity<Void> verifyBranch(@PathVariable @NotBlank String sourceType,
@PathVariable @NotBlank String branch, @RequestBody @Valid VerifyBranchRequest request) {
log.info("Start to verify source type: {} branch: {}.", sourceType, branch);
switch (SourceType.matchSourceType(sourceType)) {
case GITHUB -> {
gitHubService.verifyCanReadTargetBranch(request.getRepository(), branch, request.getToken());
log.info("Successfully verify source type: {} branch: {}.", sourceType, branch);
}
default -> {
log.error("Failed to verify source type: {} branch: {}.", sourceType, branch);
throw new BadRequestException("Source type is incorrect.");
}
}
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}

}
25 changes: 25 additions & 0 deletions backend/src/main/java/heartbeat/controller/source/SourceType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package heartbeat.controller.source;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum SourceType {

GITHUB("github"),

ANOTHERSOURCETYPE("anotherSourceType");

private String value;

public static SourceType matchSourceType(String value) {
return switch (value) {
case "github" -> GITHUB;
default -> ANOTHERSOURCETYPE;
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

@Data
@Builder
@Deprecated
public class GitHubResponse {

private LinkedHashSet<String> githubRepos;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
package heartbeat.controller.source.dto;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import static heartbeat.controller.source.GithubController.TOKEN_PATTER;

@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class SourceControlDTO {

private String type;

@Valid
@NotBlank(message = "Token cannot be empty.")
@Pattern(regexp = "^(ghp|gho|ghu|ghs|ghr)_([a-zA-Z0-9]{36})$", message = "token's pattern is incorrect")
@NotNull(message = "Token cannot be empty.")
@Pattern(regexp = TOKEN_PATTER, message = "token's pattern is incorrect")
private String token;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package heartbeat.controller.source.dto;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import static heartbeat.controller.source.GithubController.TOKEN_PATTER;

@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class VerifyBranchRequest {

@NotNull(message = "Token cannot be empty.")
@Pattern(regexp = TOKEN_PATTER, message = "token's pattern is incorrect")
private String token;

@NotBlank(message = "Repository is required.")
private String repository;

}
Loading

0 comments on commit 7cab7c3

Please sign in to comment.