🗃️ Event Table Name Change

- SQL Injection Prevent
This commit is contained in:
hyojin kim 2025-12-31 10:37:20 +09:00
부모 1d2a3c53c8
커밋 6aba0f55b0
7개의 변경된 파일46개의 추가작업 그리고 14개의 파일을 삭제

파일 보기

@ -43,7 +43,7 @@ public class ComplianceImportRangeJobConfig extends BaseMultiStepJobConfig<Compl
private final BatchDateService batchDateService;
protected String getApiKey() {return "COMPLIANCE_IMPORT_API";}
protected String getBatchUpdateSql() {
return "UPDATE SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW() WHERE API_KEY = '" + getApiKey() + "'";}
return String.format("UPDATE SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
@Override
protected int getChunkSize() {

파일 보기

@ -1,6 +1,6 @@
package com.snp.batch.jobs.event.batch.config;
import com.snp.batch.common.batch.config.BaseJobConfig;
import com.snp.batch.common.batch.config.BaseMultiStepJobConfig;
import com.snp.batch.jobs.event.batch.dto.EventDetailDto;
import com.snp.batch.jobs.event.batch.entity.EventDetailEntity;
import com.snp.batch.jobs.event.batch.processor.EventDataProcessor;
@ -10,10 +10,14 @@ import com.snp.batch.service.BatchDateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
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.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -23,7 +27,7 @@ import org.springframework.web.reactive.function.client.WebClient;
@Slf4j
@Configuration
public class EventImportJobConfig extends BaseJobConfig<EventDetailDto, EventDetailEntity> {
public class EventImportJobConfig extends BaseMultiStepJobConfig<EventDetailDto, EventDetailEntity> {
private final JdbcTemplate jdbcTemplate;
private final WebClient maritimeApiWebClient;
@ -32,6 +36,10 @@ public class EventImportJobConfig extends BaseJobConfig<EventDetailDto, EventDet
private final EventDataWriter eventDataWriter;
private final BatchDateService batchDateService;
protected String getApiKey() {return "EVENT_IMPORT_API";}
protected String getBatchUpdateSql() {
return String.format("UPDATE SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
@Override
protected int getChunkSize() {
return 10; // API에서 5000개씩 가져오므로 chunk도 5000으로 설정
@ -62,6 +70,14 @@ public class EventImportJobConfig extends BaseJobConfig<EventDetailDto, EventDet
return "eventImportStep";
}
@Override
protected Job createJobFlow(JobBuilder jobBuilder) {
return jobBuilder
.start(eventImportStep())
.next(eventLastExecutionUpdateStep())
.build();
}
@Override
protected ItemReader<EventDetailDto> createReader() {
return new EventDataReader(maritimeApiWebClient, jdbcTemplate, batchDateService);
@ -85,4 +101,25 @@ public class EventImportJobConfig extends BaseJobConfig<EventDetailDto, EventDet
return step();
}
/**
* 2단계: 모든 스텝 성공 배치 실행 로그(날짜) 업데이트
*/
@Bean
public Tasklet eventLastExecutionUpdateTasklet() {
return (contribution, chunkContext) -> {
log.info(">>>>> 모든 스텝 성공: BATCH_LAST_EXECUTION 업데이트 시작");
jdbcTemplate.execute(getBatchUpdateSql());
log.info(">>>>> BATCH_LAST_EXECUTION 업데이트 완료");
return RepeatStatus.FINISHED;
};
}
@Bean(name = "EventLastExecutionUpdateStep")
public Step eventLastExecutionUpdateStep() {
return new StepBuilder("EventLastExecutionUpdateStep", jobRepository)
.tasklet(eventLastExecutionUpdateTasklet(), transactionManager)
.build();
}
}

파일 보기

@ -44,7 +44,7 @@ public class EventDataReader extends BaseApiReader<EventDetailDto> {
}
protected String getApiKey() {
return "EVENT_IMPORT_JOB";
return "EVENT_IMPORT_API";
}
// 배치 처리 상태
@ -66,7 +66,7 @@ public class EventDataReader extends BaseApiReader<EventDetailDto> {
log.info("Event API 호출");
EventResponse response = callEventApiWithBatch();
// 2-1. Event List 에서 EventID List 추출
// TODO: 2-2. Event List 에서 Map<EventId,Map<StartDate,EndDate>> 추출
// 2-2. Event List 에서 Map<EventId,Map<StartDate,EndDate>> 추출
eventIds = extractEventIdList(response);
log.info("EvnetId List 추출 완료 : {} 개", eventIds.size());
@ -168,11 +168,6 @@ public class EventDataReader extends BaseApiReader<EventDetailDto> {
int totalBatches = (int) Math.ceil((double) eventIds.size() / batchSize);
try {
if (data == null) {
// 3. 배치 성공 상태 업데이트 (트랜잭션 커밋 직전에 실행)
LocalDate successDate = LocalDate.now(); // 현재 배치 실행 시점의 날짜 (Reader의 toDay와 동일한 )
batchDateService.updateLastSuccessDate(getApiKey(), successDate);
log.info("batch_last_execution update 완료 : {}", getApiKey());
log.info("[{}] 전체 {} 개 배치 처리 완료", getReaderName(), totalBatches);
log.info("[{}] 총 {} 개의 Event ID에 대한 API 호출 종료",
getReaderName(), eventIds.size());

파일 보기

@ -47,7 +47,7 @@ public class EventRepositoryImpl extends BaseJdbcRepository<EventDetailEntity, L
@Override
protected String getUpdateSql() {
return """
INSERT INTO snp_data.event_detail (
INSERT INTO snp_data.event (
Event_ID, Incident_ID, IHSLRorIMOShipNo, Vessel_Name, Vessel_Type,
Event_Type, Significance, Headline, Location_Name,
Published_Date, Event_Start_Date, Event_End_Date, batch_flag

파일 보기

@ -3,7 +3,7 @@ package com.snp.batch.jobs.event.batch.repository;
public class EventSql {
public static String getEventDetailUpdateSql(){
return """
INSERT INTO new_snp.event_detail (
INSERT INTO new_snp.event (
event_id, incident_id, ihslrorimoshipno, published_date, event_start_date, event_end_date,
attempted_boarding, cargo_loading_status_code, casualty_action,
casualty_zone, casualty_zone_code, component2, country_code,

파일 보기

@ -13,7 +13,6 @@ import java.util.List;
@Component
public class EventDataWriter extends BaseWriter<EventDetailEntity> {
private final EventRepository eventRepository;
protected String getApiKey() {return "EVENT_IMPORT_JOB";}
public EventDataWriter(EventRepository eventRepository) {
super("EventRepository");
this.eventRepository = eventRepository;

파일 보기

@ -38,7 +38,8 @@ public class RiskImportRangeJobConfig extends BaseMultiStepJobConfig<RiskDto, Ri
protected String getApiKey() {return "RISK_IMPORT_API";}
protected String getBatchUpdateSql() {
return "UPDATE SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW() WHERE API_KEY = '" + getApiKey() + "'";}
return String.format("UPDATE SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
@Override
protected int getChunkSize() {