🗃️ Event Table Name Change
- SQL Injection Prevent
This commit is contained in:
부모
1d2a3c53c8
커밋
6aba0f55b0
@ -43,7 +43,7 @@ public class ComplianceImportRangeJobConfig extends BaseMultiStepJobConfig<Compl
|
|||||||
private final BatchDateService batchDateService;
|
private final BatchDateService batchDateService;
|
||||||
protected String getApiKey() {return "COMPLIANCE_IMPORT_API";}
|
protected String getApiKey() {return "COMPLIANCE_IMPORT_API";}
|
||||||
protected String getBatchUpdateSql() {
|
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
|
@Override
|
||||||
protected int getChunkSize() {
|
protected int getChunkSize() {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package com.snp.batch.jobs.event.batch.config;
|
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.dto.EventDetailDto;
|
||||||
import com.snp.batch.jobs.event.batch.entity.EventDetailEntity;
|
import com.snp.batch.jobs.event.batch.entity.EventDetailEntity;
|
||||||
import com.snp.batch.jobs.event.batch.processor.EventDataProcessor;
|
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 lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.batch.core.Job;
|
import org.springframework.batch.core.Job;
|
||||||
import org.springframework.batch.core.Step;
|
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.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.ItemProcessor;
|
||||||
import org.springframework.batch.item.ItemReader;
|
import org.springframework.batch.item.ItemReader;
|
||||||
import org.springframework.batch.item.ItemWriter;
|
import org.springframework.batch.item.ItemWriter;
|
||||||
|
import org.springframework.batch.repeat.RepeatStatus;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@ -23,7 +27,7 @@ import org.springframework.web.reactive.function.client.WebClient;
|
|||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Configuration
|
@Configuration
|
||||||
public class EventImportJobConfig extends BaseJobConfig<EventDetailDto, EventDetailEntity> {
|
public class EventImportJobConfig extends BaseMultiStepJobConfig<EventDetailDto, EventDetailEntity> {
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
private final WebClient maritimeApiWebClient;
|
private final WebClient maritimeApiWebClient;
|
||||||
|
|
||||||
@ -32,6 +36,10 @@ public class EventImportJobConfig extends BaseJobConfig<EventDetailDto, EventDet
|
|||||||
private final EventDataWriter eventDataWriter;
|
private final EventDataWriter eventDataWriter;
|
||||||
private final BatchDateService batchDateService;
|
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
|
@Override
|
||||||
protected int getChunkSize() {
|
protected int getChunkSize() {
|
||||||
return 10; // API에서 5000개씩 가져오므로 chunk도 5000으로 설정
|
return 10; // API에서 5000개씩 가져오므로 chunk도 5000으로 설정
|
||||||
@ -62,6 +70,14 @@ public class EventImportJobConfig extends BaseJobConfig<EventDetailDto, EventDet
|
|||||||
return "eventImportStep";
|
return "eventImportStep";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Job createJobFlow(JobBuilder jobBuilder) {
|
||||||
|
return jobBuilder
|
||||||
|
.start(eventImportStep())
|
||||||
|
.next(eventLastExecutionUpdateStep())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ItemReader<EventDetailDto> createReader() {
|
protected ItemReader<EventDetailDto> createReader() {
|
||||||
return new EventDataReader(maritimeApiWebClient, jdbcTemplate, batchDateService);
|
return new EventDataReader(maritimeApiWebClient, jdbcTemplate, batchDateService);
|
||||||
@ -85,4 +101,25 @@ public class EventImportJobConfig extends BaseJobConfig<EventDetailDto, EventDet
|
|||||||
return step();
|
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() {
|
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 호출");
|
log.info("Event API 호출");
|
||||||
EventResponse response = callEventApiWithBatch();
|
EventResponse response = callEventApiWithBatch();
|
||||||
// 2-1. Event List 에서 EventID List 추출
|
// 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);
|
eventIds = extractEventIdList(response);
|
||||||
log.info("EvnetId List 추출 완료 : {} 개", eventIds.size());
|
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);
|
int totalBatches = (int) Math.ceil((double) eventIds.size() / batchSize);
|
||||||
try {
|
try {
|
||||||
if (data == null) {
|
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("[{}] 전체 {} 개 배치 처리 완료", getReaderName(), totalBatches);
|
||||||
log.info("[{}] 총 {} 개의 Event ID에 대한 API 호출 종료",
|
log.info("[{}] 총 {} 개의 Event ID에 대한 API 호출 종료",
|
||||||
getReaderName(), eventIds.size());
|
getReaderName(), eventIds.size());
|
||||||
|
|||||||
@ -47,7 +47,7 @@ public class EventRepositoryImpl extends BaseJdbcRepository<EventDetailEntity, L
|
|||||||
@Override
|
@Override
|
||||||
protected String getUpdateSql() {
|
protected String getUpdateSql() {
|
||||||
return """
|
return """
|
||||||
INSERT INTO snp_data.event_detail (
|
INSERT INTO snp_data.event (
|
||||||
Event_ID, Incident_ID, IHSLRorIMOShipNo, Vessel_Name, Vessel_Type,
|
Event_ID, Incident_ID, IHSLRorIMOShipNo, Vessel_Name, Vessel_Type,
|
||||||
Event_Type, Significance, Headline, Location_Name,
|
Event_Type, Significance, Headline, Location_Name,
|
||||||
Published_Date, Event_Start_Date, Event_End_Date, batch_flag
|
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 class EventSql {
|
||||||
public static String getEventDetailUpdateSql(){
|
public static String getEventDetailUpdateSql(){
|
||||||
return """
|
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,
|
event_id, incident_id, ihslrorimoshipno, published_date, event_start_date, event_end_date,
|
||||||
attempted_boarding, cargo_loading_status_code, casualty_action,
|
attempted_boarding, cargo_loading_status_code, casualty_action,
|
||||||
casualty_zone, casualty_zone_code, component2, country_code,
|
casualty_zone, casualty_zone_code, component2, country_code,
|
||||||
|
|||||||
@ -13,7 +13,6 @@ import java.util.List;
|
|||||||
@Component
|
@Component
|
||||||
public class EventDataWriter extends BaseWriter<EventDetailEntity> {
|
public class EventDataWriter extends BaseWriter<EventDetailEntity> {
|
||||||
private final EventRepository eventRepository;
|
private final EventRepository eventRepository;
|
||||||
protected String getApiKey() {return "EVENT_IMPORT_JOB";}
|
|
||||||
public EventDataWriter(EventRepository eventRepository) {
|
public EventDataWriter(EventRepository eventRepository) {
|
||||||
super("EventRepository");
|
super("EventRepository");
|
||||||
this.eventRepository = eventRepository;
|
this.eventRepository = eventRepository;
|
||||||
|
|||||||
@ -38,7 +38,8 @@ public class RiskImportRangeJobConfig extends BaseMultiStepJobConfig<RiskDto, Ri
|
|||||||
|
|
||||||
protected String getApiKey() {return "RISK_IMPORT_API";}
|
protected String getApiKey() {return "RISK_IMPORT_API";}
|
||||||
protected String getBatchUpdateSql() {
|
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
|
@Override
|
||||||
protected int getChunkSize() {
|
protected int getChunkSize() {
|
||||||
|
|||||||
불러오는 중...
Reference in New Issue
Block a user