Skip to content

Commit

Permalink
ADM-873: [frontend][backend] feat: optimize generate report api (#1271)
Browse files Browse the repository at this point in the history
* ADM-873: [backend] feat: modify url and add metricTypes list in request and modify relevant test

* ADM-873: [backend] feat: optimize GenerateReporterService logic and delete some unused tests

* Revert "ADM-822: [frontend] fix: fix pooling logic (#1102)"

* ADM-873: [backend] test: modify tests

* ADM-873: [backend] test: add tests to cover all new logic

* ADM-873: [backend] fix: fix the bug that can not delete metricDataCompleted file

* ADM-873: [backend] test: delete unused method

* ADM-873: [backend] feat: change metricDataCompleted type to Boolean

* ADM-873: [backend] refactor: rename method generateReportByType to generateReport

* ADM-873: [backend] docs: update generate report sequence diagram

* ADM-873: [backend] feat: add async thread

* ADM-873:[backend] feat: update logic for exception condition

* ADM-873:[backend] fix: update generate report logic

* ADM-873: [frontend]feat: add metricTypes into IBasicReportRequestDTO

* ADM-873: [frontend]feat: fetch data in ReportStep component

* ADM-873: [frontend]feat: combine startToRequestBoardData and startToRequestDoraData

* ADM-873: [frontend]fix: fix test

* ADM-873: [frontend]feat: modify source

* ADM-873: [frontend] fix: fix unit test

* ADM-873: [frontend]fix: fix test

* ADM-873: [frontend]feat: combine startToRequestData and startToRequestDoraData

* ADM-873: [frontend]refactor: extract getReportRequestBody from BoardMetrics and DoraMetrics

* ADM-873: [frontend]refactor: refactor ReportStep

* ADM-873: [frontend]feat: add test for useGenerateReportEffect

* ADM-873: [frontend]refactor: refactor code

* ADM-873: [frontend]feat: add test fpr ReportStep

* ADM-873: [backend] feat: modify url and add metricTypes list in request and modify relevant test

* ADM-873: [backend] feat: optimize GenerateReporterService logic and delete some unused tests

* ADM-873: [backend] test: modify tests

* ADM-873: [backend] test: add tests to cover all new logic

* ADM-873: [backend] fix: fix the bug that can not delete metricDataCompleted file

* ADM-873: [backend] test: delete unused method

* ADM-873: [backend] feat: change metricDataCompleted type to Boolean

* ADM-873: [backend] refactor: rename method generateReportByType to generateReport

* ADM-873: [backend] docs: update generate report sequence diagram

* ADM-873: [backend] feat: add async thread

* ADM-873:[backend] feat: update logic for exception condition

* ADM-873:[backend] fix: update generate report logic

* ADM-873:[backend] fix: update test

* ADM-873:[backend] fix: fix sonar issue

* ADM-873:[backend] fix: refactor smell code

* ADM-873:[backend] fix: rename constant name

* ADM-873:[backend] fix: rename constant name

* ADM-873:[frontend]fix: fix the error handling

* ADM-873:[frontend]fix: treating null value as request completed.

* ADM-873:[frontend]refactor: rename areAllMetricsCompleted to areMetricsLoading

* ADM-873:[frontend]fix: fix define of isBoardMetricsLoading

* ADM-873:[frontend]refactor: refactor areMetricsLoading

* ADM-873:[frontend]fix: fix conflict

* ADM-873:[frontend]refactor: refactor code

* ADM-873:[frontend]refactor: remove isBackFromDetail

* ADM-873:[frontend]refactor: remove unnecessary includeRework

* ADM-873:[frontend]feat: add overallMetricsCompleted & stop polling based on the status of allMetricsCompleted

* ADM-873:[frontend]fix: fix test

* ADM-873:[frontend]refactor: optimizing disabled logic

* ADM-893:[backend] fix: add overall metric completed to update logic for button

* ADM-893:[backend] fix: fix some sonar error and refactor

* ADM-893:[backend] fix: fix pmd error

* ADM-893:[backend] fix: fix sonar error

* ADM-893:[docs] fix: update logic for design

* Revert "ADM-873:[frontend]refactor: optimizing disabled logic"

This reverts commit de4c74e.

* ADM-893:[docs] docs: update description for allMetricCompleted

* ADM-873:[frontend][backend] fix: update metric type to enum when generate report

* ADM-873:[backend] fix: because update metric to enum so fix test

* ADM-873:[frontend]fix: fix test description from biz aspect

* ADM-873:[backend] fix: fix test Codacy Static Code Analysis

* ADM-873:[backend] fix: refactor code

* ADM-873:[backend] fix: format code

* ADM-873:[backend] fix: fix sonar

* ADM-873:[backend] fix: add test for report generator

* ADM-873:[backend] fix:fix smell code

* ADM-873:[frontend]refactor: refactor error handler

---------

Co-authored-by: Shiqi Yuan <[email protected]>
Co-authored-by: yulongcai <[email protected]>
Co-authored-by: GuangbinMa <[email protected]>
Co-authored-by: yulongcai <[email protected]>
  • Loading branch information
5 people authored Apr 2, 2024
1 parent 70b8595 commit 723dbd0
Show file tree
Hide file tree
Showing 45 changed files with 1,120 additions and 726 deletions.
1 change: 1 addition & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ dependencies {
testAnnotationProcessor 'org.projectlombok:lombok:1.18.32'
implementation 'com.opencsv:opencsv:5.9'
implementation 'org.apache.commons:commons-text:1.11.0'
implementation 'org.awaitility:awaitility:3.1.6'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import heartbeat.controller.report.dto.request.GenerateReportRequest;
import heartbeat.controller.report.dto.request.ReportType;
import heartbeat.controller.report.dto.request.MetricType;
import heartbeat.controller.report.dto.response.CallbackResponse;
import heartbeat.controller.report.dto.response.ReportResponse;
import heartbeat.service.report.GenerateReporterService;
Expand Down Expand Up @@ -54,23 +53,15 @@ public InputStreamResource exportCSV(
public ResponseEntity<ReportResponse> generateReport(@PathVariable String reportId) {
log.info("Start to generate report_reportId: {}", reportId);
ReportResponse reportResponse = generateReporterService.getComposedReportResponse(reportId);
if (reportResponse.isAllMetricsCompleted()) {
log.info("Successfully generate Report_reportId: {}, reports: {}", reportId, reportResponse);
generateReporterService.generateCSVForMetric(reportResponse, reportId);
return ResponseEntity.status(HttpStatus.CREATED).body(reportResponse);
}
return ResponseEntity.status(HttpStatus.OK).body(reportResponse);
}

@PostMapping("{metricType}")
public ResponseEntity<CallbackResponse> generateReport(
@Schema(type = "string", allowableValues = { "board", "dora" },
accessMode = Schema.AccessMode.READ_ONLY) @PathVariable MetricType metricType,
@RequestBody GenerateReportRequest request) {
log.info("Start to generate report_metricType: {}", metricType);
reportService.generateReportByType(request, metricType);
@PostMapping
public ResponseEntity<CallbackResponse> generateReport(@RequestBody GenerateReportRequest request) {
log.info("Start to generate report");
reportService.generateReport(request);
String callbackUrl = "/reports/" + request.getCsvTimeStamp();
log.info("Successfully generate report_metricsType: {}", metricType);
log.info("Successfully generate report");
return ResponseEntity.status(HttpStatus.ACCEPTED)
.body(CallbackResponse.builder().callbackUrl(callbackUrl).interval(interval).build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public class GenerateReportRequest {

private List<String> metrics;

private List<MetricType> metricTypes;

private JiraBoardSetting jiraBoardSetting;

private BuildKiteSetting buildKiteSetting;
Expand Down Expand Up @@ -81,11 +83,6 @@ public String getBoardReportId() {
return IdUtil.getBoardReportId(this.csvTimeStamp);
}

@JsonIgnore
public String getDoraReportId() {
return IdUtil.getDoraReportId(this.csvTimeStamp);
}

@JsonIgnore
public GenerateReportRequest toPipelineRequest() {
return GenerateReportRequest.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.Optional;

@Builder
@NoArgsConstructor
@AllArgsConstructor
Expand All @@ -17,6 +19,8 @@ public class MetricsDataCompleted {

private Boolean doraMetricsCompleted;

private Boolean overallMetricCompleted;

public Boolean boardMetricsCompleted() {
return boardMetricsCompleted;
}
Expand All @@ -25,4 +29,13 @@ public Boolean doraMetricsCompleted() {
return doraMetricsCompleted;
}

public Boolean overallMetricCompleted() {
return overallMetricCompleted;
}

public Boolean allMetricsCompleted() {
return Optional.ofNullable(boardMetricsCompleted).orElse(true)
&& Optional.ofNullable(doraMetricsCompleted).orElse(true) && overallMetricCompleted;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ public class ReportResponse {

private Long exportValidityTime;

private boolean boardMetricsCompleted;
private Boolean boardMetricsCompleted;

private boolean doraMetricsCompleted;
private Boolean doraMetricsCompleted;

private boolean allMetricsCompleted;
private Boolean overallMetricsCompleted;

private Boolean allMetricsCompleted;

public ReportResponse(Long exportValidityTime) {
this.exportValidityTime = exportValidityTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,12 @@
import heartbeat.controller.report.dto.response.MetricsDataCompleted;
import heartbeat.exception.GenerateReportException;
import heartbeat.handler.base.AsyncDataBaseHandler;
import heartbeat.service.report.MetricsDataDTO;
import heartbeat.util.IdUtil;
import heartbeat.util.ValueUtil;
import jakarta.annotation.Nullable;
import lombok.RequiredArgsConstructor;
import lombok.Synchronized;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.Objects;
import java.util.stream.Stream;

import static heartbeat.handler.base.FIleType.METRICS_DATA_COMPLETED;

Expand All @@ -25,6 +19,8 @@
@RequiredArgsConstructor
public class AsyncMetricsDataHandler extends AsyncDataBaseHandler {

private static final String GENERATE_REPORT_ERROR = "Failed to update metrics data completed through this timestamp.";

public void putMetricsDataCompleted(String timeStamp, MetricsDataCompleted metricsDataCompleted) {
try {
acquireLock(METRICS_DATA_COMPLETED, timeStamp);
Expand All @@ -47,8 +43,8 @@ public void deleteExpireMetricsDataCompletedFile(long currentTimeStamp, File dir
public void updateMetricsDataCompletedInHandler(String metricDataFileId, MetricType metricType) {
MetricsDataCompleted previousMetricsCompleted = getMetricsDataCompleted(metricDataFileId);
if (previousMetricsCompleted == null) {
log.error("Failed to update metrics data completed through this timestamp.");
throw new GenerateReportException("Failed to update metrics data completed through this timestamp.");
log.error(GENERATE_REPORT_ERROR);
throw new GenerateReportException(GENERATE_REPORT_ERROR);
}
switch (metricType) {
case BOARD -> previousMetricsCompleted.setBoardMetricsCompleted(true);
Expand All @@ -59,31 +55,14 @@ public void updateMetricsDataCompletedInHandler(String metricDataFileId, MetricT
putMetricsDataCompleted(metricDataFileId, previousMetricsCompleted);
}

public MetricsDataDTO getReportReadyStatusByTimeStamp(String timeStamp) {
Boolean boardReadyStatus = getReadyStatus(IdUtil.getBoardReportId(timeStamp), MetricType.BOARD);
boolean isBoardReady = ValueUtil.valueOrDefault(false, boardReadyStatus);

Boolean doraReadyStatus = getReadyStatus(IdUtil.getDoraReportId(timeStamp), MetricType.DORA);
boolean isDoraReady = ValueUtil.valueOrDefault(false, doraReadyStatus);

boolean isReportReady = Stream.of(boardReadyStatus, doraReadyStatus)
.filter(Objects::nonNull)
.allMatch(Boolean::booleanValue);
return new MetricsDataDTO(isBoardReady, isDoraReady, isReportReady);
}

@Nullable
private Boolean getReadyStatus(String fileId, MetricType metricType) {
MetricsDataCompleted metricsDataCompleted = getMetricsDataCompleted(fileId);
if (metricsDataCompleted == null) {
return null;
}
else if (metricType == MetricType.BOARD) {
return metricsDataCompleted.boardMetricsCompleted();
}
else {
return metricsDataCompleted.doraMetricsCompleted();
public void updateOverallMetricsCompletedInHandler(String metricDataFileId) {
MetricsDataCompleted previousMetricsCompleted = getMetricsDataCompleted(metricDataFileId);
if (previousMetricsCompleted == null) {
log.error(GENERATE_REPORT_ERROR);
throw new GenerateReportException(GENERATE_REPORT_ERROR);
}
previousMetricsCompleted.setOverallMetricCompleted(true);
putMetricsDataCompleted(metricDataFileId, previousMetricsCompleted);
}

}
Loading

0 comments on commit 723dbd0

Please sign in to comment.