Compare commits

...

1 커밋

작성자 SHA1 메시지 날짜
hyojin-kim4
20b8520a04 🔖 Batch Release Version : 1.1.0 (#5)
 S&P 수집 배치 데이터 검증값 추가 (정규화 이전)
* AIS
* Movements
* Events
* Risk&Compliance
* PSC
* Ships
* Facilities
---------

Co-authored-by: Kim JiMyeung <jmkim@gcsc8932.onmicrosoft.com>
Co-authored-by: HeungTak Lee <htlee@gcsc.co.kr>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 19:13:11 +09:00
125개의 변경된 파일1986개의 추가작업 그리고 3361개의 파일을 삭제

파일 보기

@ -13,7 +13,7 @@
</parent> </parent>
<groupId>com.snp</groupId> <groupId>com.snp</groupId>
<artifactId>snp-batch</artifactId> <artifactId>snp-batch-validation</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
<name>SNP Batch</name> <name>SNP Batch</name>
<description>Spring Batch project for JSON to PostgreSQL with Web GUI</description> <description>Spring Batch project for JSON to PostgreSQL with Web GUI</description>

파일 보기

@ -43,4 +43,22 @@ public abstract class BaseEntity {
* 컬럼: updated_by (VARCHAR(100)) * 컬럼: updated_by (VARCHAR(100))
*/ */
private String updatedBy; private String updatedBy;
/**
* 배치 실행 ID
* 컬럼: job_execution_id (int8)
*/
private Long jobExecutionId;
/**
* 배치 공통 필드 설정을 위한 편의 메서드
*/
@SuppressWarnings("unchecked")
public <T extends BaseEntity> T setBatchInfo(Long jobExecutionId, String createdBy) {
this.jobExecutionId = jobExecutionId;
this.createdBy = createdBy;
// 필요시 생성일시 강제 설정 (JPA Auditing을 경우)
if (this.createdAt == null) this.createdAt = LocalDateTime.now();
return (T) this;
}
} }

파일 보기

@ -170,6 +170,125 @@ public abstract class BaseApiReader<T> implements ItemReader<T> {
} }
} }
protected <T, R> List<R> executeWrapperApiCall(
String baseUrl,
String path,
Class<T> responseWrapperClass, // Stat5CodeApiResponse.class 등을 받음
Function<T, List<R>> listExtractor, // 결과 객체에서 리스트를 꺼내는 로직
BatchApiLogService logService) {
String fullUri = UriComponentsBuilder.fromHttpUrl(baseUrl)
.path(path)
.build()
.toUriString();
long startTime = System.currentTimeMillis();
int statusCode = 200;
String errorMessage = null;
Long responseSize = 0L;
try {
log.info("[{}] API 요청 시작: {}", getReaderName(), fullUri);
// 1. List<R> 아닌 Wrapper 객체(T) 받아옵니다.
T response = webClient.get()
.uri(uriBuilder -> uriBuilder.path(path).build())
.retrieve()
.bodyToMono(responseWrapperClass)
.block();
// 2. 추출 함수(listExtractor) 사용하여 내부 리스트를 꺼냅니다.
List<R> result = (response != null) ? listExtractor.apply(response) : Collections.emptyList();
responseSize = (long) result.size();
return result;
} catch (WebClientResponseException e) {
statusCode = e.getStatusCode().value();
errorMessage = String.format("API Error: %s", e.getResponseBodyAsString());
throw e;
} catch (Exception e) {
statusCode = 500;
errorMessage = String.format("System Error: %s", e.getMessage());
throw e;
} finally {
long duration = System.currentTimeMillis() - startTime;
logService.saveLog(BatchApiLog.builder()
.apiRequestLocation(getReaderName())
.requestUri(fullUri)
.httpMethod("GET")
.statusCode(statusCode)
.responseTimeMs(duration)
.responseCount(responseSize)
.errorMessage(errorMessage)
.createdAt(LocalDateTime.now())
.jobExecutionId(this.jobExecutionId)
.stepExecutionId(this.stepExecutionId)
.build());
}
}
protected <R> List<R> executeListApiCall(
String baseUrl,
String path,
ParameterizedTypeReference<List<R>> typeReference,
BatchApiLogService logService) {
String fullUri = UriComponentsBuilder.fromHttpUrl(baseUrl)
.path(path)
.build()
.toUriString();
long startTime = System.currentTimeMillis();
int statusCode = 200;
String errorMessage = null;
Long responseSize = 0L;
try {
log.info("[{}] API 요청 시작: {}", getReaderName(), fullUri);
List<R> result = webClient.get()
.uri(uriBuilder -> {
uriBuilder.path(path);
return uriBuilder.build();
})
.retrieve()
.bodyToMono(typeReference)
.block();
responseSize = (result != null) ? (long) result.size() : 0L;
return result;
} catch (WebClientResponseException e) {
// API 서버에서 응답은 왔으나 에러인 경우 (4xx, 5xx)
statusCode = e.getStatusCode().value();
errorMessage = String.format("API Error: %s", e.getResponseBodyAsString());
throw e;
} catch (Exception e) {
// 네트워크 오류, 타임아웃 기타 예외
statusCode = 500;
errorMessage = String.format("System Error: %s", e.getMessage());
throw e;
} finally {
// 성공/실패 여부와 관계없이 무조건 로그 저장
long duration = System.currentTimeMillis() - startTime;
logService.saveLog(BatchApiLog.builder()
.apiRequestLocation(getReaderName())
.requestUri(fullUri)
.httpMethod("GET")
.statusCode(statusCode)
.responseTimeMs(duration)
.responseCount(responseSize)
.errorMessage(errorMessage)
.createdAt(LocalDateTime.now())
.jobExecutionId(this.jobExecutionId) // 추가
.stepExecutionId(this.stepExecutionId) // 추가
.build());
}
}
/** /**
* API 호출 로그 적재 통합 메서드 * API 호출 로그 적재 통합 메서드
* Response Json 구조 : { "data": [...] } * Response Json 구조 : { "data": [...] }

파일 보기

@ -7,7 +7,7 @@ import org.hibernate.annotations.CreationTimestamp;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@Entity @Entity
@Table(name = "batch_api_log", schema = "snp_data") @Table(name = "batch_api_log", schema = "t_snp_data")
@Getter @Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED) @NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor @AllArgsConstructor

파일 보기

@ -7,9 +7,12 @@ import com.snp.batch.jobs.common.batch.processor.FlagCodeDataProcessor;
import com.snp.batch.jobs.common.batch.reader.FlagCodeDataReader; import com.snp.batch.jobs.common.batch.reader.FlagCodeDataReader;
import com.snp.batch.jobs.common.batch.repository.FlagCodeRepository; import com.snp.batch.jobs.common.batch.repository.FlagCodeRepository;
import com.snp.batch.jobs.common.batch.writer.FlagCodeDataWriter; import com.snp.batch.jobs.common.batch.writer.FlagCodeDataWriter;
import com.snp.batch.jobs.facility.batch.reader.PortDataReader;
import com.snp.batch.service.BatchApiLogService;
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.configuration.annotation.StepScope;
import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemReader;
@ -25,8 +28,14 @@ import org.springframework.web.reactive.function.client.WebClient;
@Configuration @Configuration
public class FlagCodeImportJobConfig extends BaseJobConfig<FlagCodeDto, FlagCodeEntity> { public class FlagCodeImportJobConfig extends BaseJobConfig<FlagCodeDto, FlagCodeEntity> {
private final FlagCodeDataProcessor flagCodeDataProcessor;
private final FlagCodeDataReader flagCodeDataReader;
private final FlagCodeRepository flagCodeRepository; private final FlagCodeRepository flagCodeRepository;
private final WebClient maritimeApiWebClient; private final WebClient maritimeApiWebClient;
private final BatchApiLogService batchApiLogService;
@Value("${app.batch.ship-api.url}")
private String maritimeApiUrl;
@Value("${app.batch.chunk-size:1000}") @Value("${app.batch.chunk-size:1000}")
private int chunkSize; private int chunkSize;
@ -39,10 +48,16 @@ public class FlagCodeImportJobConfig extends BaseJobConfig<FlagCodeDto, FlagCode
JobRepository jobRepository, JobRepository jobRepository,
PlatformTransactionManager transactionManager, PlatformTransactionManager transactionManager,
FlagCodeRepository flagCodeRepository, FlagCodeRepository flagCodeRepository,
@Qualifier("maritimeApiWebClient") WebClient maritimeApiWebClient) { FlagCodeDataProcessor flagCodeDataProcessor,
@Qualifier("maritimeApiWebClient") WebClient maritimeApiWebClient,
FlagCodeDataReader flagCodeDataReader,
BatchApiLogService batchApiLogService) {
super(jobRepository, transactionManager); super(jobRepository, transactionManager);
this.flagCodeRepository = flagCodeRepository; this.flagCodeRepository = flagCodeRepository;
this.maritimeApiWebClient = maritimeApiWebClient; this.maritimeApiWebClient = maritimeApiWebClient;
this.flagCodeDataProcessor = flagCodeDataProcessor;
this.flagCodeDataReader = flagCodeDataReader;
this.batchApiLogService = batchApiLogService;
} }
@Override @Override
@ -57,14 +72,29 @@ public class FlagCodeImportJobConfig extends BaseJobConfig<FlagCodeDto, FlagCode
@Override @Override
protected ItemReader<FlagCodeDto> createReader() { protected ItemReader<FlagCodeDto> createReader() {
return new FlagCodeDataReader(maritimeApiWebClient); return flagCodeDataReader;
}
@Bean
@StepScope
public FlagCodeDataReader flagCodeDataReader(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId, // SpEL로 ID 추출
@Value("#{stepExecution.id}") Long stepExecutionId
) {
FlagCodeDataReader reader = new FlagCodeDataReader(maritimeApiWebClient, batchApiLogService, maritimeApiUrl);
reader.setExecutionIds(jobExecutionId, stepExecutionId); // ID 세팅
return reader;
} }
@Override @Override
protected ItemProcessor<FlagCodeDto, FlagCodeEntity> createProcessor() { protected ItemProcessor<FlagCodeDto, FlagCodeEntity> createProcessor() {
return new FlagCodeDataProcessor(flagCodeRepository); return flagCodeDataProcessor;
}
@Bean
@StepScope
public FlagCodeDataProcessor flagCodeDataProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
return new FlagCodeDataProcessor(jobExecutionId);
} }
@Override @Override
protected ItemWriter<FlagCodeEntity> createWriter() { protected ItemWriter<FlagCodeEntity> createWriter() {
return new FlagCodeDataWriter(flagCodeRepository); return new FlagCodeDataWriter(flagCodeRepository);

파일 보기

@ -7,14 +7,17 @@ import com.snp.batch.jobs.common.batch.processor.Stat5CodeDataProcessor;
import com.snp.batch.jobs.common.batch.reader.Stat5CodeDataReader; import com.snp.batch.jobs.common.batch.reader.Stat5CodeDataReader;
import com.snp.batch.jobs.common.batch.repository.Stat5CodeRepository; import com.snp.batch.jobs.common.batch.repository.Stat5CodeRepository;
import com.snp.batch.jobs.common.batch.writer.Stat5CodeDataWriter; import com.snp.batch.jobs.common.batch.writer.Stat5CodeDataWriter;
import com.snp.batch.service.BatchApiLogService;
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.configuration.annotation.StepScope;
import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.JobRepository;
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.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
@ -24,16 +27,27 @@ import org.springframework.web.reactive.function.client.WebClient;
@Configuration @Configuration
public class Stat5CodeImportJobConfig extends BaseJobConfig<Stat5CodeDto, Stat5CodeEntity> { public class Stat5CodeImportJobConfig extends BaseJobConfig<Stat5CodeDto, Stat5CodeEntity> {
private final Stat5CodeDataProcessor stat5CodeDataProcessor;
private final Stat5CodeDataReader stat5CodeDataReader;
private final Stat5CodeRepository stat5CodeRepository; private final Stat5CodeRepository stat5CodeRepository;
private final BatchApiLogService batchApiLogService;
private final WebClient maritimeAisApiWebClient; private final WebClient maritimeAisApiWebClient;
@Value("${app.batch.ais-api.url}")
private String maritimeAisApiUrl;
public Stat5CodeImportJobConfig( public Stat5CodeImportJobConfig(
JobRepository jobRepository, JobRepository jobRepository,
PlatformTransactionManager transactionManager, PlatformTransactionManager transactionManager,
Stat5CodeRepository stat5CodeRepository, Stat5CodeRepository stat5CodeRepository,
@Qualifier("maritimeAisApiWebClient") WebClient maritimeAisApiWebClient) { @Qualifier("maritimeAisApiWebClient") WebClient maritimeAisApiWebClient,
Stat5CodeDataProcessor stat5CodeDataProcessor,
Stat5CodeDataReader stat5CodeDataReader,
BatchApiLogService batchApiLogService) {
super(jobRepository, transactionManager); super(jobRepository, transactionManager);
this.stat5CodeRepository = stat5CodeRepository; this.stat5CodeRepository = stat5CodeRepository;
this.maritimeAisApiWebClient = maritimeAisApiWebClient; this.maritimeAisApiWebClient = maritimeAisApiWebClient;
this.stat5CodeDataProcessor = stat5CodeDataProcessor;
this.stat5CodeDataReader = stat5CodeDataReader;
this.batchApiLogService = batchApiLogService;
} }
@Override @Override
@ -45,11 +59,27 @@ public class Stat5CodeImportJobConfig extends BaseJobConfig<Stat5CodeDto, Stat5C
} }
@Override @Override
protected ItemReader<Stat5CodeDto> createReader() { return new Stat5CodeDataReader(maritimeAisApiWebClient); } protected ItemReader<Stat5CodeDto> createReader() { return stat5CodeDataReader; }
@Bean
@StepScope
public Stat5CodeDataReader stat5CodeDataReader(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId, // SpEL로 ID 추출
@Value("#{stepExecution.id}") Long stepExecutionId
) {
Stat5CodeDataReader reader = new Stat5CodeDataReader(maritimeAisApiWebClient, batchApiLogService, maritimeAisApiUrl);
reader.setExecutionIds(jobExecutionId, stepExecutionId); // ID 세팅
return reader;
}
@Override @Override
protected ItemProcessor<Stat5CodeDto, Stat5CodeEntity> createProcessor() { return new Stat5CodeDataProcessor(stat5CodeRepository); } protected ItemProcessor<Stat5CodeDto, Stat5CodeEntity> createProcessor() { return stat5CodeDataProcessor; }
@Bean
@StepScope
public Stat5CodeDataProcessor stat5CodeDataProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
return new Stat5CodeDataProcessor(jobExecutionId);
}
@Override @Override
protected ItemWriter<Stat5CodeEntity> createWriter() { return new Stat5CodeDataWriter(stat5CodeRepository); } protected ItemWriter<Stat5CodeEntity> createWriter() { return new Stat5CodeDataWriter(stat5CodeRepository); }

파일 보기

@ -3,16 +3,16 @@ package com.snp.batch.jobs.common.batch.processor;
import com.snp.batch.common.batch.processor.BaseProcessor; import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.common.batch.dto.FlagCodeDto; import com.snp.batch.jobs.common.batch.dto.FlagCodeDto;
import com.snp.batch.jobs.common.batch.entity.FlagCodeEntity; import com.snp.batch.jobs.common.batch.entity.FlagCodeEntity;
import com.snp.batch.jobs.common.batch.repository.FlagCodeRepository;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
@Slf4j @Slf4j
public class FlagCodeDataProcessor extends BaseProcessor<FlagCodeDto, FlagCodeEntity> { public class FlagCodeDataProcessor extends BaseProcessor<FlagCodeDto, FlagCodeEntity> {
private final FlagCodeRepository commonCodeRepository; private final Long jobExecutionId;
public FlagCodeDataProcessor(FlagCodeRepository commonCodeRepository) { public FlagCodeDataProcessor(@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
this.commonCodeRepository = commonCodeRepository; this.jobExecutionId = jobExecutionId;
} }
@Override @Override
@ -24,6 +24,8 @@ public class FlagCodeDataProcessor extends BaseProcessor<FlagCodeDto, FlagCodeEn
.decode(dto.getDecode()) .decode(dto.getDecode())
.iso2(dto.getIso2()) .iso2(dto.getIso2())
.iso3(dto.getIso3()) .iso3(dto.getIso3())
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
log.debug("국가코드 데이터 처리 완료: FlagCode={}", dto.getCode()); log.debug("국가코드 데이터 처리 완료: FlagCode={}", dto.getCode());

파일 보기

@ -3,16 +3,16 @@ package com.snp.batch.jobs.common.batch.processor;
import com.snp.batch.common.batch.processor.BaseProcessor; import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.common.batch.dto.Stat5CodeDto; import com.snp.batch.jobs.common.batch.dto.Stat5CodeDto;
import com.snp.batch.jobs.common.batch.entity.Stat5CodeEntity; import com.snp.batch.jobs.common.batch.entity.Stat5CodeEntity;
import com.snp.batch.jobs.common.batch.repository.Stat5CodeRepository;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
@Slf4j @Slf4j
public class Stat5CodeDataProcessor extends BaseProcessor<Stat5CodeDto, Stat5CodeEntity> { public class Stat5CodeDataProcessor extends BaseProcessor<Stat5CodeDto, Stat5CodeEntity> {
private final Stat5CodeRepository stat5CodeRepository; private final Long jobExecutionId;
public Stat5CodeDataProcessor(Stat5CodeRepository stat5CodeRepository) { public Stat5CodeDataProcessor(@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
this.stat5CodeRepository = stat5CodeRepository; this.jobExecutionId = jobExecutionId;
} }
@Override @Override
@ -30,6 +30,8 @@ public class Stat5CodeDataProcessor extends BaseProcessor<Stat5CodeDto, Stat5Cod
.Level5Decode(dto.getLevel5Decode()) .Level5Decode(dto.getLevel5Decode())
.Description(dto.getDescription()) .Description(dto.getDescription())
.Release(Integer.toString(dto.getRelease())) .Release(Integer.toString(dto.getRelease()))
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
log.debug("Stat5Code 데이터 처리 완료: Stat5Code={}", dto.getLevel5()); log.debug("Stat5Code 데이터 처리 완료: Stat5Code={}", dto.getLevel5());

파일 보기

@ -3,17 +3,22 @@ package com.snp.batch.jobs.common.batch.reader;
import com.snp.batch.common.batch.reader.BaseApiReader; import com.snp.batch.common.batch.reader.BaseApiReader;
import com.snp.batch.jobs.common.batch.dto.FlagCodeApiResponse; import com.snp.batch.jobs.common.batch.dto.FlagCodeApiResponse;
import com.snp.batch.jobs.common.batch.dto.FlagCodeDto; import com.snp.batch.jobs.common.batch.dto.FlagCodeDto;
import com.snp.batch.service.BatchApiLogService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
@Slf4j @Slf4j
public class FlagCodeDataReader extends BaseApiReader<FlagCodeDto> { public class FlagCodeDataReader extends BaseApiReader<FlagCodeDto> {
private final BatchApiLogService batchApiLogService;
public FlagCodeDataReader(WebClient webClient) { String maritimeApiUrl;
public FlagCodeDataReader(WebClient webClient, BatchApiLogService batchApiLogService, String maritimeApiUrl) {
super(webClient); // BaseApiReader에 WebClient 전달 super(webClient); // BaseApiReader에 WebClient 전달
this.batchApiLogService = batchApiLogService;
this.maritimeApiUrl = maritimeApiUrl;
} }
// ======================================== // ========================================
@ -24,28 +29,25 @@ public class FlagCodeDataReader extends BaseApiReader<FlagCodeDto> {
protected String getReaderName() { protected String getReaderName() {
return "FlagCodeDataReader"; return "FlagCodeDataReader";
} }
@Override
protected String getApiPath() {
return "/MaritimeWCF/APSShipService.svc/RESTFul/GetAssociatedFlagISOByName";
}
@Override @Override
protected List<FlagCodeDto> fetchDataFromApi() { protected List<FlagCodeDto> fetchDataFromApi() {
try { try {
log.info("GetAssociatedFlagISOByName API 호출 시작"); log.info("GetAssociatedFlagISOByName API 호출 시작");
FlagCodeApiResponse response = webClient // 공통 함수 호출
.get() List<FlagCodeDto> result = executeWrapperApiCall(
.uri(uriBuilder -> uriBuilder maritimeApiUrl, // 베이스 URL (필드 또는 설정값)
.path("/MaritimeWCF/APSShipService.svc/RESTFul/GetAssociatedFlagISOByName") getApiPath(), // API 경로
.build()) FlagCodeApiResponse.class, // 응답을 받을 래퍼 클래스
.retrieve() FlagCodeApiResponse::getAssociatedFlagISODetails, // 리스트 추출 함수 (메서드 참조)
.bodyToMono(FlagCodeApiResponse.class) batchApiLogService // 로그 서비스
.block(); );
// 결과가 null일 경우 리스트 반환 (안전장치)
if (response != null && response.getAssociatedFlagISODetails() != null) { return result != null ? result : Collections.emptyList();
log.info("API 응답 성공: 총 {} 건의 국가코드 데이터 수신", response.getAssociatedCount());
return response.getAssociatedFlagISODetails();
} else {
log.warn("API 응답이 null이거나 국가코드 데이터가 없습니다");
return new ArrayList<>();
}
} catch (Exception e) { } catch (Exception e) {
log.error("GetAssociatedFlagISOByName API 호출 실패", e); log.error("GetAssociatedFlagISOByName API 호출 실패", e);

파일 보기

@ -3,43 +3,46 @@ package com.snp.batch.jobs.common.batch.reader;
import com.snp.batch.common.batch.reader.BaseApiReader; import com.snp.batch.common.batch.reader.BaseApiReader;
import com.snp.batch.jobs.common.batch.dto.Stat5CodeApiResponse; import com.snp.batch.jobs.common.batch.dto.Stat5CodeApiResponse;
import com.snp.batch.jobs.common.batch.dto.Stat5CodeDto; import com.snp.batch.jobs.common.batch.dto.Stat5CodeDto;
import com.snp.batch.service.BatchApiLogService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
@Slf4j @Slf4j
public class Stat5CodeDataReader extends BaseApiReader<Stat5CodeDto> { public class Stat5CodeDataReader extends BaseApiReader<Stat5CodeDto> {
public Stat5CodeDataReader(WebClient webClient) { private final BatchApiLogService batchApiLogService;
String maritimeAisApiUrl;
public Stat5CodeDataReader(WebClient webClient, BatchApiLogService batchApiLogService, String maritimeAisApiUrl) {
super(webClient); // BaseApiReader에 WebClient 전달 super(webClient); // BaseApiReader에 WebClient 전달
this.batchApiLogService = batchApiLogService;
this.maritimeAisApiUrl = maritimeAisApiUrl;
} }
@Override @Override
protected String getReaderName() { protected String getReaderName() {
return "Stat5CodeDataReader"; return "Stat5CodeDataReader";
} }
@Override @Override
protected String getApiPath() {
return "/AisSvc.svc/AIS/GetStatcodes";
}
@Override
protected List<Stat5CodeDto> fetchDataFromApi() { protected List<Stat5CodeDto> fetchDataFromApi() {
try { try {
log.info("GetStatcodes API 호출 시작"); log.info("GetStatcodes API 호출 시작");
Stat5CodeApiResponse response = webClient // 공통 함수 호출
.get() List<Stat5CodeDto> result = executeWrapperApiCall(
.uri(uriBuilder -> uriBuilder maritimeAisApiUrl, // 베이스 URL (필드 또는 설정값)
.path("/AisSvc.svc/AIS/GetStatcodes") getApiPath(), // API 경로
.build()) Stat5CodeApiResponse.class, // 응답을 받을 래퍼 클래스
.retrieve() Stat5CodeApiResponse::getStatcodeArr, // 리스트 추출 함수 (메서드 참조)
.bodyToMono(Stat5CodeApiResponse.class) batchApiLogService // 로그 서비스
.block(); );
// 결과가 null일 경우 리스트 반환 (안전장치)
if (response != null && response.getStatcodeArr() != null) { return result != null ? result : Collections.emptyList();
log.info("API 응답 성공: 총 {} 건의 Stat5Code 데이터 수신", response.getStatcodeArr().size());
return response.getStatcodeArr();
} else {
log.warn("API 응답이 null이거나 Stat5Code 데이터가 없습니다");
return new ArrayList<>();
}
} catch (Exception e) { } catch (Exception e) {
log.error("GetAssociatedFlagISOByName API 호출 실패", e); log.error("GetAssociatedFlagISOByName API 호출 실패", e);
log.error("에러 메시지: {}", e.getMessage()); log.error("에러 메시지: {}", e.getMessage());

파일 보기

@ -8,6 +8,7 @@ import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.Types;
import java.util.List; import java.util.List;
@Slf4j @Slf4j
@ -25,7 +26,7 @@ public class FlagCodeRepositoryImpl extends BaseJdbcRepository<FlagCodeEntity, S
@Override @Override
protected String getTableName() { protected String getTableName() {
return "snp_data.flagcode"; return "t_snp_data.flagcode";
} }
@ -37,17 +38,11 @@ public class FlagCodeRepositoryImpl extends BaseJdbcRepository<FlagCodeEntity, S
@Override @Override
protected String getUpdateSql() { protected String getUpdateSql() {
return """ return """
INSERT INTO snp_data.flagcode ( INSERT INTO %s(
datasetversion, code, decode, iso2, iso3 datasetversion, code, decode, iso2, iso3,
) VALUES (?, ?, ?, ?, ?) job_execution_id, created_by
ON CONFLICT (code) ) VALUES (?, ?, ?, ?, ?, ?, ?);
DO UPDATE SET """.formatted(getTableName());
datasetversion = EXCLUDED.datasetversion,
decode = EXCLUDED.decode,
iso2 = EXCLUDED.iso2,
iso3 = EXCLUDED.iso3,
batch_flag = 'N'
""";
} }
@Override @Override
@ -63,6 +58,8 @@ public class FlagCodeRepositoryImpl extends BaseJdbcRepository<FlagCodeEntity, S
ps.setString(idx++, entity.getDecode()); ps.setString(idx++, entity.getDecode());
ps.setString(idx++, entity.getIso2()); ps.setString(idx++, entity.getIso2());
ps.setString(idx++, entity.getIso3()); ps.setString(idx++, entity.getIso3());
ps.setObject(idx++, entity.getJobExecutionId(), Types.INTEGER);
ps.setString(idx++, entity.getCreatedBy());
} }
@Override @Override

파일 보기

@ -8,6 +8,7 @@ import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.Types;
import java.util.List; import java.util.List;
@Slf4j @Slf4j
@ -24,7 +25,7 @@ public class Stat5CodeRepositoryImpl extends BaseJdbcRepository<Stat5CodeEntity,
@Override @Override
protected String getTableName() { protected String getTableName() {
return "snp_data.stat5code"; return "t_snp_data.stat5code";
} }
@Override @Override
@ -45,25 +46,11 @@ public class Stat5CodeRepositoryImpl extends BaseJdbcRepository<Stat5CodeEntity,
@Override @Override
protected String getUpdateSql() { protected String getUpdateSql() {
return """ return """
INSERT INTO snp_data.stat5code ( INSERT INTO %s(
level1, level1decode, level2, level2decode, level3, level3decode, level4, level4decode, level5, level5decode, description, release level1, level1decode, level2, level2decode, level3, level3decode, level4, level4decode, level5, level5decode, description, release,
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) job_execution_id, created_by
ON CONFLICT (level1, level2, level3, level4, level5) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
DO UPDATE SET """.formatted(getTableName());
level1 = EXCLUDED.level1,
level1decode = EXCLUDED.level1decode,
level2 = EXCLUDED.level2,
level2decode = EXCLUDED.level2decode,
level3 = EXCLUDED.level3,
level3decode = EXCLUDED.level3decode,
level4 = EXCLUDED.level4,
level4decode = EXCLUDED.level4decode,
level5 = EXCLUDED.level5,
level5decode = EXCLUDED.level5decode,
description = EXCLUDED.description,
release = EXCLUDED.release,
batch_flag = 'N'
""";
} }
@Override @Override
@ -86,6 +73,8 @@ public class Stat5CodeRepositoryImpl extends BaseJdbcRepository<Stat5CodeEntity,
ps.setString(idx++, entity.getLevel5Decode()); ps.setString(idx++, entity.getLevel5Decode());
ps.setString(idx++, entity.getDescription()); ps.setString(idx++, entity.getDescription());
ps.setString(idx++, entity.getRelease()); ps.setString(idx++, entity.getRelease());
ps.setObject(idx++, entity.getJobExecutionId(), Types.INTEGER);
ps.setString(idx++, entity.getCreatedBy());
} }
@Override @Override

파일 보기

@ -2,12 +2,9 @@ package com.snp.batch.jobs.compliance.batch.config;
import com.snp.batch.common.batch.config.BaseMultiStepJobConfig; import com.snp.batch.common.batch.config.BaseMultiStepJobConfig;
import com.snp.batch.jobs.compliance.batch.dto.CompanyComplianceDto; import com.snp.batch.jobs.compliance.batch.dto.CompanyComplianceDto;
import com.snp.batch.jobs.compliance.batch.dto.ComplianceDto;
import com.snp.batch.jobs.compliance.batch.entity.CompanyComplianceEntity; import com.snp.batch.jobs.compliance.batch.entity.CompanyComplianceEntity;
import com.snp.batch.jobs.compliance.batch.entity.ComplianceEntity;
import com.snp.batch.jobs.compliance.batch.processor.CompanyComplianceDataProcessor; import com.snp.batch.jobs.compliance.batch.processor.CompanyComplianceDataProcessor;
import com.snp.batch.jobs.compliance.batch.reader.CompanyComplianceDataRangeReader; import com.snp.batch.jobs.compliance.batch.reader.CompanyComplianceDataRangeReader;
import com.snp.batch.jobs.compliance.batch.reader.ComplianceDataRangeReader;
import com.snp.batch.jobs.compliance.batch.writer.CompanyComplianceDataWriter; import com.snp.batch.jobs.compliance.batch.writer.CompanyComplianceDataWriter;
import com.snp.batch.service.BatchApiLogService; import com.snp.batch.service.BatchApiLogService;
import com.snp.batch.service.BatchDateService; import com.snp.batch.service.BatchDateService;
@ -52,7 +49,7 @@ public class CompanyComplianceImportRangeJobConfig extends BaseMultiStepJobConfi
private String maritimeServiceApiUrl; private String maritimeServiceApiUrl;
protected String getApiKey() {return "COMPANY_COMPLIANCE_IMPORT_API";} protected String getApiKey() {return "COMPANY_COMPLIANCE_IMPORT_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_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() {
@ -91,7 +88,7 @@ public class CompanyComplianceImportRangeJobConfig extends BaseMultiStepJobConfi
protected Job createJobFlow(JobBuilder jobBuilder) { protected Job createJobFlow(JobBuilder jobBuilder) {
return jobBuilder return jobBuilder
.start(companyComplianceImportRangeStep()) // 1단계 실행 .start(companyComplianceImportRangeStep()) // 1단계 실행
.next(companyComplianceHistoryValueChangeManageStep()) // 2단계 실행 (2단계 실패 실행 ) // .next(companyComplianceHistoryValueChangeManageStep()) // 2단계 실행 (2단계 실패 실행 )
.next(companyComplianceLastExecutionUpdateStep()) // 3단계: 모두 완료 , BATCH_LAST_EXECUTION 마지막 성공일자 업데이트 .next(companyComplianceLastExecutionUpdateStep()) // 3단계: 모두 완료 , BATCH_LAST_EXECUTION 마지막 성공일자 업데이트
.build(); .build();
} }
@ -115,7 +112,12 @@ public class CompanyComplianceImportRangeJobConfig extends BaseMultiStepJobConfi
protected ItemProcessor<CompanyComplianceDto, CompanyComplianceEntity> createProcessor() { protected ItemProcessor<CompanyComplianceDto, CompanyComplianceEntity> createProcessor() {
return companyComplianceDataProcessor; return companyComplianceDataProcessor;
} }
@Bean
@StepScope
public CompanyComplianceDataProcessor companyComplianceDataProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
return new CompanyComplianceDataProcessor(jobExecutionId);
}
@Override @Override
protected ItemWriter<CompanyComplianceEntity> createWriter() { protected ItemWriter<CompanyComplianceEntity> createWriter() {
return companyComplianceDataWriter; return companyComplianceDataWriter;

파일 보기

@ -28,7 +28,8 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
import java.time.*; import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Map; import java.util.Map;
@ -47,7 +48,7 @@ public class ComplianceImportRangeJobConfig extends BaseMultiStepJobConfig<Compl
private String maritimeServiceApiUrl; private String maritimeServiceApiUrl;
protected String getApiKey() {return "COMPLIANCE_IMPORT_API";} protected String getApiKey() {return "COMPLIANCE_IMPORT_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_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() {
@ -87,7 +88,7 @@ public class ComplianceImportRangeJobConfig extends BaseMultiStepJobConfig<Compl
protected Job createJobFlow(JobBuilder jobBuilder) { protected Job createJobFlow(JobBuilder jobBuilder) {
return jobBuilder return jobBuilder
.start(complianceImportRangeStep()) // 1단계 실행 .start(complianceImportRangeStep()) // 1단계 실행
.next(complianceHistoryValueChangeManageStep()) // 2단계 실행 (2단계 실패 실행 ) // .next(complianceHistoryValueChangeManageStep()) // 2단계 실행 (2단계 실패 실행 )
.next(complianceLastExecutionUpdateStep()) // 3단계: 모두 완료 , BATCH_LAST_EXECUTION 마지막 성공일자 업데이트 .next(complianceLastExecutionUpdateStep()) // 3단계: 모두 완료 , BATCH_LAST_EXECUTION 마지막 성공일자 업데이트
.build(); .build();
} }
@ -112,6 +113,13 @@ public class ComplianceImportRangeJobConfig extends BaseMultiStepJobConfig<Compl
return complianceDataProcessor; return complianceDataProcessor;
} }
@Bean
@StepScope
public ComplianceDataProcessor complianceDataProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
return new ComplianceDataProcessor(jobExecutionId);
}
@Override @Override
protected ItemWriter<ComplianceEntity> createWriter() { protected ItemWriter<ComplianceEntity> createWriter() {
return complianceDataWriter; return complianceDataWriter;

파일 보기

@ -4,12 +4,16 @@ import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.compliance.batch.dto.CompanyComplianceDto; import com.snp.batch.jobs.compliance.batch.dto.CompanyComplianceDto;
import com.snp.batch.jobs.compliance.batch.entity.CompanyComplianceEntity; import com.snp.batch.jobs.compliance.batch.entity.CompanyComplianceEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Slf4j @Slf4j
@Component @Component
public class CompanyComplianceDataProcessor extends BaseProcessor<CompanyComplianceDto, CompanyComplianceEntity> { public class CompanyComplianceDataProcessor extends BaseProcessor<CompanyComplianceDto, CompanyComplianceEntity> {
private final Long jobExecutionId;
public CompanyComplianceDataProcessor(@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
this.jobExecutionId = jobExecutionId;
}
@Override @Override
protected CompanyComplianceEntity processItem(CompanyComplianceDto dto) throws Exception { protected CompanyComplianceEntity processItem(CompanyComplianceDto dto) throws Exception {
@ -30,6 +34,8 @@ public class CompanyComplianceDataProcessor extends BaseProcessor<CompanyComplia
.companyOnSwissSanctionList(dto.getCompanyOnSwissSanctionList()) .companyOnSwissSanctionList(dto.getCompanyOnSwissSanctionList())
.companyOnUAESanctionList(dto.getCompanyOnUAESanctionList()) .companyOnUAESanctionList(dto.getCompanyOnUAESanctionList())
.companyOnUNSanctionList(dto.getCompanyOnUNSanctionList()) .companyOnUNSanctionList(dto.getCompanyOnUNSanctionList())
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
return entity; return entity;
} }

파일 보기

@ -4,11 +4,16 @@ import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.compliance.batch.dto.ComplianceDto; import com.snp.batch.jobs.compliance.batch.dto.ComplianceDto;
import com.snp.batch.jobs.compliance.batch.entity.ComplianceEntity; import com.snp.batch.jobs.compliance.batch.entity.ComplianceEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Slf4j @Slf4j
@Component @Component
public class ComplianceDataProcessor extends BaseProcessor<ComplianceDto, ComplianceEntity> { public class ComplianceDataProcessor extends BaseProcessor<ComplianceDto, ComplianceEntity> {
private final Long jobExecutionId;
public ComplianceDataProcessor(@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
this.jobExecutionId = jobExecutionId;
}
@Override @Override
protected ComplianceEntity processItem(ComplianceDto dto) throws Exception { protected ComplianceEntity processItem(ComplianceDto dto) throws Exception {
@ -50,6 +55,8 @@ public class ComplianceDataProcessor extends BaseProcessor<ComplianceDto, Compli
.shipSTSPartnerNonComplianceLast12m(dto.getShipSTSPartnerNonComplianceLast12m()) .shipSTSPartnerNonComplianceLast12m(dto.getShipSTSPartnerNonComplianceLast12m())
.shipSwissSanctionList(dto.getShipSwissSanctionList()) .shipSwissSanctionList(dto.getShipSwissSanctionList())
.shipUNSanctionList(dto.getShipUNSanctionList()) .shipUNSanctionList(dto.getShipUNSanctionList())
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
return entity; return entity;

파일 보기

@ -6,5 +6,5 @@ import java.util.List;
public interface CompanyComplianceRepository { public interface CompanyComplianceRepository {
void saveCompanyComplianceAll(List<CompanyComplianceEntity> items); void saveCompanyComplianceAll(List<CompanyComplianceEntity> items);
void saveCompanyComplianceHistoryAll(List<CompanyComplianceEntity> items); // void saveCompanyComplianceHistoryAll(List<CompanyComplianceEntity> items);
} }

파일 보기

@ -20,7 +20,7 @@ public class CompanyComplianceRepositoryImpl extends BaseJdbcRepository<CompanyC
@Override @Override
protected String getTableName() { protected String getTableName() {
return null; return "t_snp_data.tb_company_compliance_info";
} }
@Override @Override
@ -40,35 +40,18 @@ public class CompanyComplianceRepositoryImpl extends BaseJdbcRepository<CompanyC
@Override @Override
protected String getUpdateSql() { protected String getUpdateSql() {
return null;
}
protected String getUpdateSql(String targetTable, String targetIndex) {
return """ return """
INSERT INTO new_snp.%s( INSERT INTO %s(
owcode, lastupdated, owcode, lastupdated,
companyoverallcompliancestatus, companyonaustraliansanctionlist, companyonbessanctionlist, companyoncanadiansanctionlist, companyinofacsanctionedcountry, companyoverallcompliancestatus, companyonaustraliansanctionlist, companyonbessanctionlist, companyoncanadiansanctionlist, companyinofacsanctionedcountry,
companyinfatfjurisdiction, companyoneusanctionlist, companyonofacsanctionlist, companyonofacnonsdnsanctionlist, companyonofacssilist, companyinfatfjurisdiction, companyoneusanctionlist, companyonofacsanctionlist, companyonofacnonsdnsanctionlist, companyonofacssilist,
companyonswisssanctionlist, companyonuaesanctionlist, companyonunsanctionlist, parentcompanycompliancerisk companyonswisssanctionlist, companyonuaesanctionlist, companyonunsanctionlist, parentcompanycompliancerisk,
job_execution_id, created_by
)VALUES( )VALUES(
?, ?::timestamp, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ?, ?::timestamp, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
)ON CONFLICT (%s) ?, ?
DO UPDATE SET );
companyoverallcompliancestatus = EXCLUDED.companyoverallcompliancestatus, """.formatted(getTableName());
companyonaustraliansanctionlist = EXCLUDED.companyonaustraliansanctionlist,
companyonbessanctionlist = EXCLUDED.companyonbessanctionlist,
companyoncanadiansanctionlist = EXCLUDED.companyoncanadiansanctionlist,
companyinofacsanctionedcountry = EXCLUDED.companyinofacsanctionedcountry,
companyinfatfjurisdiction = EXCLUDED.companyinfatfjurisdiction,
companyoneusanctionlist = EXCLUDED.companyoneusanctionlist,
companyonofacsanctionlist = EXCLUDED.companyonofacsanctionlist,
companyonofacnonsdnsanctionlist = EXCLUDED.companyonofacnonsdnsanctionlist,
companyonofacssilist = EXCLUDED.companyonofacssilist,
companyonswisssanctionlist = EXCLUDED.companyonswisssanctionlist,
companyonuaesanctionlist = EXCLUDED.companyonuaesanctionlist,
companyonunsanctionlist = EXCLUDED.companyonunsanctionlist,
parentcompanycompliancerisk = EXCLUDED.parentcompanycompliancerisk
""".formatted(targetTable, targetIndex);
} }
@Override @Override
@ -94,6 +77,8 @@ public class CompanyComplianceRepositoryImpl extends BaseJdbcRepository<CompanyC
ps.setObject(idx++, entity.getCompanyOnUAESanctionList(), Types.INTEGER); ps.setObject(idx++, entity.getCompanyOnUAESanctionList(), Types.INTEGER);
ps.setObject(idx++, entity.getCompanyOnUNSanctionList(), Types.INTEGER); ps.setObject(idx++, entity.getCompanyOnUNSanctionList(), Types.INTEGER);
ps.setObject(idx++, entity.getParentCompanyNonCompliance(), Types.INTEGER); ps.setObject(idx++, entity.getParentCompanyNonCompliance(), Types.INTEGER);
ps.setObject(idx++, entity.getJobExecutionId(), Types.INTEGER);
ps.setString(idx++, entity.getCreatedBy());
} }
@Override @Override
@ -106,7 +91,7 @@ public class CompanyComplianceRepositoryImpl extends BaseJdbcRepository<CompanyC
if (items == null || items.isEmpty()) { if (items == null || items.isEmpty()) {
return; return;
} }
jdbcTemplate.batchUpdate(getUpdateSql("tb_company_compliance_info", "owcode"), items, items.size(), jdbcTemplate.batchUpdate(getUpdateSql(), items, items.size(),
(ps, entity) -> { (ps, entity) -> {
try { try {
setUpdateParameters(ps, entity); setUpdateParameters(ps, entity);
@ -118,20 +103,4 @@ public class CompanyComplianceRepositoryImpl extends BaseJdbcRepository<CompanyC
log.info("{} 전체 저장 완료: 수정={} 건", getEntityName(), items.size()); log.info("{} 전체 저장 완료: 수정={} 건", getEntityName(), items.size());
} }
@Override
public void saveCompanyComplianceHistoryAll(List<CompanyComplianceEntity> items) {
if (items == null || items.isEmpty()) {
return;
}
jdbcTemplate.batchUpdate(getUpdateSql("tb_company_compliance_hstry", "owcode, lastupdated"), items, items.size(),
(ps, entity) -> {
try {
setUpdateParameters(ps, entity);
} catch (Exception e) {
log.error("배치 수정 파라미터 설정 실패", e);
throw new RuntimeException(e);
}
});
log.info("{} 전체 저장 완료: 수정={} 건", getEntityName(), items.size());
}
} }

파일 보기

@ -6,5 +6,5 @@ import java.util.List;
public interface ComplianceRepository { public interface ComplianceRepository {
void saveComplianceAll(List<ComplianceEntity> items); void saveComplianceAll(List<ComplianceEntity> items);
void saveComplianceHistoryAll(List<ComplianceEntity> items); // void saveComplianceHistoryAll(List<ComplianceEntity> items);
} }

파일 보기

@ -21,7 +21,7 @@ public class ComplianceRepositoryImpl extends BaseJdbcRepository<ComplianceEntit
@Override @Override
protected String getTableName() { protected String getTableName() {
return null; return "t_snp_data.compliance";
} }
@Override @Override
@ -41,12 +41,8 @@ public class ComplianceRepositoryImpl extends BaseJdbcRepository<ComplianceEntit
@Override @Override
protected String getUpdateSql() { protected String getUpdateSql() {
return null;
}
protected String getUpdateSql(String targetTable, String targetIndex) {
return """ return """
INSERT INTO new_snp.%s ( INSERT INTO %s (
lrimoshipno, dateamended, legaloverall, shipbessanctionlist, shipdarkactivityindicator, lrimoshipno, dateamended, legaloverall, shipbessanctionlist, shipdarkactivityindicator,
shipdetailsnolongermaintained, shipeusanctionlist, shipflagdisputed, shipflagsanctionedcountry, shipdetailsnolongermaintained, shipeusanctionlist, shipflagdisputed, shipflagsanctionedcountry,
shiphistoricalflagsanctionedcountry, shipofacnonsdnsanctionlist, shipofacsanctionlist, shiphistoricalflagsanctionedcountry, shipofacnonsdnsanctionlist, shipofacsanctionlist,
@ -57,47 +53,14 @@ public class ComplianceRepositoryImpl extends BaseJdbcRepository<ComplianceEntit
shipownerswisssanctionlist, shipowneruaesanctionlist, shipownerunsanctionlist, shipownerswisssanctionlist, shipowneruaesanctionlist, shipownerunsanctionlist,
shipsanctionedcountryportcalllast12m, shipsanctionedcountryportcalllast3m, shipsanctionedcountryportcalllast6m, shipsanctionedcountryportcalllast12m, shipsanctionedcountryportcalllast3m, shipsanctionedcountryportcalllast6m,
shipsecuritylegaldisputeevent, shipstspartnernoncompliancelast12m, shipswisssanctionlist, shipsecuritylegaldisputeevent, shipstspartnernoncompliancelast12m, shipswisssanctionlist,
shipunsanctionlist shipunsanctionlist,
job_execution_id, created_by
) )
VALUES ( VALUES (
?, ?::timestamptz, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ?, ?::timestamptz, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
) ?, ?
ON CONFLICT (%s) );
DO UPDATE SET """.formatted(getTableName());
legaloverall = EXCLUDED.legaloverall,
shipbessanctionlist = EXCLUDED.shipbessanctionlist,
shipdarkactivityindicator = EXCLUDED.shipdarkactivityindicator,
shipdetailsnolongermaintained = EXCLUDED.shipdetailsnolongermaintained,
shipeusanctionlist = EXCLUDED.shipeusanctionlist,
shipflagdisputed = EXCLUDED.shipflagdisputed,
shipflagsanctionedcountry = EXCLUDED.shipflagsanctionedcountry,
shiphistoricalflagsanctionedcountry = EXCLUDED.shiphistoricalflagsanctionedcountry,
shipofacnonsdnsanctionlist = EXCLUDED.shipofacnonsdnsanctionlist,
shipofacsanctionlist = EXCLUDED.shipofacsanctionlist,
shipofacadvisorylist = EXCLUDED.shipofacadvisorylist,
shipownerofacssilist = EXCLUDED.shipownerofacssilist,
shipowneraustraliansanctionlist = EXCLUDED.shipowneraustraliansanctionlist,
shipownerbessanctionlist = EXCLUDED.shipownerbessanctionlist,
shipownercanadiansanctionlist = EXCLUDED.shipownercanadiansanctionlist,
shipownereusanctionlist = EXCLUDED.shipownereusanctionlist,
shipownerfatfjurisdiction = EXCLUDED.shipownerfatfjurisdiction,
shipownerhistoricalofacsanctionedcountry = EXCLUDED.shipownerhistoricalofacsanctionedcountry,
shipownerofacsanctionlist = EXCLUDED.shipownerofacsanctionlist,
shipownerofacsanctionedcountry = EXCLUDED.shipownerofacsanctionedcountry,
shipownerparentcompanynoncompliance = EXCLUDED.shipownerparentcompanynoncompliance,
shipownerparentfatfjurisdiction = EXCLUDED.shipownerparentfatfjurisdiction,
shipownerparentofacsanctionedcountry = EXCLUDED.shipownerparentofacsanctionedcountry,
shipownerswisssanctionlist = EXCLUDED.shipownerswisssanctionlist,
shipowneruaesanctionlist = EXCLUDED.shipowneruaesanctionlist,
shipownerunsanctionlist = EXCLUDED.shipownerunsanctionlist,
shipsanctionedcountryportcalllast12m = EXCLUDED.shipsanctionedcountryportcalllast12m,
shipsanctionedcountryportcalllast3m = EXCLUDED.shipsanctionedcountryportcalllast3m,
shipsanctionedcountryportcalllast6m = EXCLUDED.shipsanctionedcountryportcalllast6m,
shipsecuritylegaldisputeevent = EXCLUDED.shipsecuritylegaldisputeevent,
shipstspartnernoncompliancelast12m = EXCLUDED.shipstspartnernoncompliancelast12m,
shipswisssanctionlist = EXCLUDED.shipswisssanctionlist,
shipunsanctionlist = EXCLUDED.shipunsanctionlist
""".formatted(targetTable, targetIndex);
} }
@Override @Override
@ -143,6 +106,8 @@ public class ComplianceRepositoryImpl extends BaseJdbcRepository<ComplianceEntit
ps.setObject(idx++, entity.getShipSTSPartnerNonComplianceLast12m(), Types.INTEGER); ps.setObject(idx++, entity.getShipSTSPartnerNonComplianceLast12m(), Types.INTEGER);
ps.setObject(idx++, entity.getShipSwissSanctionList(), Types.INTEGER); ps.setObject(idx++, entity.getShipSwissSanctionList(), Types.INTEGER);
ps.setObject(idx++, entity.getShipUNSanctionList(), Types.INTEGER); ps.setObject(idx++, entity.getShipUNSanctionList(), Types.INTEGER);
ps.setObject(idx++, entity.getJobExecutionId(), Types.INTEGER);
ps.setString(idx++, entity.getCreatedBy());
} }
@Override @Override
@ -155,24 +120,7 @@ public class ComplianceRepositoryImpl extends BaseJdbcRepository<ComplianceEntit
if (items == null || items.isEmpty()) { if (items == null || items.isEmpty()) {
return; return;
} }
jdbcTemplate.batchUpdate(getUpdateSql("compliance", "lrimoshipno"), items, items.size(), jdbcTemplate.batchUpdate(getUpdateSql(), items, items.size(),
(ps, entity) -> {
try {
setUpdateParameters(ps, entity);
} catch (Exception e) {
log.error("배치 수정 파라미터 설정 실패", e);
throw new RuntimeException(e);
}
});
log.info("{} 전체 저장 완료: 수정={} 건", getEntityName(), items.size());
}
@Override
public void saveComplianceHistoryAll(List<ComplianceEntity> items) {
if (items == null || items.isEmpty()) {
return;
}
jdbcTemplate.batchUpdate(getUpdateSql("compliance_history", "lrimoshipno, dateamended"), items, items.size(),
(ps, entity) -> { (ps, entity) -> {
try { try {
setUpdateParameters(ps, entity); setUpdateParameters(ps, entity);

파일 보기

@ -20,6 +20,6 @@ public class CompanyComplianceDataWriter extends BaseWriter<CompanyComplianceEnt
@Override @Override
protected void writeItems(List<CompanyComplianceEntity> items) throws Exception { protected void writeItems(List<CompanyComplianceEntity> items) throws Exception {
complianceRepository.saveCompanyComplianceAll(items); complianceRepository.saveCompanyComplianceAll(items);
complianceRepository.saveCompanyComplianceHistoryAll(items); // complianceRepository.saveCompanyComplianceHistoryAll(items);
} }
} }

파일 보기

@ -19,6 +19,6 @@ public class ComplianceDataWriter extends BaseWriter<ComplianceEntity> {
@Override @Override
protected void writeItems(List<ComplianceEntity> items) throws Exception { protected void writeItems(List<ComplianceEntity> items) throws Exception {
complianceRepository.saveComplianceAll(items); complianceRepository.saveComplianceAll(items);
complianceRepository.saveComplianceHistoryAll(items); // complianceRepository.saveComplianceHistoryAll(items);
} }
} }

파일 보기

@ -44,7 +44,7 @@ public class EventImportJobConfig extends BaseMultiStepJobConfig<EventDetailDto,
protected String getApiKey() {return "EVENT_IMPORT_API";} protected String getApiKey() {return "EVENT_IMPORT_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_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() {
@ -109,6 +109,14 @@ public class EventImportJobConfig extends BaseMultiStepJobConfig<EventDetailDto,
return eventDataProcessor; return eventDataProcessor;
} }
@Bean
@StepScope
public EventDataProcessor eventDataProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId
){
return new EventDataProcessor(jobExecutionId);
}
@Override @Override
protected ItemWriter<EventDetailEntity> createWriter() { return eventDataWriter; } protected ItemWriter<EventDetailEntity> createWriter() { return eventDataWriter; }

파일 보기

@ -1,12 +1,17 @@
package com.snp.batch.jobs.event.batch.processor; package com.snp.batch.jobs.event.batch.processor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.processor.BaseProcessor; import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.event.batch.dto.CargoDto; import com.snp.batch.jobs.event.batch.dto.CargoDto;
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.dto.HumanCasualtyDto; import com.snp.batch.jobs.event.batch.dto.HumanCasualtyDto;
import com.snp.batch.jobs.event.batch.dto.RelationshipDto; import com.snp.batch.jobs.event.batch.dto.RelationshipDto;
import com.snp.batch.jobs.event.batch.entity.CargoEntity;
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.entity.HumanCasualtyEntity;
import com.snp.batch.jobs.event.batch.entity.RelationshipEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -14,6 +19,12 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
@Component @Component
public class EventDataProcessor extends BaseProcessor<EventDetailDto, EventDetailEntity> { public class EventDataProcessor extends BaseProcessor<EventDetailDto, EventDetailEntity> {
private static Long jobExecutionId;
public EventDataProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId
) {
this.jobExecutionId = jobExecutionId;
}
@Override @Override
protected EventDetailEntity processItem(EventDetailDto dto) throws Exception { protected EventDetailEntity processItem(EventDetailDto dto) throws Exception {
log.debug("Event 데이터 처리 시작: Event ID = {}", dto.getEventID()); log.debug("Event 데이터 처리 시작: Event ID = {}", dto.getEventID());
@ -61,12 +72,20 @@ public class EventDataProcessor extends BaseProcessor<EventDetailDto, EventDetai
.firedUpon(dto.getFiredUpon()) .firedUpon(dto.getFiredUpon())
.eventStartDate(dto.getEventStartDate()) .eventStartDate(dto.getEventStartDate())
.eventEndDate(dto.getEventEndDate()) .eventEndDate(dto.getEventEndDate())
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.cargoes(dto.getCargoes() != null ? .cargoes(dto.getCargoes() != null ?
dto.getCargoes().stream().map(CargoDto::toEntity).collect(Collectors.toList()) : null) dto.getCargoes().stream()
.map(d -> (CargoEntity) d.toEntity().setBatchInfo(jobExecutionId, "SYSTEM"))
.collect(Collectors.toList()) : null)
.humanCasualties(dto.getHumanCasualties() != null ? .humanCasualties(dto.getHumanCasualties() != null ?
dto.getHumanCasualties().stream().map(HumanCasualtyDto::toEntity).collect(Collectors.toList()) : null) dto.getHumanCasualties().stream()
.map(d -> (HumanCasualtyEntity) d.toEntity().setBatchInfo(jobExecutionId, "SYSTEM"))
.collect(Collectors.toList()) : null)
.relationships(dto.getRelationships() != null ? .relationships(dto.getRelationships() != null ?
dto.getRelationships().stream().map(RelationshipDto::toEntity).collect(Collectors.toList()) : null) dto.getRelationships().stream()
.map(d -> (RelationshipEntity) d.toEntity().setBatchInfo(jobExecutionId, "SYSTEM"))
.collect(Collectors.toList()) : null)
.build(); .build();
log.debug("Event 데이터 처리 완료: Event ID = {}", dto.getEventID()); log.debug("Event 데이터 처리 완료: Event ID = {}", dto.getEventID());

파일 보기

@ -182,6 +182,8 @@ public class EventRepositoryImpl extends BaseJdbcRepository<EventDetailEntity, L
ps.setString(idx++, entity.getVesselName()); // vessel_name (누락됨) ps.setString(idx++, entity.getVesselName()); // vessel_name (누락됨)
ps.setString(idx++, entity.getVesselType()); // vessel_type (누락됨) ps.setString(idx++, entity.getVesselType()); // vessel_type (누락됨)
ps.setString(idx++, entity.getVesselTypeDecode()); // vessel_type_decode ps.setString(idx++, entity.getVesselTypeDecode()); // vessel_type_decode
ps.setObject(idx++, entity.getJobExecutionId(), Types.INTEGER);
ps.setString(idx++, entity.getCreatedBy());
} }
private void setCargoInsertParameters(PreparedStatement ps, CargoEntity entity)throws Exception{ private void setCargoInsertParameters(PreparedStatement ps, CargoEntity entity)throws Exception{
int idx = 1; int idx = 1;
@ -196,6 +198,8 @@ public class EventRepositoryImpl extends BaseJdbcRepository<EventDetailEntity, L
ps.setString(idx++, entity.getCargoDamage()); ps.setString(idx++, entity.getCargoDamage());
ps.setString(idx++, entity.getDangerous()); ps.setString(idx++, entity.getDangerous());
ps.setString(idx++, entity.getText()); ps.setString(idx++, entity.getText());
ps.setObject(idx++, entity.getJobExecutionId(), Types.INTEGER);
ps.setString(idx++, entity.getCreatedBy());
} }
private void setHumanCasualtyInsertParameters(PreparedStatement ps, HumanCasualtyEntity entity)throws Exception{ private void setHumanCasualtyInsertParameters(PreparedStatement ps, HumanCasualtyEntity entity)throws Exception{
int idx = 1; int idx = 1;
@ -204,6 +208,8 @@ public class EventRepositoryImpl extends BaseJdbcRepository<EventDetailEntity, L
ps.setString(idx++, entity.getType()); ps.setString(idx++, entity.getType());
ps.setString(idx++, entity.getQualifier()); ps.setString(idx++, entity.getQualifier());
ps.setObject(idx++, entity.getCount()); ps.setObject(idx++, entity.getCount());
ps.setObject(idx++, entity.getJobExecutionId(), Types.INTEGER);
ps.setString(idx++, entity.getCreatedBy());
} }
private void setRelationshipInsertParameters(PreparedStatement ps, RelationshipEntity entity)throws Exception{ private void setRelationshipInsertParameters(PreparedStatement ps, RelationshipEntity entity)throws Exception{
int idx = 1; int idx = 1;
@ -214,6 +220,8 @@ public class EventRepositoryImpl extends BaseJdbcRepository<EventDetailEntity, L
ps.setObject(idx++, entity.getEventID2()); ps.setObject(idx++, entity.getEventID2());
ps.setString(idx++, entity.getEventType()); ps.setString(idx++, entity.getEventType());
ps.setString(idx++, entity.getEventTypeCode()); ps.setString(idx++, entity.getEventTypeCode());
ps.setObject(idx++, entity.getJobExecutionId(), Types.INTEGER);
ps.setString(idx++, entity.getCreatedBy());
} }
private static void setStringOrNull(PreparedStatement ps, int index, String value) throws Exception { private static void setStringOrNull(PreparedStatement ps, int index, String value) throws Exception {

파일 보기

@ -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 ( INSERT INTO t_snp_data.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,
@ -14,109 +14,59 @@ public class EventSql {
pollutant_unit, registered_owner_code_at_time, registered_owner_at_time, pollutant_unit, registered_owner_code_at_time, registered_owner_at_time,
registered_owner_country_code_at_time, registered_owner_country_at_time, registered_owner_country_code_at_time, registered_owner_country_at_time,
vessel_dwt, vessel_flag_code, vessel_flag_decode, vessel_gt, vessel_dwt, vessel_flag_code, vessel_flag_decode, vessel_gt,
vessel_name, vessel_type, vessel_type_decode vessel_name, vessel_type, vessel_type_decode,
job_execution_id, created_by
) )
VALUES ( VALUES (
?, ?, ?, ?::timestamptz,?::timestamptz,?::timestamptz, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?::timestamptz,?::timestamptz,?::timestamptz, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ? ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
) ?, ?
ON CONFLICT (event_id) );
DO UPDATE SET
incident_id = EXCLUDED.incident_id,
ihslrorimoshipno = EXCLUDED.ihslrorimoshipno,
published_date = EXCLUDED.published_date,
event_start_date = EXCLUDED.event_start_date,
event_end_date = EXCLUDED.event_end_date,
attempted_boarding = EXCLUDED.attempted_boarding,
cargo_loading_status_code = EXCLUDED.cargo_loading_status_code,
casualty_action = EXCLUDED.casualty_action,
casualty_zone = EXCLUDED.casualty_zone,
casualty_zone_code = EXCLUDED.casualty_zone_code,
component2 = EXCLUDED.component2,
country_code = EXCLUDED.country_code,
date_of_build = EXCLUDED.date_of_build,
description = EXCLUDED.description,
environment_location = EXCLUDED.environment_location,
location_name = EXCLUDED.location_name,
marsden_grid_reference = EXCLUDED.marsden_grid_reference,
town_name = EXCLUDED.town_name,
event_type = EXCLUDED.event_type,
event_type_detail = EXCLUDED.event_type_detail,
event_type_detail_id = EXCLUDED.event_type_detail_id,
event_type_id = EXCLUDED.event_type_id,
fired_upon = EXCLUDED.fired_upon,
headline = EXCLUDED.headline,
ldt_at_time = EXCLUDED.ldt_at_time,
significance = EXCLUDED.significance,
weather = EXCLUDED.weather,
pollutant = EXCLUDED.pollutant,
pollutant_quantity = EXCLUDED.pollutant_quantity,
pollutant_unit = EXCLUDED.pollutant_unit,
registered_owner_code_at_time = EXCLUDED.registered_owner_code_at_time,
registered_owner_at_time = EXCLUDED.registered_owner_at_time,
registered_owner_country_code_at_time = EXCLUDED.registered_owner_country_code_at_time,
registered_owner_country_at_time = EXCLUDED.registered_owner_country_at_time,
vessel_dwt = EXCLUDED.vessel_dwt,
vessel_flag_code = EXCLUDED.vessel_flag_code,
vessel_flag_decode = EXCLUDED.vessel_flag_decode,
vessel_gt = EXCLUDED.vessel_gt,
vessel_name = EXCLUDED.vessel_name,
vessel_type = EXCLUDED.vessel_type,
vessel_type_decode = EXCLUDED.vessel_type_decode
"""; """;
} }
public static String getEventCargoSql(){ public static String getEventCargoSql(){
return """ return """
INSERT INTO new_snp.event_cargo ( INSERT INTO t_snp_data.event_cargo (
event_id, "sequence", ihslrorimoshipno, "type", quantity, event_id, "sequence", ihslrorimoshipno, "type", quantity,
unit_short, unit, cargo_damage, dangerous, "text" unit_short, unit, cargo_damage, dangerous, "text",
job_execution_id, created_by
) )
VALUES ( VALUES (
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ? ?, ?, ?, ?, ?,
) ?, ?
ON CONFLICT (event_id, ihslrorimoshipno, "type", "sequence") );
DO UPDATE SET
quantity = EXCLUDED.quantity,
unit_short = EXCLUDED.unit_short,
unit = EXCLUDED.unit,
cargo_damage = EXCLUDED.cargo_damage,
dangerous = EXCLUDED.dangerous,
"text" = EXCLUDED."text"
"""; """;
} }
public static String getEventRelationshipSql(){ public static String getEventRelationshipSql(){
return """ return """
INSERT INTO new_snp.event_relationship ( INSERT INTO t_snp_data.event_relationship (
incident_id, event_id, relationship_type, relationship_type_code, incident_id, event_id, relationship_type, relationship_type_code,
event_id_2, event_type, event_type_code event_id_2, event_type, event_type_code,
job_execution_id, created_by
) )
VALUES ( VALUES (
?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ? ?, ?, ?,
) ?, ?
ON CONFLICT (incident_id, event_id, event_id_2, event_type_code, relationship_type_code) );
DO UPDATE SET
relationship_type = EXCLUDED.relationship_type,
event_type = EXCLUDED.event_type
"""; """;
} }
public static String getEventHumanCasualtySql(){ public static String getEventHumanCasualtySql(){
return """ return """
INSERT INTO new_snp.event_humancasualty ( INSERT INTO t_snp_data.event_humancasualty (
event_id, "scope", "type", qualifier, "count" event_id, "scope", "type", qualifier, "count",
job_execution_id, created_by
) )
VALUES ( VALUES (
?, ?, ?, ?, ? ?, ?, ?, ?, ?,
) ?, ?
ON CONFLICT (event_id, "scope", "type", qualifier) );
DO UPDATE SET
"count" = EXCLUDED."count"
"""; """;
} }
} }

파일 보기

@ -6,14 +6,17 @@ import com.snp.batch.jobs.facility.batch.entity.PortEntity;
import com.snp.batch.jobs.facility.batch.processor.PortDataProcessor; import com.snp.batch.jobs.facility.batch.processor.PortDataProcessor;
import com.snp.batch.jobs.facility.batch.reader.PortDataReader; import com.snp.batch.jobs.facility.batch.reader.PortDataReader;
import com.snp.batch.jobs.facility.batch.writer.PortDataWriter; import com.snp.batch.jobs.facility.batch.writer.PortDataWriter;
import com.snp.batch.service.BatchApiLogService;
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.configuration.annotation.StepScope;
import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.JobRepository;
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.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
@ -26,9 +29,12 @@ public class PortImportJobConfig extends BaseJobConfig<PortDto, PortEntity> {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final WebClient maritimeServiceApiWebClient; private final WebClient maritimeServiceApiWebClient;
private final PortDataProcessor portDataProcessor;
private final PortDataWriter portDataWriter; private final PortDataWriter portDataWriter;
private final PortDataReader portDataReader;
private final BatchApiLogService batchApiLogService;
@Value("${app.batch.webservice-api.url}")
private String maritimeServiceApiUrl;
@Override @Override
protected int getChunkSize() { protected int getChunkSize() {
@ -37,46 +43,65 @@ public class PortImportJobConfig extends BaseJobConfig<PortDto, PortEntity> {
public PortImportJobConfig( public PortImportJobConfig(
JobRepository jobRepository, JobRepository jobRepository,
PlatformTransactionManager transactionManager, PlatformTransactionManager transactionManager,
PortDataProcessor portDataProcessor, PortDataReader portDataReader,
PortDataWriter portDataWriter, PortDataWriter portDataWriter,
JdbcTemplate jdbcTemplate, JdbcTemplate jdbcTemplate,
@Qualifier("maritimeServiceApiWebClient")WebClient maritimeServiceApiWebClient) { @Qualifier("maritimeServiceApiWebClient")WebClient maritimeServiceApiWebClient,
BatchApiLogService batchApiLogService) {
super(jobRepository, transactionManager); super(jobRepository, transactionManager);
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.maritimeServiceApiWebClient = maritimeServiceApiWebClient; this.maritimeServiceApiWebClient = maritimeServiceApiWebClient;
this.portDataProcessor = portDataProcessor;
this.portDataWriter = portDataWriter; this.portDataWriter = portDataWriter;
this.portDataReader = portDataReader;
this.batchApiLogService = batchApiLogService;
} }
@Override @Override
protected String getJobName() { protected String getJobName() {
return "portImportJob"; return "PortImportJob";
} }
@Override @Override
protected String getStepName() { protected String getStepName() {
return "portImportStep"; return "PortImportStep";
} }
@Override @Override
protected ItemReader<PortDto> createReader() { protected ItemReader<PortDto> createReader() {
return new PortDataReader(maritimeServiceApiWebClient, jdbcTemplate); return portDataReader;
}
@Bean
@StepScope
public PortDataReader portDataReader(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId, // SpEL로 ID 추출
@Value("#{stepExecution.id}") Long stepExecutionId
) {
PortDataReader reader = new PortDataReader(maritimeServiceApiWebClient, jdbcTemplate, batchApiLogService, maritimeServiceApiUrl);
reader.setExecutionIds(jobExecutionId, stepExecutionId); // ID 세팅
return reader;
} }
@Override @Override
protected ItemProcessor<PortDto, PortEntity> createProcessor() { protected ItemProcessor<PortDto, PortEntity> createProcessor() {
return portDataProcessor; // 2. 메서드 호출 방식으로 변경
return portDataProcessor(null);
}
@Bean
@StepScope
public PortDataProcessor portDataProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
return new PortDataProcessor(jobExecutionId);
} }
@Override @Override
protected ItemWriter<PortEntity> createWriter() { return portDataWriter; } protected ItemWriter<PortEntity> createWriter() { return portDataWriter; }
@Bean(name = "portImportJob") @Bean(name = "PortImportJob")
public Job portImportJob() { public Job portImportJob() {
return job(); return job();
} }
@Bean(name = "portImportStep") @Bean(name = "PortImportStep")
public Step portImportStep() { public Step portImportStep() {
return step(); return step();
} }

파일 보기

@ -4,11 +4,17 @@ import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.facility.batch.dto.PortDto; import com.snp.batch.jobs.facility.batch.dto.PortDto;
import com.snp.batch.jobs.facility.batch.entity.PortEntity; import com.snp.batch.jobs.facility.batch.entity.PortEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Slf4j @Slf4j
@Component @Component
public class PortDataProcessor extends BaseProcessor<PortDto, PortEntity> { public class PortDataProcessor extends BaseProcessor<PortDto, PortEntity> {
private static Long jobExecutionId;
public PortDataProcessor(@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
this.jobExecutionId = jobExecutionId;
}
@Override @Override
protected PortEntity processItem(PortDto dto) throws Exception { protected PortEntity processItem(PortDto dto) throws Exception {
log.debug("Port 데이터 처리 시작: Port ID = {}", dto.getPortId()); log.debug("Port 데이터 처리 시작: Port ID = {}", dto.getPortId());
@ -71,6 +77,8 @@ public class PortDataProcessor extends BaseProcessor<PortDto, PortEntity> {
.freeTradeZone(dto.getFreeTradeZone()) .freeTradeZone(dto.getFreeTradeZone())
.ecoPort(dto.getEcoPort()) .ecoPort(dto.getEcoPort())
.emissionControlArea(dto.getEmissionControlArea()) .emissionControlArea(dto.getEmissionControlArea())
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
log.debug("Port 데이터 처리 완료: Port ID = {}", dto.getPortId()); log.debug("Port 데이터 처리 완료: Port ID = {}", dto.getPortId());

파일 보기

@ -3,6 +3,7 @@ package com.snp.batch.jobs.facility.batch.reader;
import com.snp.batch.common.batch.reader.BaseApiReader; import com.snp.batch.common.batch.reader.BaseApiReader;
import com.snp.batch.jobs.facility.batch.dto.PortDto; import com.snp.batch.jobs.facility.batch.dto.PortDto;
import com.snp.batch.jobs.shipimport.batch.dto.ShipApiResponse; import com.snp.batch.jobs.shipimport.batch.dto.ShipApiResponse;
import com.snp.batch.service.BatchApiLogService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ParameterizedTypeReference;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
@ -17,11 +18,14 @@ public class PortDataReader extends BaseApiReader<PortDto> {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private List<String> allImoNumbers; private List<String> allImoNumbers;
private int currentBatchIndex = 0; private int currentBatchIndex = 0;
private final int batchSize = 100; private final int batchSize = 5000;
private final BatchApiLogService batchApiLogService;
public PortDataReader(WebClient webClient, JdbcTemplate jdbcTemplate) { String maritimeServiceApiUrl;
public PortDataReader(WebClient webClient, JdbcTemplate jdbcTemplate, BatchApiLogService batchApiLogService, String maritimeServiceApiUrl) {
super(webClient); super(webClient);
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.batchApiLogService = batchApiLogService;
this.maritimeServiceApiUrl = maritimeServiceApiUrl;
} }
@Override @Override
@ -57,13 +61,12 @@ public class PortDataReader extends BaseApiReader<PortDto> {
} }
private List<PortDto> callFacilityPortApiWithBatch() { private List<PortDto> callFacilityPortApiWithBatch() {
String url = getApiPath(); return executeListApiCall(
log.debug("[{}] API 호출: {}", getReaderName(), url); maritimeServiceApiUrl,
return webClient.get() getApiPath(),
.uri(url) new ParameterizedTypeReference<List<PortDto>>() {},
.retrieve() batchApiLogService
.bodyToMono(new ParameterizedTypeReference<List<PortDto>>() {}) );
.block();
} }
} }

파일 보기

@ -21,7 +21,7 @@ public class FacilityRepositoryImpl extends BaseJdbcRepository<PortEntity, Long>
@Override @Override
protected String getTableName() { protected String getTableName() {
return null; return "t_snp_data.facility_port";
} }
@Override @Override
@ -42,73 +42,24 @@ public class FacilityRepositoryImpl extends BaseJdbcRepository<PortEntity, Long>
@Override @Override
protected String getUpdateSql() { protected String getUpdateSql() {
return """ return """
INSERT INTO snp_data.facility_port ( INSERT INTO %s(
port_ID, old_ID, status, port_Name, unlocode, countryCode, country_Name, region_Name, continent_Name, master_POID, port_ID, old_ID, status, port_Name, unlocode, countryCode, country_Name, region_Name, continent_Name, master_POID,
dec_Lat, dec_Long, position_lat, position_long, position_z, position_m, position_hasZ, position_hasM, position_isNull, position_stSrid, time_Zone, dayLight_Saving_Time, dec_Lat, dec_Long, position_lat, position_long, position_z, position_m, position_hasZ, position_hasM, position_isNull, position_stSrid, time_Zone, dayLight_Saving_Time,
maximum_Draft, max_LOA, max_Beam, max_DWT, max_Offshore_Draught, max_Offshore_LOA, max_Offshore_BCM, max_Offshore_DWT, maximum_Draft, max_LOA, max_Beam, max_DWT, max_Offshore_Draught, max_Offshore_LOA, max_Offshore_BCM, max_Offshore_DWT,
breakbulk_Facilities, container_Facilities, dry_Bulk_Facilities, liquid_Facilities, roRo_Facilities, passenger_Facilities, dry_Dock_Facilities, breakbulk_Facilities, container_Facilities, dry_Bulk_Facilities, liquid_Facilities, roRo_Facilities, passenger_Facilities, dry_Dock_Facilities,
lpG_Facilities, lnG_Facilities, lnG_Bunker, dO_Bunker, fO_Bunker, ispS_Compliant, csI_Compliant, free_Trade_Zone, ecO_Port, emission_Control_Area, wS_Port, lpG_Facilities, lnG_Facilities, lnG_Bunker, dO_Bunker, fO_Bunker, ispS_Compliant, csI_Compliant, free_Trade_Zone, ecO_Port, emission_Control_Area, wS_Port,
last_Update, entry_Date, batch_flag last_Update, entry_Date,
job_execution_id, created_by
) VALUES ( ) VALUES (
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?::timestamptz, ?::timestamptz, 'N' ?::timestamptz, ?::timestamptz,
) ON CONFLICT (port_ID) DO UPDATE ?, ?
SET );
old_ID = EXCLUDED.old_ID, """.formatted(getTableName());
status = EXCLUDED.status,
port_Name = EXCLUDED.port_Name,
unlocode = EXCLUDED.unlocode,
countryCode = EXCLUDED.countryCode,
country_Name = EXCLUDED.country_Name,
region_Name = EXCLUDED.region_Name,
continent_Name = EXCLUDED.continent_Name,
master_POID = EXCLUDED.master_POID,
dec_Lat = EXCLUDED.dec_Lat,
dec_Long = EXCLUDED.dec_Long,
position_lat = EXCLUDED.position_lat,
position_long = EXCLUDED.position_long,
position_z = EXCLUDED.position_z,
position_m = EXCLUDED.position_m,
position_hasZ = EXCLUDED.position_hasZ,
position_hasM = EXCLUDED.position_hasM,
position_isNull = EXCLUDED.position_isNull,
position_stSrid = EXCLUDED.position_stSrid,
time_Zone = EXCLUDED.time_Zone,
dayLight_Saving_Time = EXCLUDED.dayLight_Saving_Time,
maximum_Draft = EXCLUDED.maximum_Draft,
max_LOA = EXCLUDED.max_LOA,
max_Beam = EXCLUDED.max_Beam,
max_DWT = EXCLUDED.max_DWT,
max_Offshore_Draught = EXCLUDED.max_Offshore_Draught,
max_Offshore_LOA = EXCLUDED.max_Offshore_LOA,
max_Offshore_BCM = EXCLUDED.max_Offshore_BCM,
max_Offshore_DWT = EXCLUDED.max_Offshore_DWT,
breakbulk_Facilities = EXCLUDED.breakbulk_Facilities,
container_Facilities = EXCLUDED.container_Facilities,
dry_Bulk_Facilities = EXCLUDED.dry_Bulk_Facilities,
liquid_Facilities = EXCLUDED.liquid_Facilities,
roRo_Facilities = EXCLUDED.roRo_Facilities,
passenger_Facilities = EXCLUDED.passenger_Facilities,
dry_Dock_Facilities = EXCLUDED.dry_Dock_Facilities,
lpG_Facilities = EXCLUDED.lpG_Facilities,
lnG_Facilities = EXCLUDED.lnG_Facilities,
lnG_Bunker = EXCLUDED.lnG_Bunker,
dO_Bunker = EXCLUDED.dO_Bunker,
fO_Bunker = EXCLUDED.fO_Bunker,
ispS_Compliant = EXCLUDED.ispS_Compliant,
csI_Compliant = EXCLUDED.csI_Compliant,
free_Trade_Zone = EXCLUDED.free_Trade_Zone,
ecO_Port = EXCLUDED.ecO_Port,
emission_Control_Area = EXCLUDED.emission_Control_Area,
wS_Port = EXCLUDED.wS_Port,
last_Update = EXCLUDED.last_Update,
entry_Date = EXCLUDED.entry_Date,
batch_flag = 'N'
""";
} }
@Override @Override
@ -176,6 +127,8 @@ public class FacilityRepositoryImpl extends BaseJdbcRepository<PortEntity, Long>
setIntegerOrNull(ps, idx++, entity.getWsPort()); // 원본 위치: 마지막 부분 (INT8에 맞게 setLongOrNull 사용 가정) setIntegerOrNull(ps, idx++, entity.getWsPort()); // 원본 위치: 마지막 부분 (INT8에 맞게 setLongOrNull 사용 가정)
ps.setString(idx++, entity.getLastUpdate()); // String 대신 Timestamp 타입이 JDBC 표준에 적합합니다. ps.setString(idx++, entity.getLastUpdate()); // String 대신 Timestamp 타입이 JDBC 표준에 적합합니다.
ps.setString(idx++, entity.getEntryDate()); // String 대신 Timestamp 타입이 JDBC 표준에 적합합니다. ps.setString(idx++, entity.getEntryDate()); // String 대신 Timestamp 타입이 JDBC 표준에 적합합니다.
ps.setObject(idx++, entity.getJobExecutionId(), Types.INTEGER);
ps.setString(idx++, entity.getCreatedBy());
} }
@Override @Override

파일 보기

@ -1,5 +1,6 @@
package com.snp.batch.jobs.movement.batch.config; package com.snp.batch.jobs.movement.batch.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.config.BaseMultiStepJobConfig; import com.snp.batch.common.batch.config.BaseMultiStepJobConfig;
import com.snp.batch.jobs.movement.batch.dto.AnchorageCallsDto; import com.snp.batch.jobs.movement.batch.dto.AnchorageCallsDto;
import com.snp.batch.jobs.movement.batch.entity.AnchorageCallsEntity; import com.snp.batch.jobs.movement.batch.entity.AnchorageCallsEntity;
@ -39,12 +40,13 @@ public class AnchorageCallsRangeJobConfig extends BaseMultiStepJobConfig<Anchora
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final BatchDateService batchDateService; private final BatchDateService batchDateService;
private final BatchApiLogService batchApiLogService; private final BatchApiLogService batchApiLogService;
private final ObjectMapper objectMapper;
@Value("${app.batch.webservice-api.url}") @Value("${app.batch.webservice-api.url}")
private String maritimeServiceApiUrl; private String maritimeServiceApiUrl;
protected String getApiKey() {return "ANCHORAGE_CALLS_IMPORT_API";} protected String getApiKey() {return "ANCHORAGE_CALLS_IMPORT_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
public AnchorageCallsRangeJobConfig( public AnchorageCallsRangeJobConfig(
@ -56,7 +58,8 @@ public class AnchorageCallsRangeJobConfig extends BaseMultiStepJobConfig<Anchora
@Qualifier("maritimeServiceApiWebClient")WebClient maritimeServiceApiWebClient, @Qualifier("maritimeServiceApiWebClient")WebClient maritimeServiceApiWebClient,
JdbcTemplate jdbcTemplate, JdbcTemplate jdbcTemplate,
BatchDateService batchDateService, BatchDateService batchDateService,
BatchApiLogService batchApiLogService BatchApiLogService batchApiLogService,
ObjectMapper objectMapper
) { ) {
super(jobRepository, transactionManager); super(jobRepository, transactionManager);
this.anchorageCallsProcessor = anchorageCallsProcessor; this.anchorageCallsProcessor = anchorageCallsProcessor;
@ -66,6 +69,7 @@ public class AnchorageCallsRangeJobConfig extends BaseMultiStepJobConfig<Anchora
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.batchDateService = batchDateService; this.batchDateService = batchDateService;
this.batchApiLogService = batchApiLogService; this.batchApiLogService = batchApiLogService;
this.objectMapper = objectMapper;
} }
@Override @Override
@ -106,6 +110,14 @@ public class AnchorageCallsRangeJobConfig extends BaseMultiStepJobConfig<Anchora
protected ItemProcessor<AnchorageCallsDto, AnchorageCallsEntity> createProcessor() { protected ItemProcessor<AnchorageCallsDto, AnchorageCallsEntity> createProcessor() {
return anchorageCallsProcessor; return anchorageCallsProcessor;
} }
@Bean
@StepScope
public AnchorageCallsProcessor anchorageCallsProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper
) {
return new AnchorageCallsProcessor(jobExecutionId, objectMapper);
}
@Override @Override
protected ItemWriter<AnchorageCallsEntity> createWriter() { // 타입 변경 protected ItemWriter<AnchorageCallsEntity> createWriter() { // 타입 변경

파일 보기

@ -1,5 +1,6 @@
package com.snp.batch.jobs.movement.batch.config; package com.snp.batch.jobs.movement.batch.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.config.BaseMultiStepJobConfig; import com.snp.batch.common.batch.config.BaseMultiStepJobConfig;
import com.snp.batch.jobs.movement.batch.dto.BerthCallsDto; import com.snp.batch.jobs.movement.batch.dto.BerthCallsDto;
import com.snp.batch.jobs.movement.batch.entity.BerthCallsEntity; import com.snp.batch.jobs.movement.batch.entity.BerthCallsEntity;
@ -44,7 +45,7 @@ public class BerthCallsRangJobConfig extends BaseMultiStepJobConfig<BerthCallsDt
private String maritimeServiceApiUrl; private String maritimeServiceApiUrl;
protected String getApiKey() {return "BERTH_CALLS_IMPORT_API";} protected String getApiKey() {return "BERTH_CALLS_IMPORT_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
public BerthCallsRangJobConfig( public BerthCallsRangJobConfig(
JobRepository jobRepository, JobRepository jobRepository,
@ -104,6 +105,15 @@ public class BerthCallsRangJobConfig extends BaseMultiStepJobConfig<BerthCallsDt
return berthCallsProcessor; return berthCallsProcessor;
} }
@Bean
@StepScope
public BerthCallsProcessor berthCallsProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper
) {
return new BerthCallsProcessor(jobExecutionId, objectMapper);
}
@Override @Override
protected ItemWriter<BerthCallsEntity> createWriter() { protected ItemWriter<BerthCallsEntity> createWriter() {
return berthCallsWriter; return berthCallsWriter;

파일 보기

@ -1,5 +1,6 @@
package com.snp.batch.jobs.movement.batch.config; package com.snp.batch.jobs.movement.batch.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.config.BaseMultiStepJobConfig; import com.snp.batch.common.batch.config.BaseMultiStepJobConfig;
import com.snp.batch.jobs.movement.batch.dto.CurrentlyAtDto; import com.snp.batch.jobs.movement.batch.dto.CurrentlyAtDto;
import com.snp.batch.jobs.movement.batch.entity.CurrentlyAtEntity; import com.snp.batch.jobs.movement.batch.entity.CurrentlyAtEntity;
@ -44,7 +45,7 @@ public class CurrentlyAtRangeJobConfig extends BaseMultiStepJobConfig<CurrentlyA
private String maritimeServiceApiUrl; private String maritimeServiceApiUrl;
protected String getApiKey() {return "CURRENTLY_AT_IMPORT_API";} protected String getApiKey() {return "CURRENTLY_AT_IMPORT_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
public CurrentlyAtRangeJobConfig( public CurrentlyAtRangeJobConfig(
JobRepository jobRepository, JobRepository jobRepository,
@ -103,7 +104,14 @@ public class CurrentlyAtRangeJobConfig extends BaseMultiStepJobConfig<CurrentlyA
protected ItemProcessor<CurrentlyAtDto, CurrentlyAtEntity> createProcessor() { protected ItemProcessor<CurrentlyAtDto, CurrentlyAtEntity> createProcessor() {
return currentlyAtProcessor; return currentlyAtProcessor;
} }
@Bean
@StepScope
public CurrentlyAtProcessor currentlyAtProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper
) {
return new CurrentlyAtProcessor(jobExecutionId, objectMapper);
}
@Override @Override
protected ItemWriter<CurrentlyAtEntity> createWriter() { // 타입 변경 protected ItemWriter<CurrentlyAtEntity> createWriter() { // 타입 변경
return currentlyAtWriter; return currentlyAtWriter;

파일 보기

@ -1,5 +1,6 @@
package com.snp.batch.jobs.movement.batch.config; package com.snp.batch.jobs.movement.batch.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.config.BaseMultiStepJobConfig; import com.snp.batch.common.batch.config.BaseMultiStepJobConfig;
import com.snp.batch.jobs.movement.batch.dto.DestinationDto; import com.snp.batch.jobs.movement.batch.dto.DestinationDto;
import com.snp.batch.jobs.movement.batch.entity.DestinationEntity; import com.snp.batch.jobs.movement.batch.entity.DestinationEntity;
@ -32,8 +33,8 @@ import org.springframework.web.reactive.function.client.WebClient;
@Configuration @Configuration
public class DestinationsRangeJobConfig extends BaseMultiStepJobConfig<DestinationDto, DestinationEntity> { public class DestinationsRangeJobConfig extends BaseMultiStepJobConfig<DestinationDto, DestinationEntity> {
private final DestinationProcessor DestinationProcessor; private final DestinationProcessor destinationProcessor;
private final DestinationWriter DestinationWriter; private final DestinationWriter destinationWriter;
private final DestinationRangeReader destinationRangeReader; private final DestinationRangeReader destinationRangeReader;
private final WebClient maritimeApiWebClient; private final WebClient maritimeApiWebClient;
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
@ -44,14 +45,14 @@ public class DestinationsRangeJobConfig extends BaseMultiStepJobConfig<Destinati
private String maritimeServiceApiUrl; private String maritimeServiceApiUrl;
protected String getApiKey() {return "DESTINATIONS_IMPORT_API";} protected String getApiKey() {return "DESTINATIONS_IMPORT_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
public DestinationsRangeJobConfig( public DestinationsRangeJobConfig(
JobRepository jobRepository, JobRepository jobRepository,
PlatformTransactionManager transactionManager, PlatformTransactionManager transactionManager,
DestinationProcessor DestinationProcessor, DestinationProcessor destinationProcessor,
DestinationWriter DestinationWriter, DestinationWriter destinationWriter,
DestinationRangeReader destinationRangeReader, DestinationRangeReader destinationRangeReader,
@Qualifier("maritimeServiceApiWebClient") WebClient maritimeApiWebClient, @Qualifier("maritimeServiceApiWebClient") WebClient maritimeApiWebClient,
JdbcTemplate jdbcTemplate, JdbcTemplate jdbcTemplate,
@ -59,8 +60,8 @@ public class DestinationsRangeJobConfig extends BaseMultiStepJobConfig<Destinati
BatchApiLogService batchApiLogService BatchApiLogService batchApiLogService
) { // ObjectMapper 주입 추가 ) { // ObjectMapper 주입 추가
super(jobRepository, transactionManager); super(jobRepository, transactionManager);
this.DestinationProcessor = DestinationProcessor; this.destinationProcessor = destinationProcessor;
this.DestinationWriter = DestinationWriter; this.destinationWriter = destinationWriter;
this.destinationRangeReader = destinationRangeReader; this.destinationRangeReader = destinationRangeReader;
this.maritimeApiWebClient = maritimeApiWebClient; this.maritimeApiWebClient = maritimeApiWebClient;
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
@ -102,12 +103,21 @@ public class DestinationsRangeJobConfig extends BaseMultiStepJobConfig<Destinati
} }
@Override @Override
protected ItemProcessor<DestinationDto, DestinationEntity> createProcessor() { protected ItemProcessor<DestinationDto, DestinationEntity> createProcessor() {
return DestinationProcessor; return destinationProcessor;
}
@Bean
@StepScope
public DestinationProcessor destinationProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper
) {
return new DestinationProcessor(jobExecutionId, objectMapper);
} }
@Override @Override
protected ItemWriter<DestinationEntity> createWriter() { // 타입 변경 protected ItemWriter<DestinationEntity> createWriter() { // 타입 변경
return DestinationWriter; return destinationWriter;
} }
@Override @Override

파일 보기

@ -1,5 +1,6 @@
package com.snp.batch.jobs.movement.batch.config; package com.snp.batch.jobs.movement.batch.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.config.BaseMultiStepJobConfig; import com.snp.batch.common.batch.config.BaseMultiStepJobConfig;
import com.snp.batch.jobs.movement.batch.dto.PortCallsDto; import com.snp.batch.jobs.movement.batch.dto.PortCallsDto;
import com.snp.batch.jobs.movement.batch.entity.PortCallsEntity; import com.snp.batch.jobs.movement.batch.entity.PortCallsEntity;
@ -44,7 +45,7 @@ public class ShipPortCallsRangeJobConfig extends BaseMultiStepJobConfig<PortCall
private String maritimeServiceApiUrl; private String maritimeServiceApiUrl;
protected String getApiKey() {return "PORT_CALLS_IMPORT_API";} protected String getApiKey() {return "PORT_CALLS_IMPORT_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
public ShipPortCallsRangeJobConfig( public ShipPortCallsRangeJobConfig(
JobRepository jobRepository, JobRepository jobRepository,
@ -106,6 +107,15 @@ public class ShipPortCallsRangeJobConfig extends BaseMultiStepJobConfig<PortCall
return portCallsProcessor; return portCallsProcessor;
} }
@Bean
@StepScope
public PortCallsProcessor portCallsProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper
) {
return new PortCallsProcessor(jobExecutionId, objectMapper);
}
@Override @Override
protected ItemWriter<PortCallsEntity> createWriter() { // 타입 변경 protected ItemWriter<PortCallsEntity> createWriter() { // 타입 변경
return portCallsWriter; return portCallsWriter;

파일 보기

@ -1,5 +1,6 @@
package com.snp.batch.jobs.movement.batch.config; package com.snp.batch.jobs.movement.batch.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.config.BaseMultiStepJobConfig; import com.snp.batch.common.batch.config.BaseMultiStepJobConfig;
import com.snp.batch.jobs.movement.batch.dto.StsOperationDto; import com.snp.batch.jobs.movement.batch.dto.StsOperationDto;
import com.snp.batch.jobs.movement.batch.entity.StsOperationEntity; import com.snp.batch.jobs.movement.batch.entity.StsOperationEntity;
@ -44,7 +45,7 @@ public class StsOperationRangeJobConfig extends BaseMultiStepJobConfig<StsOperat
private String maritimeServiceApiUrl; private String maritimeServiceApiUrl;
protected String getApiKey() {return "STS_OPERATION_IMPORT_API";} protected String getApiKey() {return "STS_OPERATION_IMPORT_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
public StsOperationRangeJobConfig( public StsOperationRangeJobConfig(
@ -104,6 +105,14 @@ public class StsOperationRangeJobConfig extends BaseMultiStepJobConfig<StsOperat
protected ItemProcessor<StsOperationDto, StsOperationEntity> createProcessor() { protected ItemProcessor<StsOperationDto, StsOperationEntity> createProcessor() {
return stsOperationProcessor; return stsOperationProcessor;
} }
@Bean
@StepScope
public StsOperationProcessor stsOperationProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper
) {
return new StsOperationProcessor(jobExecutionId, objectMapper);
}
@Override @Override
protected ItemWriter<StsOperationEntity> createWriter() { // 타입 변경 protected ItemWriter<StsOperationEntity> createWriter() { // 타입 변경

파일 보기

@ -1,5 +1,6 @@
package com.snp.batch.jobs.movement.batch.config; package com.snp.batch.jobs.movement.batch.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.config.BaseMultiStepJobConfig; import com.snp.batch.common.batch.config.BaseMultiStepJobConfig;
import com.snp.batch.jobs.movement.batch.dto.TerminalCallsDto; import com.snp.batch.jobs.movement.batch.dto.TerminalCallsDto;
import com.snp.batch.jobs.movement.batch.entity.TerminalCallsEntity; import com.snp.batch.jobs.movement.batch.entity.TerminalCallsEntity;
@ -44,7 +45,7 @@ public class TerminalCallsRangeJobConfig extends BaseMultiStepJobConfig<Terminal
private String maritimeServiceApiUrl; private String maritimeServiceApiUrl;
protected String getApiKey() {return "TERMINAL_CALLS_IMPORT_API";} protected String getApiKey() {return "TERMINAL_CALLS_IMPORT_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
public TerminalCallsRangeJobConfig( public TerminalCallsRangeJobConfig(
@ -104,6 +105,14 @@ public class TerminalCallsRangeJobConfig extends BaseMultiStepJobConfig<Terminal
protected ItemProcessor<TerminalCallsDto, TerminalCallsEntity> createProcessor() { protected ItemProcessor<TerminalCallsDto, TerminalCallsEntity> createProcessor() {
return terminalCallsProcessor; return terminalCallsProcessor;
} }
@Bean
@StepScope
public TerminalCallsProcessor terminalCallsProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper
) {
return new TerminalCallsProcessor(jobExecutionId, objectMapper);
}
@Override @Override
protected ItemWriter<TerminalCallsEntity> createWriter() { // 타입 변경 protected ItemWriter<TerminalCallsEntity> createWriter() { // 타입 변경

파일 보기

@ -44,7 +44,7 @@ public class TransitsRangeJobConfig extends BaseMultiStepJobConfig<TransitsDto,
private String maritimeServiceApiUrl; private String maritimeServiceApiUrl;
protected String getApiKey() {return "TRANSITS_IMPORT_API";} protected String getApiKey() {return "TRANSITS_IMPORT_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
public TransitsRangeJobConfig( public TransitsRangeJobConfig(
JobRepository jobRepository, JobRepository jobRepository,
@ -104,6 +104,14 @@ public class TransitsRangeJobConfig extends BaseMultiStepJobConfig<TransitsDto,
return transitsProcessor; return transitsProcessor;
} }
@Bean
@StepScope
public TransitsProcessor transitsProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId
) {
return new TransitsProcessor(jobExecutionId);
}
@Override @Override
protected ItemWriter<TransitsEntity> createWriter() { // 타입 변경 protected ItemWriter<TransitsEntity> createWriter() { // 타입 변경
return transitsWriter; return transitsWriter;

파일 보기

@ -1,12 +1,10 @@
package com.snp.batch.jobs.movement.batch.entity; package com.snp.batch.jobs.movement.batch.entity;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.GeneratedValue; import com.snp.batch.common.batch.entity.BaseEntity;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.SequenceGenerator;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
@ -16,7 +14,8 @@ import java.time.LocalDateTime;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class AnchorageCallsEntity { @EqualsAndHashCode(callSuper = true)
public class AnchorageCallsEntity extends BaseEntity {
private Long id; private Long id;

파일 보기

@ -1,12 +1,10 @@
package com.snp.batch.jobs.movement.batch.entity; package com.snp.batch.jobs.movement.batch.entity;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.GeneratedValue; import com.snp.batch.common.batch.entity.BaseEntity;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.SequenceGenerator;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
@ -16,7 +14,8 @@ import java.time.LocalDateTime;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class BerthCallsEntity { @EqualsAndHashCode(callSuper = true)
public class BerthCallsEntity extends BaseEntity {
private Long id; private Long id;

파일 보기

@ -1,12 +1,10 @@
package com.snp.batch.jobs.movement.batch.entity; package com.snp.batch.jobs.movement.batch.entity;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.GeneratedValue; import com.snp.batch.common.batch.entity.BaseEntity;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.SequenceGenerator;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
@ -16,7 +14,8 @@ import java.time.LocalDateTime;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class CurrentlyAtEntity { @EqualsAndHashCode(callSuper = true)
public class CurrentlyAtEntity extends BaseEntity {
private String movementType; private String movementType;
private String imolRorIHSNumber; private String imolRorIHSNumber;
private LocalDateTime movementDate; private LocalDateTime movementDate;

파일 보기

@ -1,8 +1,10 @@
package com.snp.batch.jobs.movement.batch.entity; package com.snp.batch.jobs.movement.batch.entity;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.snp.batch.common.batch.entity.BaseEntity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
@ -12,7 +14,8 @@ import java.time.LocalDateTime;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class DarkActivityEntity { @EqualsAndHashCode(callSuper = true)
public class DarkActivityEntity extends BaseEntity {
private Long id; private Long id;

파일 보기

@ -1,8 +1,10 @@
package com.snp.batch.jobs.movement.batch.entity; package com.snp.batch.jobs.movement.batch.entity;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.snp.batch.common.batch.entity.BaseEntity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
@ -12,7 +14,8 @@ import java.time.LocalDateTime;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class DestinationEntity { @EqualsAndHashCode(callSuper = true)
public class DestinationEntity extends BaseEntity {
private String movementType; private String movementType;
private String imolRorIHSNumber; private String imolRorIHSNumber;
private LocalDateTime movementDate; private LocalDateTime movementDate;

파일 보기

@ -1,12 +1,10 @@
package com.snp.batch.jobs.movement.batch.entity; package com.snp.batch.jobs.movement.batch.entity;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.GeneratedValue; import com.snp.batch.common.batch.entity.BaseEntity;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.SequenceGenerator;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
@ -16,12 +14,9 @@ import java.time.LocalDateTime;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class PortCallsEntity { @EqualsAndHashCode(callSuper = true)
@Id public class PortCallsEntity extends BaseEntity {
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ship_movement_id_seq")
@SequenceGenerator(name = "ship_movement_id_seq", sequenceName = "ship_movement_id_seq", allocationSize = 1)
private Long id; private Long id;
private String movementType; private String movementType;
private String imolRorIHSNumber; private String imolRorIHSNumber;
private LocalDateTime movementDate; private LocalDateTime movementDate;

파일 보기

@ -1,8 +1,10 @@
package com.snp.batch.jobs.movement.batch.entity; package com.snp.batch.jobs.movement.batch.entity;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.snp.batch.common.batch.entity.BaseEntity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
@ -12,7 +14,8 @@ import java.time.LocalDateTime;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class StsOperationEntity { @EqualsAndHashCode(callSuper = true)
public class StsOperationEntity extends BaseEntity {
private Long id; private Long id;

파일 보기

@ -2,8 +2,10 @@ package com.snp.batch.jobs.movement.batch.entity;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.snp.batch.common.batch.entity.BaseEntity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
@ -13,7 +15,8 @@ import java.time.LocalDateTime;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class TerminalCallsEntity { @EqualsAndHashCode(callSuper = true)
public class TerminalCallsEntity extends BaseEntity {
private Long id; private Long id;

파일 보기

@ -1,7 +1,9 @@
package com.snp.batch.jobs.movement.batch.entity; package com.snp.batch.jobs.movement.batch.entity;
import com.snp.batch.common.batch.entity.BaseEntity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
@ -11,7 +13,8 @@ import java.time.LocalDateTime;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class TransitsEntity { @EqualsAndHashCode(callSuper = true)
public class TransitsEntity extends BaseEntity {
private String movementType; private String movementType;
private String imolRorIHSNumber; private String imolRorIHSNumber;
private LocalDateTime movementDate; private LocalDateTime movementDate;

파일 보기

@ -6,33 +6,28 @@ import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.movement.batch.dto.AnchorageCallsDto; import com.snp.batch.jobs.movement.batch.dto.AnchorageCallsDto;
import com.snp.batch.jobs.movement.batch.entity.AnchorageCallsEntity; import com.snp.batch.jobs.movement.batch.entity.AnchorageCallsEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/**
* 선박 상세 정보 Processor
* ShipDetailDto ShipDetailEntity 변환
*/
/**
* 선박 상세 정보 Processor (해시 비교 증분 데이터 추출)
* I: ShipDetailComparisonData (DB 해시 + API Map Data)
* O: ShipDetailUpdate (변경분)
*/
@Slf4j @Slf4j
@Component @Component
public class AnchorageCallsProcessor extends BaseProcessor<AnchorageCallsDto, AnchorageCallsEntity> { public class AnchorageCallsProcessor extends BaseProcessor<AnchorageCallsDto, AnchorageCallsEntity> {
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final Long jobExecutionId;
public AnchorageCallsProcessor(ObjectMapper objectMapper) { public AnchorageCallsProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper)
{
this.jobExecutionId = jobExecutionId;
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
} }
@Override @Override
protected AnchorageCallsEntity processItem(AnchorageCallsDto dto) throws Exception { protected AnchorageCallsEntity processItem(AnchorageCallsDto dto) throws Exception {
log.debug("선박 상세 정보 처리 시작: imoNumber={}, facilityName={}", log.debug("AnchorageCalls 정보 처리 시작: imoNumber={}, facilityName={}",
dto.getImolRorIHSNumber(), dto.getFacilityName()); dto.getImolRorIHSNumber(), dto.getFacilityName());
JsonNode positionNode = null; JsonNode positionNode = null;
@ -60,6 +55,8 @@ public class AnchorageCallsProcessor extends BaseProcessor<AnchorageCallsDto, An
.destination(dto.getDestination()) .destination(dto.getDestination())
.iso2(dto.getIso2()) .iso2(dto.getIso2())
.position(positionNode) // JsonNode로 매핑 .position(positionNode) // JsonNode로 매핑
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
return entity; return entity;

파일 보기

@ -6,33 +6,29 @@ import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.movement.batch.dto.BerthCallsDto; import com.snp.batch.jobs.movement.batch.dto.BerthCallsDto;
import com.snp.batch.jobs.movement.batch.entity.BerthCallsEntity; import com.snp.batch.jobs.movement.batch.entity.BerthCallsEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/**
* 선박 상세 정보 Processor
* ShipDetailDto ShipDetailEntity 변환
*/
/**
* 선박 상세 정보 Processor (해시 비교 증분 데이터 추출)
* I: ShipDetailComparisonData (DB 해시 + API Map Data)
* O: ShipDetailUpdate (변경분)
*/
@Slf4j @Slf4j
@Component @Component
public class BerthCallsProcessor extends BaseProcessor<BerthCallsDto, BerthCallsEntity> { public class BerthCallsProcessor extends BaseProcessor<BerthCallsDto, BerthCallsEntity> {
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final Long jobExecutionId;
public BerthCallsProcessor(ObjectMapper objectMapper) { public BerthCallsProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper)
{
this.jobExecutionId = jobExecutionId;
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
} }
@Override @Override
protected BerthCallsEntity processItem(BerthCallsDto dto) throws Exception { protected BerthCallsEntity processItem(BerthCallsDto dto) throws Exception {
log.debug("선박 상세 정보 처리 시작: imoNumber={}, facilityName={}", log.debug("BerthCalls 정보 처리 시작: imoNumber={}, facilityName={}",
dto.getImolRorIHSNumber(), dto.getFacilityName()); dto.getImolRorIHSNumber(), dto.getFacilityName());
JsonNode positionNode = null; JsonNode positionNode = null;
@ -60,6 +56,8 @@ public class BerthCallsProcessor extends BaseProcessor<BerthCallsDto, BerthCalls
.parentCallId(dto.getParentCallId()) .parentCallId(dto.getParentCallId())
.iso2(dto.getIso2()) .iso2(dto.getIso2())
.eventStartDate(LocalDateTime.parse(dto.getEventStartDate())) .eventStartDate(LocalDateTime.parse(dto.getEventStartDate()))
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
return entity; return entity;

파일 보기

@ -6,33 +6,29 @@ import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.movement.batch.dto.CurrentlyAtDto; import com.snp.batch.jobs.movement.batch.dto.CurrentlyAtDto;
import com.snp.batch.jobs.movement.batch.entity.CurrentlyAtEntity; import com.snp.batch.jobs.movement.batch.entity.CurrentlyAtEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/**
* 선박 상세 정보 Processor
* ShipDetailDto ShipDetailEntity 변환
*/
/**
* 선박 상세 정보 Processor (해시 비교 증분 데이터 추출)
* I: ShipDetailComparisonData (DB 해시 + API Map Data)
* O: ShipDetailUpdate (변경분)
*/
@Slf4j @Slf4j
@Component @Component
public class CurrentlyAtProcessor extends BaseProcessor<CurrentlyAtDto, CurrentlyAtEntity> { public class CurrentlyAtProcessor extends BaseProcessor<CurrentlyAtDto, CurrentlyAtEntity> {
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final Long jobExecutionId;
public CurrentlyAtProcessor(ObjectMapper objectMapper) { public CurrentlyAtProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper)
{
this.jobExecutionId = jobExecutionId;
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
} }
@Override @Override
protected CurrentlyAtEntity processItem(CurrentlyAtDto dto) throws Exception { protected CurrentlyAtEntity processItem(CurrentlyAtDto dto) throws Exception {
log.debug("Currently 정보 처리 시작: imoNumber={}, facilityName={}", log.debug("CurrentlyAt 정보 처리 시작: imoNumber={}, facilityName={}",
dto.getImolRorIHSNumber(), dto.getFacilityName()); dto.getImolRorIHSNumber(), dto.getFacilityName());
JsonNode positionNode = null; JsonNode positionNode = null;
@ -63,6 +59,8 @@ public class CurrentlyAtProcessor extends BaseProcessor<CurrentlyAtDto, Currentl
.destination(dto.getDestination()) .destination(dto.getDestination())
.iso2(dto.getIso2()) .iso2(dto.getIso2())
.position(positionNode) // JsonNode로 매핑 .position(positionNode) // JsonNode로 매핑
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
return entity; return entity;

파일 보기

@ -6,33 +6,28 @@ import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.movement.batch.dto.DestinationDto; import com.snp.batch.jobs.movement.batch.dto.DestinationDto;
import com.snp.batch.jobs.movement.batch.entity.DestinationEntity; import com.snp.batch.jobs.movement.batch.entity.DestinationEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/**
* 선박 상세 정보 Processor
* ShipDetailDto ShipDetailEntity 변환
*/
/**
* 선박 상세 정보 Processor (해시 비교 증분 데이터 추출)
* I: ShipDetailComparisonData (DB 해시 + API Map Data)
* O: ShipDetailUpdate (변경분)
*/
@Slf4j @Slf4j
@Component @Component
public class DestinationProcessor extends BaseProcessor<DestinationDto, DestinationEntity> { public class DestinationProcessor extends BaseProcessor<DestinationDto, DestinationEntity> {
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final Long jobExecutionId;
public DestinationProcessor(ObjectMapper objectMapper) { public DestinationProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper)
{
this.jobExecutionId = jobExecutionId;
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
} }
@Override @Override
protected DestinationEntity processItem(DestinationDto dto) throws Exception { protected DestinationEntity processItem(DestinationDto dto) throws Exception {
log.debug("선박 상세 정보 처리 시작: imoNumber={}, facilityName={}", log.debug("Destinations 정보 처리 시작: imoNumber={}, facilityName={}",
dto.getImolRorIHSNumber(), dto.getFacilityName()); dto.getImolRorIHSNumber(), dto.getFacilityName());
JsonNode positionNode = null; JsonNode positionNode = null;
@ -54,6 +49,8 @@ public class DestinationProcessor extends BaseProcessor<DestinationDto, Destinat
.longitude(dto.getLongitude()) .longitude(dto.getLongitude())
.position(positionNode) // JsonNode로 매핑 .position(positionNode) // JsonNode로 매핑
.iso2(dto.getIso2()) .iso2(dto.getIso2())
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
return entity; return entity;
} }

파일 보기

@ -6,33 +6,28 @@ import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.movement.batch.dto.PortCallsDto; import com.snp.batch.jobs.movement.batch.dto.PortCallsDto;
import com.snp.batch.jobs.movement.batch.entity.PortCallsEntity; import com.snp.batch.jobs.movement.batch.entity.PortCallsEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/**
* 선박 상세 정보 Processor
* ShipDetailDto ShipDetailEntity 변환
*/
/**
* 선박 상세 정보 Processor (해시 비교 증분 데이터 추출)
* I: ShipDetailComparisonData (DB 해시 + API Map Data)
* O: ShipDetailUpdate (변경분)
*/
@Slf4j @Slf4j
@Component @Component
public class PortCallsProcessor extends BaseProcessor<PortCallsDto, PortCallsEntity> { public class PortCallsProcessor extends BaseProcessor<PortCallsDto, PortCallsEntity> {
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final Long jobExecutionId;
public PortCallsProcessor(ObjectMapper objectMapper) { public PortCallsProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper)
{
this.jobExecutionId = jobExecutionId;
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
} }
@Override @Override
protected PortCallsEntity processItem(PortCallsDto dto) throws Exception { protected PortCallsEntity processItem(PortCallsDto dto) throws Exception {
log.debug("선박 상세 정보 처리 시작: imoNumber={}, facilityName={}", log.debug("PortCalls 정보 처리 시작: imoNumber={}, facilityName={}",
dto.getImolRorIHSNumber(), dto.getFacilityName()); dto.getImolRorIHSNumber(), dto.getFacilityName());
JsonNode positionNode = null; JsonNode positionNode = null;
@ -63,7 +58,8 @@ public class PortCallsProcessor extends BaseProcessor<PortCallsDto, PortCallsEnt
.destination(dto.getDestination()) .destination(dto.getDestination())
.iso2(dto.getIso2()) .iso2(dto.getIso2())
.position(positionNode) // JsonNode로 매핑 .position(positionNode) // JsonNode로 매핑
.schemaType("PORTCALL") // API 타입 구분 .jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
return entity; return entity;

파일 보기

@ -6,33 +6,28 @@ import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.movement.batch.dto.StsOperationDto; import com.snp.batch.jobs.movement.batch.dto.StsOperationDto;
import com.snp.batch.jobs.movement.batch.entity.StsOperationEntity; import com.snp.batch.jobs.movement.batch.entity.StsOperationEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/**
* 선박 상세 정보 Processor
* ShipDetailDto ShipDetailEntity 변환
*/
/**
* 선박 상세 정보 Processor (해시 비교 증분 데이터 추출)
* I: ShipDetailComparisonData (DB 해시 + API Map Data)
* O: ShipDetailUpdate (변경분)
*/
@Slf4j @Slf4j
@Component @Component
public class StsOperationProcessor extends BaseProcessor<StsOperationDto, StsOperationEntity> { public class StsOperationProcessor extends BaseProcessor<StsOperationDto, StsOperationEntity> {
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final Long jobExecutionId;
public StsOperationProcessor(ObjectMapper objectMapper) { public StsOperationProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper)
{
this.jobExecutionId = jobExecutionId;
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
} }
@Override @Override
protected StsOperationEntity processItem(StsOperationDto dto) throws Exception { protected StsOperationEntity processItem(StsOperationDto dto) throws Exception {
log.debug("선박 상세 정보 처리 시작: imoNumber={}, facilityName={}", log.debug("StsOperations 정보 처리 시작: imoNumber={}, facilityName={}",
dto.getImolRorIHSNumber(), dto.getFacilityName()); dto.getImolRorIHSNumber(), dto.getFacilityName());
JsonNode positionNode = null; JsonNode positionNode = null;
@ -61,6 +56,8 @@ public class StsOperationProcessor extends BaseProcessor<StsOperationDto, StsOpe
.stsLocation(dto.getStsLocation()) .stsLocation(dto.getStsLocation())
.stsType(dto.getStsType()) .stsType(dto.getStsType())
.eventStartDate(LocalDateTime.parse(dto.getEventStartDate())) .eventStartDate(LocalDateTime.parse(dto.getEventStartDate()))
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
return entity; return entity;

파일 보기

@ -6,33 +6,29 @@ import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.movement.batch.dto.TerminalCallsDto; import com.snp.batch.jobs.movement.batch.dto.TerminalCallsDto;
import com.snp.batch.jobs.movement.batch.entity.TerminalCallsEntity; import com.snp.batch.jobs.movement.batch.entity.TerminalCallsEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/**
* 선박 상세 정보 Processor
* ShipDetailDto ShipDetailEntity 변환
*/
/**
* 선박 상세 정보 Processor (해시 비교 증분 데이터 추출)
* I: ShipDetailComparisonData (DB 해시 + API Map Data)
* O: ShipDetailUpdate (변경분)
*/
@Slf4j @Slf4j
@Component @Component
public class TerminalCallsProcessor extends BaseProcessor<TerminalCallsDto, TerminalCallsEntity> { public class TerminalCallsProcessor extends BaseProcessor<TerminalCallsDto, TerminalCallsEntity> {
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final Long jobExecutionId;
public TerminalCallsProcessor(ObjectMapper objectMapper) { public TerminalCallsProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId,
ObjectMapper objectMapper)
{
this.jobExecutionId = jobExecutionId;
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
} }
@Override @Override
protected TerminalCallsEntity processItem(TerminalCallsDto dto) throws Exception { protected TerminalCallsEntity processItem(TerminalCallsDto dto) throws Exception {
log.debug("선박 상세 정보 처리 시작: imoNumber={}, facilityName={}", log.debug("TerminalCalls 정보 처리 시작: imoNumber={}, facilityName={}",
dto.getImolRorIHSNumber(), dto.getFacilityName()); dto.getImolRorIHSNumber(), dto.getFacilityName());
JsonNode positionNode = null; JsonNode positionNode = null;
@ -63,6 +59,8 @@ public class TerminalCallsProcessor extends BaseProcessor<TerminalCallsDto, Term
.subFacilityId(dto.getSubFacilityId()) .subFacilityId(dto.getSubFacilityId())
.subFacilityName(dto.getSubFacilityName()) .subFacilityName(dto.getSubFacilityName())
.subFacilityType(dto.getSubFacilityType()) .subFacilityType(dto.getSubFacilityType())
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
return entity; return entity;

파일 보기

@ -1,36 +1,30 @@
package com.snp.batch.jobs.movement.batch.processor; package com.snp.batch.jobs.movement.batch.processor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.processor.BaseProcessor; import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.movement.batch.dto.TransitsDto; import com.snp.batch.jobs.movement.batch.dto.TransitsDto;
import com.snp.batch.jobs.movement.batch.entity.TransitsEntity; import com.snp.batch.jobs.movement.batch.entity.TransitsEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/**
* 선박 상세 정보 Processor
* ShipDetailDto ShipDetailEntity 변환
*/
/**
* 선박 상세 정보 Processor (해시 비교 증분 데이터 추출)
* I: ShipDetailComparisonData (DB 해시 + API Map Data)
* O: ShipDetailUpdate (변경분)
*/
@Slf4j @Slf4j
@Component @Component
public class TransitsProcessor extends BaseProcessor<TransitsDto, TransitsEntity> { public class TransitsProcessor extends BaseProcessor<TransitsDto, TransitsEntity> {
// private final ObjectMapper objectMapper; private final Long jobExecutionId;
// public TransitsProcessor(ObjectMapper objectMapper) { public TransitsProcessor(
// this.objectMapper = objectMapper; @Value("#{stepExecution.jobExecution.id}") Long jobExecutionId)
// } {
this.jobExecutionId = jobExecutionId;
}
@Override @Override
protected TransitsEntity processItem(TransitsDto dto) throws Exception { protected TransitsEntity processItem(TransitsDto dto) throws Exception {
log.debug("선박 상세 정보 처리 시작: imoNumber={}, facilityName={}", log.debug("Transits 정보 처리 시작: imoNumber={}, facilityName={}",
dto.getImolRorIHSNumber(), dto.getFacilityName()); dto.getImolRorIHSNumber(), dto.getFacilityName());
TransitsEntity entity = TransitsEntity.builder() TransitsEntity entity = TransitsEntity.builder()
@ -40,6 +34,8 @@ public class TransitsProcessor extends BaseProcessor<TransitsDto, TransitsEntity
.facilityName(dto.getFacilityName()) .facilityName(dto.getFacilityName())
.facilityType(dto.getFacilityType()) .facilityType(dto.getFacilityType())
.draught(dto.getDraught()) .draught(dto.getDraught())
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
return entity; return entity;
} }

파일 보기

@ -1,6 +1,5 @@
package com.snp.batch.jobs.movement.batch.repository; package com.snp.batch.jobs.movement.batch.repository;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.repository.BaseJdbcRepository; import com.snp.batch.common.batch.repository.BaseJdbcRepository;
import com.snp.batch.jobs.movement.batch.entity.AnchorageCallsEntity; import com.snp.batch.jobs.movement.batch.entity.AnchorageCallsEntity;
@ -10,15 +9,10 @@ import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types;
import java.util.List; import java.util.List;
/**
* 선박 상세 정보 Repository 구현체
* BaseJdbcRepository를 상속하여 JDBC 기반 CRUD 구현
*/
@Slf4j @Slf4j
@Repository("anchorageCallsRepository") @Repository("anchorageCallsRepository")
public class AnchorageCallsRepositoryImpl extends BaseJdbcRepository<AnchorageCallsEntity, String> public class AnchorageCallsRepositoryImpl extends BaseJdbcRepository<AnchorageCallsEntity, String>
@ -30,8 +24,7 @@ public class AnchorageCallsRepositoryImpl extends BaseJdbcRepository<AnchorageCa
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Override @Override
protected String getTableName() { protected String getTableName() {
// return "snp_data.t_anchoragecall"; return "t_snp_data.t_anchoragecall";
return "new_snp.t_anchoragecall";
} }
@Override @Override
@ -46,10 +39,8 @@ public class AnchorageCallsRepositoryImpl extends BaseJdbcRepository<AnchorageCa
@Override @Override
public String getInsertSql() { public String getInsertSql() {
/*return """
INSERT INTO snp_data.t_anchoragecall(*/
return """ return """
INSERT INTO new_snp.t_anchoragecall( INSERT INTO %s(
imo, imo,
mvmn_type, mvmn_type,
mvmn_dt, mvmn_dt,
@ -67,28 +58,10 @@ public class AnchorageCallsRepositoryImpl extends BaseJdbcRepository<AnchorageCa
lon, lon,
dstn, dstn,
iso2_ntn_cd, iso2_ntn_cd,
lcinfo lcinfo,
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) job_execution_id, created_by
ON CONFLICT (imo,mvmn_type, mvmn_dt) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
DO UPDATE SET """.formatted(getTableName());
mvmn_type = EXCLUDED.mvmn_type,
mvmn_dt = EXCLUDED.mvmn_dt,
stpov_id = EXCLUDED.stpov_id,
fclty_id = EXCLUDED.fclty_id,
fclty_nm = EXCLUDED.fclty_nm,
fclty_type = EXCLUDED.fclty_type,
lwrnk_fclty_id = EXCLUDED.lwrnk_fclty_id,
lwrnk_fclty_nm = EXCLUDED.lwrnk_fclty_nm,
lwrnk_fclty_type = EXCLUDED.lwrnk_fclty_type,
ntn_cd = EXCLUDED.ntn_cd,
ntn_nm = EXCLUDED.ntn_nm,
draft = EXCLUDED.draft,
lat = EXCLUDED.lat,
lon = EXCLUDED.lon,
dstn = EXCLUDED.dstn,
iso2_ntn_cd = EXCLUDED.iso2_ntn_cd,
lcinfo = EXCLUDED.lcinfo
""";
} }
@Override @Override
@ -122,8 +95,8 @@ public class AnchorageCallsRepositoryImpl extends BaseJdbcRepository<AnchorageCa
} else { } else {
ps.setNull(i++, java.sql.Types.OTHER); ps.setNull(i++, java.sql.Types.OTHER);
} }
ps.setObject(i++, e.getJobExecutionId(), Types.INTEGER);
// ps.setString(i++, e.getSchemaType()); ps.setString(i++, e.getCreatedBy());
} }
@ -150,53 +123,7 @@ public class AnchorageCallsRepositoryImpl extends BaseJdbcRepository<AnchorageCa
public void saveAll(List<AnchorageCallsEntity> entities) { public void saveAll(List<AnchorageCallsEntity> entities) {
if (entities == null || entities.isEmpty()) return; if (entities == null || entities.isEmpty()) return;
// log.info("ShipMovement 저장 시작 = {}건", entities.size());
batchInsert(entities); batchInsert(entities);
} }
/**
* ShipDetailEntity RowMapper
*/
private static class AnchorageCallsRowMapper implements RowMapper<AnchorageCallsEntity> {
@Override
public AnchorageCallsEntity mapRow(ResultSet rs, int rowNum) throws SQLException {
AnchorageCallsEntity entity = AnchorageCallsEntity.builder()
.id(rs.getLong("id"))
.imolRorIHSNumber(rs.getString("imolRorIHSNumber"))
.portCallId(rs.getObject("portCallId", Integer.class))
.facilityId(rs.getObject("facilityId", Integer.class))
.facilityName(rs.getString("facilityName"))
.facilityType(rs.getString("facilityType"))
.subFacilityId(rs.getObject("subFacilityId", Integer.class))
.subFacilityName(rs.getString("subFacilityName"))
.subFacilityType(rs.getString("subFacilityType"))
.countryCode(rs.getString("countryCode"))
.countryName(rs.getString("countryName"))
.draught(rs.getObject("draught", Double.class))
.latitude(rs.getObject("latitude", Double.class))
.longitude(rs.getObject("longitude", Double.class))
.destination(rs.getString("destination"))
.iso2(rs.getString("iso2"))
.position(parseJson(rs.getString("position")))
.build();
Timestamp movementDate = rs.getTimestamp("movementDate");
if (movementDate != null) {
entity.setMovementDate(movementDate.toLocalDateTime());
}
return entity;
}
private JsonNode parseJson(String json) {
try {
if (json == null) return null;
return new ObjectMapper().readTree(json);
} catch (Exception e) {
throw new RuntimeException("JSON 파싱 오류: " + json);
}
}
}
} }

파일 보기

@ -1,6 +1,5 @@
package com.snp.batch.jobs.movement.batch.repository; package com.snp.batch.jobs.movement.batch.repository;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.repository.BaseJdbcRepository; import com.snp.batch.common.batch.repository.BaseJdbcRepository;
import com.snp.batch.jobs.movement.batch.entity.BerthCallsEntity; import com.snp.batch.jobs.movement.batch.entity.BerthCallsEntity;
@ -10,15 +9,10 @@ import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types;
import java.util.List; import java.util.List;
/**
* 선박 상세 정보 Repository 구현체
* BaseJdbcRepository를 상속하여 JDBC 기반 CRUD 구현
*/
@Slf4j @Slf4j
@Repository("BerthCallsRepository") @Repository("BerthCallsRepository")
public class BerthCallsRepositoryImpl extends BaseJdbcRepository<BerthCallsEntity, String> public class BerthCallsRepositoryImpl extends BaseJdbcRepository<BerthCallsEntity, String>
@ -30,8 +24,7 @@ public class BerthCallsRepositoryImpl extends BaseJdbcRepository<BerthCallsEntit
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Override @Override
protected String getTableName() { protected String getTableName() {
// return "snp_data.t_berthcall"; return "t_snp_data.t_berthcall";
return "new_snp.t_berthcall";
} }
@Override @Override
@ -46,10 +39,8 @@ public class BerthCallsRepositoryImpl extends BaseJdbcRepository<BerthCallsEntit
@Override @Override
public String getInsertSql() { public String getInsertSql() {
/*return """
INSERT INTO snp_data.t_berthcall(*/
return """ return """
INSERT INTO new_snp.t_berthcall( INSERT INTO %s(
imo, imo,
mvmn_type, mvmn_type,
mvmn_dt, mvmn_dt,
@ -67,28 +58,10 @@ public class BerthCallsRepositoryImpl extends BaseJdbcRepository<BerthCallsEntit
prnt_call_id, prnt_call_id,
iso2_ntn_cd, iso2_ntn_cd,
evt_start_dt, evt_start_dt,
lcinfo lcinfo,
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) job_execution_id, created_by
ON CONFLICT (imo, mvmn_type, mvmn_dt) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
DO UPDATE SET """.formatted(getTableName());
mvmn_type = EXCLUDED.mvmn_type,
mvmn_dt = EXCLUDED.mvmn_dt,
fclty_id = EXCLUDED.fclty_id,
fclty_nm = EXCLUDED.fclty_nm,
fclty_type = EXCLUDED.fclty_type,
up_fclty_id = EXCLUDED.up_fclty_id,
up_fclty_nm = EXCLUDED.up_fclty_nm,
up_fclty_type = EXCLUDED.up_fclty_type,
ntn_cd = EXCLUDED.ntn_cd,
ntn_nm = EXCLUDED.ntn_nm,
draft = EXCLUDED.draft,
lat = EXCLUDED.lat,
lon = EXCLUDED.lon,
prnt_call_id = EXCLUDED.prnt_call_id,
iso2_ntn_cd = EXCLUDED.iso2_ntn_cd,
evt_start_dt = EXCLUDED.evt_start_dt,
lcinfo = EXCLUDED.lcinfo
""";
} }
@Override @Override
@ -122,6 +95,8 @@ public class BerthCallsRepositoryImpl extends BaseJdbcRepository<BerthCallsEntit
} else { } else {
ps.setNull(i++, java.sql.Types.OTHER); ps.setNull(i++, java.sql.Types.OTHER);
} }
ps.setObject(i++, e.getJobExecutionId(), Types.INTEGER);
ps.setString(i++, e.getCreatedBy());
} }
private void setDoubleOrNull(PreparedStatement ps, int index, Double value) throws Exception { private void setDoubleOrNull(PreparedStatement ps, int index, Double value) throws Exception {
@ -147,47 +122,7 @@ public class BerthCallsRepositoryImpl extends BaseJdbcRepository<BerthCallsEntit
public void saveAll(List<BerthCallsEntity> entities) { public void saveAll(List<BerthCallsEntity> entities) {
if (entities == null || entities.isEmpty()) return; if (entities == null || entities.isEmpty()) return;
// log.info("BerthCalls 저장 시작 = {}건", entities.size());
batchInsert(entities); batchInsert(entities);
} }
/**
* ShipDetailEntity RowMapper
*/
private static class BerthCallsRowMapper implements RowMapper<BerthCallsEntity> {
@Override
public BerthCallsEntity mapRow(ResultSet rs, int rowNum) throws SQLException {
BerthCallsEntity entity = BerthCallsEntity.builder()
.id(rs.getLong("id"))
.imolRorIHSNumber(rs.getString("imolRorIHSNumber"))
.facilityId(rs.getObject("facilityId", Integer.class))
.facilityName(rs.getString("facilityName"))
.facilityType(rs.getString("facilityType"))
.countryCode(rs.getString("countryCode"))
.countryName(rs.getString("countryName"))
.draught(rs.getObject("draught", Double.class))
.latitude(rs.getObject("latitude", Double.class))
.longitude(rs.getObject("longitude", Double.class))
.position(parseJson(rs.getString("position")))
.build();
Timestamp movementDate = rs.getTimestamp("movementDate");
if (movementDate != null) {
entity.setMovementDate(movementDate.toLocalDateTime());
}
return entity;
}
private JsonNode parseJson(String json) {
try {
if (json == null) return null;
return new ObjectMapper().readTree(json);
} catch (Exception e) {
throw new RuntimeException("JSON 파싱 오류: " + json);
}
}
}
} }

파일 보기

@ -10,12 +10,9 @@ import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types;
import java.util.List; import java.util.List;
/**
* 선박 상세 정보 Repository 구현체
* BaseJdbcRepository를 상속하여 JDBC 기반 CRUD 구현
*/
@Slf4j @Slf4j
@Repository("CurrentlyAtRepository") @Repository("CurrentlyAtRepository")
public class CurrentlyAtRepositoryImpl extends BaseJdbcRepository<CurrentlyAtEntity, String> public class CurrentlyAtRepositoryImpl extends BaseJdbcRepository<CurrentlyAtEntity, String>
@ -27,8 +24,7 @@ public class CurrentlyAtRepositoryImpl extends BaseJdbcRepository<CurrentlyAtEnt
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Override @Override
protected String getTableName() { protected String getTableName() {
// return "snp_data.t_currentlyat"; return "t_snp_data.t_currentlyat";
return "new_snp.t_currentlyat";
} }
@Override @Override
@ -43,10 +39,8 @@ public class CurrentlyAtRepositoryImpl extends BaseJdbcRepository<CurrentlyAtEnt
@Override @Override
public String getInsertSql() { public String getInsertSql() {
/*return """
INSERT INTO snp_data.t_currentlyat(*/
return """ return """
INSERT INTO new_snp.t_currentlyat( INSERT INTO %s(
imo, imo,
mvmn_type, mvmn_type,
mvmn_dt, mvmn_dt,
@ -67,31 +61,10 @@ public class CurrentlyAtRepositoryImpl extends BaseJdbcRepository<CurrentlyAtEnt
lon, lon,
dstn, dstn,
iso2_ntn_cd, iso2_ntn_cd,
lcinfo lcinfo,
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) job_execution_id, created_by
ON CONFLICT (imo, mvmn_type, mvmn_dt) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
DO UPDATE SET """.formatted(getTableName());
mvmn_type = EXCLUDED.mvmn_type,
mvmn_dt = EXCLUDED.mvmn_dt,
stpov_id = EXCLUDED.stpov_id,
fclty_id = EXCLUDED.fclty_id,
fclty_nm = EXCLUDED.fclty_nm,
fclty_type = EXCLUDED.fclty_type,
lwrnk_fclty_id = EXCLUDED.lwrnk_fclty_id,
lwrnk_fclty_nm = EXCLUDED.lwrnk_fclty_nm,
lwrnk_fclty_type = EXCLUDED.lwrnk_fclty_type,
up_fclty_id = EXCLUDED.up_fclty_id,
up_fclty_nm = EXCLUDED.up_fclty_nm,
up_fclty_type = EXCLUDED.up_fclty_type,
ntn_cd = EXCLUDED.ntn_cd,
ntn_nm = EXCLUDED.ntn_nm,
draft = EXCLUDED.draft,
lat = EXCLUDED.lat,
lon = EXCLUDED.lon,
dstn = EXCLUDED.dstn,
iso2_ntn_cd = EXCLUDED.iso2_ntn_cd,
lcinfo = EXCLUDED.lcinfo
""";
} }
@Override @Override
@ -128,8 +101,8 @@ public class CurrentlyAtRepositoryImpl extends BaseJdbcRepository<CurrentlyAtEnt
} else { } else {
ps.setNull(i++, java.sql.Types.OTHER); ps.setNull(i++, java.sql.Types.OTHER);
} }
ps.setObject(i++, e.getJobExecutionId(), Types.INTEGER);
// ps.setString(i++, e.getSchemaType()); ps.setString(i++, e.getCreatedBy());
} }
@ -156,7 +129,6 @@ public class CurrentlyAtRepositoryImpl extends BaseJdbcRepository<CurrentlyAtEnt
public void saveAll(List<CurrentlyAtEntity> entities) { public void saveAll(List<CurrentlyAtEntity> entities) {
if (entities == null || entities.isEmpty()) return; if (entities == null || entities.isEmpty()) return;
// log.info("CurrentltAt 저장 시작 = {}건", entities.size());
batchInsert(entities); batchInsert(entities);
} }

파일 보기

@ -10,12 +10,9 @@ import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types;
import java.util.List; import java.util.List;
/**
* 선박 상세 정보 Repository 구현체
* BaseJdbcRepository를 상속하여 JDBC 기반 CRUD 구현
*/
@Slf4j @Slf4j
@Repository("DestinationRepository") @Repository("DestinationRepository")
public class DestinationRepositoryImpl extends BaseJdbcRepository<DestinationEntity, String> public class DestinationRepositoryImpl extends BaseJdbcRepository<DestinationEntity, String>
@ -27,8 +24,7 @@ public class DestinationRepositoryImpl extends BaseJdbcRepository<DestinationEnt
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Override @Override
protected String getTableName() { protected String getTableName() {
// return "snp_data.t_destination"; return "t_snp_data.t_destination";
return "new_snp.t_destination";
} }
@Override @Override
@ -46,7 +42,7 @@ public class DestinationRepositoryImpl extends BaseJdbcRepository<DestinationEnt
/*return """ /*return """
INSERT INTO snp_data.t_destination(*/ INSERT INTO snp_data.t_destination(*/
return """ return """
INSERT INTO new_snp.t_destination( INSERT INTO %s(
imo, imo,
mvmn_type, mvmn_type,
mvmn_dt, mvmn_dt,
@ -58,22 +54,10 @@ public class DestinationRepositoryImpl extends BaseJdbcRepository<DestinationEnt
lat, lat,
lon, lon,
iso2_ntn_cd, iso2_ntn_cd,
lcinfo lcinfo,
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) job_execution_id, created_by
ON CONFLICT (imo) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
DO UPDATE SET """.formatted(getTableName());
mvmn_type = EXCLUDED.mvmn_type,
mvmn_dt = EXCLUDED.mvmn_dt,
fclty_id = EXCLUDED.fclty_id,
fclty_nm = EXCLUDED.fclty_nm,
fclty_type = EXCLUDED.fclty_type,
ntn_cd = EXCLUDED.ntn_cd,
ntn_nm = EXCLUDED.ntn_nm,
lat = EXCLUDED.lat,
lon = EXCLUDED.lon,
iso2_ntn_cd = EXCLUDED.iso2_ntn_cd,
lcinfo = EXCLUDED.lcinfo
""";
} }
@Override @Override
@ -101,6 +85,8 @@ public class DestinationRepositoryImpl extends BaseJdbcRepository<DestinationEnt
} else { } else {
ps.setNull(i++, java.sql.Types.OTHER); ps.setNull(i++, java.sql.Types.OTHER);
} }
ps.setObject(i++, e.getJobExecutionId(), Types.INTEGER);
ps.setString(i++, e.getCreatedBy());
} }
private void setDoubleOrNull(PreparedStatement ps, int index, Double value) throws Exception { private void setDoubleOrNull(PreparedStatement ps, int index, Double value) throws Exception {

파일 보기

@ -4,13 +4,9 @@ import com.snp.batch.jobs.movement.batch.entity.PortCallsEntity;
import java.util.List; import java.util.List;
/**
* 선박 상세 정보 Repository 인터페이스
*/
public interface PortCallsRepository { public interface PortCallsRepository {
void saveAll(List<PortCallsEntity> entities); void saveAll(List<PortCallsEntity> entities);
boolean existsByPortCallId(Integer portCallId);
} }

파일 보기

@ -1,6 +1,5 @@
package com.snp.batch.jobs.movement.batch.repository; package com.snp.batch.jobs.movement.batch.repository;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.repository.BaseJdbcRepository; import com.snp.batch.common.batch.repository.BaseJdbcRepository;
import com.snp.batch.jobs.movement.batch.entity.PortCallsEntity; import com.snp.batch.jobs.movement.batch.entity.PortCallsEntity;
@ -10,15 +9,10 @@ import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types;
import java.util.List; import java.util.List;
/**
* 선박 상세 정보 Repository 구현체
* BaseJdbcRepository를 상속하여 JDBC 기반 CRUD 구현
*/
@Slf4j @Slf4j
@Repository("ShipMovementRepository") @Repository("ShipMovementRepository")
public class PortCallsRepositoryImpl extends BaseJdbcRepository<PortCallsEntity, String> public class PortCallsRepositoryImpl extends BaseJdbcRepository<PortCallsEntity, String>
@ -30,8 +24,7 @@ public class PortCallsRepositoryImpl extends BaseJdbcRepository<PortCallsEntity,
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Override @Override
protected String getTableName() { protected String getTableName() {
// return "snp_data.t_ship_stpov_info"; return "t_snp_data.t_ship_stpov_info";
return "new_snp.t_ship_stpov_info";
} }
@Override @Override
@ -46,10 +39,8 @@ public class PortCallsRepositoryImpl extends BaseJdbcRepository<PortCallsEntity,
@Override @Override
public String getInsertSql() { public String getInsertSql() {
// return """
// INSERT INTO snp_data.t_ship_stpov_info(
return """ return """
INSERT INTO new_snp.t_ship_stpov_info( INSERT INTO %s(
imo, imo,
mvmn_type, mvmn_type,
mvmn_dt, mvmn_dt,
@ -70,62 +61,15 @@ public class PortCallsRepositoryImpl extends BaseJdbcRepository<PortCallsEntity,
lon, lon,
dstn, dstn,
iso2_ntn_cd, iso2_ntn_cd,
lcinfo lcinfo,
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) job_execution_id, created_by
ON CONFLICT (imo, mvmn_type, mvmn_dt) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
DO UPDATE SET """.formatted(getTableName());
mvmn_type = EXCLUDED.mvmn_type,
mvmn_dt = EXCLUDED.mvmn_dt,
stpov_id = EXCLUDED.stpov_id,
fclty_id = EXCLUDED.fclty_id,
fclty_nm = EXCLUDED.fclty_nm,
fclty_type = EXCLUDED.fclty_type,
lwrnk_fclty_id = EXCLUDED.lwrnk_fclty_id,
lwrnk_fclty_nm = EXCLUDED.lwrnk_fclty_nm,
lwrnk_fclty_type = EXCLUDED.lwrnk_fclty_type,
up_fclty_id = EXCLUDED.up_fclty_id,
up_fclty_nm = EXCLUDED.up_fclty_nm,
up_fclty_type = EXCLUDED.up_fclty_type,
ntn_cd = EXCLUDED.ntn_cd,
draft = EXCLUDED.draft,
lat = EXCLUDED.lat,
lon = EXCLUDED.lon,
dstn = EXCLUDED.dstn,
iso2_ntn_cd = EXCLUDED.iso2_ntn_cd,
lcinfo = EXCLUDED.lcinfo
""";
} }
@Override @Override
protected String getUpdateSql() { protected String getUpdateSql() {
return """ return null;
UPDATE snp_data.t_ship_stpov_info
SET vesselid = ?,
maritimemobileserviceidentitymmsinumber = ?,
shipname = ?,
callsign = ?,
flagname = ?,
portofregistry = ?,
classificationsociety = ?,
shiptypelevel5 = ?,
shiptypelevel5subtype = ?,
yearofbuild = ?,
shipbuilder = ?,
lengthoverallloa = ?,
breadthmoulded = ?,
"depth" = ?,
draught = ?,
grosstonnage = ?,
deadweight = ?,
teu = ?,
speedservice = ?,
mainenginetype = ?,
status = ?,
operator = ?,
flagcode = ?,
shiptypelevel2 = ?
WHERE ihslrorimoshipno = ?
""";
} }
@Override @Override
@ -135,7 +79,6 @@ public class PortCallsRepositoryImpl extends BaseJdbcRepository<PortCallsEntity,
ps.setString(i++, e.getMovementType()); // mvmn_type ps.setString(i++, e.getMovementType()); // mvmn_type
ps.setTimestamp(i++, e.getMovementDate() != null ? Timestamp.valueOf(e.getMovementDate()) : null); // mvmn_dt ps.setTimestamp(i++, e.getMovementDate() != null ? Timestamp.valueOf(e.getMovementDate()) : null); // mvmn_dt
ps.setObject(i++, e.getPortCallId()); // stpov_id ps.setObject(i++, e.getPortCallId()); // stpov_id
// stpov_type는 'PORTCALL' 하드코딩되었으므로 세팅 안함
ps.setObject(i++, e.getFacilityId()); // fclty_id ps.setObject(i++, e.getFacilityId()); // fclty_id
ps.setString(i++, e.getFacilityName()); // fclty_nm ps.setString(i++, e.getFacilityName()); // fclty_nm
ps.setString(i++, e.getFacilityType()); // fclty_type ps.setString(i++, e.getFacilityType()); // fclty_type
@ -158,8 +101,8 @@ public class PortCallsRepositoryImpl extends BaseJdbcRepository<PortCallsEntity,
} else { } else {
ps.setNull(i++, java.sql.Types.OTHER); ps.setNull(i++, java.sql.Types.OTHER);
} }
ps.setObject(i++, e.getJobExecutionId(), Types.INTEGER);
// ps.setString(i++, e.getSchemaType()); ps.setString(i++, e.getCreatedBy());
} }
@ -179,7 +122,7 @@ public class PortCallsRepositoryImpl extends BaseJdbcRepository<PortCallsEntity,
@Override @Override
protected RowMapper<PortCallsEntity> getRowMapper() { protected RowMapper<PortCallsEntity> getRowMapper() {
return new ShipMovementRowMapper(); return null;
} }
@Override @Override
@ -190,65 +133,4 @@ public class PortCallsRepositoryImpl extends BaseJdbcRepository<PortCallsEntity,
batchInsert(entities); batchInsert(entities);
} }
@Override
public boolean existsByPortCallId(Integer portCallId) {
String sql = """
SELECT COUNT(1)
FROM ship_movement
WHERE portCallId = ?
""";
Integer count = jdbcTemplate.queryForObject(sql, Integer.class, portCallId);
return count != null && count > 0;
}
/**
* ShipDetailEntity RowMapper
*/
private static class ShipMovementRowMapper implements RowMapper<PortCallsEntity> {
@Override
public PortCallsEntity mapRow(ResultSet rs, int rowNum) throws SQLException {
PortCallsEntity entity = PortCallsEntity.builder()
.id(rs.getLong("id"))
.imolRorIHSNumber(rs.getString("imolRorIHSNumber"))
.portCallId(rs.getObject("portCallId", Integer.class))
.facilityId(rs.getObject("facilityId", Integer.class))
.facilityName(rs.getString("facilityName"))
.facilityType(rs.getString("facilityType"))
.subFacilityId(rs.getObject("subFacilityId", Integer.class))
.subFacilityName(rs.getString("subFacilityName"))
.subFacilityType(rs.getString("subFacilityType"))
.parentFacilityId(rs.getObject("parentFacilityId", Integer.class))
.parentFacilityName(rs.getString("parentFacilityName"))
.parentFacilityType(rs.getString("parentFacilityType"))
.countryCode(rs.getString("countryCode"))
.countryName(rs.getString("countryName"))
.draught(rs.getObject("draught", Double.class))
.latitude(rs.getObject("latitude", Double.class))
.longitude(rs.getObject("longitude", Double.class))
.destination(rs.getString("destination"))
.iso2(rs.getString("iso2"))
.position(parseJson(rs.getString("position")))
.schemaType(rs.getString("schemaType"))
.build();
Timestamp movementDate = rs.getTimestamp("movementDate");
if (movementDate != null) {
entity.setMovementDate(movementDate.toLocalDateTime());
}
return entity;
}
private JsonNode parseJson(String json) {
try {
if (json == null) return null;
return new com.fasterxml.jackson.databind.ObjectMapper().readTree(json);
} catch (Exception e) {
throw new RuntimeException("JSON 파싱 오류: " + json);
}
}
}
} }

파일 보기

@ -10,12 +10,9 @@ import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types;
import java.util.List; import java.util.List;
/**
* 선박 상세 정보 Repository 구현체
* BaseJdbcRepository를 상속하여 JDBC 기반 CRUD 구현
*/
@Slf4j @Slf4j
@Repository("StsOperationRepository") @Repository("StsOperationRepository")
public class StsOperationRepositoryImpl extends BaseJdbcRepository<StsOperationEntity, String> public class StsOperationRepositoryImpl extends BaseJdbcRepository<StsOperationEntity, String>
@ -27,8 +24,7 @@ public class StsOperationRepositoryImpl extends BaseJdbcRepository<StsOperationE
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Override @Override
protected String getTableName() { protected String getTableName() {
// return "snp_data.t_stsoperation"; return "t_snp_data.t_stsoperation";
return "new_snp.t_stsoperation";
} }
@Override @Override
@ -43,10 +39,8 @@ public class StsOperationRepositoryImpl extends BaseJdbcRepository<StsOperationE
@Override @Override
public String getInsertSql() { public String getInsertSql() {
// return """
// INSERT INTO snp_data.t_stsoperation(
return """ return """
INSERT INTO new_snp.t_stsoperation( INSERT INTO %s(
imo, imo,
mvmn_type, mvmn_type,
mvmn_dt, mvmn_dt,
@ -65,29 +59,10 @@ public class StsOperationRepositoryImpl extends BaseJdbcRepository<StsOperationE
sts_location, sts_location,
sts_type, sts_type,
evt_start_dt, evt_start_dt,
lcinfo lcinfo,
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) job_execution_id, created_by
ON CONFLICT (imo, mvmn_type, mvmn_dt, fclty_id) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
DO UPDATE SET """.formatted(getTableName());
mvmn_type = EXCLUDED.mvmn_type,
mvmn_dt = EXCLUDED.mvmn_dt,
fclty_id = EXCLUDED.fclty_id,
fclty_nm = EXCLUDED.fclty_nm,
fclty_type = EXCLUDED.fclty_type,
up_fclty_id = EXCLUDED.up_fclty_id,
up_fclty_nm = EXCLUDED.up_fclty_nm,
up_fclty_type = EXCLUDED.up_fclty_type,
draft = EXCLUDED.draft,
lat = EXCLUDED.lat,
lon = EXCLUDED.lon,
prnt_call_id = EXCLUDED.prnt_call_id,
ntn_cd = EXCLUDED.ntn_cd,
ntn_nm = EXCLUDED.ntn_nm,
sts_location = EXCLUDED.sts_location,
sts_type = EXCLUDED.sts_type,
evt_start_dt = EXCLUDED.evt_start_dt,
lcinfo = EXCLUDED.lcinfo
""";
} }
@Override @Override
@ -122,6 +97,8 @@ public class StsOperationRepositoryImpl extends BaseJdbcRepository<StsOperationE
} else { } else {
ps.setNull(i++, java.sql.Types.OTHER); ps.setNull(i++, java.sql.Types.OTHER);
} }
ps.setObject(i++, e.getJobExecutionId(), Types.INTEGER);
ps.setString(i++, e.getCreatedBy());
} }
private void setDoubleOrNull(PreparedStatement ps, int index, Double value) throws Exception { private void setDoubleOrNull(PreparedStatement ps, int index, Double value) throws Exception {

파일 보기

@ -10,12 +10,9 @@ import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types;
import java.util.List; import java.util.List;
/**
* 선박 상세 정보 Repository 구현체
* BaseJdbcRepository를 상속하여 JDBC 기반 CRUD 구현
*/
@Slf4j @Slf4j
@Repository("TerminalCallsRepository") @Repository("TerminalCallsRepository")
public class TerminalCallsRepositoryImpl extends BaseJdbcRepository<TerminalCallsEntity, String> public class TerminalCallsRepositoryImpl extends BaseJdbcRepository<TerminalCallsEntity, String>
@ -27,8 +24,7 @@ public class TerminalCallsRepositoryImpl extends BaseJdbcRepository<TerminalCall
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Override @Override
protected String getTableName() { protected String getTableName() {
// return "snp_data.t_terminalcall"; return "t_snp_data.t_terminalcall";
return "new_snp.t_terminalcall";
} }
@Override @Override
@ -46,7 +42,7 @@ public class TerminalCallsRepositoryImpl extends BaseJdbcRepository<TerminalCall
// return """ // return """
// INSERT INTO snp_data.t_terminalcall( // INSERT INTO snp_data.t_terminalcall(
return """ return """
INSERT INTO new_snp.t_terminalcall( INSERT INTO %s(
imo, imo,
mvmn_type, mvmn_type,
mvmn_dt, mvmn_dt,
@ -67,31 +63,10 @@ public class TerminalCallsRepositoryImpl extends BaseJdbcRepository<TerminalCall
lcinfo, lcinfo,
sub_fclty_id, sub_fclty_id,
sub_fclty_nm, sub_fclty_nm,
sub_fclty_type sub_fclty_type,
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) job_execution_id, created_by
ON CONFLICT (imo, mvmn_type, mvmn_dt) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
DO UPDATE SET """.formatted(getTableName());
mvmn_type = EXCLUDED.mvmn_type,
mvmn_dt = EXCLUDED.mvmn_dt,
fclty_id = EXCLUDED.fclty_id,
fclty_nm = EXCLUDED.fclty_nm,
fclty_type = EXCLUDED.fclty_type,
up_fclty_id = EXCLUDED.up_fclty_id,
up_fclty_nm = EXCLUDED.up_fclty_nm,
up_fclty_type = EXCLUDED.up_fclty_type,
ntn_cd = EXCLUDED.ntn_cd,
ntn_nm = EXCLUDED.ntn_nm,
draft = EXCLUDED.draft,
lat = EXCLUDED.lat,
lon = EXCLUDED.lon,
prnt_call_id = EXCLUDED.prnt_call_id,
iso2_ntn_cd = EXCLUDED.iso2_ntn_cd,
evt_start_dt = EXCLUDED.evt_start_dt,
lcinfo = EXCLUDED.lcinfo,
sub_fclty_id = EXCLUDED.sub_fclty_id,
sub_fclty_nm = EXCLUDED.sub_fclty_nm,
sub_fclty_type = EXCLUDED.sub_fclty_type
""";
} }
@Override @Override
@ -128,6 +103,8 @@ public class TerminalCallsRepositoryImpl extends BaseJdbcRepository<TerminalCall
ps.setObject(i++, e.getSubFacilityId()); ps.setObject(i++, e.getSubFacilityId());
ps.setString(i++, e.getSubFacilityName()); ps.setString(i++, e.getSubFacilityName());
ps.setString(i++, e.getSubFacilityType()); ps.setString(i++, e.getSubFacilityType());
ps.setObject(i++, e.getJobExecutionId(), Types.INTEGER);
ps.setString(i++, e.getCreatedBy());
} }
private void setDoubleOrNull(PreparedStatement ps, int index, Double value) throws Exception { private void setDoubleOrNull(PreparedStatement ps, int index, Double value) throws Exception {
@ -153,7 +130,6 @@ public class TerminalCallsRepositoryImpl extends BaseJdbcRepository<TerminalCall
public void saveAll(List<TerminalCallsEntity> entities) { public void saveAll(List<TerminalCallsEntity> entities) {
if (entities == null || entities.isEmpty()) return; if (entities == null || entities.isEmpty()) return;
// log.info("TerminallCalls 저장 시작 = {}건", entities.size());
batchInsert(entities); batchInsert(entities);
} }

파일 보기

@ -10,12 +10,9 @@ import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types;
import java.util.List; import java.util.List;
/**
* 선박 상세 정보 Repository 구현체
* BaseJdbcRepository를 상속하여 JDBC 기반 CRUD 구현
*/
@Slf4j @Slf4j
@Repository("TransitsRepository") @Repository("TransitsRepository")
public class TransitsRepositoryImpl extends BaseJdbcRepository<TransitsEntity, String> public class TransitsRepositoryImpl extends BaseJdbcRepository<TransitsEntity, String>
@ -27,8 +24,7 @@ public class TransitsRepositoryImpl extends BaseJdbcRepository<TransitsEntity, S
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Override @Override
protected String getTableName() { protected String getTableName() {
// return "snp_data.t_transit"; return "t_snp_data.t_transit";
return "new_snp.t_transit";
} }
@Override @Override
@ -43,25 +39,17 @@ public class TransitsRepositoryImpl extends BaseJdbcRepository<TransitsEntity, S
@Override @Override
public String getInsertSql() { public String getInsertSql() {
// return """
// INSERT INTO snp_data.t_transit(
return """ return """
INSERT INTO new_snp.t_transit( INSERT INTO %s(
imo, imo,
mvmn_type, mvmn_type,
mvmn_dt, mvmn_dt,
fclty_nm, fclty_nm,
fclty_type, fclty_type,
draft draft,
) VALUES (?, ?, ?, ?, ?, ?) job_execution_id, created_by
ON CONFLICT (imo, mvmn_type, mvmn_dt) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?);
DO UPDATE SET """.formatted(getTableName());
mvmn_type = EXCLUDED.mvmn_type,
mvmn_dt = EXCLUDED.mvmn_dt,
fclty_nm = EXCLUDED.fclty_nm,
fclty_type = EXCLUDED.fclty_type,
draft = EXCLUDED.draft
""";
} }
@Override @Override
@ -78,6 +66,8 @@ public class TransitsRepositoryImpl extends BaseJdbcRepository<TransitsEntity, S
ps.setString(i++, e.getFacilityName()); // fclty_nm ps.setString(i++, e.getFacilityName()); // fclty_nm
ps.setString(i++, e.getFacilityType()); // fclty_type ps.setString(i++, e.getFacilityType()); // fclty_type
setDoubleOrNull(ps, i++, e.getDraught()); // draft setDoubleOrNull(ps, i++, e.getDraught()); // draft
ps.setObject(i++, e.getJobExecutionId(), Types.INTEGER);
ps.setString(i++, e.getCreatedBy());
} }
private void setDoubleOrNull(PreparedStatement ps, int index, Double value) throws Exception { private void setDoubleOrNull(PreparedStatement ps, int index, Double value) throws Exception {

파일 보기

@ -1,6 +1,8 @@
package com.snp.batch.jobs.pscInspection.batch.config; package com.snp.batch.jobs.pscInspection.batch.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.config.BaseMultiStepJobConfig; import com.snp.batch.common.batch.config.BaseMultiStepJobConfig;
import com.snp.batch.jobs.facility.batch.processor.PortDataProcessor;
import com.snp.batch.jobs.pscInspection.batch.dto.PscInspectionDto; import com.snp.batch.jobs.pscInspection.batch.dto.PscInspectionDto;
import com.snp.batch.jobs.pscInspection.batch.entity.PscInspectionEntity; import com.snp.batch.jobs.pscInspection.batch.entity.PscInspectionEntity;
import com.snp.batch.jobs.pscInspection.batch.processor.PscInspectionProcessor; import com.snp.batch.jobs.pscInspection.batch.processor.PscInspectionProcessor;
@ -31,7 +33,6 @@ import org.springframework.web.reactive.function.client.WebClient;
@Slf4j @Slf4j
@Configuration @Configuration
public class PscInspectionJobConfig extends BaseMultiStepJobConfig<PscInspectionDto, PscInspectionEntity> { public class PscInspectionJobConfig extends BaseMultiStepJobConfig<PscInspectionDto, PscInspectionEntity> {
private final PscInspectionProcessor pscInspectionProcessor; private final PscInspectionProcessor pscInspectionProcessor;
private final PscInspectionWriter pscInspectionWriter; private final PscInspectionWriter pscInspectionWriter;
private final PscApiReader pscApiReader; private final PscApiReader pscApiReader;
@ -44,7 +45,7 @@ public class PscInspectionJobConfig extends BaseMultiStepJobConfig<PscInspection
private String maritimeApiUrl; private String maritimeApiUrl;
protected String getApiKey() {return "PSC_IMPORT_API";} protected String getApiKey() {return "PSC_IMPORT_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
public PscInspectionJobConfig( public PscInspectionJobConfig(
JobRepository jobRepository, JobRepository jobRepository,
@ -107,6 +108,14 @@ public class PscInspectionJobConfig extends BaseMultiStepJobConfig<PscInspection
return pscInspectionProcessor; return pscInspectionProcessor;
} }
@Bean
@StepScope
public PscInspectionProcessor pscInspectionProcessor(
ObjectMapper objectMapper,
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
return new PscInspectionProcessor(objectMapper, jobExecutionId);
}
@Override @Override
protected ItemWriter<PscInspectionEntity> createWriter() { // 타입 변경 protected ItemWriter<PscInspectionEntity> createWriter() { // 타입 변경
return pscInspectionWriter; return pscInspectionWriter;

파일 보기

@ -1,7 +1,9 @@
package com.snp.batch.jobs.pscInspection.batch.entity; package com.snp.batch.jobs.pscInspection.batch.entity;
import com.snp.batch.common.batch.entity.BaseEntity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
@ -11,7 +13,8 @@ import java.time.LocalDateTime;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class PscAllCertificateEntity { @EqualsAndHashCode(callSuper = true)
public class PscAllCertificateEntity extends BaseEntity {
private String certificateId; private String certificateId;

파일 보기

@ -1,7 +1,9 @@
package com.snp.batch.jobs.pscInspection.batch.entity; package com.snp.batch.jobs.pscInspection.batch.entity;
import com.snp.batch.common.batch.entity.BaseEntity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
@ -9,7 +11,8 @@ import lombok.experimental.SuperBuilder;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class PscDefectEntity { @EqualsAndHashCode(callSuper = true)
public class PscDefectEntity extends BaseEntity {
private String defectId; private String defectId;

파일 보기

@ -1,10 +1,9 @@
package com.snp.batch.jobs.pscInspection.batch.entity; package com.snp.batch.jobs.pscInspection.batch.entity;
import com.snp.batch.jobs.pscInspection.batch.dto.PscAllCertificateDto; import com.snp.batch.common.batch.entity.BaseEntity;
import com.snp.batch.jobs.pscInspection.batch.dto.PscCertificateDto;
import com.snp.batch.jobs.pscInspection.batch.dto.PscDefectDto;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
@ -16,7 +15,8 @@ import java.util.List;
@SuperBuilder @SuperBuilder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class PscInspectionEntity { @EqualsAndHashCode(callSuper = true)
public class PscInspectionEntity extends BaseEntity {
private String typeId; private String typeId;
private String dataSetVersion; private String dataSetVersion;

파일 보기

@ -1,12 +1,17 @@
package com.snp.batch.jobs.pscInspection.batch.processor; package com.snp.batch.jobs.pscInspection.batch.processor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.processor.BaseProcessor; import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.pscInspection.batch.dto.*; import com.snp.batch.jobs.pscInspection.batch.dto.PscAllCertificateDto;
import com.snp.batch.jobs.pscInspection.batch.dto.PscCertificateDto;
import com.snp.batch.jobs.pscInspection.batch.dto.PscDefectDto;
import com.snp.batch.jobs.pscInspection.batch.dto.PscInspectionDto;
import com.snp.batch.jobs.pscInspection.batch.entity.PscAllCertificateEntity; import com.snp.batch.jobs.pscInspection.batch.entity.PscAllCertificateEntity;
import com.snp.batch.jobs.pscInspection.batch.entity.PscCertificateEntity; import com.snp.batch.jobs.pscInspection.batch.entity.PscCertificateEntity;
import com.snp.batch.jobs.pscInspection.batch.entity.PscDefectEntity; import com.snp.batch.jobs.pscInspection.batch.entity.PscDefectEntity;
import com.snp.batch.jobs.pscInspection.batch.entity.PscInspectionEntity; import com.snp.batch.jobs.pscInspection.batch.entity.PscInspectionEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -15,17 +20,21 @@ import java.time.LocalDateTime;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static jakarta.xml.bind.DatatypeConverter.parseDateTime;
@Slf4j @Slf4j
@Component @Component
public class PscInspectionProcessor extends BaseProcessor<PscInspectionDto, PscInspectionEntity> { public class PscInspectionProcessor extends BaseProcessor<PscInspectionDto, PscInspectionEntity> {
private static Long jobExecutionId;
private final ObjectMapper objectMapper;
public PscInspectionProcessor(
ObjectMapper objectMapper,
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
this.objectMapper = objectMapper;
this.jobExecutionId = jobExecutionId;
}
@Override @Override
public PscInspectionEntity processItem(PscInspectionDto item) throws Exception { public PscInspectionEntity processItem(PscInspectionDto item) throws Exception {
@ -71,6 +80,8 @@ public class PscInspectionProcessor extends BaseProcessor<PscInspectionDto, PscI
entity.setSource(s(item.getSource())); entity.setSource(s(item.getSource()));
entity.setUnlocode(s(item.getUnlocode())); entity.setUnlocode(s(item.getUnlocode()));
entity.setYearOfBuild(s(item.getYearOfBuild())); entity.setYearOfBuild(s(item.getYearOfBuild()));
entity.setJobExecutionId(jobExecutionId);
entity.setCreatedBy("SYSTEM");
// 리스트 null-safe // 리스트 null-safe
entity.setDefects(item.getPscDefects() == null ? List.of() : convertDefectDtos(item.getPscDefects())); entity.setDefects(item.getPscDefects() == null ? List.of() : convertDefectDtos(item.getPscDefects()));
@ -182,6 +193,8 @@ public class PscInspectionProcessor extends BaseProcessor<PscInspectionDto, PscI
.recognisedOrgRespCode(dto.getRecognisedOrgRespCode()) .recognisedOrgRespCode(dto.getRecognisedOrgRespCode())
.recognisedOrgRespYn(dto.getRecognisedOrgRespYn()) .recognisedOrgRespYn(dto.getRecognisedOrgRespYn())
.isAccidentalDamage(dto.getIsAccidentalDamage()) .isAccidentalDamage(dto.getIsAccidentalDamage())
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build()) .build())
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@ -241,6 +254,8 @@ public class PscInspectionProcessor extends BaseProcessor<PscInspectionDto, PscI
.surveyAuthorityType(dto.getSurveyAuthorityType()) .surveyAuthorityType(dto.getSurveyAuthorityType())
.inspectionDate(dto.getInspectionDate()) .inspectionDate(dto.getInspectionDate())
.inspectedBy(dto.getInspectedBy()) .inspectedBy(dto.getInspectedBy())
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build()) .build())
.collect(Collectors.toList()); .collect(Collectors.toList());
} }

파일 보기

@ -10,6 +10,7 @@ import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types;
import java.util.List; import java.util.List;
@Slf4j @Slf4j
@ -43,7 +44,7 @@ public class PscAllCertificateRepositoryImpl extends BaseJdbcRepository<PscAllCe
@Override @Override
public String getInsertSql() { public String getInsertSql() {
return """ return """
INSERT INTO new_snp.psc_all_certificate( INSERT INTO t_snp_data.psc_all_certificate(
certificate_id, certificate_id,
data_set_version, data_set_version,
inspection_id, inspection_id,
@ -63,32 +64,13 @@ public class PscAllCertificateRepositoryImpl extends BaseJdbcRepository<PscAllCe
latest_survey_place_code, latest_survey_place_code,
survey_authority_type, survey_authority_type,
inspection_date, inspection_date,
inspected_by inspected_by,
job_execution_id, created_by
) VALUES ( ) VALUES (
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ? ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
) ?, ?
ON CONFLICT (certificate_id) );
DO UPDATE SET
data_set_version = EXCLUDED.data_set_version,
inspection_id = EXCLUDED.inspection_id,
lrno = EXCLUDED.lrno,
certificate_title_code = EXCLUDED.certificate_title_code,
certificate_title = EXCLUDED.certificate_title,
issuing_authority_code = EXCLUDED.issuing_authority_code,
issuing_authority = EXCLUDED.issuing_authority,
other_issuing_authority = EXCLUDED.other_issuing_authority,
issue_date = EXCLUDED.issue_date,
expiry_date = EXCLUDED.expiry_date,
last_survey_date = EXCLUDED.last_survey_date,
survey_authority_code = EXCLUDED.survey_authority_code,
survey_authority = EXCLUDED.survey_authority,
other_survey_authority = EXCLUDED.other_survey_authority,
latest_survey_place = EXCLUDED.latest_survey_place,
latest_survey_place_code = EXCLUDED.latest_survey_place_code,
survey_authority_type = EXCLUDED.survey_authority_type,
inspection_date = EXCLUDED.inspection_date,
inspected_by = EXCLUDED.inspected_by
"""; """;
} }
@ -122,6 +104,8 @@ public class PscAllCertificateRepositoryImpl extends BaseJdbcRepository<PscAllCe
ps.setString(i++, e.getSurveyAuthorityType()); ps.setString(i++, e.getSurveyAuthorityType());
ps.setString(i++, e.getInspectionDate()); ps.setString(i++, e.getInspectionDate());
ps.setString(i++, e.getInspectedBy()); ps.setString(i++, e.getInspectedBy());
ps.setObject(i++, e.getJobExecutionId(), Types.INTEGER);
ps.setString(i++, e.getCreatedBy());
} }
@Override @Override

파일 보기

@ -44,7 +44,7 @@ public class PscDefectRepositoryImpl extends BaseJdbcRepository<PscDefectEntity,
@Override @Override
public String getInsertSql() { public String getInsertSql() {
return """ return """
INSERT INTO new_snp.psc_defect( INSERT INTO t_snp_data.psc_defect(
defect_id, defect_id,
inspection_id, inspection_id,
data_set_version, data_set_version,
@ -68,37 +68,14 @@ public class PscDefectRepositoryImpl extends BaseJdbcRepository<PscDefectEntity,
recognised_org_resp, recognised_org_resp,
recognised_org_resp_code, recognised_org_resp_code,
recognised_org_resp_yn, recognised_org_resp_yn,
is_accidental_damage is_accidental_damage,
job_execution_id, created_by
) VALUES ( ) VALUES (
?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,
?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,
?,?,?,? ?,?,?,?,
) ?,?
ON CONFLICT (defect_id) );
DO UPDATE SET
inspection_id = EXCLUDED.inspection_id,
data_set_version = EXCLUDED.data_set_version,
action_1 = EXCLUDED.action_1,
action_2 = EXCLUDED.action_2,
action_3 = EXCLUDED.action_3,
action_code_1 = EXCLUDED.action_code_1,
action_code_2 = EXCLUDED.action_code_2,
action_code_3 = EXCLUDED.action_code_3,
class_is_responsible = EXCLUDED.class_is_responsible,
defect_code = EXCLUDED.defect_code,
defect_text = EXCLUDED.defect_text,
defective_item_code = EXCLUDED.defective_item_code,
detention_reason_deficiency = EXCLUDED.detention_reason_deficiency,
main_defect_code = EXCLUDED.main_defect_code,
main_defect_text = EXCLUDED.main_defect_text,
nature_of_defect_code = EXCLUDED.nature_of_defect_code,
nature_of_defect_decode = EXCLUDED.nature_of_defect_decode,
other_action = EXCLUDED.other_action,
other_recognised_org_resp = EXCLUDED.other_recognised_org_resp,
recognised_org_resp = EXCLUDED.recognised_org_resp,
recognised_org_resp_code = EXCLUDED.recognised_org_resp_code,
recognised_org_resp_yn = EXCLUDED.recognised_org_resp_yn,
is_accidental_damage = EXCLUDED.is_accidental_damage
"""; """;
} }
@ -136,6 +113,8 @@ public class PscDefectRepositoryImpl extends BaseJdbcRepository<PscDefectEntity,
ps.setString(i++, e.getRecognisedOrgRespCode()); ps.setString(i++, e.getRecognisedOrgRespCode());
ps.setString(i++, e.getRecognisedOrgRespYn()); ps.setString(i++, e.getRecognisedOrgRespYn());
ps.setString(i++, e.getIsAccidentalDamage()); ps.setString(i++, e.getIsAccidentalDamage());
ps.setObject(i++, e.getJobExecutionId(), Types.INTEGER);
ps.setString(i++, e.getCreatedBy());
} }
@Override @Override

파일 보기

@ -38,7 +38,7 @@ public class PscInspectionRepositoryImpl extends BaseJdbcRepository<PscInspectio
@Override @Override
public String getInsertSql() { public String getInsertSql() {
return """ return """
INSERT INTO new_snp.psc_detail( INSERT INTO t_snp_data.psc_detail(
inspection_id, inspection_id,
data_set_version, data_set_version,
authorisation, authorisation,
@ -68,43 +68,14 @@ public class PscInspectionRepositoryImpl extends BaseJdbcRepository<PscInspectio
ship_type_decode, ship_type_decode,
source, source,
unlocode, unlocode,
year_of_build year_of_build,
job_execution_id, created_by
) VALUES ( ) VALUES (
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ? ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
) ?, ?
ON CONFLICT (inspection_id) );
DO UPDATE SET
data_set_version = EXCLUDED.data_set_version,
authorisation = EXCLUDED.authorisation,
call_sign = EXCLUDED.call_sign,
class = EXCLUDED.class,
charterer = EXCLUDED.charterer,
country = EXCLUDED.country,
inspection_date = EXCLUDED.inspection_date,
release_date = EXCLUDED.release_date,
ship_detained = EXCLUDED.ship_detained,
dead_weight = EXCLUDED.dead_weight,
expanded_inspection = EXCLUDED.expanded_inspection,
flag = EXCLUDED.flag,
follow_up_inspection = EXCLUDED.follow_up_inspection,
gross_tonnage = EXCLUDED.gross_tonnage,
inspection_port_decode = EXCLUDED.inspection_port_decode,
last_updated = EXCLUDED.last_updated,
ihslr_or_imo_ship_no = EXCLUDED.ihslr_or_imo_ship_no,
manager = EXCLUDED.manager,
number_of_days_detained = EXCLUDED.number_of_days_detained,
number_of_defects = EXCLUDED.number_of_defects,
number_of_part_days_detained = EXCLUDED.number_of_part_days_detained,
other_inspection_type = EXCLUDED.other_inspection_type,
owner = EXCLUDED.owner,
ship_name = EXCLUDED.ship_name,
ship_type_code = EXCLUDED.ship_type_code,
ship_type_decode = EXCLUDED.ship_type_decode,
source = EXCLUDED.source,
unlocode = EXCLUDED.unlocode,
year_of_build = EXCLUDED.year_of_build
"""; """;
} }
@ -147,6 +118,8 @@ public class PscInspectionRepositoryImpl extends BaseJdbcRepository<PscInspectio
ps.setString(i++, e.getSource()); ps.setString(i++, e.getSource());
ps.setString(i++, e.getUnlocode()); ps.setString(i++, e.getUnlocode());
ps.setString(i++, e.getYearOfBuild()); ps.setString(i++, e.getYearOfBuild());
ps.setObject(i++, e.getJobExecutionId(), Types.INTEGER);
ps.setString(i++, e.getCreatedBy());
} }
@Override @Override

파일 보기

@ -44,7 +44,7 @@ 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 String.format("UPDATE SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());} return String.format("UPDATE T_SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
@Override @Override
@ -108,6 +108,12 @@ public class RiskImportRangeJobConfig extends BaseMultiStepJobConfig<RiskDto, Ri
protected ItemProcessor<RiskDto, RiskEntity> createProcessor() { protected ItemProcessor<RiskDto, RiskEntity> createProcessor() {
return riskDataProcessor; return riskDataProcessor;
} }
@Bean
@StepScope
public RiskDataProcessor riskDataProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
return new RiskDataProcessor(jobExecutionId);
}
@Override @Override
protected ItemWriter<RiskEntity> createWriter() { return riskDataWriter; } protected ItemWriter<RiskEntity> createWriter() { return riskDataWriter; }

파일 보기

@ -4,11 +4,16 @@ import com.snp.batch.common.batch.processor.BaseProcessor;
import com.snp.batch.jobs.risk.batch.dto.RiskDto; import com.snp.batch.jobs.risk.batch.dto.RiskDto;
import com.snp.batch.jobs.risk.batch.entity.RiskEntity; import com.snp.batch.jobs.risk.batch.entity.RiskEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Slf4j @Slf4j
@Component @Component
public class RiskDataProcessor extends BaseProcessor<RiskDto, RiskEntity> { public class RiskDataProcessor extends BaseProcessor<RiskDto, RiskEntity> {
private final Long jobExecutionId;
public RiskDataProcessor(@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId) {
this.jobExecutionId = jobExecutionId;
}
@Override @Override
protected RiskEntity processItem(RiskDto dto) throws Exception { protected RiskEntity processItem(RiskDto dto) throws Exception {
log.debug("Risk 데이터 처리 시작: imoNumber={}", dto.getLrno()); log.debug("Risk 데이터 처리 시작: imoNumber={}", dto.getLrno());
@ -113,6 +118,8 @@ public class RiskDataProcessor extends BaseProcessor<RiskDto, RiskEntity> {
.russianOwnerRegistrationNarrative(dto.getRussianOwnerRegistrationNarrative()) .russianOwnerRegistrationNarrative(dto.getRussianOwnerRegistrationNarrative())
.russianSTS(dto.getRussianSTS()) .russianSTS(dto.getRussianSTS())
.russianSTSNarrative(dto.getRussianSTSNarrative()) .russianSTSNarrative(dto.getRussianSTSNarrative())
.jobExecutionId(jobExecutionId)
.createdBy("SYSTEM")
.build(); .build();
log.debug("Risk 데이터 처리 완료: imoNumber={}", dto.getLrno()); log.debug("Risk 데이터 처리 완료: imoNumber={}", dto.getLrno());

파일 보기

@ -6,5 +6,5 @@ import java.util.List;
public interface RiskRepository { public interface RiskRepository {
void saveRiskAll(List<RiskEntity> items); void saveRiskAll(List<RiskEntity> items);
void saveRiskHistoryAll(List<RiskEntity> items); // void saveRiskHistoryAll(List<RiskEntity> items);
} }

파일 보기

@ -8,6 +8,7 @@ import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.Types;
import java.util.List; import java.util.List;
@Slf4j @Slf4j
@ -20,7 +21,7 @@ public class RiskRepositoryImpl extends BaseJdbcRepository<RiskEntity, Long> imp
@Override @Override
protected String getTableName() { protected String getTableName() {
return null; return "t_snp_data.risk";
} }
@Override @Override
@ -40,12 +41,8 @@ public class RiskRepositoryImpl extends BaseJdbcRepository<RiskEntity, Long> imp
@Override @Override
protected String getUpdateSql() { protected String getUpdateSql() {
return null;
}
protected String getUpdateSql(String targetTable, String targetIndex) {
return """ return """
INSERT INTO new_snp.%s ( INSERT INTO %s(
lrno, lastupdated, lrno, lastupdated,
riskdatamaintained, dayssincelastseenonais, daysunderais, imocorrectonais, sailingundername, riskdatamaintained, dayssincelastseenonais, daysunderais, imocorrectonais, sailingundername,
anomalousmessagesfrommmsi, mostrecentdarkactivity, portcalls, portrisk, stsoperations, anomalousmessagesfrommmsi, mostrecentdarkactivity, portcalls, portrisk, stsoperations,
@ -54,7 +51,8 @@ public class RiskRepositoryImpl extends BaseJdbcRepository<RiskEntity, Long> imp
pscdetentions, currentsmccertificate, docchanges, currentclass, classstatuschanges, pscdetentions, currentsmccertificate, docchanges, currentclass, classstatuschanges,
pandicoverage, namechanges, gbochanges, ageofship, iuufishingviolation, pandicoverage, namechanges, gbochanges, ageofship, iuufishingviolation,
draughtchanges, mostrecentsanctionedportcall, singleshipoperation, fleetsafety, fleetpsc, draughtchanges, mostrecentsanctionedportcall, singleshipoperation, fleetsafety, fleetpsc,
specialsurveyoverdue, ownerunknown, russianportcall, russianownerregistration, russiansts specialsurveyoverdue, ownerunknown, russianportcall, russianownerregistration, russiansts,
job_execution_id, created_by
) )
VALUES ( VALUES (
?, ?::timestamptz, ?, ?::timestamptz,
@ -65,51 +63,10 @@ public class RiskRepositoryImpl extends BaseJdbcRepository<RiskEntity, Long> imp
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ? ?, ?, ?, ?, ?,
) ?, ?
ON CONFLICT (%s) );
DO UPDATE SET """.formatted(getTableName());
riskdatamaintained = EXCLUDED.riskdatamaintained,
dayssincelastseenonais = EXCLUDED.dayssincelastseenonais,
daysunderais = EXCLUDED.daysunderais,
imocorrectonais = EXCLUDED.imocorrectonais,
sailingundername = EXCLUDED.sailingundername,
anomalousmessagesfrommmsi = EXCLUDED.anomalousmessagesfrommmsi,
mostrecentdarkactivity = EXCLUDED.mostrecentdarkactivity,
portcalls = EXCLUDED.portcalls,
portrisk = EXCLUDED.portrisk,
stsoperations = EXCLUDED.stsoperations,
driftinghighseas = EXCLUDED.driftinghighseas,
riskevents = EXCLUDED.riskevents,
flagchanges = EXCLUDED.flagchanges,
flagparismouperformance = EXCLUDED.flagparismouperformance,
flagtokyomoupeformance = EXCLUDED.flagtokyomoupeformance,
flaguscgmouperformance = EXCLUDED.flaguscgmouperformance,
uscgqualship21 = EXCLUDED.uscgqualship21,
timesincepscinspection = EXCLUDED.timesincepscinspection,
pscinspections = EXCLUDED.pscinspections,
pscdefects = EXCLUDED.pscdefects,
pscdetentions = EXCLUDED.pscdetentions,
currentsmccertificate = EXCLUDED.currentsmccertificate,
docchanges = EXCLUDED.docchanges,
currentclass = EXCLUDED.currentclass,
classstatuschanges = EXCLUDED.classstatuschanges,
pandicoverage = EXCLUDED.pandicoverage,
namechanges = EXCLUDED.namechanges,
gbochanges = EXCLUDED.gbochanges,
ageofship = EXCLUDED.ageofship,
iuufishingviolation = EXCLUDED.iuufishingviolation,
draughtchanges = EXCLUDED.draughtchanges,
mostrecentsanctionedportcall = EXCLUDED.mostrecentsanctionedportcall,
singleshipoperation = EXCLUDED.singleshipoperation,
fleetsafety = EXCLUDED.fleetsafety,
fleetpsc = EXCLUDED.fleetpsc,
specialsurveyoverdue = EXCLUDED.specialsurveyoverdue,
ownerunknown = EXCLUDED.ownerunknown,
russianportcall = EXCLUDED.russianportcall,
russianownerregistration = EXCLUDED.russianownerregistration,
russiansts = EXCLUDED.russiansts
""".formatted(targetTable, targetIndex);
} }
@Override @Override
@ -162,6 +119,8 @@ public class RiskRepositoryImpl extends BaseJdbcRepository<RiskEntity, Long> imp
ps.setObject(idx++, entity.getRussianPortCall(), java.sql.Types.INTEGER); ps.setObject(idx++, entity.getRussianPortCall(), java.sql.Types.INTEGER);
ps.setObject(idx++, entity.getRussianOwnerRegistration(), java.sql.Types.INTEGER); ps.setObject(idx++, entity.getRussianOwnerRegistration(), java.sql.Types.INTEGER);
ps.setObject(idx++, entity.getRussianSTS(), java.sql.Types.INTEGER); ps.setObject(idx++, entity.getRussianSTS(), java.sql.Types.INTEGER);
ps.setObject(idx++, entity.getJobExecutionId(), Types.INTEGER);
ps.setString(idx++, entity.getCreatedBy());
} }
@Override @Override
@ -174,7 +133,7 @@ public class RiskRepositoryImpl extends BaseJdbcRepository<RiskEntity, Long> imp
if (items == null || items.isEmpty()) { if (items == null || items.isEmpty()) {
return; return;
} }
jdbcTemplate.batchUpdate(getUpdateSql("risk", "lrno"), items, items.size(), jdbcTemplate.batchUpdate(getUpdateSql(), items, items.size(),
(ps, entity) -> { (ps, entity) -> {
try { try {
setUpdateParameters(ps, entity); setUpdateParameters(ps, entity);
@ -187,21 +146,4 @@ public class RiskRepositoryImpl extends BaseJdbcRepository<RiskEntity, Long> imp
log.info("{} 전체 저장 완료: 수정={} 건", getEntityName(), items.size()); log.info("{} 전체 저장 완료: 수정={} 건", getEntityName(), items.size());
} }
@Override
public void saveRiskHistoryAll(List<RiskEntity> items) {
if (items == null || items.isEmpty()) {
return;
}
jdbcTemplate.batchUpdate(getUpdateSql("risk_history", "lrno, lastupdated"), items, items.size(),
(ps, entity) -> {
try {
setUpdateParameters(ps, entity);
} catch (Exception e) {
log.error("배치 수정 파라미터 설정 실패", e);
throw new RuntimeException(e);
}
});
log.info("{} 전체 저장 완료: 수정={} 건", getEntityName(), items.size());
}
} }

파일 보기

@ -19,6 +19,6 @@ public class RiskDataWriter extends BaseWriter<RiskEntity> {
@Override @Override
protected void writeItems(List<RiskEntity> items) throws Exception { protected void writeItems(List<RiskEntity> items) throws Exception {
riskRepository.saveRiskAll(items); riskRepository.saveRiskAll(items);
riskRepository.saveRiskHistoryAll(items); // riskRepository.saveRiskHistoryAll(items);
} }
} }

파일 보기

@ -1,8 +1,9 @@
package com.snp.batch.jobs.shipdetail.batch.config; package com.snp.batch.jobs.shipdetail.batch.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.config.BaseJobConfig; import com.snp.batch.common.batch.config.BaseJobConfig;
import com.snp.batch.jobs.shipdetail.batch.dto.ShipDetailComparisonData; // Reader 출력 타입 import com.snp.batch.jobs.shipdetail.batch.dto.ShipDetailDto;
import com.snp.batch.jobs.shipdetail.batch.dto.ShipDetailUpdate; // Processor 출력 타입 import com.snp.batch.jobs.shipdetail.batch.entity.ShipDetailEntity;
import com.snp.batch.jobs.shipdetail.batch.processor.ShipDetailDataProcessor; import com.snp.batch.jobs.shipdetail.batch.processor.ShipDetailDataProcessor;
import com.snp.batch.jobs.shipdetail.batch.reader.ShipDetailDataReader; import com.snp.batch.jobs.shipdetail.batch.reader.ShipDetailDataReader;
import com.snp.batch.jobs.shipdetail.batch.writer.ShipDetailDataWriter; import com.snp.batch.jobs.shipdetail.batch.writer.ShipDetailDataWriter;
@ -19,7 +20,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
import com.fasterxml.jackson.databind.ObjectMapper; // ObjectMapper 추가
/** /**
* 선박 상세 정보 Import Job Config * 선박 상세 정보 Import Job Config
@ -27,8 +27,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; // ObjectMapper 추가
* 특징: * 특징:
* - ship_data 테이블에서 IMO 번호 조회 * - ship_data 테이블에서 IMO 번호 조회
* - IMO 번호를 100개씩 배치로 분할 * - IMO 번호를 100개씩 배치로 분할
* - Maritime API GetShipsByIHSLRorIMONumbers 호출 * - Maritime API GetShipsByIHSLRorIMONumbersAll 호출
* TODO : GetShipsByIHSLRorIMONumbersAll 호출로 변경
* - 선박 상세 정보를 ship_detail 테이블에 저장 (UPSERT) * - 선박 상세 정보를 ship_detail 테이블에 저장 (UPSERT)
* *
* 데이터 흐름: * 데이터 흐름:
@ -41,12 +40,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; // ObjectMapper 추가
*/ */
/** /**
* 선박 상세 정보 Import Job Config * 선박 상세 정보 Import Job Config
* I: ShipDetailComparisonData (Reader 출력) * I: ShipDetailDto (Reader 출력)
* O: ShipDetailUpdate (Processor 출력) * O: ShipDetailEntity (Processor 출력)
*/ */
@Slf4j @Slf4j
@Configuration @Configuration
public class ShipDetailImportJobConfig extends BaseJobConfig<ShipDetailComparisonData, ShipDetailUpdate> { public class ShipDetailImportJobConfig extends BaseJobConfig<ShipDetailDto, ShipDetailEntity> {
private final ShipDetailDataProcessor shipDetailDataProcessor; private final ShipDetailDataProcessor shipDetailDataProcessor;
private final ShipDetailDataWriter shipDetailDataWriter; private final ShipDetailDataWriter shipDetailDataWriter;
@ -81,18 +80,17 @@ public class ShipDetailImportJobConfig extends BaseJobConfig<ShipDetailCompariso
} }
@Override @Override
protected ItemReader<ShipDetailComparisonData> createReader() { // 타입 변경 protected ItemReader<ShipDetailDto> createReader() { // 타입 변경
// Reader 생성자 수정: ObjectMapper를 전달합니다.
return new ShipDetailDataReader(maritimeApiWebClient, jdbcTemplate, objectMapper); return new ShipDetailDataReader(maritimeApiWebClient, jdbcTemplate, objectMapper);
} }
@Override @Override
protected ItemProcessor<ShipDetailComparisonData, ShipDetailUpdate> createProcessor() { protected ItemProcessor<ShipDetailDto, ShipDetailEntity> createProcessor() {
return shipDetailDataProcessor; return shipDetailDataProcessor;
} }
@Override @Override
protected ItemWriter<ShipDetailUpdate> createWriter() { // 타입 변경 protected ItemWriter<ShipDetailEntity> createWriter() { // 타입 변경
return shipDetailDataWriter; return shipDetailDataWriter;
} }

파일 보기

@ -2,8 +2,8 @@ package com.snp.batch.jobs.shipdetail.batch.config;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.snp.batch.common.batch.config.BaseMultiStepJobConfig; import com.snp.batch.common.batch.config.BaseMultiStepJobConfig;
import com.snp.batch.jobs.shipdetail.batch.dto.ShipDetailComparisonData; import com.snp.batch.jobs.shipdetail.batch.dto.ShipDetailDto;
import com.snp.batch.jobs.shipdetail.batch.dto.ShipDetailUpdate; import com.snp.batch.jobs.shipdetail.batch.entity.ShipDetailEntity;
import com.snp.batch.jobs.shipdetail.batch.processor.ShipDetailDataProcessor; import com.snp.batch.jobs.shipdetail.batch.processor.ShipDetailDataProcessor;
import com.snp.batch.jobs.shipdetail.batch.reader.ShipDetailUpdateDataReader; import com.snp.batch.jobs.shipdetail.batch.reader.ShipDetailUpdateDataReader;
import com.snp.batch.jobs.shipdetail.batch.writer.ShipDetailDataWriter; import com.snp.batch.jobs.shipdetail.batch.writer.ShipDetailDataWriter;
@ -31,7 +31,7 @@ import org.springframework.web.reactive.function.client.WebClient;
@Slf4j @Slf4j
@Configuration @Configuration
public class ShipDetailUpdateJobConfig extends BaseMultiStepJobConfig<ShipDetailComparisonData, ShipDetailUpdate> { public class ShipDetailUpdateJobConfig extends BaseMultiStepJobConfig<ShipDetailDto, ShipDetailEntity> {
private final ShipDetailDataProcessor shipDetailDataProcessor; private final ShipDetailDataProcessor shipDetailDataProcessor;
private final ShipDetailDataWriter shipDetailDataWriter; private final ShipDetailDataWriter shipDetailDataWriter;
@ -46,7 +46,7 @@ public class ShipDetailUpdateJobConfig extends BaseMultiStepJobConfig<ShipDetail
private String maritimeApiUrl; private String maritimeApiUrl;
protected String getApiKey() {return "SHIP_DETAIL_UPDATE_API";} protected String getApiKey() {return "SHIP_DETAIL_UPDATE_API";}
protected String getBatchUpdateSql() { 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());} return String.format("UPDATE T_SNP_DATA.BATCH_LAST_EXECUTION SET LAST_SUCCESS_DATE = NOW(), UPDATED_AT = NOW() WHERE API_KEY = '%s'", getApiKey());}
public ShipDetailUpdateJobConfig( public ShipDetailUpdateJobConfig(
@ -101,17 +101,24 @@ public class ShipDetailUpdateJobConfig extends BaseMultiStepJobConfig<ShipDetail
} }
@Override @Override
protected ItemReader<ShipDetailComparisonData> createReader() { // 타입 변경 protected ItemReader<ShipDetailDto> createReader() { // 타입 변경
return shipDetailUpdateDataReader; return shipDetailUpdateDataReader;
} }
@Override @Override
protected ItemProcessor<ShipDetailComparisonData, ShipDetailUpdate> createProcessor() { protected ItemProcessor<ShipDetailDto, ShipDetailEntity> createProcessor() {
return shipDetailDataProcessor; return shipDetailDataProcessor;
} }
@Bean
@StepScope
public ShipDetailDataProcessor shipDetailDataProcessor(
@Value("#{stepExecution.jobExecution.id}") Long jobExecutionId
) {
return new ShipDetailDataProcessor(jobExecutionId);
}
@Override @Override
protected ItemWriter<ShipDetailUpdate> createWriter() { // 타입 변경 protected ItemWriter<ShipDetailEntity> createWriter() { // 타입 변경
return shipDetailDataWriter; return shipDetailDataWriter;
} }

파일 보기

@ -2,6 +2,7 @@ package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.AdditionalInformationEntity;
import lombok.*; import lombok.*;
@Getter @Getter
@ -44,4 +45,22 @@ public class AdditionalInformationDto {
private String satComID; private String satComID;
@JsonProperty("SatComAnsBack") @JsonProperty("SatComAnsBack")
private String satComAnsBack; private String satComAnsBack;
public AdditionalInformationEntity toEntity() {
return AdditionalInformationEntity.builder()
.lrno(this.lrno)
.shipemail(this.shipEmail)
.waterdepthmax(this.waterDepthMax)
.drilldepthmax(this.drillDepthMax)
.drillbargeind(this.drillBargeInd)
.productionvesselind(this.productionVesselInd)
.deckheatexchangerind(this.deckHeatExchangerInd)
.deckheatexchangermaterial(this.deckHeatExchangerMaterial)
.tweendeckportable(this.tweenDeckPortable)
.tweendeckfixed(this.tweenDeckFixed)
.satcomid(this.satComID)
.satcomansback(this.satComAnsBack)
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getVersion() : null)
.build();
}
} }

파일 보기

@ -1,5 +1,6 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.BareBoatCharterHistoryEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -27,4 +28,15 @@ public class BareBoatCharterHistoryDto {
private String bbChartererCode; private String bbChartererCode;
@JsonProperty("BBCharterer") @JsonProperty("BBCharterer")
private String bbCharterer; private String bbCharterer;
public BareBoatCharterHistoryEntity toEntity() {
return BareBoatCharterHistoryEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.lrno(this.lrno)
.sequence(this.sequence)
.effectiveDate(this.effectiveDate)
.bbChartererCode(this.bbChartererCode)
.bbCharterer(this.bbCharterer)
.build();
}
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.CallSignAndMmsiHistoryEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -28,5 +29,15 @@ public class CallSignAndMmsiHistoryDto {
private String mmsi; private String mmsi;
@JsonProperty("EffectiveDate") @JsonProperty("EffectiveDate")
private String effectiveDate; private String effectiveDate;
// MMSI는 JSON에 없으므로 DTO에 포함하지 않음. Entity에서 처리.
public CallSignAndMmsiHistoryEntity toEntity() {
return CallSignAndMmsiHistoryEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.lrno(this.lrno)
.sequence(this.seqNo) // SeqNo -> sequence 매핑
.callsign(this.callSign)
.mmsi(this.mmsi) // DTO에 정의된 mmsi 필드 사용
.effectiveDate(this.effectiveDate)
.build();
}
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.ClassHistoryEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -34,4 +35,18 @@ public class ClassHistoryDto {
private String lrno; private String lrno;
@JsonProperty("Sequence") @JsonProperty("Sequence")
private String sequence; private String sequence;
public ClassHistoryEntity toEntity() {
return ClassHistoryEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
._class(this._class)
.classCode(this.classCode)
.classIndicator(this.classIndicator)
.classID(this.classID)
.currentIndicator(this.currentIndicator)
.effectiveDate(this.effectiveDate)
.lrno(this.lrno)
.sequence(this.sequence)
.build();
}
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.CompanyDetailEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -79,4 +80,39 @@ public class CompanyDetailDto {
@JsonProperty("DataSetVersion") @JsonProperty("DataSetVersion")
private String dataSetVersion; private String dataSetVersion;
} }
public CompanyDetailEntity toEntity() {
return CompanyDetailEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.owcode(this.owcode)
.shortcompanyname(this.shortCompanyName)
.countryname(this.countryName)
.townname(this.townName)
.telephone(this.telephone)
.telex(this.telex)
.emailaddress(this.emailaddress)
.website(this.website)
.fullname(this.fullName)
.careofcode(this.careOfCode)
.roomfloorbuilding1(this.roomFloorBuilding1)
.roomfloorbuilding2(this.roomFloorBuilding2)
.roomfloorbuilding3(this.roomFloorBuilding3)
.pobox(this.poBox)
.streetnumber(this.streetNumber)
.street(this.street)
.prepostcode(this.prePostcode)
.postpostcode(this.postPostcode)
.nationalityofregistration(this.nationalityofRegistration)
.nationalityofcontrol(this.nationalityofControl)
.locationcode(this.locationCode)
.nationalityofregistrationcode(this.nationalityofRegistrationCode)
.nationalityofcontrolcode(this.nationalityofControlCode)
.lastchangedate(this.lastChangeDate)
.parentcompany(this.parentCompany)
.companystatus(this.companyStatus)
.fulladdress(this.fullAddress)
.facsimile(this.facsimile)
.foundeddate(this.foundedDate)
.build();
}
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.CompanyVesselRelationshipEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -61,4 +62,31 @@ public class CompanyVesselRelationshipDto {
private String technicalManagerGroup; private String technicalManagerGroup;
@JsonProperty("TechnicalManagerGroupCode") @JsonProperty("TechnicalManagerGroupCode")
private String technicalManagerGroupCode; private String technicalManagerGroupCode;
public CompanyVesselRelationshipEntity toEntity() {
return CompanyVesselRelationshipEntity.builder()
.datasetversion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.doccode(this.docCode)
.doccompany(this.docCompany)
.docgroup(this.docGroup)
.docgroupcode(this.docGroupCode)
.groupbeneficialowner(this.groupBeneficialOwner)
.groupbeneficialownercode(this.groupBeneficialOwnerCode)
.lrno(this.lrno)
.operator(this.operator)
.operatorcode(this.operatorCode)
.operatorgroup(this.operatorGroup)
.operatorgroupcode(this.operatorGroupCode)
.registeredowner(this.registeredOwner)
.registeredownercode(this.registeredOwnerCode)
.shipmanager(this.shipManager)
.shipmanagercode(this.shipManagerCode)
.shipmanagergroup(this.shipManagerGroup)
.shipmanagergroupcode(this.shipManagerGroupCode)
.technicalmanager(this.technicalManager)
.technicalmanagercode(this.technicalManagerCode)
.technicalmanagergroup(this.technicalManagerGroup)
.technicalmanagergroupcode(this.technicalManagerGroupCode)
.build();
}
} }

파일 보기

@ -2,6 +2,7 @@ package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.CrewListEntity;
import lombok.*; import lombok.*;
@Data @Data
@ -58,4 +59,22 @@ public class CrewListDto {
@JsonProperty("TotalUndeclared") @JsonProperty("TotalUndeclared")
private String totalUndeclared; private String totalUndeclared;
public CrewListEntity toEntity() {
return CrewListEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.id(this.id)
.lrno(this.lrno)
.shipname(this.shipname)
.crewlistdate(this.crewListDate)
.nationality(this.nationality)
.totalcrew(this.totalCrew)
.totalratings(this.totalRatings)
.totalofficers(this.totalOfficers)
.totalcadets(this.totalCadets)
.totaltrainees(this.totalTrainees)
.totalridingsquad(this.totalRidingSquad)
.totalundeclared(this.totalUndeclared)
.build();
}
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.DarkActivityConfirmedEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -45,4 +46,36 @@ public class DarkActivityConfirmedDto {
@JsonProperty("Last_Port_of_Call") private String lastPortOfCall; @JsonProperty("Last_Port_of_Call") private String lastPortOfCall;
@JsonProperty("Last_Port_Country_Code") private String lastPortCountryCode; @JsonProperty("Last_Port_Country_Code") private String lastPortCountryCode;
@JsonProperty("Last_Port_Country") private String lastPortCountry; @JsonProperty("Last_Port_Country") private String lastPortCountry;
public DarkActivityConfirmedEntity toEntity() {
return DarkActivityConfirmedEntity.builder()
.datasetversion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.lrno(this.lrno)
.mmsi(this.mmsi)
.vessel_name(this.vesselName)
.dark_hours(this.darkHours)
.dark_activity(this.darkActivity)
.dark_status(this.darkStatus)
.area_id(this.areaId)
.area_name(this.areaName)
.area_country(this.areaCountry)
.dark_time(this.darkTime)
.dark_latitude(this.darkLatitude)
.dark_longitude(this.darkLongitude)
.dark_speed(this.darkSpeed)
.dark_heading(this.darkHeading)
.dark_draught(this.darkDraught)
.nextseen(this.nextSeen)
.nextseen_latitude(this.nextSeenLatitude)
.nextseen_longitude(this.nextSeenLongitude)
.nextseen_speed(this.nextSeenSpeed)
.nextseen_draught(this.nextSeenDraught)
.nextseen_heading(this.nextSeenHeading)
.dark_reported_destination(this.darkReportedDestination)
.nextseen_reported_destination(this.nextSeenReportedDestination)
.last_port_of_call(this.lastPortOfCall)
.last_port_country_code(this.lastPortCountryCode)
.last_port_country(this.lastPortCountry)
.build();
}
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.FlagHistoryEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -28,4 +29,15 @@ public class FlagHistoryDto {
private String lrno; private String lrno;
@JsonProperty("Sequence") @JsonProperty("Sequence")
private String sequence; private String sequence;
public FlagHistoryEntity toEntity() {
return FlagHistoryEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.effectiveDate(this.effectiveDate)
.flag(this.flag)
.flagCode(this.flagCode)
.lrno(this.lrno)
.sequence(this.sequence)
.build();
}
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.GroupBeneficialOwnerHistoryEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -12,7 +13,6 @@ import lombok.ToString;
@NoArgsConstructor @NoArgsConstructor
public class GroupBeneficialOwnerHistoryDto { public class GroupBeneficialOwnerHistoryDto {
// Nested class for DataSetVersion object
@Getter @Getter
@Setter @Setter
@ToString @ToString
@ -42,4 +42,16 @@ public class GroupBeneficialOwnerHistoryDto {
@JsonProperty("Sequence") @JsonProperty("Sequence")
private String sequence; // 순번 private String sequence; // 순번
public GroupBeneficialOwnerHistoryEntity toEntity() {
return GroupBeneficialOwnerHistoryEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.companyStatus(this.companyStatus)
.effectiveDate(this.effectiveDate)
.groupBeneficialOwner(this.groupBeneficialOwner)
.groupBeneficialOwnerCode(this.groupBeneficialOwnerCode)
.lrno(this.lrno)
.sequence(this.sequence)
.build();
}
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.IceClassEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -24,4 +25,13 @@ public class IceClassDto {
private String iceClassCode; private String iceClassCode;
@JsonProperty("LRNO") @JsonProperty("LRNO")
private String lrno; private String lrno;
public IceClassEntity toEntity() {
return IceClassEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.iceClass(this.iceClass)
.iceClassCode(this.iceClassCode)
.lrno(this.lrno)
.build();
}
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.NameHistoryEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -26,4 +27,14 @@ public class NameHistoryDto {
private String sequence; private String sequence;
@JsonProperty("VesselName") @JsonProperty("VesselName")
private String vesselName; private String vesselName;
public NameHistoryEntity toEntity() {
return NameHistoryEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.effectiveDate(this.effectiveDate)
.lrno(this.lrno)
.sequence(this.sequence)
.vesselName(this.vesselName)
.build();
}
} }

파일 보기

@ -1,5 +1,6 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.OperatorHistoryEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -40,4 +41,16 @@ public class OperatorHistoryDto {
@JsonProperty("Sequence") @JsonProperty("Sequence")
private String sequence; private String sequence;
public OperatorHistoryEntity toEntity() {
return OperatorHistoryEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.companyStatus(this.companyStatus)
.effectiveDate(this.effectiveDate)
.lrno(this.lrno)
.operator(this.operator)
.operatorCode(this.operatorCode)
.sequence(this.sequence)
.build();
}
} }

파일 보기

@ -2,6 +2,7 @@ package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.OwnerHistoryEntity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
@ -61,4 +62,16 @@ public class OwnerHistoryDto {
@JsonProperty("DataSetVersion") @JsonProperty("DataSetVersion")
private String version; private String version;
} }
public OwnerHistoryEntity toEntity(){
return OwnerHistoryEntity.builder()
.CompanyStatus(this.CompanyStatus)
.EffectiveDate(this.EffectiveDate)
.LRNO(this.LRNO)
.Owner(this.Owner)
.OwnerCode(this.OwnerCode)
.Sequence(this.Sequence)
.dataSetVersion(this.dataSetVersion.version)
.build();
}
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.PandIHistoryEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -30,4 +31,16 @@ public class PandIHistoryDto {
private String effectiveDate; private String effectiveDate;
@JsonProperty("Source") @JsonProperty("Source")
private String source; private String source;
public PandIHistoryEntity toEntity() {
return PandIHistoryEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.lrno(this.lrno)
.sequence(this.sequence)
.pandiclubcode(this.pandIClubCode)
.pandiclubdecode(this.pandIClubDecode)
.effectiveDate(this.effectiveDate)
.source(this.source)
.build();
}
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.SafetyManagementCertificateHistoryEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -46,4 +47,24 @@ public class SafetyManagementCertificateHistoryDto {
private String safetyManagementCertificateCompanyCode; private String safetyManagementCertificateCompanyCode;
@JsonProperty("Sequence") @JsonProperty("Sequence")
private String sequence; private String sequence;
public SafetyManagementCertificateHistoryEntity toEntity() {
return SafetyManagementCertificateHistoryEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.lrno(this.lrno)
.safetyManagementCertificateAuditor(this.safetyManagementCertificateAuditor)
.safetyManagementCertificateConventionOrVol(this.safetyManagementCertificateConventionOrVol)
.safetyManagementCertificateDateExpires(this.safetyManagementCertificateDateExpires)
.safetyManagementCertificateDateIssued(this.safetyManagementCertificateDateIssued)
.safetyManagementCertificateDOCCompany(this.safetyManagementCertificateDOCCompany)
.safetyManagementCertificateFlag(this.safetyManagementCertificateFlag)
.safetyManagementCertificateIssuer(this.safetyManagementCertificateIssuer)
.safetyManagementCertificateOtherDescription(this.safetyManagementCertificateOtherDescription)
.safetyManagementCertificateShipName(this.safetyManagementCertificateShipName)
.safetyManagementCertificateShipType(this.safetyManagementCertificateShipType)
.safetyManagementCertificateSource(this.safetyManagementCertificateSource)
.safetyManagementCertificateCompanyCode(this.safetyManagementCertificateCompanyCode)
.sequence(this.sequence)
.build();
}
} }

파일 보기

@ -476,7 +476,7 @@ public class ShipDetailDto {
* API: CompanyVesselRelationships * API: CompanyVesselRelationships
*/ */
@JsonProperty("CompanyVesselRelationships") @JsonProperty("CompanyVesselRelationships")
private List<CompanyVesselRelationshipDto> CompanyVesselRelationships; private List<CompanyVesselRelationshipDto> companyVesselRelationships;
/** /**
* 다크활동이력 정보 List * 다크활동이력 정보 List
@ -486,6 +486,6 @@ public class ShipDetailDto {
private List<DarkActivityConfirmedDto> darkActivityConfirmed; private List<DarkActivityConfirmedDto> darkActivityConfirmed;
@JsonProperty("CompanyDetailsComplexWithCodesAndParent") @JsonProperty("CompanyDetailsComplexWithCodesAndParent")
private List<CompanyDetailDto> companyDetailDtoList; private List<CompanyDetailDto> companyDetail;
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.ShipManagerHistoryEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -42,4 +43,16 @@ public class ShipManagerHistoryDto {
@JsonProperty("ShipManagerCode") @JsonProperty("ShipManagerCode")
private String shipManagerCode; private String shipManagerCode;
public ShipManagerHistoryEntity toEntity() {
return ShipManagerHistoryEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.companyStatus(this.companyStatus)
.effectiveDate(this.effectiveDate)
.lrno(this.lrno)
.sequence(this.sequence)
.shipManager(this.shipManager)
.shipManagerCode(this.shipManagerCode)
.build();
}
} }

파일 보기

@ -19,8 +19,7 @@ public class ShipResultDto {
private Integer shipCount; private Integer shipCount;
@JsonProperty("APSShipDetail") @JsonProperty("APSShipDetail")
private JsonNode shipDetailNode; private ShipDetailDto shipDetails;
// Getter and Setter
public JsonNode getShipDetailNode() { return shipDetailNode; }
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.SisterShipLinksEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -22,4 +23,12 @@ public class SisterShipLinksDto {
private String lrno; private String lrno;
@JsonProperty("LinkedLRNO") @JsonProperty("LinkedLRNO")
private String linkedLRNO; private String linkedLRNO;
public SisterShipLinksEntity toEntity() {
return SisterShipLinksEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.lrno(this.lrno)
.linkedLRNO(this.linkedLRNO)
.build();
}
} }

파일 보기

@ -1,6 +1,7 @@
package com.snp.batch.jobs.shipdetail.batch.dto; package com.snp.batch.jobs.shipdetail.batch.dto;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.snp.batch.jobs.shipdetail.batch.entity.SpecialFeatureEntity;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -26,4 +27,14 @@ public class SpecialFeatureDto {
private String specialFeature; private String specialFeature;
@JsonProperty("SpecialFeatureCode") @JsonProperty("SpecialFeatureCode")
private String specialFeatureCode; private String specialFeatureCode;
public SpecialFeatureEntity toEntity() {
return SpecialFeatureEntity.builder()
.dataSetVersion(this.dataSetVersion != null ? this.dataSetVersion.getDataSetVersion() : null)
.lrno(this.lrno)
.sequence(this.sequence)
.specialFeature(this.specialFeature)
.specialFeatureCode(this.specialFeatureCode)
.build();
}
} }

Some files were not shown because too many files have changed in this diff Show More