*/domain/content/batch
import com.codeit.playlist.domain.content.api.mapper.TmdbMapper;
import com.codeit.playlist.domain.content.api.response.TheMovieResponse;
import com.codeit.playlist.domain.content.api.service.TheMovieApiService;
import com.codeit.playlist.domain.content.entity.Content;
import com.codeit.playlist.domain.content.repository.ContentRepository;
import com.codeit.playlist.domain.content.service.TagService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Slf4j
@Component
@RequiredArgsConstructor
public class MovieTasklet implements Tasklet {
private final TheMovieApiService theMovieApiService;
private final TmdbMapper theMovieMapper;
private final ContentRepository contentRepository;
private final TagService tagService;
@Override
@Transactional
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
log.info("[콘텐츠 데이터 관리] TMDB The Movie API 데이터 배치 수집 시작");
String query = "language=ko-KR";
int invalidCount = 0;
int existCount = 0;
int languageCount = 0;
List<TheMovieResponse> movieResponseList = theMovieApiService.getApiMovie(query)
.doOnError(e -> log.error("[콘텐츠 데이터 관리] The Movie 배치 Tasklet 스트림 에러 발생 : {}", e.getMessage(), e))
.doOnComplete(() -> log.info("[콘텐츠 데이터 관리] The Movie 배치 Tasklet 스트림 동작 완료, API 데이터 수집"))
.collectList()
.block();
if(movieResponseList == null || movieResponseList.isEmpty()) {
return RepeatStatus.FINISHED;
}
for(int i = 0; i< movieResponseList.size(); i++) {
TheMovieResponse movieResponse = movieResponseList.get(i);
Content content = theMovieMapper.toContent(movieResponse, "movie");
String thumbnailUrl = movieResponse.thumbnailUrl();
if(movieResponse.apiId() == null) { // tmdb id가 없음
continue;
}
Long tmdbId = movieResponse.apiId();
if(contentRepository.existsByApiId(tmdbId)) { // tmdbId가 이미 있음
existCount++;
continue;
}
if(thumbnailUrl != null && !thumbnailUrl.isBlank()) {
content.setThumbnailUrl("https://image.tmdb.org/t/p/w500" + thumbnailUrl);
}
if(movieResponse.description() == null || movieResponse.description().isBlank()) { // 설명이 없음
invalidCount++;
continue;
}
if(movieResponse.title() == null) { // 타이틀이 없음
continue;
}
Content resultContent = contentRepository.save(content); // 썸네일까지 set된 content
if(movieResponse.genreIds() != null && !movieResponse.genreIds().isEmpty()) {
tagService.saveMovieTagToContent(resultContent, movieResponse.genreIds());
}
}
log.debug("[콘텐츠 데이터 관리] TMDB The Movie API에서 한글이 한글자도 없는 콘텐츠 횟수 : {}", languageCount);
log.debug("[콘텐츠 데이터 관리] TMDB The Movie API가 이만큼 비어있었어요. count : {}", invalidCount);
log.debug("[콘텐츠 데이터 관리] TMDB The Movie API contents가 이만큼 없어요. count : {}", existCount);
log.debug("[콘텐츠 데이터 관리] The Movie API 콘텐츠와 태그 수집 완료");
return RepeatStatus.FINISHED;
}
}'Playlist > Spring Batch' 카테고리의 다른 글
| BatchConfig (0) | 2025.12.17 |
|---|---|
| SportContentTasklet (0) | 2025.12.17 |
| TvSeriesTasklet (0) | 2025.12.17 |
| ContentScheduler (0) | 2025.12.17 |
| Spring Batch, 배치 (0) | 2025.11.14 |