Skip to content

Commit

Permalink
Merge pull request #38 from 2024-Iris/issue-detail
Browse files Browse the repository at this point in the history
이슈 상세보기 및 댓글 조회 기능 구현
  • Loading branch information
dokkisan authored Sep 8, 2024
2 parents 5b50b89 + 4ed76c4 commit d3c3380
Show file tree
Hide file tree
Showing 31 changed files with 672 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import lombok.extern.slf4j.Slf4j;
import site.iris.issuefy.exception.github.GithubApiException;
import site.iris.issuefy.exception.network.LokiException;
import site.iris.issuefy.exception.network.NetworkException;
import site.iris.issuefy.exception.resource.ResourceNotFoundException;
import site.iris.issuefy.exception.validation.ValidationException;
Expand Down Expand Up @@ -60,6 +61,11 @@ public ResponseEntity<ErrorResponse> handleValidationException(NetworkException
return ResponseEntity.status(e.getStatus()).body(new ErrorResponse(e.getMessage()));
}

@ExceptionHandler(LokiException.class)
public ResponseEntity<ErrorResponse> handleLokiException(LokiException e) {
return ResponseEntity.status(e.getStatus()).body(new ErrorResponse(e.getMessage()));
}

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleAll(Exception e) {
return createErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ private Object logController(ProceedingJoinPoint joinPoint, String controllerTyp
public void logServiceException(JoinPoint joinPoint, Exception ex) {
Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
String methodName = joinPoint.getSignature().getName();
logger.error("Exception in method: {} - Error: {}", methodName, ex.getMessage(), ex);
logger.error("Exception in method: {} - Error: {}", methodName, ex.getMessage());
}

@Around("execution(* site.iris.issuefy.service..*.github*(..))")
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/site/iris/issuefy/config/WebClientConfig.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package site.iris.issuefy.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class WebClientConfig {

@Value("${loki.url}")
private String lokiUrl;

@Bean(name = "apiWebClient")
public WebClient apiWebClient() {
return WebClient.builder()
Expand All @@ -20,6 +27,13 @@ public WebClient accessTokenWebClient() {
.baseUrl("https://github.com/")
.build();
}

@Bean(name = "lokiWebClient")
public WebClient lokiWebClient() {
return WebClient.builder()
.baseUrl(lokiUrl)
.build();
}
}


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

import lombok.RequiredArgsConstructor;
import site.iris.issuefy.entity.Jwt;
import site.iris.issuefy.filter.JwtAuthenticationFilter;
import site.iris.issuefy.model.dto.UserDto;
import site.iris.issuefy.response.OauthResponse;
import site.iris.issuefy.service.AuthenticationService;
Expand All @@ -33,7 +34,7 @@ public ResponseEntity<OauthResponse> login(@RequestParam String code) {
claims.put("githubId", userDto.getGithubId());
Jwt jwt = tokenProvider.createJwt(claims);

MDC.put("githubId", userDto.getGithubId());
MDC.put("user", JwtAuthenticationFilter.maskId(userDto.getGithubId()));
return ResponseEntity.ok()
.body(OauthResponse.of(userDto.getGithubId(), userDto.getEmail(), userDto.getGithubProfileImage(),
userDto.isAlertStatus(), jwt
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package site.iris.issuefy.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;
import site.iris.issuefy.response.DashBoardResponse;
import site.iris.issuefy.service.DashBoardService;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/dashboard")
public class DashBoardController {
private final DashBoardService dashBoardService;

@GetMapping
public ResponseEntity<DashBoardResponse> dashboard(@RequestAttribute String githubId) {
DashBoardResponse dashBoardResponse = dashBoardService.getDashBoardFromLoki(githubId);
return ResponseEntity.ok().body(dashBoardResponse);
}
}
14 changes: 12 additions & 2 deletions src/main/java/site/iris/issuefy/controller/IssueController.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;
import site.iris.issuefy.response.IssueDetailAndCommentsResponse;
import site.iris.issuefy.response.PagedRepositoryIssuesResponse;
import site.iris.issuefy.response.StarRepositoryIssuesResponse;
import site.iris.issuefy.service.IssueService;
Expand All @@ -34,13 +35,22 @@ public ResponseEntity<PagedRepositoryIssuesResponse> getIssuesByRepoName(@PathVa
return ResponseEntity.status(HttpStatus.OK).body(response);
}

@GetMapping("/issue_star")
@GetMapping("/{org_name}/{repo_name}/issues/{issue_number}")
public ResponseEntity<IssueDetailAndCommentsResponse> getIssueDetails(@PathVariable("org_name") String orgName,
@PathVariable("repo_name") String repoName,
@PathVariable("issue_number") String issueNumber, @RequestAttribute String githubId) {
IssueDetailAndCommentsResponse issueDetailAndCommentResponse = issueService.getIssueDetailAndComments(orgName,
repoName, issueNumber, githubId);
return ResponseEntity.status(HttpStatus.OK).body(issueDetailAndCommentResponse);
}

@GetMapping("/issue-star")
public ResponseEntity<StarRepositoryIssuesResponse> getIssueStar(@RequestAttribute String githubId) {
StarRepositoryIssuesResponse response = issueService.getStarredRepositoryIssuesResponse(githubId);
return ResponseEntity.status(HttpStatus.OK).body(response);
}

@PutMapping("/issue_star/{gh_issue_id}")
@PutMapping("/issue-star/{gh_issue_id}")
public ResponseEntity<Void> updateIssueStar(@RequestAttribute String githubId,
@PathVariable("gh_issue_id") Long issueId) {
issueService.toggleIssueStar(githubId, issueId);
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/site/iris/issuefy/entity/Issue.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Entity
@NoArgsConstructor
@Getter
@Table(name = "issue")
@ToString
public class Issue {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/site/iris/issuefy/eums/DashBoardRank.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package site.iris.issuefy.eums;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum DashBoardRank {
S(80, "S"),
A(60, "A"),
B(40, "B"),
C(20, "C"),
D(0, "D");

private final int threshold;
private final String label;

public static String getRankLabel(int score) {
for (DashBoardRank rank : values()) {
if (score >= rank.threshold) {
return rank.label;
}
}
return D.label;
}
}
1 change: 1 addition & 0 deletions src/main/java/site/iris/issuefy/eums/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public enum ErrorCode {
INVALID_TOKEN_TYPE(HttpStatus.UNAUTHORIZED, "Invalid token type"),
INVALID_REPOSITORY_URL(HttpStatus.BAD_REQUEST, "Invalid Repository URL"),
REPOSITORY_BODY_EMPTY(HttpStatus.INTERNAL_SERVER_ERROR, "Repository info body is empty"),
LOKI_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, "Loki Query error"),
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "Internal Server Error");

private final HttpStatus status;
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/site/iris/issuefy/eums/LokiQuery.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package site.iris.issuefy.eums;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum LokiQuery {
NUMBER_OF_WEEKLY_VISIT(
"sum(count_over_time({job=\"issuefylog\"} |= \"[%s]\" |= \"Response: 200 GET /api/login - Method: login \" [6d]))"),
NUMBER_OF_WEEKLY_REPOSITORY_ADDED(
"sum(count_over_time({job=\"issuefylog\"} |= \"[%s]\" |= \"Request: POST /api/subscriptions - Method: addRepository \" [6d]))");

private final String query;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package site.iris.issuefy.exception.network;

import org.springframework.http.HttpStatus;

public class LokiException extends NetworkException {
public LokiException(String message, HttpStatus status) {
super(message, status);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull Ht

Claims claims = tokenProvider.getClaims(token);
String githubId = (String)claims.get("githubId");

//TODO 아이디 해시값으로 처리
MDC.put("user", maskId(githubId));
request.setAttribute("githubId", githubId);

Expand Down
25 changes: 25 additions & 0 deletions src/main/java/site/iris/issuefy/model/dto/CommentsDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package site.iris.issuefy.model.dto;

import java.time.LocalDateTime;

import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Data;

@Data
public class CommentsDto {
@JsonProperty("id")
private Long id;

@JsonProperty("user")
private IssueUserDto issueUserDto;

@JsonProperty("created_at")
private LocalDateTime createdAt;

@JsonProperty("updated_at")
private LocalDateTime updatedAt;

@JsonProperty("body")
private String body;
}
35 changes: 35 additions & 0 deletions src/main/java/site/iris/issuefy/model/dto/IssueDetailDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package site.iris.issuefy.model.dto;

import java.time.LocalDateTime;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Data;

@Data
public class IssueDetailDto {
@JsonProperty("number")
private Long id;

@JsonProperty("title")
private String title;

@JsonProperty("state")
private String state;

@JsonProperty("user")
private IssueUserDto issueUserDto;

@JsonProperty("created_at")
private LocalDateTime createdAt;

@JsonProperty("updated_at")
private LocalDateTime updatedAt;

@JsonProperty("body")
private String body;

@JsonProperty("labels")
private List<LabelDto> labels;
}
2 changes: 1 addition & 1 deletion src/main/java/site/iris/issuefy/model/dto/IssueDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@Data
@AllArgsConstructor
public class IssueDto {
@JsonProperty("id")
@JsonProperty("number")
private Long ghIssueId;

private String title;
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/site/iris/issuefy/model/dto/IssueUserDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package site.iris.issuefy.model.dto;

import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Data;

@Data
public class IssueUserDto {
@JsonProperty("login")
private String githubId;

@JsonProperty("avatar_url")
private String githubProfileImage;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package site.iris.issuefy.model.dto;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Data;

@Data
public class LokiQueryAddRepositoryDto {
private String addRepositoryCount = "0";

@JsonProperty("data")
private void unpackData(Data data) {
if (data.getResult() != null && !data.getResult().isEmpty()) {
addRepositoryCount = data.getResult().get(0).getValue().get(1);
}
}

@lombok.Data
private static class Data {
private List<Result> result;
}

@lombok.Data
private static class Result {
private List<String> value;
}
}
29 changes: 29 additions & 0 deletions src/main/java/site/iris/issuefy/model/dto/LokiQueryVisitDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package site.iris.issuefy.model.dto;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Data;

@Data
public class LokiQueryVisitDto {
private String visitCount = "0";

@JsonProperty("data")
private void unpackData(Data data) {
if (data.getResult() != null && !data.getResult().isEmpty()) {
visitCount = data.getResult().get(0).getValue().get(1);
}
}

@lombok.Data
private static class Data {
private List<Result> result;
}

@lombok.Data
private static class Result {
private List<String> value;
}
}
21 changes: 21 additions & 0 deletions src/main/java/site/iris/issuefy/response/DashBoardResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package site.iris.issuefy.response;

import java.time.LocalDate;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class DashBoardResponse {
private LocalDate startDate;
private LocalDate endDate;
private String rank;
private String visitCount;
private String addRepositoryCount;

public static DashBoardResponse of(LocalDate startDate, LocalDate endDate, String rank, String visitCount,
String addRepositoryCount) {
return new DashBoardResponse(startDate, endDate, rank, visitCount, addRepositoryCount);
}
}
Loading

0 comments on commit d3c3380

Please sign in to comment.