feat(markers): implement marker entity & service
This commit is contained in:
@@ -108,4 +108,11 @@ public class GlobalExceptionHandler {
|
||||
APIResponse<Void> response = new APIResponse<>(ERROR, ex.getMessage(), null);
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
|
||||
}
|
||||
|
||||
@ExceptionHandler(NotStreaming.class)
|
||||
public ResponseEntity<APIResponse<Void>> handleNotStreaming(NotStreaming ex) {
|
||||
logger.error("NotStreaming: {}", ex.getMessage());
|
||||
APIResponse<Void> response = new APIResponse<>(ERROR, ex.getMessage(), null);
|
||||
return ResponseEntity.status(HttpStatus.CONFLICT).body(response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.ddf.vodsystem.controllers;
|
||||
|
||||
import com.ddf.vodsystem.controllers.dto.MarkerCreateRequest;
|
||||
import com.ddf.vodsystem.controllers.dto.MarkerResponse;
|
||||
import com.ddf.vodsystem.dto.APIResponse;
|
||||
import com.ddf.vodsystem.entities.Marker;
|
||||
import com.ddf.vodsystem.services.MarkerService;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/markers")
|
||||
public class MarkerController {
|
||||
private static final String SUCCESS = "success";
|
||||
|
||||
private final MarkerService markerService;
|
||||
|
||||
public MarkerController(MarkerService markerService) {
|
||||
this.markerService = markerService;
|
||||
}
|
||||
|
||||
@GetMapping("")
|
||||
public ResponseEntity<APIResponse<List<MarkerResponse>>> getMarkers() {
|
||||
List<MarkerResponse> markers = markerService.getUserMarkers().stream()
|
||||
.map(this::convertToDTO)
|
||||
.toList();
|
||||
|
||||
return ResponseEntity.ok(
|
||||
new APIResponse<>(SUCCESS, "Markers retrieved successfully", markers)
|
||||
);
|
||||
}
|
||||
|
||||
@PostMapping("")
|
||||
public ResponseEntity<APIResponse<MarkerResponse>> createMarker(@Valid @RequestBody MarkerCreateRequest request) {
|
||||
Marker marker = markerService.create(request.message());
|
||||
|
||||
return ResponseEntity.ok(
|
||||
new APIResponse<>(SUCCESS, "Marker created successfully", convertToDTO(marker))
|
||||
);
|
||||
}
|
||||
|
||||
private MarkerResponse convertToDTO(Marker marker) {
|
||||
return new MarkerResponse(
|
||||
marker.getId(),
|
||||
marker.getUser().getId(),
|
||||
marker.getStream().getId(),
|
||||
marker.getMessage(),
|
||||
marker.getTimestamp()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.ddf.vodsystem.controllers.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public record MarkerCreateRequest(
|
||||
@NotBlank String message
|
||||
) {}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.ddf.vodsystem.controllers.dto;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public record MarkerResponse(
|
||||
Long id,
|
||||
Long userId,
|
||||
Long streamId,
|
||||
String message,
|
||||
Instant timestamp
|
||||
) {}
|
||||
33
src/main/java/com/ddf/vodsystem/entities/Marker.java
Normal file
33
src/main/java/com/ddf/vodsystem/entities/Marker.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.ddf.vodsystem.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Entity
|
||||
@Table(name = "markers")
|
||||
@Data
|
||||
public class Marker {
|
||||
@Id
|
||||
@Column(name = "id", nullable = false, unique = true)
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JsonIgnore
|
||||
@JoinColumn(name = "user_id", nullable = false)
|
||||
private User user;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JsonIgnore
|
||||
@JoinColumn(name = "stream_id", nullable = false)
|
||||
private Stream stream;
|
||||
|
||||
@Column(name = "message", length = 255)
|
||||
private String message;
|
||||
|
||||
@Column(name = "timestamp")
|
||||
private Instant timestamp;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.ddf.vodsystem.exceptions;
|
||||
|
||||
public class NotStreaming extends RuntimeException {
|
||||
public NotStreaming(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.ddf.vodsystem.repositories;
|
||||
|
||||
import com.ddf.vodsystem.entities.Marker;
|
||||
import com.ddf.vodsystem.entities.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface MarkerRepository extends JpaRepository<Marker, Long> {
|
||||
@Query("SELECT m FROM Marker m WHERE m.user = ?1")
|
||||
List<Marker> findByUser(User user);
|
||||
}
|
||||
@@ -174,7 +174,7 @@ public class ClipService {
|
||||
Path file = directoryService.resolvePath(path);
|
||||
|
||||
if (!Files.exists(file)) {
|
||||
throw new JobNotFound("Thumbnail file not found");
|
||||
throw new ClipNotFound("Thumbnail file not found");
|
||||
}
|
||||
|
||||
return new FileSystemResource(file);
|
||||
|
||||
52
src/main/java/com/ddf/vodsystem/services/MarkerService.java
Normal file
52
src/main/java/com/ddf/vodsystem/services/MarkerService.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package com.ddf.vodsystem.services;
|
||||
|
||||
import com.ddf.vodsystem.entities.Marker;
|
||||
import com.ddf.vodsystem.entities.Stream;
|
||||
import com.ddf.vodsystem.entities.User;
|
||||
import com.ddf.vodsystem.exceptions.NotAuthenticated;
|
||||
import com.ddf.vodsystem.exceptions.NotStreaming;
|
||||
import com.ddf.vodsystem.repositories.MarkerRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class MarkerService {
|
||||
|
||||
private final UserService userService;
|
||||
private final StreamService streamService;
|
||||
private final MarkerRepository markerRepository;
|
||||
|
||||
public MarkerService(UserService userService, StreamService streamService, MarkerRepository markerRepository) {
|
||||
this.userService = userService;
|
||||
this.streamService = streamService;
|
||||
this.markerRepository = markerRepository;
|
||||
}
|
||||
|
||||
public List<Marker> getUserMarkers() {
|
||||
Optional<User> user = userService.getLoggedInUser();
|
||||
|
||||
if (user.isEmpty()) {
|
||||
throw new NotAuthenticated("Must be logged in to get markers");
|
||||
}
|
||||
|
||||
return markerRepository.findByUser(user.get());
|
||||
}
|
||||
|
||||
public Marker create(String message) {
|
||||
Optional<Stream> stream = streamService.getActiveStream();
|
||||
|
||||
if (stream.isEmpty()) {
|
||||
throw new NotStreaming("User must be streaming to mark");
|
||||
}
|
||||
|
||||
Marker marker = new Marker();
|
||||
marker.setStream(stream.get());
|
||||
marker.setUser(stream.get().getUser());
|
||||
marker.setMessage(message);
|
||||
marker.setTimestamp(Instant.now());
|
||||
return markerRepository.saveAndFlush(marker);
|
||||
}
|
||||
}
|
||||
@@ -54,4 +54,15 @@ CREATE TABLE IF NOT EXISTS vods (
|
||||
video_path VARCHAR(255) NOT NULL,
|
||||
thumbnail_path VARCHAR(255) NOT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS markers (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL,
|
||||
stream_id BIGINT NOT NULL,
|
||||
message VARCHAR(255),
|
||||
timestamp TIMESTAMPTZ DEFAULT NOW(),
|
||||
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (stream_id) REFERENCES streams(id) ON DELETE CASCADE
|
||||
);
|
||||
Reference in New Issue
Block a user