Skip to content

Commit

Permalink
Merge pull request #30 from f-lab-edu/issue29
Browse files Browse the repository at this point in the history
[Issue29] 영상 메타데이터 관련 기능 구현
  • Loading branch information
misim3 authored Nov 7, 2024
2 parents 06148ca + e88d54f commit 78cc1a0
Show file tree
Hide file tree
Showing 12 changed files with 498 additions and 11 deletions.
3 changes: 2 additions & 1 deletion mitube-app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'io.rest-assured:rest-assured:5.3.1'
}

tasks.named('bootBuildImage') {
Expand All @@ -22,4 +23,4 @@ tasks.named('bootBuildImage') {

tasks.named('test') {
useJUnitPlatform()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ public WebSecurityCustomizer webSecurityCustomizer() {
"/comments/**",
"/channels/**",
"/home",
"/videofiles/**"
"/videofiles/**",
"/videoMetadata/**"
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.misim.controller;

import com.misim.controller.model.Response.MetadataResponse;
import com.misim.entity.VideoMetadata;
import com.misim.exception.CommonResponse;
import com.misim.service.VideoMetadataService;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/videoMetadata")
public class VideoMetadataController {

private final VideoMetadataService videoMetadataService;

public VideoMetadataController(VideoMetadataService videoMetadataService) {
this.videoMetadataService = videoMetadataService;
}

@GetMapping("/{videoMetadataId}")
public CommonResponse<MetadataResponse> getVideoMetadata(@PathVariable Long videoMetadataId) {

VideoMetadata metadata = videoMetadataService.read(videoMetadataId);

MetadataResponse response = new MetadataResponse(metadata.getViewCount(), metadata.getLikeCount(), metadata.getDislikeCount());

return CommonResponse
.<MetadataResponse>builder()
.body(response)
.build();
}

@PostMapping("/{videoMetadataId}/view")
public void addVideoMetadataViewCount(@PathVariable Long videoMetadataId) {

videoMetadataService.updateViewCount(videoMetadataId);
}

@PostMapping("/{videoMetadataId}/like")
public void addVideoMetadataLikeCount(@PathVariable Long videoMetadataId, @RequestParam Boolean isChecked) {

videoMetadataService.updateLikeCount(videoMetadataId, isChecked);
}

@PostMapping("/{videoMetadataId}/dislike")
public void addVideoMetadataDislikeCount(@PathVariable Long videoMetadataId, @RequestParam Boolean isChecked) {

videoMetadataService.updateDislikeCount(videoMetadataId, isChecked);
}

@DeleteMapping("/{videoMetadataId}")
public void deleteVideoMetadata(@PathVariable Long videoMetadataId) {

videoMetadataService.delete(videoMetadataId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.misim.controller.model.Response;

public record MetadataResponse (
Long viewCount, Long likeCount, Long dislikeCount
) {
}
14 changes: 9 additions & 5 deletions mitube-app/src/main/java/com/misim/entity/VideoCatalog.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -24,16 +24,20 @@ public class VideoCatalog extends BaseTimeEntity {

private String description;

@ManyToOne
private Integer categoryId;

@OneToOne
private VideoFile videoFile;

private Integer categoryId;
@OneToOne
private VideoMetadata videoMetadata;

@Builder
public VideoCatalog(String title, String description, VideoFile videoFile, Integer categoryId) {
public VideoCatalog(String title, String description, Integer categoryId, VideoFile videoFile, VideoMetadata videoMetadata) {
this.title = title;
this.description = description;
this.videoFile = videoFile;
this.categoryId = categoryId;
this.videoFile = videoFile;
this.videoMetadata = videoMetadata;
}
}
56 changes: 56 additions & 0 deletions mitube-app/src/main/java/com/misim/entity/VideoMetadata.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.misim.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor
public class VideoMetadata extends BaseTimeEntity{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private Long viewCount;

private Long likeCount;

private Long dislikeCount;

@Builder
public VideoMetadata(Long viewCount, Long likeCount, Long dislikeCount) {
this.viewCount = viewCount;
this.likeCount = likeCount;
this.dislikeCount = dislikeCount;
}

public void incrementViewCount() {
this.viewCount++;
}

public void incrementLikeCount() {
this.likeCount++;
}

public void incrementDislikeCount() {
this.dislikeCount++;
}

public void decrementLikeCount() {
if (this.likeCount > 0) {
this.likeCount--;
}
}

public void decrementDislikeCount() {
if (this.dislikeCount > 0) {
this.dislikeCount--;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
package com.misim.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

@Order(value = 1)
@ExceptionHandler(MitubeException.class)
public ResponseEntity<CommonResponse<?>> handleMitubeException(MitubeException e) {

e.fillInStackTrace();
log.error("Handler MitubeException: {}", e.getMessage(), e);

CommonResponse<?> commonResponse = new CommonResponse<>(e.getErrorCode().getCode(),
e.getErrorCode().getMessage(), null);
Expand All @@ -23,7 +25,7 @@ public ResponseEntity<CommonResponse<?>> handleMitubeException(MitubeException e
@ExceptionHandler(Exception.class)
public ResponseEntity<CommonResponse<?>> handleUnknownException(Exception e) {

e.fillInStackTrace();
log.error("Handler UnknownException: {}", e.getMessage(), e);

CommonResponse<?> commonResponse = new CommonResponse<>(
MitubeErrorCode.UNKNOWN_EXCEPTION.getCode(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.misim.repository;

import com.misim.entity.VideoMetadata;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface VideoMetadataRepository extends JpaRepository<VideoMetadata, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.misim.service;

import com.misim.entity.VideoMetadata;
import com.misim.repository.VideoMetadataRepository;
import java.util.NoSuchElementException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class VideoMetadataService {

private final VideoMetadataRepository videoMetadataRepository;

public VideoMetadata create() {

VideoMetadata metadata = VideoMetadata.builder()
.viewCount(0L)
.likeCount(0L)
.dislikeCount(0L)
.build();

return videoMetadataRepository.save(metadata);
}

public VideoMetadata read(Long id) {

return videoMetadataRepository.findById(id)
.orElseThrow(NoSuchElementException::new);
}

public Long readViewCount(Long id) {

return videoMetadataRepository.findById(id)
.orElseThrow(NoSuchElementException::new)
.getViewCount();
}

public Long readLikeCount(Long id) {

return videoMetadataRepository.findById(id)
.orElseThrow(NoSuchElementException::new)
.getLikeCount();
}

public Long readDislikeCount(Long id) {

return videoMetadataRepository.findById(id)
.orElseThrow(NoSuchElementException::new)
.getDislikeCount();
}

public void updateViewCount(Long id) {

VideoMetadata metadata = videoMetadataRepository.findById(id)
.orElseThrow(NoSuchElementException::new);

metadata.incrementViewCount();

videoMetadataRepository.save(metadata);
}

public void updateLikeCount(Long id, boolean isChecked) {

VideoMetadata metadata = videoMetadataRepository.findById(id)
.orElseThrow(NoSuchElementException::new);

if (isChecked) {
metadata.incrementLikeCount();
} else {
metadata.decrementLikeCount();
}

videoMetadataRepository.save(metadata);
}

public void updateDislikeCount(Long id, boolean isChecked) {

VideoMetadata metadata = videoMetadataRepository.findById(id)
.orElseThrow(NoSuchElementException::new);

if (isChecked) {
metadata.incrementDislikeCount();
} else {
metadata.decrementDislikeCount();
}

videoMetadataRepository.save(metadata);
}

public void delete(Long id) {

videoMetadataRepository.deleteById(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ void testStreamVideo_Success() throws Exception {
// given
Long videoId = 1L;
VideoFile videoFile = new VideoFile("path/to/video.mp4");
VideoCatalog videoCatalog = new VideoCatalog("title", "description", videoFile, 0);
VideoCatalog videoCatalog = new VideoCatalog("title", "description", 0, videoFile, null);
when(videoService.getVideo(videoId)).thenReturn(videoCatalog);

byte[] videoContent = "test video content".getBytes();
Expand All @@ -101,4 +101,4 @@ void testStreamVideo_VideoNotFound() throws Exception {
mockMvc.perform(get("/videofiles/1"))
.andExpect(status().isNotFound());
}
}
}
Loading

0 comments on commit 78cc1a0

Please sign in to comment.