diff --git a/src/main/java/confeti/confetibatchserver/api/music/facade/MusicSyncFacade.java b/src/main/java/confeti/confetibatchserver/api/music/facade/MusicSyncFacade.java new file mode 100644 index 0000000..844f3c1 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/api/music/facade/MusicSyncFacade.java @@ -0,0 +1,36 @@ +package confeti.confetibatchserver.api.music.facade; + +import confeti.confetibatchserver.domain.music.artist.Artist; +import confeti.confetibatchserver.domain.music.artist.application.ArtistService; +import confeti.confetibatchserver.domain.music.artist.vo.ConfetiArtist; +import confeti.confetibatchserver.domain.music.song.application.SongService; +import confeti.confetibatchserver.domain.music.song.vo.ConfetiSong; +import confeti.confetibatchserver.external.service.MusicAPIHandler; +import confeti.confetibatchserver.global.annotation.Facade; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; + +@Facade +@RequiredArgsConstructor +public class MusicSyncFacade { + + private final MusicAPIHandler musicAPIHandler; + private final ArtistService artistService; + private final SongService songService; + + public void upsertSongByArtistId(String artistId) { + List fetchedSongs = musicAPIHandler.getAllSongsByArtistId(artistId); + songService.upsert(artistId, fetchedSongs); + } + + public void upsertArtists(List artists) { + Set artistIds = artists.stream().map(ConfetiArtist::getId) + .collect(Collectors.toSet()); + List fetchedArtists = musicAPIHandler.getArtistsByIds(artistIds); + List updatedArtists = artistService.getUpdatedArtists(artists, fetchedArtists); + artistService.upsertArtists(updatedArtists); + } + +} diff --git a/src/main/java/confeti/confetibatchserver/config/ThreadPoolConfig.java b/src/main/java/confeti/confetibatchserver/config/ThreadPoolConfig.java new file mode 100644 index 0000000..6671747 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/config/ThreadPoolConfig.java @@ -0,0 +1,29 @@ +package confeti.confetibatchserver.config; + +import java.util.concurrent.ThreadPoolExecutor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +@Configuration +public class ThreadPoolConfig { + + public static final String MUSIC_SYNC_EXECUTOR = "musicSyncExecutor"; + + @Bean(MUSIC_SYNC_EXECUTOR) + public ThreadPoolTaskExecutor batchThreadPool() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + + executor.setCorePoolSize(10); + executor.setMaxPoolSize(20); + executor.setQueueCapacity(50); + executor.setThreadNamePrefix("music-sync-worker-"); + + executor.setRejectedExecutionHandler( + new ThreadPoolExecutor.CallerRunsPolicy()); // 큐가 꽉 차면 메인 스레드가 작업을 처리 + executor.setWaitForTasksToCompleteOnShutdown(true); // 종료 시 작업 계속하도록 + executor.initialize(); + + return executor; + } +} diff --git a/src/main/java/confeti/confetibatchserver/domain/batch/stepconfig/StepConfig.java b/src/main/java/confeti/confetibatchserver/domain/batch/stepconfig/StepConfig.java index 8f093db..b598e1b 100644 --- a/src/main/java/confeti/confetibatchserver/domain/batch/stepconfig/StepConfig.java +++ b/src/main/java/confeti/confetibatchserver/domain/batch/stepconfig/StepConfig.java @@ -1,6 +1,5 @@ package confeti.confetibatchserver.domain.batch.stepconfig; -import confeti.confetibatchserver.job.JobInfo; import confeti.confetibatchserver.job.StepInfo; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -20,9 +19,6 @@ public class StepConfig { @Enumerated(EnumType.STRING) private StepInfo stepInfo; - @Enumerated(EnumType.STRING) - private JobInfo jobInfo; - @Column(nullable = false) private int chunkSize; diff --git a/src/main/java/confeti/confetibatchserver/domain/music/artist/Artist.java b/src/main/java/confeti/confetibatchserver/domain/music/artist/Artist.java index 9e7b53d..483fbcf 100644 --- a/src/main/java/confeti/confetibatchserver/domain/music/artist/Artist.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/artist/Artist.java @@ -7,7 +7,6 @@ import jakarta.persistence.Id; import jakarta.persistence.Table; import java.time.LocalDateTime; -import java.util.Objects; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -55,10 +54,4 @@ public static Artist from(ConfetiArtist artist) { .build(); } - public boolean isDifferentData(ConfetiArtist artist) { - return !Objects.equals(id, artist.getId()) - || !Objects.equals(name, artist.getName()) - || !Objects.equals(artworkUrl, artist.getProfileUrl()); - } - } \ No newline at end of file diff --git a/src/main/java/confeti/confetibatchserver/domain/music/artist/application/ArtistService.java b/src/main/java/confeti/confetibatchserver/domain/music/artist/application/ArtistService.java index 3df441b..54d7b77 100644 --- a/src/main/java/confeti/confetibatchserver/domain/music/artist/application/ArtistService.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/artist/application/ArtistService.java @@ -22,24 +22,24 @@ public void upsertArtists(Collection artists) { } public List getUpdatedArtists( - List savedArtists, + List savedArtists, List newArtists ) { - Map savedArtistById = artistsToMap(savedArtists); + Map savedArtistById = artistsToMap(savedArtists); return newArtists.stream() .filter(artist -> { - Artist savedArtist = savedArtistById.get(artist.getId()); + ConfetiArtist savedArtist = savedArtistById.get(artist.getId()); return savedArtist != null && savedArtist.isDifferentData(artist); }) .map(Artist::from) .toList(); } - private Map artistsToMap(Collection artists) { + private Map artistsToMap(Collection artists) { return artists.stream() .collect(Collectors.toMap( - Artist::getId, + ConfetiArtist::getId, Function.identity(), (exist, replacement) -> exist)); } diff --git a/src/main/java/confeti/confetibatchserver/domain/music/artist/vo/ConfetiArtist.java b/src/main/java/confeti/confetibatchserver/domain/music/artist/vo/ConfetiArtist.java index 4e4525d..d386f1a 100644 --- a/src/main/java/confeti/confetibatchserver/domain/music/artist/vo/ConfetiArtist.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/artist/vo/ConfetiArtist.java @@ -1,5 +1,6 @@ package confeti.confetibatchserver.domain.music.artist.vo; +import java.util.Objects; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; @@ -18,4 +19,10 @@ public static ConfetiArtist of(String id, String name, String profileUrl) { return new ConfetiArtist(id, name, profileUrl); } + public boolean isDifferentData(ConfetiArtist artist) { + return !Objects.equals(id, artist.getId()) + || !Objects.equals(name, artist.getName()) + || !Objects.equals(profileUrl, artist.getProfileUrl()); + } + } diff --git a/src/main/java/confeti/confetibatchserver/domain/music/artistsong/infra/repository/ArtistSongRepository.java b/src/main/java/confeti/confetibatchserver/domain/music/artistsong/infra/repository/ArtistSongRepository.java index 4975166..3d602dc 100644 --- a/src/main/java/confeti/confetibatchserver/domain/music/artistsong/infra/repository/ArtistSongRepository.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/artistsong/infra/repository/ArtistSongRepository.java @@ -1,8 +1,19 @@ package confeti.confetibatchserver.domain.music.artistsong.infra.repository; import confeti.confetibatchserver.domain.music.artistsong.ArtistSong; +import confeti.confetibatchserver.domain.music.song.Song; +import feign.Param; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + public interface ArtistSongRepository extends JpaRepository { + @Query(value = """ + SELECT s + FROM Song as s + JOIN ArtistSong AS a_s ON a_s.artistId = :artistId + """) + List findAllSongByArtistId(@Param("artistId") String artistId); } diff --git a/src/main/java/confeti/confetibatchserver/domain/music/song/Song.java b/src/main/java/confeti/confetibatchserver/domain/music/song/Song.java index 47a7e9d..ceac793 100644 --- a/src/main/java/confeti/confetibatchserver/domain/music/song/Song.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/song/Song.java @@ -1,5 +1,6 @@ package confeti.confetibatchserver.domain.music.song; +import confeti.confetibatchserver.domain.music.song.vo.ConfetiSong; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EntityListeners; @@ -7,6 +8,7 @@ import jakarta.persistence.Table; import java.time.LocalDateTime; import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.data.annotation.CreatedDate; @@ -24,12 +26,12 @@ public class Song { @Column(nullable = false) private String id; - @Column(length = 100, nullable = false) + @Column(length = 1000, nullable = false) private String trackName; - @Column(length = 100) + @Column(length = 1000) private String artistName; - + @Column(length = 3000) private String artworkUrl; @@ -42,5 +44,24 @@ public class Song { @LastModifiedDate private LocalDateTime updatedAt; -} + @Builder + private Song(String id, String trackName, String artistName, String artworkUrl, + String previewUrl) { + this.id = id; + this.trackName = trackName; + this.artistName = artistName; + this.artworkUrl = artworkUrl; + this.previewUrl = previewUrl; + } + + public static Song from(ConfetiSong confetiSong) { + return Song.builder() + .id(confetiSong.getId()) + .trackName(confetiSong.getTrackName()) + .artistName(confetiSong.getArtistName()) + .artworkUrl(confetiSong.getArtworkUrl()) + .previewUrl(confetiSong.getPreviewUrl()) + .build(); + } +} diff --git a/src/main/java/confeti/confetibatchserver/domain/music/song/application/SongService.java b/src/main/java/confeti/confetibatchserver/domain/music/song/application/SongService.java new file mode 100644 index 0000000..c4e53c4 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/domain/music/song/application/SongService.java @@ -0,0 +1,53 @@ +package confeti.confetibatchserver.domain.music.song.application; + +import confeti.confetibatchserver.domain.music.song.infra.repository.SongRepository; +import confeti.confetibatchserver.domain.music.song.vo.ConfetiSong; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Service +@RequiredArgsConstructor +public class SongService { + + private final SongRepository songRepository; + + @Transactional + public void upsert(String artistId, List songs) { + Map songMapByArtistId = getConfetiSongMapByArtistId( + artistId); + List upsertSongs = getUpsertSongs(songs, songMapByArtistId); + + songRepository.upsertSongsWithArtistId(artistId, upsertSongs); + } + + private Map getConfetiSongMapByArtistId(String artistId) { + return songRepository.findAllConfetiSongsByArtistId(artistId).stream() + .collect(Collectors.toMap(ConfetiSong::getId, Function.identity())); + } + + private List getUpsertSongs( + List fetchedSongs, + Map songMapByArtistId + ) { + List upsertSongs = new ArrayList<>(); + for (ConfetiSong fetchedSong : fetchedSongs) { + ConfetiSong song = songMapByArtistId.get(fetchedSong.getId()); + if (song == null) { + upsertSongs.add(fetchedSong); + continue; + } + if (fetchedSong.isDifferentData(song)) { + upsertSongs.add(fetchedSong); + } + } + return upsertSongs; + } +} diff --git a/src/main/java/confeti/confetibatchserver/domain/music/song/infra/repository/SongJdbcRepository.java b/src/main/java/confeti/confetibatchserver/domain/music/song/infra/repository/SongJdbcRepository.java new file mode 100644 index 0000000..3f10912 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/domain/music/song/infra/repository/SongJdbcRepository.java @@ -0,0 +1,11 @@ +package confeti.confetibatchserver.domain.music.song.infra.repository; + +import confeti.confetibatchserver.domain.music.song.vo.ConfetiSong; +import java.util.List; + +public interface SongJdbcRepository { + + void upsertSongsWithArtistId(String artistId, List songs); + + List findAllConfetiSongsByArtistId(String artistId); +} diff --git a/src/main/java/confeti/confetibatchserver/domain/music/song/infra/repository/SongJdbcRepositoryImpl.java b/src/main/java/confeti/confetibatchserver/domain/music/song/infra/repository/SongJdbcRepositoryImpl.java new file mode 100644 index 0000000..ce1fc55 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/domain/music/song/infra/repository/SongJdbcRepositoryImpl.java @@ -0,0 +1,73 @@ +package confeti.confetibatchserver.domain.music.song.infra.repository; + +import confeti.confetibatchserver.domain.music.song.vo.ConfetiSong; +import java.util.List; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.namedparam.SqlParameterSource; +import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +@Repository +@RequiredArgsConstructor +public class SongJdbcRepositoryImpl implements SongJdbcRepository { + + private final NamedParameterJdbcTemplate namedJdbcTemplate; + + private final String BULK_UPSERT_SONGS_SQL = """ + INSERT INTO songs (id, track_name, artwork_url, artist_name, preview_url, created_at, updated_at) + VALUES (:id, :trackName, :artworkUrl, :artistName, :previewUrl, NOW(), null) + ON DUPLICATE KEY UPDATE + track_name = VALUES(track_name), + artwork_url = VALUES(artwork_url), + artist_name = VALUES(artist_name), + preview_url = VALUES(preview_url), + updated_at = NOW() + """; + private final String BULK_INSERT_ARTIST_SONGS_SQL = """ + INSERT IGNORE INTO artist_songs (song_id, artist_id) + VALUES (:songId, :artistId) + """; + private final String SELECT_CONFETI_SONGS_BY_ARTIST_ID_SQL = """ + SELECT s.id as id, + s.track_name as trackName, + s.artwork_url as artworkUrl, + s.artist_name as artistName, + s.preview_url as previewUrl + FROM songs as s + INNER JOIN artist_songs as a_s ON a_s.song_id = s.id AND a_s.artist_id = :artistId + """; + + @Transactional + public void upsertSongsWithArtistId(String artistId, List songs) { + SqlParameterSource[] songParams = SqlParameterSourceUtils.createBatch(songs); + namedJdbcTemplate.batchUpdate(BULK_UPSERT_SONGS_SQL, songParams); + + MapSqlParameterSource[] artistSongParams = songs.stream() + .map(song -> new MapSqlParameterSource() + .addValue("songId", song.getId()) + .addValue("artistId", artistId)) + .toArray(MapSqlParameterSource[]::new); + namedJdbcTemplate.batchUpdate(BULK_INSERT_ARTIST_SONGS_SQL, artistSongParams); + } + + @Override + public List findAllConfetiSongsByArtistId(String artistId) { + Map params = Map.of("artistId", artistId); + + return namedJdbcTemplate.query( + SELECT_CONFETI_SONGS_BY_ARTIST_ID_SQL, + params, + (rs, rowNum) -> ConfetiSong.builder() + .id(rs.getString("id")) + .trackName(rs.getString("trackName")) + .artworkUrl(rs.getString("artworkUrl")) + .artistName(rs.getString("artistName")) + .previewUrl(rs.getString("previewUrl")) + .build() + ); + } +} diff --git a/src/main/java/confeti/confetibatchserver/domain/music/song/infra/repository/SongRepository.java b/src/main/java/confeti/confetibatchserver/domain/music/song/infra/repository/SongRepository.java index 30b510e..ee5fa46 100644 --- a/src/main/java/confeti/confetibatchserver/domain/music/song/infra/repository/SongRepository.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/song/infra/repository/SongRepository.java @@ -3,7 +3,7 @@ import confeti.confetibatchserver.domain.music.song.Song; import org.springframework.data.jpa.repository.JpaRepository; -public interface SongRepository extends JpaRepository { +public interface SongRepository extends JpaRepository, SongJdbcRepository { } diff --git a/src/main/java/confeti/confetibatchserver/domain/music/song/vo/ConfetiSong.java b/src/main/java/confeti/confetibatchserver/domain/music/song/vo/ConfetiSong.java new file mode 100644 index 0000000..1f4398b --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/domain/music/song/vo/ConfetiSong.java @@ -0,0 +1,38 @@ +package confeti.confetibatchserver.domain.music.song.vo; + +import java.util.Objects; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PROTECTED) +public class ConfetiSong { + + private String id; + + private String trackName; + + private String artworkUrl; + + private String artistName; + + private String previewUrl; + + public static ConfetiSong of(String id, String trackName, + String artworkUrl, String artistName, String previewUrl + ) { + return new ConfetiSong(id, trackName, artworkUrl, artistName, previewUrl); + } + + public boolean isDifferentData(ConfetiSong song) { + return !Objects.equals(this.artistName, song.getArtistName()) + || !Objects.equals(this.trackName, song.getTrackName()) + || !Objects.equals(this.artworkUrl, song.getArtworkUrl()) + || !Objects.equals(this.previewUrl, song.getPreviewUrl()); + } +} diff --git a/src/main/java/confeti/confetibatchserver/external/client/AppleMusicFeignClient.java b/src/main/java/confeti/confetibatchserver/external/client/AppleMusicFeignClient.java index e32129d..68005d3 100644 --- a/src/main/java/confeti/confetibatchserver/external/client/AppleMusicFeignClient.java +++ b/src/main/java/confeti/confetibatchserver/external/client/AppleMusicFeignClient.java @@ -45,7 +45,8 @@ AppleMusicArtistsResponse getRelatedArtistsById( @GetMapping("/artists/{id}/view/top-songs") AppleMusicMusicsResponse getArtistTopSongsById( @PathVariable String id, - @RequestParam String limit + @RequestParam String limit, + @RequestParam String offset ); @GetMapping("/artists/{id}/songs") diff --git a/src/main/java/confeti/confetibatchserver/external/client/dto/music/AppleMusicMusicResponse.java b/src/main/java/confeti/confetibatchserver/external/client/dto/music/AppleMusicMusicResponse.java index da9e718..0834b44 100644 --- a/src/main/java/confeti/confetibatchserver/external/client/dto/music/AppleMusicMusicResponse.java +++ b/src/main/java/confeti/confetibatchserver/external/client/dto/music/AppleMusicMusicResponse.java @@ -1,5 +1,8 @@ package confeti.confetibatchserver.external.client.dto.music; +import confeti.confetibatchserver.domain.music.song.vo.ConfetiSong; +import java.util.Optional; + public record AppleMusicMusicResponse( String id, String type, @@ -7,4 +10,24 @@ public record AppleMusicMusicResponse( AppleMusicMusicRelationshipsResponse relationships ) { + public ConfetiSong toConfetiSong() { + Optional optAttributes = Optional.ofNullable( + attributes()); + String trackName = optAttributes.map(AppleMusicMusicAttributesResponse::name).orElse(null); + String artworkUrl = optAttributes.map(attributes -> + attributes.artwork().url()).orElse(null); + String artistName = optAttributes.map(AppleMusicMusicAttributesResponse::artistName) + .orElse(null); + String previewUrl = optAttributes.flatMap(attributes -> attributes.previews().stream() + .findFirst() + .map(AppleMusicMusicPreviewResponse::url) + ).orElse(null); + + return ConfetiSong.of(id, + trackName, + artworkUrl, + artistName, + previewUrl + ); + } } diff --git a/src/main/java/confeti/confetibatchserver/external/service/AppleMusicAPIHandler.java b/src/main/java/confeti/confetibatchserver/external/service/AppleMusicAPIHandler.java new file mode 100644 index 0000000..6f3d438 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/external/service/AppleMusicAPIHandler.java @@ -0,0 +1,49 @@ +package confeti.confetibatchserver.external.service; + +import confeti.confetibatchserver.domain.music.artist.vo.ConfetiArtist; +import confeti.confetibatchserver.domain.music.song.vo.ConfetiSong; +import confeti.confetibatchserver.external.client.AppleMusicFeignClient; +import confeti.confetibatchserver.external.client.dto.artist.AppleMusicArtistsResponse; +import confeti.confetibatchserver.external.client.dto.music.AppleMusicMusicResponse; +import confeti.confetibatchserver.external.client.dto.music.AppleMusicMusicsResponse; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class AppleMusicAPIHandler implements MusicAPIHandler { + + private final static String QUERY_PARAMETER_IDS_DELIMITER = ","; + private final static int ARTIST_TOP_SONG_FETCH_SIZE = 100; + + private final AppleMusicFeignClient appleMusicFeignClient; + + @Override + public List getAllSongsByArtistId(String artistId) { + int offset = 0; + List allSongs = new ArrayList<>(100); + String next = null; + do { + AppleMusicMusicsResponse response = appleMusicFeignClient.getArtistTopSongsById( + artistId, String.valueOf(ARTIST_TOP_SONG_FETCH_SIZE), String.valueOf(offset)); + if (response.data() != null) { + allSongs.addAll(response.data()); + } + next = response.next(); + offset += ARTIST_TOP_SONG_FETCH_SIZE; + } while (next != null); + + return allSongs.stream().map(AppleMusicMusicResponse::toConfetiSong).toList(); + } + + @Override + public List getArtistsByIds(Collection artistIds) { + String joinedArtistIds = String.join(QUERY_PARAMETER_IDS_DELIMITER, artistIds); + AppleMusicArtistsResponse fetchedArtistResponses = appleMusicFeignClient.getArtists( + joinedArtistIds); + return fetchedArtistResponses.toConfetiArtists(); + } +} diff --git a/src/main/java/confeti/confetibatchserver/external/service/MusicAPIHandler.java b/src/main/java/confeti/confetibatchserver/external/service/MusicAPIHandler.java new file mode 100644 index 0000000..7bca3a2 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/external/service/MusicAPIHandler.java @@ -0,0 +1,13 @@ +package confeti.confetibatchserver.external.service; + +import confeti.confetibatchserver.domain.music.artist.vo.ConfetiArtist; +import confeti.confetibatchserver.domain.music.song.vo.ConfetiSong; +import java.util.Collection; +import java.util.List; + +public interface MusicAPIHandler { + + List getAllSongsByArtistId(String artistId); + + List getArtistsByIds(Collection artistIds); +} diff --git a/src/main/java/confeti/confetibatchserver/global/annotation/Facade.java b/src/main/java/confeti/confetibatchserver/global/annotation/Facade.java new file mode 100644 index 0000000..5d0bb9b --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/global/annotation/Facade.java @@ -0,0 +1,14 @@ +package confeti.confetibatchserver.global.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.springframework.stereotype.Component; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +@Component +public @interface Facade { + +} diff --git a/src/main/java/confeti/confetibatchserver/job/JobInfo.java b/src/main/java/confeti/confetibatchserver/job/JobInfo.java index b2426b6..b7102a6 100644 --- a/src/main/java/confeti/confetibatchserver/job/JobInfo.java +++ b/src/main/java/confeti/confetibatchserver/job/JobInfo.java @@ -7,7 +7,7 @@ @RequiredArgsConstructor public enum JobInfo { - ARTIST_SYNC_JOB("artistSyncJob"); + ARTIST_SONG_SYNC_JOB("artistSongSyncJob"); private final String jobName; } diff --git a/src/main/java/confeti/confetibatchserver/job/StepInfo.java b/src/main/java/confeti/confetibatchserver/job/StepInfo.java index cd50986..10bd6f6 100644 --- a/src/main/java/confeti/confetibatchserver/job/StepInfo.java +++ b/src/main/java/confeti/confetibatchserver/job/StepInfo.java @@ -6,7 +6,8 @@ @Getter @RequiredArgsConstructor public enum StepInfo { - ARTIST_SYNC_STEP(JobInfo.ARTIST_SYNC_JOB, "artistSyncStep"); + ARTIST_SYNC_STEP(JobInfo.ARTIST_SONG_SYNC_JOB, "artistSyncStep"), + ARTIST_SONG_SYNC_STEP(JobInfo.ARTIST_SONG_SYNC_JOB, "artistSongSyncStep"); private final JobInfo jobInfo; private final String name; diff --git a/src/main/java/confeti/confetibatchserver/job/artist/ArtistQueryProvider.java b/src/main/java/confeti/confetibatchserver/job/artist/ArtistQueryProvider.java deleted file mode 100644 index 5014764..0000000 --- a/src/main/java/confeti/confetibatchserver/job/artist/ArtistQueryProvider.java +++ /dev/null @@ -1,35 +0,0 @@ -package confeti.confetibatchserver.job.artist; - -import confeti.confetibatchserver.domain.music.artist.Artist; -import java.util.HashMap; -import java.util.Map; -import javax.sql.DataSource; -import org.springframework.batch.item.database.Order; -import org.springframework.batch.item.database.PagingQueryProvider; -import org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Component; - -@Component -public class ArtistQueryProvider { - - public static final RowMapper ARTIST_MAPPER = (rs, rowNum) -> Artist.builder() - .id(rs.getString("id")) - .name(rs.getString("name")) - .artworkUrl(rs.getString("artwork_url")) - .build(); - - public PagingQueryProvider selectAllArtists(DataSource dataSource) throws Exception { - SqlPagingQueryProviderFactoryBean queryProvider = new SqlPagingQueryProviderFactoryBean(); - queryProvider.setDataSource(dataSource); - - queryProvider.setSelectClause("id, name, artwork_url"); - queryProvider.setFromClause("FROM artists"); - - Map sortKey = new HashMap<>(); - sortKey.put("id", Order.ASCENDING); - queryProvider.setSortKeys(sortKey); - - return queryProvider.getObject(); - } -} diff --git a/src/main/java/confeti/confetibatchserver/job/artist/ArtistSyncJobConfig.java b/src/main/java/confeti/confetibatchserver/job/artist/ArtistSyncJobConfig.java deleted file mode 100644 index 762a398..0000000 --- a/src/main/java/confeti/confetibatchserver/job/artist/ArtistSyncJobConfig.java +++ /dev/null @@ -1,95 +0,0 @@ -package confeti.confetibatchserver.job.artist; - -import static confeti.confetibatchserver.job.JobInfo.ARTIST_SYNC_JOB; -import static confeti.confetibatchserver.job.StepInfo.ARTIST_SYNC_STEP; -import static confeti.confetibatchserver.job.artist.ArtistQueryProvider.ARTIST_MAPPER; - -import confeti.confetibatchserver.domain.batch.stepconfig.StepConfig; -import confeti.confetibatchserver.domain.batch.stepconfig.application.StepConfigService; -import confeti.confetibatchserver.domain.music.artist.Artist; -import confeti.confetibatchserver.domain.music.artist.application.ArtistService; -import confeti.confetibatchserver.external.client.AppleMusicFeignClient; -import confeti.confetibatchserver.logger.JobLoggingListener; -import feign.RetryableException; -import java.io.IOException; -import javax.sql.DataSource; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.annotation.JobScope; -import org.springframework.batch.core.configuration.annotation.StepScope; -import org.springframework.batch.core.job.builder.JobBuilder; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.step.builder.StepBuilder; -import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.item.database.builder.JdbcPagingItemReaderBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.transaction.PlatformTransactionManager; - -@Slf4j -@Configuration -@RequiredArgsConstructor -public class ArtistSyncJobConfig { - - public static final String JOB_PARAMETER_DATE = "requestDate"; - - private final PlatformTransactionManager platformTransactionManager; - - private final StepConfigService stepConfigService; - private final JobRepository jobRepository; - private final ArtistQueryProvider artistQueryProvider; - - @Bean - public Job artistSyncJob(Step artistSyncStep) { - return new JobBuilder(ARTIST_SYNC_JOB.getJobName(), jobRepository) - .start(artistSyncStep) - .listener(new JobLoggingListener()) - .build(); - } - - @Bean - @JobScope - public Step artistSyncStep( - ItemReader artistSyncReader, - ItemWriter artistSyncWriter - ) throws Exception { - StepConfig stepConfig = stepConfigService.getByStepInfo(ARTIST_SYNC_STEP); - - return new StepBuilder(ARTIST_SYNC_STEP.getName(), jobRepository) - .chunk(stepConfig.getChunkSize(), - platformTransactionManager) - .reader(artistSyncReader) - .writer(artistSyncWriter) - .faultTolerant() - .retry(RetryableException.class) // Feign의 재시도 가능 예외 - .retry(IOException.class) - .retryLimit(3) - .build(); - } - - @Bean - @StepScope - public ItemReader artistSyncReader(DataSource dataSource) throws Exception { - StepConfig stepConfig = stepConfigService.getByStepInfo(ARTIST_SYNC_STEP); - return new JdbcPagingItemReaderBuilder() - .name("artistSyncReader") - .dataSource(dataSource) - .fetchSize(stepConfig.getFetchSize()) - .pageSize(stepConfig.getPageSize()) - .rowMapper(ARTIST_MAPPER) - .queryProvider(artistQueryProvider.selectAllArtists(dataSource)) - .build(); - } - - @Bean - public ItemWriter artistSyncWriter( - ArtistService artistService, - AppleMusicFeignClient appleMusicFeignClient - ) { - return new BulkArtistUpsertWriter(artistService, appleMusicFeignClient); - } - -} diff --git a/src/main/java/confeti/confetibatchserver/job/artist/BulkArtistUpsertWriter.java b/src/main/java/confeti/confetibatchserver/job/artist/BulkArtistUpsertWriter.java deleted file mode 100644 index 3beec31..0000000 --- a/src/main/java/confeti/confetibatchserver/job/artist/BulkArtistUpsertWriter.java +++ /dev/null @@ -1,42 +0,0 @@ -package confeti.confetibatchserver.job.artist; - -import confeti.confetibatchserver.domain.music.artist.Artist; -import confeti.confetibatchserver.domain.music.artist.application.ArtistService; -import confeti.confetibatchserver.domain.music.artist.vo.ConfetiArtist; -import confeti.confetibatchserver.external.client.AppleMusicFeignClient; -import confeti.confetibatchserver.external.client.dto.artist.AppleMusicArtistsResponse; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.batch.item.Chunk; -import org.springframework.batch.item.ItemWriter; - -@Slf4j -@RequiredArgsConstructor -public class BulkArtistUpsertWriter implements ItemWriter { - - private static final String QUERY_PARAMETER_IDS_DELIMITER = ","; - - private final ArtistService artistService; - private final AppleMusicFeignClient appleMusicFeignClient; - - @Override - public void write(Chunk chunks) { - List savedArtists = new ArrayList<>(chunks.getItems()); - List fetchedArtists = getFetchedArtists(savedArtists); - List updatedArtists = artistService.getUpdatedArtists(savedArtists, fetchedArtists); - artistService.upsertArtists(updatedArtists); - - } - - private List getFetchedArtists(Collection artists) { - String artistIds = artists.stream().map(Artist::getId) - .collect(Collectors.joining(QUERY_PARAMETER_IDS_DELIMITER)); - AppleMusicArtistsResponse fetchedArtistResponses = appleMusicFeignClient.getArtists( - artistIds); - return fetchedArtistResponses.toConfetiArtists(); - } -} \ No newline at end of file diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSyncJobConfig.java b/src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSyncJobConfig.java new file mode 100644 index 0000000..b958e5d --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSyncJobConfig.java @@ -0,0 +1,129 @@ +package confeti.confetibatchserver.job.artistsongsync; + +import static confeti.confetibatchserver.config.ThreadPoolConfig.MUSIC_SYNC_EXECUTOR; +import static confeti.confetibatchserver.job.JobInfo.ARTIST_SONG_SYNC_JOB; +import static confeti.confetibatchserver.job.StepInfo.ARTIST_SONG_SYNC_STEP; +import static confeti.confetibatchserver.job.StepInfo.ARTIST_SYNC_STEP; + +import confeti.confetibatchserver.api.music.facade.MusicSyncFacade; +import confeti.confetibatchserver.domain.batch.stepconfig.StepConfig; +import confeti.confetibatchserver.domain.batch.stepconfig.application.StepConfigService; +import confeti.confetibatchserver.domain.music.artist.vo.ConfetiArtist; +import confeti.confetibatchserver.job.artistsongsync.query.ArtistQueryProvider; +import confeti.confetibatchserver.job.artistsongsync.reader.ArtistIdReader; +import confeti.confetibatchserver.job.artistsongsync.reader.ConfetiArtistReader; +import confeti.confetibatchserver.job.artistsongsync.writer.BulkArtistSongUpsertWriter; +import confeti.confetibatchserver.job.artistsongsync.writer.BulkArtistUpsertWriter; +import confeti.confetibatchserver.logger.JobLoggingListener; +import feign.RetryableException; +import java.io.IOException; +import java.util.concurrent.Executor; +import javax.sql.DataSource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.configuration.annotation.JobScope; +import org.springframework.batch.core.configuration.annotation.StepScope; +import org.springframework.batch.core.job.builder.JobBuilder; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.builder.StepBuilder; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.ItemWriter; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.PlatformTransactionManager; + +@Slf4j +@Configuration +@RequiredArgsConstructor +public class ArtistSyncJobConfig { + + public static final String JOB_PARAMETER_DATE = "requestDate"; + + private final PlatformTransactionManager platformTransactionManager; + + private final StepConfigService stepConfigService; + private final JobRepository jobRepository; + private final ArtistQueryProvider artistQueryProvider; + + @Bean + public Job artistSongSyncJob(Step artistSyncStep, Step artistSongSyncStep) { + return new JobBuilder(ARTIST_SONG_SYNC_JOB.getJobName(), jobRepository) + .start(artistSyncStep) + .next(artistSongSyncStep) + .listener(new JobLoggingListener()) + .build(); + } + + @Bean + @JobScope + public Step artistSongSyncStep( + ItemReader artistIdReader, + ItemWriter artistSongSyncWriter + ) throws Exception { + StepConfig stepConfig = stepConfigService.getByStepInfo(ARTIST_SONG_SYNC_STEP); + + return new StepBuilder(stepConfig.getStepInfo().getName(), jobRepository) + .chunk(stepConfig.getChunkSize(), + platformTransactionManager) + .reader(artistIdReader) + .writer(artistSongSyncWriter) + .faultTolerant() + .retry(RetryableException.class) // Feign의 재시도 가능 예외 + .retry(IOException.class) + .retryLimit(3) + .build(); + } + + @Bean + @JobScope + public Step artistSyncStep( + ItemReader confetiArtistReader, + ItemWriter artistSyncWriter + ) throws Exception { + StepConfig stepConfig = stepConfigService.getByStepInfo(ARTIST_SYNC_STEP); + + return new StepBuilder(stepConfig.getStepInfo().getName(), jobRepository) + .chunk(stepConfig.getChunkSize(), + platformTransactionManager) + .reader(confetiArtistReader) + .writer(artistSyncWriter) + .faultTolerant() + .retry(RetryableException.class) // Feign의 재시도 가능 예외 + .retry(IOException.class) + .retryLimit(3) + .build(); + } + + @Bean + @StepScope + public ItemReader artistIdReader(DataSource dataSource) throws Exception { + StepConfig stepConfig = stepConfigService.getByStepInfo(ARTIST_SYNC_STEP); + return new ArtistIdReader(dataSource, stepConfig, artistQueryProvider); + } + + @Bean + @StepScope + public ItemReader confetiArtistReader(DataSource dataSource) throws Exception { + StepConfig stepConfig = stepConfigService.getByStepInfo(ARTIST_SYNC_STEP); + return new ConfetiArtistReader(dataSource, stepConfig, artistQueryProvider); + } + + @Bean + public ItemWriter artistSyncWriter( + MusicSyncFacade musicSyncFacade + ) { + return new BulkArtistUpsertWriter(musicSyncFacade); + } + + @Bean + public ItemWriter artistSongSyncWriter( + MusicSyncFacade musicSyncFacade, + @Qualifier(MUSIC_SYNC_EXECUTOR) Executor executor + ) { + return new BulkArtistSongUpsertWriter(musicSyncFacade, executor); + } + +} diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/query/ArtistQueryProvider.java b/src/main/java/confeti/confetibatchserver/job/artistsongsync/query/ArtistQueryProvider.java new file mode 100644 index 0000000..cc4343c --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/job/artistsongsync/query/ArtistQueryProvider.java @@ -0,0 +1,55 @@ +package confeti.confetibatchserver.job.artistsongsync.query; + +import confeti.confetibatchserver.domain.music.artist.vo.ConfetiArtist; +import java.util.HashMap; +import java.util.Map; +import javax.sql.DataSource; +import org.springframework.batch.item.database.Order; +import org.springframework.batch.item.database.PagingQueryProvider; +import org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; + +@Component +public class ArtistQueryProvider { + + private static final String ARTIST_ID = "id"; + public static final RowMapper ARTIST_ID_MAPPER = ((rs, rowNum) -> rs.getString( + ARTIST_ID)); + private static final String ARTIST_NAME = "name"; + private static final String ARTIST_PROFILE_URL = "artwork_url"; + public static final RowMapper CONFETI_ARTIST_MAPPER = (rs, rowNum) -> + ConfetiArtist.of( + rs.getString(ARTIST_ID), + rs.getString(ARTIST_NAME), + rs.getString(ARTIST_PROFILE_URL)); + + public PagingQueryProvider selectAllArtists(DataSource dataSource) throws Exception { + SqlPagingQueryProviderFactoryBean queryProvider = new SqlPagingQueryProviderFactoryBean(); + queryProvider.setDataSource(dataSource); + + queryProvider.setSelectClause("id, name, artwork_url"); + queryProvider.setFromClause("FROM artists"); + + Map sortKey = new HashMap<>(); + sortKey.put(ARTIST_ID, Order.ASCENDING); + queryProvider.setSortKeys(sortKey); + + return queryProvider.getObject(); + } + + public PagingQueryProvider selectAllArtistIds(DataSource dataSource) throws Exception { + SqlPagingQueryProviderFactoryBean queryProvider = new SqlPagingQueryProviderFactoryBean(); + queryProvider.setDataSource(dataSource); + + queryProvider.setSelectClause("id"); + queryProvider.setFromClause("FROM artists"); + + Map sortKey = new HashMap<>(); + sortKey.put(ARTIST_ID, Order.ASCENDING); + queryProvider.setSortKeys(sortKey); + + return queryProvider.getObject(); + } + +} diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/reader/ArtistIdReader.java b/src/main/java/confeti/confetibatchserver/job/artistsongsync/reader/ArtistIdReader.java new file mode 100644 index 0000000..f5255d4 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/job/artistsongsync/reader/ArtistIdReader.java @@ -0,0 +1,24 @@ +package confeti.confetibatchserver.job.artistsongsync.reader; + +import static confeti.confetibatchserver.job.artistsongsync.query.ArtistQueryProvider.ARTIST_ID_MAPPER; + +import confeti.confetibatchserver.domain.batch.stepconfig.StepConfig; +import confeti.confetibatchserver.job.artistsongsync.query.ArtistQueryProvider; +import javax.sql.DataSource; +import org.springframework.batch.item.database.JdbcPagingItemReader; + +public class ArtistIdReader extends JdbcPagingItemReader { + + public ArtistIdReader(DataSource dataSource, + StepConfig stepConfig, ArtistQueryProvider queryProvider + ) throws Exception { + + setName("artistIdReader"); + setDataSource(dataSource); + setFetchSize(stepConfig.getFetchSize()); + setPageSize(stepConfig.getPageSize()); + setRowMapper(ARTIST_ID_MAPPER); + setQueryProvider(queryProvider.selectAllArtistIds(dataSource)); + } + +} diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/reader/ConfetiArtistReader.java b/src/main/java/confeti/confetibatchserver/job/artistsongsync/reader/ConfetiArtistReader.java new file mode 100644 index 0000000..c56b4d2 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/job/artistsongsync/reader/ConfetiArtistReader.java @@ -0,0 +1,24 @@ +package confeti.confetibatchserver.job.artistsongsync.reader; + +import static confeti.confetibatchserver.job.artistsongsync.query.ArtistQueryProvider.CONFETI_ARTIST_MAPPER; + +import confeti.confetibatchserver.domain.batch.stepconfig.StepConfig; +import confeti.confetibatchserver.domain.music.artist.vo.ConfetiArtist; +import confeti.confetibatchserver.job.artistsongsync.query.ArtistQueryProvider; +import javax.sql.DataSource; +import org.springframework.batch.item.database.JdbcPagingItemReader; + +public class ConfetiArtistReader extends JdbcPagingItemReader { + + public ConfetiArtistReader(DataSource dataSource, + StepConfig stepConfig, ArtistQueryProvider artistQueryProvider + ) throws Exception { + + setName("confetiArtistReader"); + setDataSource(dataSource); + setFetchSize(stepConfig.getFetchSize()); + setPageSize(stepConfig.getPageSize()); + setRowMapper(CONFETI_ARTIST_MAPPER); + setQueryProvider(artistQueryProvider.selectAllArtists(dataSource)); + } +} diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/writer/BulkArtistSongUpsertWriter.java b/src/main/java/confeti/confetibatchserver/job/artistsongsync/writer/BulkArtistSongUpsertWriter.java new file mode 100644 index 0000000..dde9b02 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/job/artistsongsync/writer/BulkArtistSongUpsertWriter.java @@ -0,0 +1,43 @@ +package confeti.confetibatchserver.job.artistsongsync.writer; + + +import static confeti.confetibatchserver.config.ThreadPoolConfig.MUSIC_SYNC_EXECUTOR; + +import confeti.confetibatchserver.api.music.facade.MusicSyncFacade; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.batch.item.Chunk; +import org.springframework.batch.item.ItemWriter; +import org.springframework.beans.factory.annotation.Qualifier; + +@Slf4j +@RequiredArgsConstructor +public class BulkArtistSongUpsertWriter implements ItemWriter { + + private final MusicSyncFacade musicSyncFacade; + + @Qualifier(MUSIC_SYNC_EXECUTOR) + private final Executor executor; + + @Override + public void write(Chunk chunk) throws Exception { + List artistIds = chunk.getItems(); + + List> futures = artistIds.stream() + .map(artistId -> CompletableFuture.runAsync(() -> { + try { + musicSyncFacade.upsertSongByArtistId(artistId); + } catch (Exception e) { + // 데이터 삽입 중 오류 발생 시 로그만 남기고 다음 작업을 계속 수행 + log.error("Error to sync ArtistSong artist: " + artistId, e); + } + }, executor)) + .toList(); + + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); + } + +} diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/writer/BulkArtistUpsertWriter.java b/src/main/java/confeti/confetibatchserver/job/artistsongsync/writer/BulkArtistUpsertWriter.java new file mode 100644 index 0000000..d02e7a0 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/job/artistsongsync/writer/BulkArtistUpsertWriter.java @@ -0,0 +1,22 @@ +package confeti.confetibatchserver.job.artistsongsync.writer; + +import confeti.confetibatchserver.api.music.facade.MusicSyncFacade; +import confeti.confetibatchserver.domain.music.artist.vo.ConfetiArtist; +import java.util.ArrayList; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.batch.item.Chunk; +import org.springframework.batch.item.ItemWriter; + +@Slf4j +@RequiredArgsConstructor +public class BulkArtistUpsertWriter implements ItemWriter { + + private final MusicSyncFacade musicSyncFacade; + + @Override + public void write(Chunk chunks) { + musicSyncFacade.upsertArtists(new ArrayList<>(chunks.getItems())); + } + +} \ No newline at end of file diff --git a/src/main/java/confeti/confetibatchserver/scheduler/ArtistSyncSchedule.java b/src/main/java/confeti/confetibatchserver/scheduler/ArtistSyncSchedule.java index a6d14b9..0e9165f 100644 --- a/src/main/java/confeti/confetibatchserver/scheduler/ArtistSyncSchedule.java +++ b/src/main/java/confeti/confetibatchserver/scheduler/ArtistSyncSchedule.java @@ -1,10 +1,10 @@ package confeti.confetibatchserver.scheduler; -import static confeti.confetibatchserver.job.JobInfo.ARTIST_SYNC_JOB; +import static confeti.confetibatchserver.job.JobInfo.ARTIST_SONG_SYNC_JOB; import confeti.confetibatchserver.domain.batch.jobconfig.JobConfig; import confeti.confetibatchserver.domain.batch.jobconfig.application.JobConfigService; -import confeti.confetibatchserver.job.artist.ArtistSyncJobConfig; +import confeti.confetibatchserver.job.artistsongsync.ArtistSyncJobConfig; import java.time.LocalDate; import lombok.RequiredArgsConstructor; import org.springframework.batch.core.JobParameters; @@ -27,7 +27,7 @@ public class ArtistSyncSchedule { zone = "${schedules.artist-sync.zone}" ) public void runArtistSyncJob() throws Exception { - JobConfig jobConfig = jobConfigService.getByJobInfo(ARTIST_SYNC_JOB); + JobConfig jobConfig = jobConfigService.getByJobInfo(ARTIST_SONG_SYNC_JOB); if (jobConfig.isActive()) { String date = LocalDate.now().toString(); @@ -35,7 +35,7 @@ public void runArtistSyncJob() throws Exception { .addString(ArtistSyncJobConfig.JOB_PARAMETER_DATE, date) .toJobParameters(); - jobLauncher.run(jobRegistry.getJob(ARTIST_SYNC_JOB.getJobName()), jobParameters); + jobLauncher.run(jobRegistry.getJob(ARTIST_SONG_SYNC_JOB.getJobName()), jobParameters); } } diff --git a/src/main/resources/common/application-apple-music.yml b/src/main/resources/common/application-apple-music.yml index 16685c2..45701ef 100644 --- a/src/main/resources/common/application-apple-music.yml +++ b/src/main/resources/common/application-apple-music.yml @@ -38,7 +38,7 @@ spring: on-profile: prod apple-music: api: - host: 10.0.0.232 + host: https://external.confeti.xyz path: /apple-music-api ---