From b2167d4ec79adfb13c0cd5f415ad24cf234f2b17 Mon Sep 17 00:00:00 2001 From: hyojin kim Date: Mon, 15 Dec 2025 12:23:54 +0900 Subject: [PATCH] =?UTF-8?q?:sparkles:=20Event=20Range=20=EC=84=B8=ED=8C=85?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD=20-=20API=5FKET=20?= =?UTF-8?q?=EC=84=B8=ED=8C=85=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../batch/config/EventImportJobConfig.java | 8 +++++-- .../event/batch/reader/EventDataReader.java | 24 +++++++++++++++---- .../event/batch/writer/EventDataWriter.java | 13 ++++++++-- .../reader/ShipDetailUpdateDataReader.java | 7 +++--- .../snp/batch/service/BatchDateService.java | 11 ++++----- 5 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/snp/batch/jobs/event/batch/config/EventImportJobConfig.java b/src/main/java/com/snp/batch/jobs/event/batch/config/EventImportJobConfig.java index 9c35796..40c38be 100644 --- a/src/main/java/com/snp/batch/jobs/event/batch/config/EventImportJobConfig.java +++ b/src/main/java/com/snp/batch/jobs/event/batch/config/EventImportJobConfig.java @@ -6,6 +6,7 @@ import com.snp.batch.jobs.event.batch.entity.EventEntity; import com.snp.batch.jobs.event.batch.processor.EventDataProcessor; import com.snp.batch.jobs.event.batch.reader.EventDataReader; import com.snp.batch.jobs.event.batch.writer.EventDataWriter; +import com.snp.batch.service.BatchDateService; import lombok.extern.slf4j.Slf4j; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; @@ -29,6 +30,7 @@ public class EventImportJobConfig extends BaseJobConfig { private final EventDataProcessor eventDataProcessor; private final EventDataWriter eventDataWriter; + private final BatchDateService batchDateService; @Override protected int getChunkSize() { @@ -40,12 +42,14 @@ public class EventImportJobConfig extends BaseJobConfig { EventDataProcessor eventDataProcessor, EventDataWriter eventDataWriter, JdbcTemplate jdbcTemplate, - @Qualifier("maritimeApiWebClient")WebClient maritimeApiWebClient) { + @Qualifier("maritimeApiWebClient")WebClient maritimeApiWebClient, + BatchDateService batchDateService) { super(jobRepository, transactionManager); this.jdbcTemplate = jdbcTemplate; this.maritimeApiWebClient = maritimeApiWebClient; this.eventDataProcessor = eventDataProcessor; this.eventDataWriter = eventDataWriter; + this.batchDateService = batchDateService; } @Override @@ -60,7 +64,7 @@ public class EventImportJobConfig extends BaseJobConfig { @Override protected ItemReader createReader() { - return new EventDataReader(maritimeApiWebClient, jdbcTemplate); + return new EventDataReader(maritimeApiWebClient, jdbcTemplate, batchDateService); } @Override diff --git a/src/main/java/com/snp/batch/jobs/event/batch/reader/EventDataReader.java b/src/main/java/com/snp/batch/jobs/event/batch/reader/EventDataReader.java index ba15574..e50ef36 100644 --- a/src/main/java/com/snp/batch/jobs/event/batch/reader/EventDataReader.java +++ b/src/main/java/com/snp/batch/jobs/event/batch/reader/EventDataReader.java @@ -3,6 +3,7 @@ package com.snp.batch.jobs.event.batch.reader; import com.snp.batch.common.batch.reader.BaseApiReader; import com.snp.batch.jobs.event.batch.dto.EventDto; import com.snp.batch.jobs.event.batch.dto.EventResponse; +import com.snp.batch.service.BatchDateService; import lombok.extern.slf4j.Slf4j; import org.springframework.core.ParameterizedTypeReference; import org.springframework.jdbc.core.JdbcTemplate; @@ -10,14 +11,17 @@ import org.springframework.web.reactive.function.client.WebClient; import java.util.ArrayList; import java.util.List; +import java.util.Map; @Slf4j public class EventDataReader extends BaseApiReader { private final JdbcTemplate jdbcTemplate; + private final BatchDateService batchDateService; // ✨ BatchDateService 필드 추가 - public EventDataReader(WebClient webClient, JdbcTemplate jdbcTemplate) { + public EventDataReader(WebClient webClient, JdbcTemplate jdbcTemplate, BatchDateService batchDateService) { super(webClient); this.jdbcTemplate = jdbcTemplate; + this.batchDateService = batchDateService; } @Override @@ -27,8 +31,9 @@ public class EventDataReader extends BaseApiReader { @Override protected String getApiPath() { - return "MaritimeWCF/MaritimeAndTradeEventsService.svc/RESTFul/GetEventListByEventChangeDateRange?fromYear=2025&fromMonth=01&fromDay=01&fromHour=00&fromMinute=00&toYear=2025&toMonth=12&toDay=31&toHour=00&toMinute=00"; + return "/MaritimeWCF/MaritimeAndTradeEventsService.svc/RESTFul/GetEventListByEventChangeDateRange"; } + protected String getApiKey() {return "EVENT_IMPORT_JOB";} @Override protected List fetchDataFromApi() { @@ -52,10 +57,21 @@ public class EventDataReader extends BaseApiReader { } private EventResponse callEventApiWithBatch() { + Map params = batchDateService.getShipUpdateApiDateParams(getApiKey()); + String url = getApiPath(); - log.debug("[{}] API 호출: {}", getReaderName(), url); + log.info("[{}] API 호출: {}", getReaderName(), url); + return webClient.get() - .uri(url) + .uri(url, uriBuilder -> uriBuilder + // 맵에서 파라미터 값을 동적으로 가져와 세팅 + .queryParam("fromYear", params.get("fromYear")) + .queryParam("fromMonth", params.get("fromMonth")) + .queryParam("fromDay", params.get("fromDay")) + .queryParam("toYear", params.get("toYear")) + .queryParam("toMonth", params.get("toMonth")) + .queryParam("toDay", params.get("toDay")) + .build()) .retrieve() .bodyToMono(EventResponse.class) .block(); diff --git a/src/main/java/com/snp/batch/jobs/event/batch/writer/EventDataWriter.java b/src/main/java/com/snp/batch/jobs/event/batch/writer/EventDataWriter.java index 5914587..9a61e6a 100644 --- a/src/main/java/com/snp/batch/jobs/event/batch/writer/EventDataWriter.java +++ b/src/main/java/com/snp/batch/jobs/event/batch/writer/EventDataWriter.java @@ -3,24 +3,33 @@ package com.snp.batch.jobs.event.batch.writer; import com.snp.batch.common.batch.writer.BaseWriter; import com.snp.batch.jobs.event.batch.entity.EventEntity; import com.snp.batch.jobs.event.batch.repository.EventRepository; +import com.snp.batch.service.BatchDateService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import java.time.LocalDate; import java.util.List; @Slf4j @Component public class EventDataWriter extends BaseWriter { - private final EventRepository eventRepository; - public EventDataWriter(EventRepository eventRepository) { + private final BatchDateService batchDateService; // ✨ BatchDateService 필드 추가 + protected String getApiKey() {return "EVENT_IMPORT_JOB";} + public EventDataWriter(EventRepository eventRepository, BatchDateService batchDateService) { super("EventRepository"); this.eventRepository = eventRepository; + this.batchDateService = batchDateService; } @Override protected void writeItems(List items) throws Exception { eventRepository.saveEventAll(items); log.info("Event 저장 완료: 수정={} 건", items.size()); + + // ✨ 배치 성공 시 상태 업데이트 (트랜잭션 커밋 직전에 실행) + LocalDate successDate = LocalDate.now(); + batchDateService.updateLastSuccessDate(getApiKey(), successDate); + log.info("batch_last_execution update 완료 : {}", getApiKey()); } } diff --git a/src/main/java/com/snp/batch/jobs/shipdetail/batch/reader/ShipDetailUpdateDataReader.java b/src/main/java/com/snp/batch/jobs/shipdetail/batch/reader/ShipDetailUpdateDataReader.java index 6465807..d1ec383 100644 --- a/src/main/java/com/snp/batch/jobs/shipdetail/batch/reader/ShipDetailUpdateDataReader.java +++ b/src/main/java/com/snp/batch/jobs/shipdetail/batch/reader/ShipDetailUpdateDataReader.java @@ -40,6 +40,7 @@ public class ShipDetailUpdateDataReader extends BaseApiReader allImoNumbers; @@ -251,7 +252,7 @@ public class ShipDetailUpdateDataReader extends BaseApiReader params = batchDateService.getShipUpdateApiDateParams(); + Map params = batchDateService.getShipUpdateApiDateParams(getApiKey()); String url = getShipUpdateApiPath(); log.info("[{}] API 호출: {}", getReaderName(), url); @@ -292,8 +293,8 @@ public class ShipDetailUpdateDataReader extends BaseApiReader getShipUpdateApiDateParams() { + public Map getShipUpdateApiDateParams(String apiKey) { // 1. 마지막 성공 일자 (FROM 날짜)를 DB에서 조회 // 조회된 값이 없으면 (최초 실행), API 호출 시점의 하루 전 날짜를 사용합니다. - LocalDate lastDate = repository.findLastSuccessDate(API_KEY) + LocalDate lastDate = repository.findLastSuccessDate(apiKey) .orElse(LocalDate.now().minusDays(1)); // 2. 현재 실행 시점의 일자 (TO 날짜) 계산 @@ -52,14 +51,14 @@ public class BatchDateService { * @param successDate API 호출 성공 시 사용된 to 날짜 */ @Transactional // UPDATE 쿼리를 사용하므로 트랜잭션 필요 - public void updateLastSuccessDate(LocalDate successDate) { + public void updateLastSuccessDate(String apiKey, LocalDate successDate) { // ✨ apiKey 추가 // 1. UPDATE 시도 - int updatedRows = repository.updateLastSuccessDate(API_KEY, successDate); + int updatedRows = repository.updateLastSuccessDate(apiKey, successDate); // 2. 업데이트된 레코드가 없다면 (최초 실행), INSERT 수행 if (updatedRows == 0) { - BatchLastExecution entity = new BatchLastExecution(API_KEY, successDate); + BatchLastExecution entity = new BatchLastExecution(apiKey, successDate); repository.save(entity); } }