Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
*/
package org.gridsuite.monitor.server.controllers;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
Expand Down Expand Up @@ -34,9 +37,11 @@ public class MonitorController {
private final MonitorService monitorService;

public static final String HEADER_USER_ID = "userId";
private final ObjectMapper objectMapper;

public MonitorController(MonitorService monitorService) {
public MonitorController(MonitorService monitorService, ObjectMapper objectMapper) {
this.monitorService = monitorService;
this.objectMapper = objectMapper;
}

@PostMapping("/execute/security-analysis")
Expand All @@ -61,9 +66,19 @@ public ResponseEntity<List<ReportPage>> getExecutionReports(@Parameter(descripti
@GetMapping("/executions/{executionId}/results")
@Operation(summary = "Get results for an execution")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The execution results")})
public ResponseEntity<List<String>> getExecutionResults(@Parameter(description = "Execution UUID") @PathVariable UUID executionId) {
public ResponseEntity<List<JsonNode>> getExecutionResults(@Parameter(description = "Execution UUID") @PathVariable UUID executionId) {
List<String> results = monitorService.getResults(executionId);
return ResponseEntity.ok(results);

// To make it easier to view the results during monitoring development, we return a List<JsonNode>.
// Note that the return type can be changed later when developing the front end.
List<JsonNode> resultsJsonNode = results.stream().map(resultString -> {
try {
return objectMapper.readValue(resultString, JsonNode.class);
} catch (JsonProcessingException e) {
throw new IllegalStateException(String.format("Unable to serialize result to JSON: %s", resultString), e);
}
}).toList();
Comment on lines +74 to +80
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Error message incorrectly says "serialize" instead of "deserialize".

The operation readValue is deserialization (parsing JSON string to object), not serialization. Additionally, if resultString is null, this will throw a NullPointerException rather than the expected JsonProcessingException.

Proposed fix
         List<JsonNode> resultsJsonNode = results.stream().map(resultString -> {
             try {
                 return objectMapper.readValue(resultString, JsonNode.class);
             } catch (JsonProcessingException e) {
-                throw new IllegalStateException(String.format("Unable to serialize result to JSON: %s", resultString), e);
+                throw new IllegalStateException(String.format("Unable to deserialize result from JSON: %s", resultString), e);
             }
         }).toList();

If null results are possible from monitorService.getResults(), consider filtering them out or handling explicitly:

List<JsonNode> resultsJsonNode = results.stream()
    .filter(Objects::nonNull)
    .map(resultString -> { ... })
    .toList();
🤖 Prompt for AI Agents
In
`@monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/MonitorController.java`
around lines 74 - 80, The error message in MonitorController is misleading and
nulls can cause NPEs: change the exception text in the objectMapper.readValue
handler to say "Unable to deserialize result from JSON: <resultString>" (or
similar) and guard against null entries from results before calling readValue;
e.g., filter the results stream with Objects::nonNull or add an explicit null
check in the lambda so nulls are handled (throw a clear IllegalStateException
like "Result is null" or skip them), referencing the results variable, the
objectMapper.readValue(...) call, and the lambda in the stream.

return ResponseEntity.ok(resultsJsonNode);
}

@GetMapping("/executions")
Expand Down
Loading