From a7818fbebc4bc73c9cde80e684404a5e807e7ff4 Mon Sep 17 00:00:00 2001 From: Dylan De Faoite Date: Thu, 25 Jun 2026 20:36:39 +0100 Subject: [PATCH] fix(maintainability): clean up reliability issues --- .../ddf/vodsystem/controllers/StreamController.java | 11 ++++++----- .../com/ddf/vodsystem/controllers/UserController.java | 7 ++++--- .../java/com/ddf/vodsystem/services/MediaService.java | 3 +-- .../java/com/ddf/vodsystem/services/UserService.java | 4 +++- .../ddf/vodsystem/services/media/MetadataService.java | 10 ++++++---- .../services/media/StreamActionsService.java | 3 ++- 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/ddf/vodsystem/controllers/StreamController.java b/src/main/java/com/ddf/vodsystem/controllers/StreamController.java index 21b9762..f51441a 100644 --- a/src/main/java/com/ddf/vodsystem/controllers/StreamController.java +++ b/src/main/java/com/ddf/vodsystem/controllers/StreamController.java @@ -16,6 +16,7 @@ import java.util.Optional; @RequestMapping("/api/v1/stream") public class StreamController { private static final Logger logger = LoggerFactory.getLogger(StreamController.class); + private static final String SUCCESS = "success"; private final StreamService streamService; @@ -28,7 +29,7 @@ public class StreamController { public ResponseEntity> startStream(@RequestParam("name") String streamKey) { logger.info("Stream start callback for key: {}", streamKey); Stream stream = streamService.startStream(streamKey); - return ResponseEntity.ok(new APIResponse<>("success", "Stream started", stream)); + return ResponseEntity.ok(new APIResponse<>(SUCCESS, "Stream started", stream)); } // Called by nginx on_publish_done @@ -36,26 +37,26 @@ public class StreamController { public ResponseEntity> stopStream(@RequestParam("name") String streamKey) { logger.info("Stream stop callback for key: {}", streamKey); streamService.endStream(streamKey); - return ResponseEntity.ok(new APIResponse<>("success", "Stream ended", null)); + return ResponseEntity.ok(new APIResponse<>(SUCCESS, "Stream ended", null)); } // Called by nginx on_update @PostMapping("/heartbeat") public ResponseEntity> heartbeat(@RequestParam("name") String streamKey) { streamService.heartbeatStream(streamKey); - return ResponseEntity.ok(new APIResponse<>("success", "Heartbeat recorded", null)); + return ResponseEntity.ok(new APIResponse<>(SUCCESS, "Heartbeat recorded", null)); } @GetMapping("/history/{userId}") public ResponseEntity>> getStreamHistory(@PathVariable Long userId) { List history = streamService.getStreamHistory(userId); - return ResponseEntity.ok(new APIResponse<>("success", "Stream history retrieved", history)); + return ResponseEntity.ok(new APIResponse<>(SUCCESS, "Stream history retrieved", history)); } @GetMapping("/current") public ResponseEntity> getCurrentStream() { Optional stream = streamService.getActiveStream(); - return stream.map(value -> ResponseEntity.ok(new APIResponse<>("success", + return stream.map(value -> ResponseEntity.ok(new APIResponse<>(SUCCESS, "Streaming status retrieved", new StreamResponse(true, value.getId())))).orElseGet(() -> ResponseEntity.ok(new APIResponse<>("success", "Streaming status retrieved", diff --git a/src/main/java/com/ddf/vodsystem/controllers/UserController.java b/src/main/java/com/ddf/vodsystem/controllers/UserController.java index dead6ab..b44c677 100644 --- a/src/main/java/com/ddf/vodsystem/controllers/UserController.java +++ b/src/main/java/com/ddf/vodsystem/controllers/UserController.java @@ -20,6 +20,7 @@ public class UserController { @Value("${jwt.expiration}") private long jwtExpiration; + private static final String SUCCESS = "success"; public UserController(UserService userService) { this.userService = userService; @@ -34,7 +35,7 @@ public class UserController { } return ResponseEntity.ok( - new APIResponse<>("success", "User retrieved successfully", user.get()) + new APIResponse<>(SUCCESS, "User retrieved successfully", user.get()) ); } @@ -54,7 +55,7 @@ public class UserController { response.addHeader("Set-Cookie", cookie.toString()); return ResponseEntity.ok( - new APIResponse<>("success", "Logged in successfully", new Token(jwt)) + new APIResponse<>(SUCCESS, "Logged in successfully", new Token(jwt)) ); } @@ -71,7 +72,7 @@ public class UserController { response.addHeader("Set-Cookie", cookie.toString()); return ResponseEntity.ok( - new APIResponse<>("success", "Logged out successfully", null) + new APIResponse<>(SUCCESS, "Logged out successfully", null) ); } } \ No newline at end of file diff --git a/src/main/java/com/ddf/vodsystem/services/MediaService.java b/src/main/java/com/ddf/vodsystem/services/MediaService.java index 8a791a9..db7ffb0 100644 --- a/src/main/java/com/ddf/vodsystem/services/MediaService.java +++ b/src/main/java/com/ddf/vodsystem/services/MediaService.java @@ -16,7 +16,6 @@ import java.nio.file.Path; import java.time.Duration; import java.time.Instant; import java.util.*; -import java.util.stream.Collectors; import java.util.stream.Stream; @Service @@ -215,7 +214,7 @@ public class MediaService { return segMs < endMs && (segMs + HLS_SEGMENT_LENGTH * 1000) > startMs; }) .sorted(Comparator.comparingLong(this::parseTimestampMs)) - .collect(Collectors.toList()); + .toList(); } } diff --git a/src/main/java/com/ddf/vodsystem/services/UserService.java b/src/main/java/com/ddf/vodsystem/services/UserService.java index ae5d28c..a312f64 100644 --- a/src/main/java/com/ddf/vodsystem/services/UserService.java +++ b/src/main/java/com/ddf/vodsystem/services/UserService.java @@ -28,6 +28,8 @@ public class UserService { private final UserRepository userRepository; private final JwtService jwtService; + private static final SecureRandom SECURE_RANDOM = new SecureRandom(); + public UserService(UserRepository userRepository, JwtService jwtService, @Value("${google.client.id}") String googleClientId) { @@ -116,7 +118,7 @@ public class UserService { private String generateStreamKey() { byte[] bytes = new byte[24]; - new SecureRandom().nextBytes(bytes); + SECURE_RANDOM.nextBytes(bytes); return HexFormat.of().formatHex(bytes); } } diff --git a/src/main/java/com/ddf/vodsystem/services/media/MetadataService.java b/src/main/java/com/ddf/vodsystem/services/media/MetadataService.java index 85f3330..9bf26b0 100644 --- a/src/main/java/com/ddf/vodsystem/services/media/MetadataService.java +++ b/src/main/java/com/ddf/vodsystem/services/media/MetadataService.java @@ -20,6 +20,8 @@ import java.util.concurrent.Future; public class MetadataService { private static final Logger logger = LoggerFactory.getLogger(MetadataService.class); + private static final String DURATION = "duration"; + @Async("ffmpegTaskExecutor") public Future getVideoMetadata(Path file) { logger.info("Getting metadata for file {}", file); @@ -78,8 +80,8 @@ public class MetadataService { } private Float extractDuration(JsonNode streamNode) { - if (streamNode.has("duration")) { - return Float.valueOf(streamNode.get("duration").asText()); + if (streamNode.has(DURATION)) { + return Float.valueOf(streamNode.get(DURATION).asText()); } throw new FFMPEGException("ffprobe duration missing"); @@ -115,8 +117,8 @@ public class MetadataService { } private void extractEndPointFromFormat(ClipOptions metadata, JsonNode formatNode) { - if (formatNode != null && formatNode.has("duration") && metadata.getDuration() == null) { - metadata.setDuration(Float.parseFloat(formatNode.get("duration").asText())); + if (formatNode != null && formatNode.has(DURATION) && metadata.getDuration() == null) { + metadata.setDuration(Float.parseFloat(formatNode.get(DURATION).asText())); } } diff --git a/src/main/java/com/ddf/vodsystem/services/media/StreamActionsService.java b/src/main/java/com/ddf/vodsystem/services/media/StreamActionsService.java index 201cc22..670a5dd 100644 --- a/src/main/java/com/ddf/vodsystem/services/media/StreamActionsService.java +++ b/src/main/java/com/ddf/vodsystem/services/media/StreamActionsService.java @@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import java.io.IOException; import java.nio.file.Path; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -75,7 +76,7 @@ public class StreamActionsService { progressTracker.markComplete(); return CompletableFuture.completedFuture(outputFile); - } catch (Exception e) { + } catch (IOException | InterruptedException e) { logger.error("Failed to save section to '{}'", outputFile, e); return CompletableFuture.failedFuture(e); }