From cf7b30ef61e8fde33ebb06a9f3839b1aff0d6d54 Mon Sep 17 00:00:00 2001 From: jher235 Date: Thu, 1 Jan 2026 22:35:55 +0900 Subject: [PATCH 01/17] =?UTF-8?q?CONFETI-76=20feat:=20ConfetiRelatedArtist?= =?UTF-8?q?=20vo=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vo/ConfetiRelatedArtist.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/confeti/confetibatchserver/domain/music/relatedartist/vo/ConfetiRelatedArtist.java diff --git a/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/vo/ConfetiRelatedArtist.java b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/vo/ConfetiRelatedArtist.java new file mode 100644 index 0000000..f90352a --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/vo/ConfetiRelatedArtist.java @@ -0,0 +1,26 @@ +package confeti.confetibatchserver.domain.music.relatedartist.vo; + +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 ConfetiRelatedArtist { + + private Long id; + private String artistId; + private String relatedArtistId; + + public static ConfetiRelatedArtist of(String artistId, String relatedArtistId) { + return ConfetiRelatedArtist.builder() + .artistId(artistId) + .relatedArtistId(relatedArtistId) + .build(); + } + +} From 6e452aa4371698260792367798ddde30ba9d3126 Mon Sep 17 00:00:00 2001 From: jher235 Date: Thu, 1 Jan 2026 22:42:37 +0900 Subject: [PATCH 02/17] =?UTF-8?q?CONFETI-76=20feat:=20JdbcRepository=20?= =?UTF-8?q?=EB=8F=84=EC=9E=85=20=EB=B0=8F=20artistId=EB=A1=9C=20ConfetiRel?= =?UTF-8?q?atedArtist=20=EB=AA=A9=EB=A1=9D=20=EB=B0=98=ED=99=98=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RelatedArtistJdbcRepository.java | 11 +++++ .../RelatedArtistJdbcRepositoryImpl.java | 41 +++++++++++++++++++ .../repository/RelatedArtistRepository.java | 3 +- 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepository.java create mode 100644 src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepositoryImpl.java diff --git a/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepository.java b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepository.java new file mode 100644 index 0000000..e3cf7ce --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepository.java @@ -0,0 +1,11 @@ +package confeti.confetibatchserver.domain.music.relatedartist.infra.repository; + +import confeti.confetibatchserver.domain.music.relatedartist.vo.ConfetiRelatedArtist; +import java.util.Collection; +import java.util.List; + +public interface RelatedArtistJdbcRepository { + + List findAllConfetiRelatedArtistIdsByArtistIds( + Collection artistIds); +} diff --git a/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepositoryImpl.java b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepositoryImpl.java new file mode 100644 index 0000000..3b62b2e --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepositoryImpl.java @@ -0,0 +1,41 @@ +package confeti.confetibatchserver.domain.music.relatedartist.infra.repository; + +import confeti.confetibatchserver.domain.music.relatedartist.vo.ConfetiRelatedArtist; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class RelatedArtistJdbcRepositoryImpl implements RelatedArtistJdbcRepository { + + private static final String SELECT_RELATED_ARTIST_QUERY = """ + SELECT + ra.id as id, + ra.artist_id as artistId + ra.related_artist_id as relatedArtistId + FROM related_artists as ra + WHERE ra.artist_id IN (:artistId) + """; + private final NamedParameterJdbcTemplate namedParameterJdbcTemplate; + + @Override + public List findAllConfetiRelatedArtistIdsByArtistIds( + Collection artistIds + ) { + Map params = Map.of("artistId", artistIds); + + return namedParameterJdbcTemplate.query( + SELECT_RELATED_ARTIST_QUERY, + params, + (rs, rowNum) -> ConfetiRelatedArtist.builder() + .id(rs.getLong("id")) + .artistId(rs.getString("artist_id")) + .relatedArtistId(rs.getString("related_artist_id")) + .build()); + } + +} diff --git a/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistRepository.java b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistRepository.java index 2986a08..17d7ff3 100644 --- a/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistRepository.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistRepository.java @@ -3,6 +3,7 @@ import confeti.confetibatchserver.domain.music.relatedartist.RelatedArtist; import org.springframework.data.jpa.repository.JpaRepository; -public interface RelatedArtistRepository extends JpaRepository { +public interface RelatedArtistRepository extends JpaRepository, + RelatedArtistJdbcRepository { } From a8ea4a8e2c9c61c91e2a471be0295f193bfcf985 Mon Sep 17 00:00:00 2001 From: jher235 Date: Thu, 1 Jan 2026 23:47:14 +0900 Subject: [PATCH 03/17] =?UTF-8?q?CONFETI-76=20feat:=20relatedArtist=20Sync?= =?UTF-8?q?=20Job=20=EB=B0=8F=20Step=20=EC=84=A4=EC=A0=95=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/confeti/confetibatchserver/job/JobInfo.java | 3 ++- src/main/java/confeti/confetibatchserver/job/StepInfo.java | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/confeti/confetibatchserver/job/JobInfo.java b/src/main/java/confeti/confetibatchserver/job/JobInfo.java index b7102a6..a9bbb36 100644 --- a/src/main/java/confeti/confetibatchserver/job/JobInfo.java +++ b/src/main/java/confeti/confetibatchserver/job/JobInfo.java @@ -7,7 +7,8 @@ @RequiredArgsConstructor public enum JobInfo { - ARTIST_SONG_SYNC_JOB("artistSongSyncJob"); + ARTIST_SONG_SYNC_JOB("artistSongSyncJob"), + RELATED_ARTIST_SYNC_JOB("relatedArtistSyncJob"); 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 10bd6f6..a0d899d 100644 --- a/src/main/java/confeti/confetibatchserver/job/StepInfo.java +++ b/src/main/java/confeti/confetibatchserver/job/StepInfo.java @@ -7,7 +7,9 @@ @RequiredArgsConstructor public enum StepInfo { ARTIST_SYNC_STEP(JobInfo.ARTIST_SONG_SYNC_JOB, "artistSyncStep"), - ARTIST_SONG_SYNC_STEP(JobInfo.ARTIST_SONG_SYNC_JOB, "artistSongSyncStep"); + ARTIST_SONG_SYNC_STEP(JobInfo.ARTIST_SONG_SYNC_JOB, "artistSongSyncStep"), + + RELATED_ARTIST_SYNC_STEP(JobInfo.RELATED_ARTIST_SYNC_JOB, "relatedArtistSyncStep"); private final JobInfo jobInfo; private final String name; From 8560553314a334d867d0c119a6207e93c39772a2 Mon Sep 17 00:00:00 2001 From: jher235 Date: Thu, 1 Jan 2026 23:48:28 +0900 Subject: [PATCH 04/17] =?UTF-8?q?CONFETI-76=20feat:=20relatedArtist=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20=EA=B0=80=EC=A0=B8?= =?UTF-8?q?=EC=98=A4=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?-=20getRelatedArtistsById=20=EC=97=90=20offset=20=ED=8C=8C?= =?UTF-8?q?=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/AppleMusicFeignClient.java | 11 ++-------- .../service/AppleMusicAPIHandler.java | 21 +++++++++++++++++++ .../external/service/MusicAPIHandler.java | 7 +++++-- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/main/java/confeti/confetibatchserver/external/client/AppleMusicFeignClient.java b/src/main/java/confeti/confetibatchserver/external/client/AppleMusicFeignClient.java index 68005d3..0930e88 100644 --- a/src/main/java/confeti/confetibatchserver/external/client/AppleMusicFeignClient.java +++ b/src/main/java/confeti/confetibatchserver/external/client/AppleMusicFeignClient.java @@ -28,18 +28,11 @@ AppleMusicArtistsResponse getArtists( @RequestParam String ids ); - @GetMapping("/artists/{id}/view/{view}") - @Deprecated - AppleMusicArtistsResponse getRelatedArtistsById( - @PathVariable String id, - @PathVariable String view, - @RequestParam String limit - ); - @GetMapping("/artists/{id}/view/similar-artists") AppleMusicArtistsResponse getRelatedArtistsById( @PathVariable String id, - @RequestParam String limit + @RequestParam String limit, + @RequestParam String offset ); @GetMapping("/artists/{id}/view/top-songs") diff --git a/src/main/java/confeti/confetibatchserver/external/service/AppleMusicAPIHandler.java b/src/main/java/confeti/confetibatchserver/external/service/AppleMusicAPIHandler.java index 6f3d438..b6da0b0 100644 --- a/src/main/java/confeti/confetibatchserver/external/service/AppleMusicAPIHandler.java +++ b/src/main/java/confeti/confetibatchserver/external/service/AppleMusicAPIHandler.java @@ -18,6 +18,7 @@ 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 static int RELATED_ARTIST_FETCH_SIZE = 100; private final AppleMusicFeignClient appleMusicFeignClient; @@ -46,4 +47,24 @@ public List getArtistsByIds(Collection artistIds) { joinedArtistIds); return fetchedArtistResponses.toConfetiArtists(); } + + @Override + public List getAllRelatedArtistIds(String artistId) { + int offset = 0; + String next = null; + List relatedArtistIds = new ArrayList<>(); + do { + AppleMusicArtistsResponse relatedArtists = appleMusicFeignClient.getRelatedArtistsById( + artistId, String.valueOf(RELATED_ARTIST_FETCH_SIZE), String.valueOf(offset)); + next = relatedArtists.next(); + + if (relatedArtistIds.isEmpty()) { // 사이즈 초기화 + relatedArtistIds = new ArrayList<>(relatedArtists.data().size()); + } + relatedArtistIds.addAll(relatedArtists.toArtistIds()); + offset += RELATED_ARTIST_FETCH_SIZE; + } while (next != null); + + return relatedArtistIds; + } } diff --git a/src/main/java/confeti/confetibatchserver/external/service/MusicAPIHandler.java b/src/main/java/confeti/confetibatchserver/external/service/MusicAPIHandler.java index 7bca3a2..797f1eb 100644 --- a/src/main/java/confeti/confetibatchserver/external/service/MusicAPIHandler.java +++ b/src/main/java/confeti/confetibatchserver/external/service/MusicAPIHandler.java @@ -7,7 +7,10 @@ public interface MusicAPIHandler { - List getAllSongsByArtistId(String artistId); + List getAllSongsByArtistId(final String artistId); + + List getArtistsByIds(final Collection artistIds); + + List getAllRelatedArtistIds(final String artistId); - List getArtistsByIds(Collection artistIds); } From 61cd2b6a62d55bf3fdab94fc6f3a8900a746a2b5 Mon Sep 17 00:00:00 2001 From: jher235 Date: Thu, 1 Jan 2026 23:48:54 +0900 Subject: [PATCH 05/17] =?UTF-8?q?CONFETI-76=20feat:=20=EB=B2=8C=ED=81=AC?= =?UTF-8?q?=20insert,=20delete=20=EB=A5=BC=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RelatedArtistJdbcRepository.java | 4 +++ .../RelatedArtistJdbcRepositoryImpl.java | 35 ++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepository.java b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepository.java index e3cf7ce..7eb2f56 100644 --- a/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepository.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepository.java @@ -8,4 +8,8 @@ public interface RelatedArtistJdbcRepository { List findAllConfetiRelatedArtistIdsByArtistIds( Collection artistIds); + + void bulkInsert(Collection relatedArtists); + + void bulkDelete(Collection relatedArtists); } diff --git a/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepositoryImpl.java b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepositoryImpl.java index 3b62b2e..f5679e6 100644 --- a/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepositoryImpl.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepositoryImpl.java @@ -5,6 +5,7 @@ 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.stereotype.Repository; @@ -15,11 +16,23 @@ public class RelatedArtistJdbcRepositoryImpl implements RelatedArtistJdbcReposit private static final String SELECT_RELATED_ARTIST_QUERY = """ SELECT ra.id as id, - ra.artist_id as artistId + ra.artist_id as artistId, ra.related_artist_id as relatedArtistId FROM related_artists as ra WHERE ra.artist_id IN (:artistId) """; + + private static final String BULK_INSERT_RELATED_ARTIST_QUERY = """ + INSERT IGNORE INTO related_artists (artist_id, related_artist_id, created_at, updated_at) + VALUES (:artistId, :relatedArtistId, NOW(), null) + """; + + private static final String BULK_DELETE_RELATED_ARTIST_QUERY = """ + DELETE + FROM related_artists as ra + WHERE ra.artist_id = :artistId AND ra.related_artist_id = :related_artist_id + """; + private final NamedParameterJdbcTemplate namedParameterJdbcTemplate; @Override @@ -38,4 +51,24 @@ public List findAllConfetiRelatedArtistIdsByArtistIds( .build()); } + @Override + public void bulkInsert(Collection relatedArtists) { + MapSqlParameterSource[] parameterSource = relatedArtists.stream() + .map(relatedArtist -> new MapSqlParameterSource() + .addValue("artistId", relatedArtist.getArtistId()) + .addValue("relatedArtistId", relatedArtist.getRelatedArtistId()) + ).toArray(MapSqlParameterSource[]::new); + namedParameterJdbcTemplate.batchUpdate(BULK_INSERT_RELATED_ARTIST_QUERY, parameterSource); + } + + @Override + public void bulkDelete(Collection relatedArtists) { + MapSqlParameterSource[] parameterSource = relatedArtists.stream() + .map(relatedArtist -> new MapSqlParameterSource() + .addValue("artistId", relatedArtist.getArtistId()) + .addValue("relatedArtistId", relatedArtist.getRelatedArtistId()) + ).toArray(MapSqlParameterSource[]::new); + namedParameterJdbcTemplate.batchUpdate(BULK_DELETE_RELATED_ARTIST_QUERY, parameterSource); + } + } From fa390602a681dab87f391ca0869b99cb7e6d3b3a Mon Sep 17 00:00:00 2001 From: jher235 Date: Thu, 1 Jan 2026 23:49:38 +0900 Subject: [PATCH 06/17] =?UTF-8?q?CONFETI-76=20feat:=20AppleMusicArtistsRes?= =?UTF-8?q?ponse=20=EC=97=90=20next=20=ED=95=84=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/dto/artist/AppleMusicArtistsResponse.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/confeti/confetibatchserver/external/client/dto/artist/AppleMusicArtistsResponse.java b/src/main/java/confeti/confetibatchserver/external/client/dto/artist/AppleMusicArtistsResponse.java index 0797abc..86004ff 100644 --- a/src/main/java/confeti/confetibatchserver/external/client/dto/artist/AppleMusicArtistsResponse.java +++ b/src/main/java/confeti/confetibatchserver/external/client/dto/artist/AppleMusicArtistsResponse.java @@ -4,6 +4,7 @@ import java.util.List; public record AppleMusicArtistsResponse( + String next, List data ) { @@ -12,4 +13,10 @@ public List toConfetiArtists() { .map(AppleMusicArtistResponse::toConfetiArtist) .toList(); } + + public List toArtistIds() { + return data.stream() + .map(AppleMusicArtistResponse::id) + .toList(); + } } From b8d27088e6c05d8cc3c0960b09a2b568309c438f Mon Sep 17 00:00:00 2001 From: jher235 Date: Thu, 1 Jan 2026 23:50:54 +0900 Subject: [PATCH 07/17] =?UTF-8?q?CONFETI-76=20feat:=20RelatedArtistSync=20?= =?UTF-8?q?processor=20=EA=B5=AC=ED=98=84=20-=20ArtistRelations=20?= =?UTF-8?q?=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98=EC=97=AC=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EB=A5=BC=20=EC=A0=84=EB=8B=AC=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EA=B5=AC=ED=98=84.=20confetiRelatedArtist?= =?UTF-8?q?=20=EB=B3=B4=EB=8B=A4=20=EA=B5=AC=EC=A1=B0=EA=B0=80=20=ED=9A=A8?= =?UTF-8?q?=EC=9C=A8=EC=A0=81=EC=9D=B4=EB=9D=BC=EA=B3=A0=20=ED=8C=90?= =?UTF-8?q?=EB=8B=A8=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/ArtistRelations.java | 10 ++++++++++ .../processor/RelatedArtistSyncProcessor.java | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/main/java/confeti/confetibatchserver/job/relatedartistsync/dto/ArtistRelations.java create mode 100644 src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java diff --git a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/dto/ArtistRelations.java b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/dto/ArtistRelations.java new file mode 100644 index 0000000..6d64fbd --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/dto/ArtistRelations.java @@ -0,0 +1,10 @@ +package confeti.confetibatchserver.job.relatedartistsync.dto; + +import java.util.List; + +public record ArtistRelations( + String artistId, + List relatedArtistIds +) { + +} diff --git a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java new file mode 100644 index 0000000..e7605ef --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java @@ -0,0 +1,19 @@ +package confeti.confetibatchserver.job.relatedartistsync.processor; + +import confeti.confetibatchserver.external.service.MusicAPIHandler; +import confeti.confetibatchserver.job.relatedartistsync.dto.ArtistRelations; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.batch.item.ItemProcessor; + +@RequiredArgsConstructor +public class RelatedArtistSyncProcessor implements ItemProcessor { + + private final MusicAPIHandler musicAPIHandler; + + @Override + public ArtistRelations process(String item) throws Exception { + List allRelatedArtistIds = musicAPIHandler.getAllRelatedArtistIds(item); + return new ArtistRelations(item, allRelatedArtistIds); + } +} From 2dffc6a87b644daf3c44fc59f2254207138527c9 Mon Sep 17 00:00:00 2001 From: jher235 Date: Thu, 1 Jan 2026 23:54:41 +0900 Subject: [PATCH 08/17] =?UTF-8?q?CONFETI-76=20feat:=20RelatedArtistService?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=20-=20=ED=95=B4=EB=8B=B9=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4=20=EB=82=B4=EB=B6=80=EC=97=90=EC=84=9C=20DB?= =?UTF-8?q?=EC=9D=98=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=A4=EA=B3=A0=20=EC=A0=95=ED=95=A9=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EB=A7=9E=EC=B6=94=EB=8A=94=20=EC=9E=91=EC=97=85?= =?UTF-8?q?=EC=9D=84=20=EB=AA=A8=EB=91=90=20=EC=A7=84=ED=96=89=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=ED=95=A8=20-=20=EB=B0=B0=EC=B9=98=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=20=ED=8A=B9=EC=84=B1=20=EC=83=81=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EB=A5=BC=20=EC=A0=84=EB=8B=AC=ED=95=A0=20?= =?UTF-8?q?=EB=95=8C=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=EC=9D=B4=20Map>,=20List,=20List=20=EB=93=B1=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=8B=AC=EB=9D=BC=EC=A7=80=EB=8A=94=20=ED=98=95?= =?UTF-8?q?=ED=83=9C=EA=B0=80=20=EB=90=90=EB=8A=94=EB=8D=B0,=20=EC=9D=B4?= =?UTF-8?q?=EB=A5=BC=20=ED=8C=8C=EC=82=AC=EB=93=9C=20=EB=8B=A8=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EA=B4=80=EB=A6=AC=ED=95=98=EB=A9=B4=EC=84=9C=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=EB=A5=BC=20=ED=98=B8=EC=B6=9C?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B2=83=EB=B3=B4=EB=8B=A4=20newArtistRel?= =?UTF-8?q?ations=20=EB=9D=BC=EB=8A=94=20=ED=8C=8C=EB=9D=BC=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=EB=A5=BC=20=ED=95=9C=EB=B2=88=EC=97=90=20=EC=A0=84?= =?UTF-8?q?=EB=8B=AC=ED=95=98=EB=8A=94=EA=B2=8C=20=EB=8D=94=20=EC=A2=8B?= =?UTF-8?q?=EB=8B=A4=EA=B3=A0=20=ED=8C=90=EB=8B=A8=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/RelatedArtistService.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/main/java/confeti/confetibatchserver/domain/music/relatedartist/application/RelatedArtistService.java diff --git a/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/application/RelatedArtistService.java b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/application/RelatedArtistService.java new file mode 100644 index 0000000..7ddac67 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/application/RelatedArtistService.java @@ -0,0 +1,80 @@ +package confeti.confetibatchserver.domain.music.relatedartist.application; + +import confeti.confetibatchserver.domain.music.relatedartist.infra.repository.RelatedArtistRepository; +import confeti.confetibatchserver.domain.music.relatedartist.vo.ConfetiRelatedArtist; +import confeti.confetibatchserver.job.relatedartistsync.dto.ArtistRelations; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class RelatedArtistService { + + private final RelatedArtistRepository relatedArtistRepository; + + public Map> getRelatedArtistIds(Collection artistIds) { + return relatedArtistRepository.findAllConfetiRelatedArtistIdsByArtistIds(artistIds).stream() + .collect(Collectors.groupingBy( + ConfetiRelatedArtist::getArtistId, + Collectors.mapping(ConfetiRelatedArtist::getRelatedArtistId, Collectors.toSet()) + )); + } + + @Transactional + public void reconcile( + List newArtistRelations + ) { + Map> oldRelatedArtistIdsByArtistId = getRelatedArtistIds( + newArtistRelations.stream().map(ArtistRelations::artistId).toList()); + List insertRelation = new ArrayList<>(); + List deleteRelation = new ArrayList<>(); + + newArtistRelations.forEach(newRelation -> { + String currentArtistId = newRelation.artistId(); + Set oldRelatedArtistIds = new HashSet<>( + oldRelatedArtistIdsByArtistId.getOrDefault(currentArtistId, Set.of())); + List newRelatedArtistIds = newRelation.relatedArtistIds(); + deleteRelation.addAll( + toDeleteRelation(currentArtistId, oldRelatedArtistIds, newRelatedArtistIds)); + insertRelation.addAll( + toInsertRelation(currentArtistId, oldRelatedArtistIds, newRelatedArtistIds)); + }); + relatedArtistRepository.bulkInsert(insertRelation); + relatedArtistRepository.bulkDelete(deleteRelation); + } + + public Set toDeleteRelation( + String artistId, + Collection oldRelatedArtistIds, + Collection newRelatedArtistIds + ) { + Set deleteRelatedArtistIds = new HashSet<>(oldRelatedArtistIds); + deleteRelatedArtistIds.removeAll(newRelatedArtistIds); + + return deleteRelatedArtistIds.stream() + .map(relatedArtistId -> ConfetiRelatedArtist.of(artistId, relatedArtistId)) + .collect(Collectors.toSet()); + } + + public Set toInsertRelation( + String artistId, + Collection oldRelatedArtistIds, + Collection newRelatedArtistIds + ) { + Set insertRelatedArtistIds = new HashSet<>(newRelatedArtistIds); + insertRelatedArtistIds.removeAll(oldRelatedArtistIds); + + return insertRelatedArtistIds.stream() + .map(relatedArtistId -> ConfetiRelatedArtist.of(artistId, relatedArtistId)) + .collect(Collectors.toSet()); + } + +} From f41cad0a5a68198fad4e9442ef8c9fba6b47a0b8 Mon Sep 17 00:00:00 2001 From: jher235 Date: Thu, 1 Jan 2026 23:55:03 +0900 Subject: [PATCH 09/17] =?UTF-8?q?CONFETI-76=20feat:=20BulkRelatedArtistUps?= =?UTF-8?q?ertWriter=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/music/facade/MusicSyncFacade.java | 9 ++++++++ .../writer/BulkRelatedArtistUpsertWriter.java | 21 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java diff --git a/src/main/java/confeti/confetibatchserver/api/music/facade/MusicSyncFacade.java b/src/main/java/confeti/confetibatchserver/api/music/facade/MusicSyncFacade.java index 844f3c1..0781684 100644 --- a/src/main/java/confeti/confetibatchserver/api/music/facade/MusicSyncFacade.java +++ b/src/main/java/confeti/confetibatchserver/api/music/facade/MusicSyncFacade.java @@ -3,14 +3,17 @@ 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.relatedartist.application.RelatedArtistService; 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 confeti.confetibatchserver.job.relatedartistsync.dto.ArtistRelations; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; @Facade @RequiredArgsConstructor @@ -19,6 +22,7 @@ public class MusicSyncFacade { private final MusicAPIHandler musicAPIHandler; private final ArtistService artistService; private final SongService songService; + private final RelatedArtistService relatedArtistService; public void upsertSongByArtistId(String artistId) { List fetchedSongs = musicAPIHandler.getAllSongsByArtistId(artistId); @@ -33,4 +37,9 @@ public void upsertArtists(List artists) { artistService.upsertArtists(updatedArtists); } + @Transactional + public void reconcileRelatedArtists(List newArtistRelations) { + relatedArtistService.reconcile(newArtistRelations); + } + } diff --git a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java new file mode 100644 index 0000000..538c252 --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java @@ -0,0 +1,21 @@ +package confeti.confetibatchserver.job.relatedartistsync.writer; + +import confeti.confetibatchserver.api.music.facade.MusicSyncFacade; +import confeti.confetibatchserver.job.relatedartistsync.dto.ArtistRelations; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.batch.item.Chunk; +import org.springframework.batch.item.ItemWriter; + +@RequiredArgsConstructor +public class BulkRelatedArtistUpsertWriter implements ItemWriter { + + private final MusicSyncFacade musicSyncFacade; + + @Override + public void write(Chunk chunk) throws Exception { + @SuppressWarnings("unchecked") + List relations = (List) chunk.getItems(); + musicSyncFacade.reconcileRelatedArtists(relations); + } +} From e703ffce334dd4c4c3ebc2a33a3abd80b02f5713 Mon Sep 17 00:00:00 2001 From: jher235 Date: Thu, 1 Jan 2026 23:55:59 +0900 Subject: [PATCH 10/17] =?UTF-8?q?CONFETI-76=20feat:=20Spring=20Batch=20Int?= =?UTF-8?q?egration=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index 1f75deb..371d809 100644 --- a/build.gradle +++ b/build.gradle @@ -34,6 +34,9 @@ dependencies { // Spring Batch Core implementation 'org.springframework.boot:spring-boot-starter-batch' + // Spring Batch Integration + implementation 'org.springframework.batch:spring-batch-integration' + // JPA implementation 'org.springframework.boot:spring-boot-starter-data-jpa' From a94592706fb4949f39ac9f33244e3433583da1af Mon Sep 17 00:00:00 2001 From: jher235 Date: Thu, 1 Jan 2026 23:56:36 +0900 Subject: [PATCH 11/17] =?UTF-8?q?CONFETI-76=20feat:=20RelatedArtistSyncJob?= =?UTF-8?q?Config=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RelatedArtistSyncJobConfig.java | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/main/java/confeti/confetibatchserver/job/relatedartistsync/RelatedArtistSyncJobConfig.java diff --git a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/RelatedArtistSyncJobConfig.java b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/RelatedArtistSyncJobConfig.java new file mode 100644 index 0000000..7b0499c --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/RelatedArtistSyncJobConfig.java @@ -0,0 +1,104 @@ +package confeti.confetibatchserver.job.relatedartistsync; + +import static confeti.confetibatchserver.config.ThreadPoolConfig.MUSIC_SYNC_EXECUTOR; +import static confeti.confetibatchserver.job.JobInfo.RELATED_ARTIST_SYNC_JOB; +import static confeti.confetibatchserver.job.StepInfo.RELATED_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.external.service.MusicAPIHandler; +import confeti.confetibatchserver.job.artistsongsync.query.ArtistQueryProvider; +import confeti.confetibatchserver.job.artistsongsync.reader.ArtistIdReader; +import confeti.confetibatchserver.job.relatedartistsync.dto.ArtistRelations; +import confeti.confetibatchserver.job.relatedartistsync.processor.RelatedArtistSyncProcessor; +import confeti.confetibatchserver.job.relatedartistsync.writer.BulkRelatedArtistUpsertWriter; +import confeti.confetibatchserver.logger.JobLoggingListener; +import feign.RetryableException; +import java.io.IOException; +import java.util.concurrent.Future; +import javax.sql.DataSource; +import lombok.RequiredArgsConstructor; +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.job.builder.JobBuilder; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.builder.StepBuilder; +import org.springframework.batch.integration.async.AsyncItemProcessor; +import org.springframework.batch.integration.async.AsyncItemWriter; +import org.springframework.batch.item.ItemReader; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.transaction.PlatformTransactionManager; + +@Configuration +@RequiredArgsConstructor +public class RelatedArtistSyncJobConfig { + + 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 relatedArtistSyncJob(Step relatedArtistSyncStep) { + return new JobBuilder(RELATED_ARTIST_SYNC_JOB.getJobName(), jobRepository) + .start(relatedArtistSyncStep) + .listener(new JobLoggingListener()) + .build(); + } + + @Bean + @JobScope + public Step relatedArtistSyncStep( + ItemReader relatedArtistStepReader, + AsyncItemProcessor relatedArtistProcessor, + AsyncItemWriter artistSongSyncWriter + ) throws Exception { + StepConfig stepConfig = stepConfigService.getByStepInfo(RELATED_ARTIST_SYNC_STEP); + + return new StepBuilder(stepConfig.getStepInfo().getName(), jobRepository) + .>chunk(stepConfig.getChunkSize(), + platformTransactionManager) + .reader(relatedArtistStepReader) + .processor(relatedArtistProcessor) + .writer(artistSongSyncWriter) + .faultTolerant() + .retry(RetryableException.class) // Feign의 재시도 가능 예외 + .retry(IOException.class) + .retryLimit(3) + .build(); + } + + @Bean + public ItemReader relatedArtistStepReader(DataSource dataSource) throws Exception { + StepConfig stepConfig = stepConfigService.getByStepInfo(RELATED_ARTIST_SYNC_STEP); + return new ArtistIdReader(dataSource, stepConfig, artistQueryProvider); + } + + @Bean + public AsyncItemProcessor relatedArtistSyncProcessor( + MusicAPIHandler musicAPIHandler, + @Qualifier(MUSIC_SYNC_EXECUTOR) TaskExecutor executor + ) { + AsyncItemProcessor processor = new AsyncItemProcessor<>(); + processor.setDelegate(new RelatedArtistSyncProcessor(musicAPIHandler)); + processor.setTaskExecutor(executor); + return processor; + } + + @Bean + public AsyncItemWriter relatedArtistSyncWriter( + MusicSyncFacade musicSyncFacade + ) { + AsyncItemWriter writer = new AsyncItemWriter<>(); + writer.setDelegate(new BulkRelatedArtistUpsertWriter(musicSyncFacade)); + return writer; + } +} From 839e2c4249626e7bd2e5b44b562d4f3aeaa70df3 Mon Sep 17 00:00:00 2001 From: jher235 Date: Fri, 2 Jan 2026 01:03:48 +0900 Subject: [PATCH 12/17] =?UTF-8?q?CONFETI-76=20fix:=20=EC=9E=98=EB=AA=BB?= =?UTF-8?q?=EB=90=9C=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/repository/RelatedArtistJdbcRepositoryImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepositoryImpl.java b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepositoryImpl.java index f5679e6..0517312 100644 --- a/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepositoryImpl.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/infra/repository/RelatedArtistJdbcRepositoryImpl.java @@ -46,8 +46,8 @@ public List findAllConfetiRelatedArtistIdsByArtistIds( params, (rs, rowNum) -> ConfetiRelatedArtist.builder() .id(rs.getLong("id")) - .artistId(rs.getString("artist_id")) - .relatedArtistId(rs.getString("related_artist_id")) + .artistId(rs.getString("artistId")) + .relatedArtistId(rs.getString("relatedArtistId")) .build()); } From fd90ec4e2aaf0b0e356c6d6bc57141443690a65a Mon Sep 17 00:00:00 2001 From: jher235 Date: Fri, 2 Jan 2026 01:05:53 +0900 Subject: [PATCH 13/17] =?UTF-8?q?CONFETI-76=20refactor:=20Exception=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=20=EC=8B=9C=20=EB=A1=9C=EA=B7=B8=EB=A5=BC=20?= =?UTF-8?q?=EB=82=A8=EA=B8=B0=EA=B3=A0=20=EC=9E=91=EC=97=85=EC=9D=84=20?= =?UTF-8?q?=EA=B3=84=EC=86=8D=20=EC=A7=84=ED=96=89=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EA=B5=AC=ED=98=84=20-=20=EC=A0=95=ED=95=A9?= =?UTF-8?q?=EC=84=B1=20=EC=9E=91=EC=97=85=EC=9D=80=20=EC=8B=B1=ED=81=AC?= =?UTF-8?q?=EA=B0=80=20=EB=A7=9E=EC=A7=80=20=EC=95=8A=EB=8A=94=EB=8B=A4?= =?UTF-8?q?=EA=B3=A0=20=ED=95=B4=EC=84=9C=20=ED=81=B0=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=EA=B0=80=20=EB=B0=9C=EC=83=9D=ED=95=98=EC=A7=84=20=EC=95=8A?= =?UTF-8?q?=EC=9C=BC=EB=AF=80=EB=A1=9C=20=EC=98=A4=EB=A5=98=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=20=EC=8B=9C=20=EB=A1=9C=EA=B7=B8=EB=A7=8C=20=EB=82=A8?= =?UTF-8?q?=EA=B8=B0=EA=B3=A0=20=EB=8B=A4=EC=9D=8C=20=EC=9E=91=EC=97=85?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=84=98=EC=96=B4=EA=B0=80=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EA=B5=AC=ED=98=84=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../processor/RelatedArtistSyncProcessor.java | 12 ++++++++++-- .../writer/BulkRelatedArtistUpsertWriter.java | 10 +++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java index e7605ef..c39a56c 100644 --- a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java +++ b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java @@ -4,8 +4,10 @@ import confeti.confetibatchserver.job.relatedartistsync.dto.ArtistRelations; import java.util.List; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.batch.item.ItemProcessor; +@Slf4j @RequiredArgsConstructor public class RelatedArtistSyncProcessor implements ItemProcessor { @@ -13,7 +15,13 @@ public class RelatedArtistSyncProcessor implements ItemProcessor allRelatedArtistIds = musicAPIHandler.getAllRelatedArtistIds(item); - return new ArtistRelations(item, allRelatedArtistIds); + try { + List allRelatedArtistIds = musicAPIHandler.getAllRelatedArtistIds(item); + return new ArtistRelations(item, allRelatedArtistIds); + } catch (Exception e) { + log.error("Error to sync RelatedArtist in processor, artist id: " + item, + e.getMessage()); + return null; + } } } diff --git a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java index 538c252..a9bb710 100644 --- a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java +++ b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java @@ -4,9 +4,11 @@ import confeti.confetibatchserver.job.relatedartistsync.dto.ArtistRelations; import java.util.List; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.batch.item.Chunk; import org.springframework.batch.item.ItemWriter; +@Slf4j @RequiredArgsConstructor public class BulkRelatedArtistUpsertWriter implements ItemWriter { @@ -16,6 +18,12 @@ public class BulkRelatedArtistUpsertWriter implements ItemWriter chunk) throws Exception { @SuppressWarnings("unchecked") List relations = (List) chunk.getItems(); - musicSyncFacade.reconcileRelatedArtists(relations); + + try { + musicSyncFacade.reconcileRelatedArtists(relations); + } catch (Exception e) { + log.error("Error to sync RelatedArtist in writer ", e); + } + } } From 732fb6a9b8f6ad396496b2bbee15b30766b63872 Mon Sep 17 00:00:00 2001 From: jher235 Date: Fri, 2 Jan 2026 02:57:49 +0900 Subject: [PATCH 14/17] =?UTF-8?q?CONFETI-76=20refactor:=20RelatedArtistSyn?= =?UTF-8?q?cSkipLogger=20=EB=8F=84=EC=9E=85=20-=20=EA=B8=B0=EC=A1=B4=20try?= =?UTF-8?q?-catch=EC=97=90=EC=84=9C=20=EC=98=88=EC=99=B8=EB=A5=BC=20?= =?UTF-8?q?=EB=8D=98=EC=A7=80=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=ED=95=98=EA=B3=A0=20=EC=9D=B4=EB=A5=BC=20listener=20=EA=B0=80?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC=ED=95=98=EB=8F=84=EB=A1=9D=20=ED=95=A8.?= =?UTF-8?q?=20=EC=B1=85=EC=9E=84=20=EB=B6=84=EB=A6=AC=EC=99=80=20retry=20?= =?UTF-8?q?=EB=93=B1=EC=9D=84=20=EC=9C=84=ED=95=A8=20-=20=20feignClient=20?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=98=88=EC=99=B8=EA=B0=80=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=ED=95=A0=20=EA=B2=BD=EC=9A=B0=20Future=20=EB=A1=9C=20?= =?UTF-8?q?=EA=B0=90=EC=8B=B8=EC=84=9C=20=EC=9D=91=EB=8B=B5=EC=9D=84=20?= =?UTF-8?q?=EC=A3=BC=EA=B8=B0=20=EB=95=8C=EB=AC=B8=EC=97=90=20artistId?= =?UTF-8?q?=EB=A5=BC=20=EC=95=8C=20=EC=88=98=20=EC=97=86=EC=9D=8C=20?= =?UTF-8?q?=EB=94=B0=EB=9D=BC=EC=84=9C=20ArtistIdAwareException=20?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20wrapping=20=ED=95=98=EC=97=AC=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=EA=B0=80=20=EB=B0=9C=EC=83=9D=ED=95=9C=20artist=20?= =?UTF-8?q?=EC=9D=98=20id=20=EB=A5=BC=20=EC=A0=84=EB=8B=AC=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exectpion/ArtistIdAwareException.java | 14 +++++++ .../RelatedArtistSyncJobConfig.java | 9 +++- .../processor/RelatedArtistSyncProcessor.java | 5 +-- .../writer/BulkRelatedArtistUpsertWriter.java | 8 +--- .../logger/RelatedArtistSyncSkipLogger.java | 42 +++++++++++++++++++ 5 files changed, 67 insertions(+), 11 deletions(-) create mode 100644 src/main/java/confeti/confetibatchserver/global/exectpion/ArtistIdAwareException.java create mode 100644 src/main/java/confeti/confetibatchserver/logger/RelatedArtistSyncSkipLogger.java diff --git a/src/main/java/confeti/confetibatchserver/global/exectpion/ArtistIdAwareException.java b/src/main/java/confeti/confetibatchserver/global/exectpion/ArtistIdAwareException.java new file mode 100644 index 0000000..37b48fa --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/global/exectpion/ArtistIdAwareException.java @@ -0,0 +1,14 @@ +package confeti.confetibatchserver.global.exectpion; + +import lombok.Getter; + +@Getter +public class ArtistIdAwareException extends RuntimeException { + + private final String artistId; + + public ArtistIdAwareException(String artistId, Exception e) { + super(e); + this.artistId = artistId; + } +} diff --git a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/RelatedArtistSyncJobConfig.java b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/RelatedArtistSyncJobConfig.java index 7b0499c..e2830e7 100644 --- a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/RelatedArtistSyncJobConfig.java +++ b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/RelatedArtistSyncJobConfig.java @@ -14,6 +14,7 @@ import confeti.confetibatchserver.job.relatedartistsync.processor.RelatedArtistSyncProcessor; import confeti.confetibatchserver.job.relatedartistsync.writer.BulkRelatedArtistUpsertWriter; import confeti.confetibatchserver.logger.JobLoggingListener; +import confeti.confetibatchserver.logger.RelatedArtistSyncSkipLogger; import feign.RetryableException; import java.io.IOException; import java.util.concurrent.Future; @@ -32,6 +33,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.task.TaskExecutor; +import org.springframework.data.crossstore.ChangeSetPersister.NotFoundException; import org.springframework.transaction.PlatformTransactionManager; @Configuration @@ -59,7 +61,8 @@ public Job relatedArtistSyncJob(Step relatedArtistSyncStep) { public Step relatedArtistSyncStep( ItemReader relatedArtistStepReader, AsyncItemProcessor relatedArtistProcessor, - AsyncItemWriter artistSongSyncWriter + AsyncItemWriter artistSongSyncWriter, + RelatedArtistSyncSkipLogger relatedArtistSyncSkipLogger ) throws Exception { StepConfig stepConfig = stepConfigService.getByStepInfo(RELATED_ARTIST_SYNC_STEP); @@ -72,7 +75,11 @@ public Step relatedArtistSyncStep( .faultTolerant() .retry(RetryableException.class) // Feign의 재시도 가능 예외 .retry(IOException.class) + .noRetry(NotFoundException.class) + .skip(Exception.class) .retryLimit(3) + .skipLimit(100) + .listener(relatedArtistSyncSkipLogger) .build(); } diff --git a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java index c39a56c..dcb1e03 100644 --- a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java +++ b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java @@ -1,6 +1,7 @@ package confeti.confetibatchserver.job.relatedartistsync.processor; import confeti.confetibatchserver.external.service.MusicAPIHandler; +import confeti.confetibatchserver.global.exectpion.ArtistIdAwareException; import confeti.confetibatchserver.job.relatedartistsync.dto.ArtistRelations; import java.util.List; import lombok.RequiredArgsConstructor; @@ -19,9 +20,7 @@ public ArtistRelations process(String item) throws Exception { List allRelatedArtistIds = musicAPIHandler.getAllRelatedArtistIds(item); return new ArtistRelations(item, allRelatedArtistIds); } catch (Exception e) { - log.error("Error to sync RelatedArtist in processor, artist id: " + item, - e.getMessage()); - return null; + throw new ArtistIdAwareException(item, e); } } } diff --git a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java index a9bb710..6df5370 100644 --- a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java +++ b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java @@ -18,12 +18,6 @@ public class BulkRelatedArtistUpsertWriter implements ItemWriter chunk) throws Exception { @SuppressWarnings("unchecked") List relations = (List) chunk.getItems(); - - try { - musicSyncFacade.reconcileRelatedArtists(relations); - } catch (Exception e) { - log.error("Error to sync RelatedArtist in writer ", e); - } - + musicSyncFacade.reconcileRelatedArtists(relations); } } diff --git a/src/main/java/confeti/confetibatchserver/logger/RelatedArtistSyncSkipLogger.java b/src/main/java/confeti/confetibatchserver/logger/RelatedArtistSyncSkipLogger.java new file mode 100644 index 0000000..458dcce --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/logger/RelatedArtistSyncSkipLogger.java @@ -0,0 +1,42 @@ +package confeti.confetibatchserver.logger; + +import confeti.confetibatchserver.global.exectpion.ArtistIdAwareException; +import confeti.confetibatchserver.job.relatedartistsync.dto.ArtistRelations; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import lombok.extern.slf4j.Slf4j; +import org.springframework.batch.core.SkipListener; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class RelatedArtistSyncSkipLogger implements SkipListener> { + + @Override + public void onSkipInProcess(String item, Throwable t) { + log.error("Error to sync RelatedArtist in processor, artist id: " + item, t); + } + + /** + * Processor 에서 Future 로 감싸서 응답을 주기 때문에 feignClient 의 응답에 문제가 있을 경우 artistId를 알 수 없음 따라서 + * ArtistIdAwareException 으로 wrapping 하여 문제가 발생한 artist 의 id 를 전달함 + */ + @Override + public void onSkipInWrite(Future item, Throwable t) { + if (t instanceof ArtistIdAwareException exception) { + log.error("Error to sync RelatedArtist in writer, artist id: " + + exception.getArtistId(), exception); + return; + } + + try { + ArtistRelations artistRelations = item.get(); + log.error("Error to sync RelatedArtist in writer, artist id: " + + artistRelations.artistId(), t); + } catch (InterruptedException | ExecutionException e) { + log.error( + "Error to sync RelatedArtist in writer and failed extract artistId from future"); + + } + } +} \ No newline at end of file From f8de9def354ffd64430ca5d084f8e7973480c65e Mon Sep 17 00:00:00 2001 From: jher235 Date: Fri, 2 Jan 2026 03:13:08 +0900 Subject: [PATCH 15/17] =?UTF-8?q?CONFETI-76=20feat:=20relatedArtist=20Sync?= =?UTF-8?q?=20=EC=8A=A4=EC=BC=80=EC=A4=84=EB=9F=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scheduler/RelatedArtistSyncSchedule.java | 43 +++++++++++++++++++ .../resources/common/application-schedule.yml | 3 ++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/confeti/confetibatchserver/scheduler/RelatedArtistSyncSchedule.java diff --git a/src/main/java/confeti/confetibatchserver/scheduler/RelatedArtistSyncSchedule.java b/src/main/java/confeti/confetibatchserver/scheduler/RelatedArtistSyncSchedule.java new file mode 100644 index 0000000..ea5f84b --- /dev/null +++ b/src/main/java/confeti/confetibatchserver/scheduler/RelatedArtistSyncSchedule.java @@ -0,0 +1,43 @@ +package confeti.confetibatchserver.scheduler; + +import static confeti.confetibatchserver.job.JobInfo.RELATED_ARTIST_SYNC_JOB; + +import confeti.confetibatchserver.domain.batch.jobconfig.JobConfig; +import confeti.confetibatchserver.domain.batch.jobconfig.application.JobConfigService; +import confeti.confetibatchserver.job.JobInfo; +import confeti.confetibatchserver.job.relatedartistsync.RelatedArtistSyncJobConfig; +import java.time.LocalDate; +import lombok.RequiredArgsConstructor; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.configuration.JobRegistry; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.Scheduled; + +@Configuration +@RequiredArgsConstructor +public class RelatedArtistSyncSchedule { + + private final JobLauncher jobLauncher; + private final JobRegistry jobRegistry; + private final JobConfigService jobConfigService; + + @Scheduled( + cron = "${schedules.related-artist-sync.cron}", + zone = "${schedules.related-artist-sync.zone}" + ) + public void runRelatedArtistSyncJob() throws Exception { + JobInfo jobInfo = RELATED_ARTIST_SYNC_JOB; + JobConfig jobConfig = jobConfigService.getByJobInfo(jobInfo); + if (jobConfig.isActive()) { + String date = LocalDate.now().toString(); + + JobParameters jobParameters = new JobParametersBuilder() + .addString(RelatedArtistSyncJobConfig.JOB_PARAMETER_DATE, date) + .toJobParameters(); + + jobLauncher.run(jobRegistry.getJob(jobInfo.getJobName()), jobParameters); + } + } +} diff --git a/src/main/resources/common/application-schedule.yml b/src/main/resources/common/application-schedule.yml index adbab51..db65ba9 100644 --- a/src/main/resources/common/application-schedule.yml +++ b/src/main/resources/common/application-schedule.yml @@ -1,4 +1,7 @@ schedules: artist-sync: cron: "0 0 4 * * *" + zone: "Asia/Seoul" + related-artist-sync: + cron: "0 0 3 * * 3" zone: "Asia/Seoul" \ No newline at end of file From dd2c77bc8ae684fe56a80eb1992a14cab2798d81 Mon Sep 17 00:00:00 2001 From: jher235 Date: Fri, 2 Jan 2026 03:16:01 +0900 Subject: [PATCH 16/17] =?UTF-8?q?CONFETI-76=20refactor:=20artistSong?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...bConfig.java => ArtistSongSyncJobConfig.java} | 2 +- .../scheduler/ArtistSyncSchedule.java | 16 +++++++++------- .../resources/common/application-schedule.yml | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) rename src/main/java/confeti/confetibatchserver/job/artistsongsync/{ArtistSyncJobConfig.java => ArtistSongSyncJobConfig.java} (99%) diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSyncJobConfig.java b/src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSongSyncJobConfig.java similarity index 99% rename from src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSyncJobConfig.java rename to src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSongSyncJobConfig.java index b958e5d..e8297cc 100644 --- a/src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSyncJobConfig.java +++ b/src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSongSyncJobConfig.java @@ -38,7 +38,7 @@ @Slf4j @Configuration @RequiredArgsConstructor -public class ArtistSyncJobConfig { +public class ArtistSongSyncJobConfig { public static final String JOB_PARAMETER_DATE = "requestDate"; diff --git a/src/main/java/confeti/confetibatchserver/scheduler/ArtistSyncSchedule.java b/src/main/java/confeti/confetibatchserver/scheduler/ArtistSyncSchedule.java index 0e9165f..fc690f2 100644 --- a/src/main/java/confeti/confetibatchserver/scheduler/ArtistSyncSchedule.java +++ b/src/main/java/confeti/confetibatchserver/scheduler/ArtistSyncSchedule.java @@ -4,7 +4,8 @@ import confeti.confetibatchserver.domain.batch.jobconfig.JobConfig; import confeti.confetibatchserver.domain.batch.jobconfig.application.JobConfigService; -import confeti.confetibatchserver.job.artistsongsync.ArtistSyncJobConfig; +import confeti.confetibatchserver.job.JobInfo; +import confeti.confetibatchserver.job.artistsongsync.ArtistSongSyncJobConfig; import java.time.LocalDate; import lombok.RequiredArgsConstructor; import org.springframework.batch.core.JobParameters; @@ -23,19 +24,20 @@ public class ArtistSyncSchedule { private final JobConfigService jobConfigService; @Scheduled( - cron = "${schedules.artist-sync.cron}", - zone = "${schedules.artist-sync.zone}" + cron = "${schedules.artist-song-sync.cron}", + zone = "${schedules.artist-song-sync.zone}" ) - public void runArtistSyncJob() throws Exception { - JobConfig jobConfig = jobConfigService.getByJobInfo(ARTIST_SONG_SYNC_JOB); + public void runArtistSongSyncJob() throws Exception { + JobInfo jobInfo = ARTIST_SONG_SYNC_JOB; + JobConfig jobConfig = jobConfigService.getByJobInfo(jobInfo); if (jobConfig.isActive()) { String date = LocalDate.now().toString(); JobParameters jobParameters = new JobParametersBuilder() - .addString(ArtistSyncJobConfig.JOB_PARAMETER_DATE, date) + .addString(ArtistSongSyncJobConfig.JOB_PARAMETER_DATE, date) .toJobParameters(); - jobLauncher.run(jobRegistry.getJob(ARTIST_SONG_SYNC_JOB.getJobName()), jobParameters); + jobLauncher.run(jobRegistry.getJob(jobInfo.getJobName()), jobParameters); } } diff --git a/src/main/resources/common/application-schedule.yml b/src/main/resources/common/application-schedule.yml index db65ba9..f7a0ee9 100644 --- a/src/main/resources/common/application-schedule.yml +++ b/src/main/resources/common/application-schedule.yml @@ -1,5 +1,5 @@ schedules: - artist-sync: + artist-song-sync: cron: "0 0 4 * * *" zone: "Asia/Seoul" related-artist-sync: From 8b730a17823be6a3ad69118f7386e6d29c930de2 Mon Sep 17 00:00:00 2001 From: jher235 Date: Fri, 2 Jan 2026 03:21:44 +0900 Subject: [PATCH 17/17] =?UTF-8?q?CONFETI-76=20chore:=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EA=B5=AC=EC=A1=B0=20=EC=88=98=EC=A0=95=20-=20reade?= =?UTF-8?q?r=EB=A5=BC=20=EC=9E=AC=EC=82=AC=EC=9A=A9=ED=95=B4=EC=95=BC?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B2=BD=EC=9A=B0=EA=B0=80=20=EC=A1=B4?= =?UTF-8?q?=EC=9E=AC=ED=95=B4=EC=84=9C=20batch=20=EA=B4=80=EB=A0=A8=20read?= =?UTF-8?q?er,=20writer,=20processor=EB=A5=BC=20domain=20=EB=82=B4?= =?UTF-8?q?=EB=B6=80=EB=A1=9C=20=EC=98=AE=EA=B9=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../music/artist/batch}/query/ArtistQueryProvider.java | 2 +- .../music/artist/batch}/reader/ArtistIdReader.java | 6 +++--- .../artist/batch}/reader/ConfetiArtistReader.java | 6 +++--- .../batch}/writer/BulkArtistSongUpsertWriter.java | 2 +- .../batch}/processor/RelatedArtistSyncProcessor.java | 2 +- .../batch}/writer/BulkRelatedArtistUpsertWriter.java | 2 +- .../song/batch}/writer/BulkArtistUpsertWriter.java | 2 +- .../job/artistsongsync/ArtistSongSyncJobConfig.java | 10 +++++----- .../relatedartistsync/RelatedArtistSyncJobConfig.java | 8 ++++---- 9 files changed, 20 insertions(+), 20 deletions(-) rename src/main/java/confeti/confetibatchserver/{job/artistsongsync => domain/music/artist/batch}/query/ArtistQueryProvider.java (96%) rename src/main/java/confeti/confetibatchserver/{job/artistsongsync => domain/music/artist/batch}/reader/ArtistIdReader.java (71%) rename src/main/java/confeti/confetibatchserver/{job/artistsongsync => domain/music/artist/batch}/reader/ConfetiArtistReader.java (73%) rename src/main/java/confeti/confetibatchserver/{job/artistsongsync => domain/music/artist/batch}/writer/BulkArtistSongUpsertWriter.java (95%) rename src/main/java/confeti/confetibatchserver/{job/relatedartistsync => domain/music/relatedartist/batch}/processor/RelatedArtistSyncProcessor.java (91%) rename src/main/java/confeti/confetibatchserver/{job/relatedartistsync => domain/music/relatedartist/batch}/writer/BulkRelatedArtistUpsertWriter.java (91%) rename src/main/java/confeti/confetibatchserver/{job/artistsongsync => domain/music/song/batch}/writer/BulkArtistUpsertWriter.java (90%) diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/query/ArtistQueryProvider.java b/src/main/java/confeti/confetibatchserver/domain/music/artist/batch/query/ArtistQueryProvider.java similarity index 96% rename from src/main/java/confeti/confetibatchserver/job/artistsongsync/query/ArtistQueryProvider.java rename to src/main/java/confeti/confetibatchserver/domain/music/artist/batch/query/ArtistQueryProvider.java index cc4343c..7b4c8a9 100644 --- a/src/main/java/confeti/confetibatchserver/job/artistsongsync/query/ArtistQueryProvider.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/artist/batch/query/ArtistQueryProvider.java @@ -1,4 +1,4 @@ -package confeti.confetibatchserver.job.artistsongsync.query; +package confeti.confetibatchserver.domain.music.artist.batch.query; import confeti.confetibatchserver.domain.music.artist.vo.ConfetiArtist; import java.util.HashMap; diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/reader/ArtistIdReader.java b/src/main/java/confeti/confetibatchserver/domain/music/artist/batch/reader/ArtistIdReader.java similarity index 71% rename from src/main/java/confeti/confetibatchserver/job/artistsongsync/reader/ArtistIdReader.java rename to src/main/java/confeti/confetibatchserver/domain/music/artist/batch/reader/ArtistIdReader.java index f5255d4..71cf5b3 100644 --- a/src/main/java/confeti/confetibatchserver/job/artistsongsync/reader/ArtistIdReader.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/artist/batch/reader/ArtistIdReader.java @@ -1,9 +1,9 @@ -package confeti.confetibatchserver.job.artistsongsync.reader; +package confeti.confetibatchserver.domain.music.artist.batch.reader; -import static confeti.confetibatchserver.job.artistsongsync.query.ArtistQueryProvider.ARTIST_ID_MAPPER; +import static confeti.confetibatchserver.domain.music.artist.batch.query.ArtistQueryProvider.ARTIST_ID_MAPPER; import confeti.confetibatchserver.domain.batch.stepconfig.StepConfig; -import confeti.confetibatchserver.job.artistsongsync.query.ArtistQueryProvider; +import confeti.confetibatchserver.domain.music.artist.batch.query.ArtistQueryProvider; import javax.sql.DataSource; import org.springframework.batch.item.database.JdbcPagingItemReader; diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/reader/ConfetiArtistReader.java b/src/main/java/confeti/confetibatchserver/domain/music/artist/batch/reader/ConfetiArtistReader.java similarity index 73% rename from src/main/java/confeti/confetibatchserver/job/artistsongsync/reader/ConfetiArtistReader.java rename to src/main/java/confeti/confetibatchserver/domain/music/artist/batch/reader/ConfetiArtistReader.java index c56b4d2..5be9c68 100644 --- a/src/main/java/confeti/confetibatchserver/job/artistsongsync/reader/ConfetiArtistReader.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/artist/batch/reader/ConfetiArtistReader.java @@ -1,10 +1,10 @@ -package confeti.confetibatchserver.job.artistsongsync.reader; +package confeti.confetibatchserver.domain.music.artist.batch.reader; -import static confeti.confetibatchserver.job.artistsongsync.query.ArtistQueryProvider.CONFETI_ARTIST_MAPPER; +import static confeti.confetibatchserver.domain.music.artist.batch.query.ArtistQueryProvider.CONFETI_ARTIST_MAPPER; import confeti.confetibatchserver.domain.batch.stepconfig.StepConfig; +import confeti.confetibatchserver.domain.music.artist.batch.query.ArtistQueryProvider; 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; diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/writer/BulkArtistSongUpsertWriter.java b/src/main/java/confeti/confetibatchserver/domain/music/artist/batch/writer/BulkArtistSongUpsertWriter.java similarity index 95% rename from src/main/java/confeti/confetibatchserver/job/artistsongsync/writer/BulkArtistSongUpsertWriter.java rename to src/main/java/confeti/confetibatchserver/domain/music/artist/batch/writer/BulkArtistSongUpsertWriter.java index dde9b02..21af8b1 100644 --- a/src/main/java/confeti/confetibatchserver/job/artistsongsync/writer/BulkArtistSongUpsertWriter.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/artist/batch/writer/BulkArtistSongUpsertWriter.java @@ -1,4 +1,4 @@ -package confeti.confetibatchserver.job.artistsongsync.writer; +package confeti.confetibatchserver.domain.music.artist.batch.writer; import static confeti.confetibatchserver.config.ThreadPoolConfig.MUSIC_SYNC_EXECUTOR; diff --git a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/batch/processor/RelatedArtistSyncProcessor.java similarity index 91% rename from src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java rename to src/main/java/confeti/confetibatchserver/domain/music/relatedartist/batch/processor/RelatedArtistSyncProcessor.java index dcb1e03..8a88779 100644 --- a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/processor/RelatedArtistSyncProcessor.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/batch/processor/RelatedArtistSyncProcessor.java @@ -1,4 +1,4 @@ -package confeti.confetibatchserver.job.relatedartistsync.processor; +package confeti.confetibatchserver.domain.music.relatedartist.batch.processor; import confeti.confetibatchserver.external.service.MusicAPIHandler; import confeti.confetibatchserver.global.exectpion.ArtistIdAwareException; diff --git a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/batch/writer/BulkRelatedArtistUpsertWriter.java similarity index 91% rename from src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java rename to src/main/java/confeti/confetibatchserver/domain/music/relatedartist/batch/writer/BulkRelatedArtistUpsertWriter.java index 6df5370..d3c2c26 100644 --- a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/writer/BulkRelatedArtistUpsertWriter.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/relatedartist/batch/writer/BulkRelatedArtistUpsertWriter.java @@ -1,4 +1,4 @@ -package confeti.confetibatchserver.job.relatedartistsync.writer; +package confeti.confetibatchserver.domain.music.relatedartist.batch.writer; import confeti.confetibatchserver.api.music.facade.MusicSyncFacade; import confeti.confetibatchserver.job.relatedartistsync.dto.ArtistRelations; diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/writer/BulkArtistUpsertWriter.java b/src/main/java/confeti/confetibatchserver/domain/music/song/batch/writer/BulkArtistUpsertWriter.java similarity index 90% rename from src/main/java/confeti/confetibatchserver/job/artistsongsync/writer/BulkArtistUpsertWriter.java rename to src/main/java/confeti/confetibatchserver/domain/music/song/batch/writer/BulkArtistUpsertWriter.java index d02e7a0..60b203a 100644 --- a/src/main/java/confeti/confetibatchserver/job/artistsongsync/writer/BulkArtistUpsertWriter.java +++ b/src/main/java/confeti/confetibatchserver/domain/music/song/batch/writer/BulkArtistUpsertWriter.java @@ -1,4 +1,4 @@ -package confeti.confetibatchserver.job.artistsongsync.writer; +package confeti.confetibatchserver.domain.music.song.batch.writer; import confeti.confetibatchserver.api.music.facade.MusicSyncFacade; import confeti.confetibatchserver.domain.music.artist.vo.ConfetiArtist; diff --git a/src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSongSyncJobConfig.java b/src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSongSyncJobConfig.java index e8297cc..e839d4c 100644 --- a/src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSongSyncJobConfig.java +++ b/src/main/java/confeti/confetibatchserver/job/artistsongsync/ArtistSongSyncJobConfig.java @@ -8,12 +8,12 @@ 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.batch.query.ArtistQueryProvider; +import confeti.confetibatchserver.domain.music.artist.batch.reader.ArtistIdReader; +import confeti.confetibatchserver.domain.music.artist.batch.reader.ConfetiArtistReader; +import confeti.confetibatchserver.domain.music.artist.batch.writer.BulkArtistSongUpsertWriter; 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.domain.music.song.batch.writer.BulkArtistUpsertWriter; import confeti.confetibatchserver.logger.JobLoggingListener; import feign.RetryableException; import java.io.IOException; diff --git a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/RelatedArtistSyncJobConfig.java b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/RelatedArtistSyncJobConfig.java index e2830e7..eb96683 100644 --- a/src/main/java/confeti/confetibatchserver/job/relatedartistsync/RelatedArtistSyncJobConfig.java +++ b/src/main/java/confeti/confetibatchserver/job/relatedartistsync/RelatedArtistSyncJobConfig.java @@ -7,12 +7,12 @@ 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.batch.query.ArtistQueryProvider; +import confeti.confetibatchserver.domain.music.artist.batch.reader.ArtistIdReader; +import confeti.confetibatchserver.domain.music.relatedartist.batch.processor.RelatedArtistSyncProcessor; +import confeti.confetibatchserver.domain.music.relatedartist.batch.writer.BulkRelatedArtistUpsertWriter; import confeti.confetibatchserver.external.service.MusicAPIHandler; -import confeti.confetibatchserver.job.artistsongsync.query.ArtistQueryProvider; -import confeti.confetibatchserver.job.artistsongsync.reader.ArtistIdReader; import confeti.confetibatchserver.job.relatedartistsync.dto.ArtistRelations; -import confeti.confetibatchserver.job.relatedartistsync.processor.RelatedArtistSyncProcessor; -import confeti.confetibatchserver.job.relatedartistsync.writer.BulkRelatedArtistUpsertWriter; import confeti.confetibatchserver.logger.JobLoggingListener; import confeti.confetibatchserver.logger.RelatedArtistSyncSkipLogger; import feign.RetryableException;