From 42294703ae5595dd4eb5af18f79aea082576e8d6 Mon Sep 17 00:00:00 2001 From: Dylan De Faoite Date: Thu, 25 Jun 2026 20:21:48 +0100 Subject: [PATCH] chore(backend): remove LocalDateTime usage, replaced with Instant --- .../ddf/vodsystem/controllers/dto/ClipResponse.java | 4 ++-- src/main/java/com/ddf/vodsystem/entities/Clip.java | 4 ++-- src/main/java/com/ddf/vodsystem/entities/Stream.java | 8 ++++---- src/main/java/com/ddf/vodsystem/entities/User.java | 4 ++-- .../ddf/vodsystem/repositories/StreamRepository.java | 4 ++-- .../java/com/ddf/vodsystem/services/ClipService.java | 4 ++-- .../com/ddf/vodsystem/services/StreamService.java | 12 ++++++------ .../java/com/ddf/vodsystem/services/UserService.java | 4 ++-- .../vodsystem/services/media/CompressionService.java | 2 +- .../services/media/StreamActionsService.java | 1 + src/main/resources/application-local.properties | 2 +- src/main/resources/application.properties | 5 ++++- src/main/resources/db/schema.sql | 4 ++-- 13 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/ddf/vodsystem/controllers/dto/ClipResponse.java b/src/main/java/com/ddf/vodsystem/controllers/dto/ClipResponse.java index d2f26de..da2bb92 100644 --- a/src/main/java/com/ddf/vodsystem/controllers/dto/ClipResponse.java +++ b/src/main/java/com/ddf/vodsystem/controllers/dto/ClipResponse.java @@ -1,6 +1,6 @@ package com.ddf.vodsystem.controllers.dto; -import java.time.LocalDateTime; +import java.time.Instant; public record ClipResponse( Long id, @@ -8,5 +8,5 @@ public record ClipResponse( String title, String description, Float duration, - LocalDateTime createdAt + Instant createdAt ) {} \ No newline at end of file diff --git a/src/main/java/com/ddf/vodsystem/entities/Clip.java b/src/main/java/com/ddf/vodsystem/entities/Clip.java index 924b0b5..eafa28e 100644 --- a/src/main/java/com/ddf/vodsystem/entities/Clip.java +++ b/src/main/java/com/ddf/vodsystem/entities/Clip.java @@ -5,7 +5,7 @@ import jakarta.persistence.*; import lombok.Data; -import java.time.LocalDateTime; +import java.time.Instant; @Entity @Table(name = "clips") @@ -28,7 +28,7 @@ public class Clip { private String description; @Column(name = "created_at") - private LocalDateTime createdAt; + private Instant createdAt; @Column(name = "width", nullable = false) private Integer width; diff --git a/src/main/java/com/ddf/vodsystem/entities/Stream.java b/src/main/java/com/ddf/vodsystem/entities/Stream.java index 325b9c3..e91805b 100644 --- a/src/main/java/com/ddf/vodsystem/entities/Stream.java +++ b/src/main/java/com/ddf/vodsystem/entities/Stream.java @@ -4,7 +4,7 @@ import jakarta.persistence.*; import lombok.Data; import com.fasterxml.jackson.annotation.JsonIgnore; -import java.time.LocalDateTime; +import java.time.Instant; @Entity @Table(name = "streams") @@ -21,11 +21,11 @@ public class Stream { private User user; @Column(name = "start_time") - private LocalDateTime startDate; + private Instant startDate; @Column(name = "end_time") - private LocalDateTime endDate; + private Instant endDate; @Column(name = "last_seen") - private LocalDateTime lastSeen; + private Instant lastSeen; } diff --git a/src/main/java/com/ddf/vodsystem/entities/User.java b/src/main/java/com/ddf/vodsystem/entities/User.java index 1d7bf69..d486403 100644 --- a/src/main/java/com/ddf/vodsystem/entities/User.java +++ b/src/main/java/com/ddf/vodsystem/entities/User.java @@ -3,7 +3,7 @@ package com.ddf.vodsystem.entities; import jakarta.persistence.*; import lombok.Data; -import java.time.LocalDateTime; +import java.time.Instant; @Entity @Table(name = "users") @@ -33,7 +33,7 @@ public class User { private Integer role; // 0: user, 1: admin @Column(name = "created_at") - private LocalDateTime createdAt; + private Instant createdAt; @Column(name = "stream_key") private String streamKey; diff --git a/src/main/java/com/ddf/vodsystem/repositories/StreamRepository.java b/src/main/java/com/ddf/vodsystem/repositories/StreamRepository.java index e1ce754..e577e36 100644 --- a/src/main/java/com/ddf/vodsystem/repositories/StreamRepository.java +++ b/src/main/java/com/ddf/vodsystem/repositories/StreamRepository.java @@ -5,7 +5,7 @@ import com.ddf.vodsystem.entities.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.List; import java.util.Optional; @@ -13,5 +13,5 @@ import java.util.Optional; public interface StreamRepository extends JpaRepository { Optional findByUserAndEndDateIsNull(User user); List findByUser(User user); - List findByEndDateIsNullAndLastSeenBefore(LocalDateTime cutoff); + List findByEndDateIsNullAndLastSeenBefore(Instant cutoff); } diff --git a/src/main/java/com/ddf/vodsystem/services/ClipService.java b/src/main/java/com/ddf/vodsystem/services/ClipService.java index c99014f..83b1f93 100644 --- a/src/main/java/com/ddf/vodsystem/services/ClipService.java +++ b/src/main/java/com/ddf/vodsystem/services/ClipService.java @@ -8,7 +8,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.List; import java.util.Optional; import java.util.concurrent.ExecutionException; @@ -208,7 +208,7 @@ public class ClipService { clip.setUser(user); clip.setTitle(options.getTitle() != null ? options.getTitle() : "Untitled Clip"); clip.setDescription(options.getDescription() != null ? options.getDescription() : ""); - clip.setCreatedAt(LocalDateTime.now()); + clip.setCreatedAt(Instant.now()); clip.setWidth(options.getWidth()); clip.setHeight(options.getHeight()); clip.setFps(options.getFps()); diff --git a/src/main/java/com/ddf/vodsystem/services/StreamService.java b/src/main/java/com/ddf/vodsystem/services/StreamService.java index ca2f39a..4603511 100644 --- a/src/main/java/com/ddf/vodsystem/services/StreamService.java +++ b/src/main/java/com/ddf/vodsystem/services/StreamService.java @@ -12,7 +12,7 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.*; @Service @@ -37,7 +37,7 @@ public class StreamService { throw new AlreadyStreaming("User " + user.getUsername() + " is already streaming."); }); - LocalDateTime now = LocalDateTime.now(); + Instant now = Instant.now(); Stream stream = new Stream(); stream.setUser(user); stream.setStartDate(now); @@ -52,7 +52,7 @@ public class StreamService { .orElseThrow(() -> new IllegalStateException( "No active stream found for user " + user.getUsername())); - stream.setEndDate(LocalDateTime.now()); + stream.setEndDate(Instant.now()); streamRepository.saveAndFlush(stream); } @@ -63,7 +63,7 @@ public class StreamService { .orElseThrow(() -> new IllegalStateException( "No active stream found for user " + user.getUsername())); - stream.setLastSeen(LocalDateTime.now()); + stream.setLastSeen(Instant.now()); streamRepository.saveAndFlush(stream); } @@ -97,11 +97,11 @@ public class StreamService { @Scheduled(fixedDelay = 30_000) @Transactional public void endStaleStreams() { - LocalDateTime cutoff = LocalDateTime.now().minusSeconds(HEARTBEAT_TIMEOUT_SECONDS); + Instant cutoff = Instant.now().minusSeconds(HEARTBEAT_TIMEOUT_SECONDS); List stale = streamRepository.findByEndDateIsNullAndLastSeenBefore(cutoff); if (stale.isEmpty()) return; - LocalDateTime now = LocalDateTime.now(); + Instant now = Instant.now(); for (Stream stream : stale) { stream.setEndDate(now); logger.warn("Stream {} for user {} ended due to heartbeat timeout", stream.getId(), stream.getUser().getUsername()); diff --git a/src/main/java/com/ddf/vodsystem/services/UserService.java b/src/main/java/com/ddf/vodsystem/services/UserService.java index 51beeaf..ae5d28c 100644 --- a/src/main/java/com/ddf/vodsystem/services/UserService.java +++ b/src/main/java/com/ddf/vodsystem/services/UserService.java @@ -17,7 +17,7 @@ import org.springframework.stereotype.Service; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.SecureRandom; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.Collections; import java.util.HexFormat; import java.util.Optional; @@ -77,7 +77,7 @@ public class UserService { if (existingUser.isEmpty()) { user.setRole(0); - user.setCreatedAt(LocalDateTime.now()); + user.setCreatedAt(Instant.now()); user.setStreamKey(generateStreamKey()); return userRepository.saveAndFlush(user); } diff --git a/src/main/java/com/ddf/vodsystem/services/media/CompressionService.java b/src/main/java/com/ddf/vodsystem/services/media/CompressionService.java index 13edcfb..883bf3c 100644 --- a/src/main/java/com/ddf/vodsystem/services/media/CompressionService.java +++ b/src/main/java/com/ddf/vodsystem/services/media/CompressionService.java @@ -38,7 +38,7 @@ public class CompressionService { outputFile, clipOptions ); - CommandOutput result = CommandRunner.run(command, line -> setProgress(line, progress, clipOptions.getDuration())); + CommandOutput result = CommandRunner.run(command, line -> CommandRunner.setProgress(line, progress, clipOptions.getDuration())); progress.markComplete(); return CompletableFuture.completedFuture(result); 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 cc196e6..201cc22 100644 --- a/src/main/java/com/ddf/vodsystem/services/media/StreamActionsService.java +++ b/src/main/java/com/ddf/vodsystem/services/media/StreamActionsService.java @@ -72,6 +72,7 @@ public class StreamActionsService { logger.info("Saving section with ({} segments) to '{}'", segments.size(), outputFile); CommandRunner.run(command, line -> CommandRunner.setProgress(line, progressTracker, duration)); + progressTracker.markComplete(); return CompletableFuture.completedFuture(outputFile); } catch (Exception e) { diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 7cd357c..ec2e735 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -1,6 +1,6 @@ spring.docker.compose.file=docker-compose.dev.yml -media.temp.inputs=./video/inputs +media.temp.inputs=./videos/inputs media.temp.outputs=./videos/outputs media.users=${MEDIA_DATA} media.streams=${STREAM_DATA} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 65f2509..9701c07 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -31,4 +31,7 @@ media.users=/app/media/ media.streams=/app/stream/ ## Server Configuration -server.servlet.session.timeout=30m \ No newline at end of file +server.servlet.session.timeout=30m + +# Serialize Instant as ISO-8601 UTC string (not epoch seconds) +spring.jackson.serialization.write-dates-as-timestamps=false \ No newline at end of file diff --git a/src/main/resources/db/schema.sql b/src/main/resources/db/schema.sql index d77fd70..2cc5bab 100644 --- a/src/main/resources/db/schema.sql +++ b/src/main/resources/db/schema.sql @@ -10,7 +10,7 @@ CREATE TABLE IF NOT EXISTS users ( name VARCHAR(100) NOT NULL, profile_picture_url VARCHAR(255), role INTEGER DEFAULT 0, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + created_at TIMESTAMPTZ DEFAULT NOW(), stream_key VARCHAR(64) NOT NULL UNIQUE ); @@ -29,7 +29,7 @@ CREATE TABLE IF NOT EXISTS clips ( user_id BIGINT NOT NULL, title VARCHAR(255) NOT NULL, description TEXT, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + created_at TIMESTAMPTZ DEFAULT NOW(), width INTEGER NOT NULL, height INTEGER NOT NULL, fps FLOAT NOT NULL,