Skip to content

Commit 45cd7c9

Browse files
Merge pull request #19 from cqse/ts/44526_metric_assessment_endpoint_npe
TS-44526 Implement parsing of new metric-assessment response
2 parents 935fdb8 + 483d5a0 commit 45cd7c9

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

src/main/java/com/teamscale/buildbreaker/evaluation/ProblemCategory.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22

33
/** The categories in which problems are divided. */
44
public enum ProblemCategory {
5-
WARNING, ERROR;
5+
WARNING, ERROR, NO_PROBLEM;
66

77
public static ProblemCategory fromRatingString(String rating) {
88
switch (rating) {
99
case "YELLOW":
1010
return WARNING;
1111
case "RED":
1212
return ERROR;
13+
default:
14+
return NO_PROBLEM;
1315
}
14-
throw new IllegalArgumentException("Unexpected rating string " + rating);
1516
}
1617
}

src/main/java/com/teamscale/buildbreaker/teamscale_client/TeamscaleClient.java

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import okhttp3.RequestBody;
2222
import okhttp3.Response;
2323
import okhttp3.ResponseBody;
24+
import org.conqat.lib.commons.assessment.Assessment;
25+
import org.conqat.lib.commons.assessment.ETrafficLightColor;
2426
import org.conqat.lib.commons.collections.Pair;
2527
import org.conqat.lib.commons.string.StringUtils;
2628

@@ -145,6 +147,11 @@ public List<MetricViolation> fetchMetricAssessments(String branchAndTimestamp, S
145147
HttpUrl url = builder.build();
146148
Request request = createAuthenticatedGetRequest(url);
147149
String response = sendRequest(request);
150+
if(response.contains("formattedTextValue")) {
151+
// With TS v2024.9 the response scheme of this internal api endpoint has changed,
152+
// removing the value "formattedTextValue". See TS-44526
153+
return parseMetricResponsePreTS20249(response);
154+
}
148155
return parseMetricResponse(response);
149156
}
150157

@@ -298,18 +305,57 @@ private static List<Finding> parseFindings(List<Map<String, Object>> findingsRaw
298305
}
299306
}
300307

301-
private List<MetricViolation> parseMetricResponse(String response) throws ParserException {
308+
private List<MetricViolation> parseMetricResponsePreTS20249(String response) throws ParserException {
302309
List<MetricViolation> result = new ArrayList<>();
303310
try {
304311
DocumentContext metricAssessments = JsonPath.parse(response);
305312
List<Map<String, Object>> metricViolations = metricAssessments.read("$..metrics.*");
306313
for (Map<String, Object> metricViolation : metricViolations) {
307-
Map<String, String> metricThresholds = (Map<String, String>) metricViolation.get("metricThresholds");
314+
ProblemCategory rating = ProblemCategory.fromRatingString((String) metricViolation.get("rating"));
315+
if(ProblemCategory.NO_PROBLEM.equals(rating)) {
316+
continue;
317+
}
318+
Map<String, Object> metricThresholds = (Map<String, Object>) metricViolation.get("metricThresholds");
308319
String displayName = metricViolation.get("displayName").toString();
309-
String yellowThreshold = metricThresholds.get("thresholdYellow");
310-
String redThreshold = metricThresholds.get("thresholdRed");
320+
String yellowThreshold = metricThresholds.get("thresholdYellow") != null ? metricThresholds.get("thresholdYellow").toString() : "";
321+
String redThreshold = metricThresholds.get("thresholdRed") != null ? metricThresholds.get("thresholdRed").toString() : "";
311322
String formattedTextValue = metricViolation.get("formattedTextValue").toString();
323+
result.add(new MetricViolation(displayName, yellowThreshold, redThreshold, formattedTextValue, rating));
324+
}
325+
return result;
326+
} catch (ClassCastException | PathNotFoundException e) {
327+
throw new ParserException("Could not parse metrics JSON response:\n" + response + "\n\nPlease contact CQSE with an error report.", e);
328+
}
329+
}
330+
331+
private List<MetricViolation> parseMetricResponse(String response) throws ParserException {
332+
List<MetricViolation> result = new ArrayList<>();
333+
try {
334+
DocumentContext metricAssessments = JsonPath.parse(response);
335+
List<Map<String, Object>> metricViolations = metricAssessments.read("$..metrics.*");
336+
for (Map<String, Object> metricViolation : metricViolations) {
312337
ProblemCategory rating = ProblemCategory.fromRatingString((String) metricViolation.get("rating"));
338+
if(ProblemCategory.NO_PROBLEM.equals(rating)) {
339+
continue;
340+
}
341+
String displayName = metricViolation.get("displayName").toString();
342+
Map<String, Object> metricThresholds = (Map<String, Object>) metricViolation.get("metricThresholds");
343+
String yellowThreshold = metricThresholds.get("thresholdYellow") != null ? metricThresholds.get("thresholdYellow").toString() : "";
344+
String redThreshold = metricThresholds.get("thresholdRed") != null ? metricThresholds.get("thresholdRed").toString() : "";
345+
Map<String, String> schemaEntry = (Map<String, String>) metricViolation.get("schemaEntry");
346+
String formattedTextValue;
347+
if("ASSESSMENT".equals(schemaEntry.get("valueType"))) {
348+
Map<String, Object> value = (Map<String, Object>) metricViolation.get("value");
349+
List<Number> mappingList = (List<Number>) value.get("mapping");
350+
int[] mapping = mappingList.stream().mapToInt(Number::intValue).toArray();
351+
Assessment assessment = new Assessment();
352+
for (int i = 0; i < mapping.length; i++) {
353+
assessment.add(ETrafficLightColor.values()[i], mapping[i]);
354+
}
355+
formattedTextValue = assessment.toFormattedColorDistributionString();
356+
} else {
357+
formattedTextValue = metricViolation.get("value").toString();
358+
}
313359
result.add(new MetricViolation(displayName, yellowThreshold, redThreshold, formattedTextValue, rating));
314360
}
315361
return result;

0 commit comments

Comments
 (0)