pscJob
This commit is contained in:
부모
6c98ebc24f
커밋
3ee6ae1bf7
@ -64,7 +64,7 @@ public class MaritimeApiWebClientConfig {
|
||||
.defaultHeaders(headers -> headers.setBasicAuth(maritimeApiUsername, maritimeApiPassword))
|
||||
.codecs(configurer -> configurer
|
||||
.defaultCodecs()
|
||||
.maxInMemorySize(30 * 1024 * 1024)) // 30MB 버퍼
|
||||
.maxInMemorySize(100 * 1024 * 1024)) // 30MB 버퍼
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,118 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.config;
|
||||
|
||||
import com.snp.batch.common.batch.config.BaseJobConfig;
|
||||
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.processor.PscInspectionProcessor;
|
||||
import com.snp.batch.jobs.pscInspection.batch.reader.PscApiReader;
|
||||
import com.snp.batch.jobs.pscInspection.batch.writer.PscInspectionWriter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.batch.core.Job;
|
||||
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.item.ItemProcessor;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
/**
|
||||
* 선박 상세 정보 Import Job Config
|
||||
*
|
||||
* 특징:
|
||||
* - ship_data 테이블에서 IMO 번호 조회
|
||||
* - IMO 번호를 100개씩 배치로 분할
|
||||
* - Maritime API GetShipsByIHSLRorIMONumbers 호출
|
||||
* TODO : GetShipsByIHSLRorIMONumbersAll 호출로 변경
|
||||
* - 선박 상세 정보를 ship_detail 테이블에 저장 (UPSERT)
|
||||
*
|
||||
* 데이터 흐름:
|
||||
* ShipMovementReader (ship_data → Maritime API)
|
||||
* ↓ (PortCallDto)
|
||||
* ShipMovementProcessor
|
||||
* ↓ (ShipMovementEntity)
|
||||
* ShipDetailDataWriter
|
||||
* ↓ (ship_movement 테이블)
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class PscInspectionJobConfig extends BaseJobConfig<PscInspectionDto, PscInspectionEntity> {
|
||||
|
||||
private final PscInspectionProcessor pscInspectionProcessor;
|
||||
private final PscInspectionWriter pscInspectionWriter;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final WebClient maritimeApiWebClient;
|
||||
|
||||
public PscInspectionJobConfig(
|
||||
JobRepository jobRepository,
|
||||
PlatformTransactionManager transactionManager,
|
||||
PscInspectionProcessor pscInspectionProcessor,
|
||||
PscInspectionWriter pscInspectionWriter,
|
||||
JdbcTemplate jdbcTemplate,
|
||||
@Qualifier("maritimeApiWebClient") WebClient maritimeApiWebClient, PscApiReader pscApiReader) { // ObjectMapper 주입 추가
|
||||
super(jobRepository, transactionManager);
|
||||
this.pscInspectionProcessor = pscInspectionProcessor;
|
||||
this.pscInspectionWriter = pscInspectionWriter;
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
this.maritimeApiWebClient = maritimeApiWebClient;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected String getJobName() {
|
||||
return "PSCDetailImportJob";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getStepName() {
|
||||
return "PSCDetailImportStep";
|
||||
}
|
||||
|
||||
@Bean
|
||||
@StepScope
|
||||
public PscApiReader pscApiReader(
|
||||
@Qualifier("maritimeApiWebClient") WebClient webClient,
|
||||
@Value("#{jobParameters['fromDate']}") String fromDate,
|
||||
@Value("#{jobParameters['toDate']}") String toDate
|
||||
) {
|
||||
return new PscApiReader(webClient, fromDate, toDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemReader<PscInspectionDto> createReader() {
|
||||
return pscApiReader(null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemProcessor<PscInspectionDto, PscInspectionEntity> createProcessor() {
|
||||
return pscInspectionProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemWriter<PscInspectionEntity> createWriter() { // 타입 변경
|
||||
return pscInspectionWriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getChunkSize() {
|
||||
return 10; // API에서 100개씩 가져오므로 chunk도 100으로 설정
|
||||
}
|
||||
|
||||
@Bean(name = "PSCDetailImportJob")
|
||||
public Job PSCDetailImportJob() {
|
||||
return job();
|
||||
}
|
||||
|
||||
@Bean(name = "PSCDetailImportStep")
|
||||
public Step PSCDetailImportStep() {
|
||||
return step();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PscAllCertificateDto {
|
||||
|
||||
@JsonProperty("Type_Id")
|
||||
private String typeId;
|
||||
|
||||
@JsonProperty("DataSetVersion")
|
||||
private PscDataSetVersionDto dataSetVersion;
|
||||
|
||||
@JsonProperty("Certificate_ID")
|
||||
private String certificateId;
|
||||
|
||||
@JsonProperty("Inspection_ID")
|
||||
private String inspectionId;
|
||||
|
||||
@JsonProperty("Lrno")
|
||||
private String lrno;
|
||||
|
||||
@JsonProperty("Certificate_Title_Code")
|
||||
private String certificateTitleCode;
|
||||
|
||||
@JsonProperty("Certificate_Title")
|
||||
private String certificateTitle;
|
||||
|
||||
@JsonProperty("Issuing_Authority_Code")
|
||||
private String issuingAuthorityCode;
|
||||
|
||||
@JsonProperty("Issuing_Authority")
|
||||
private String issuingAuthority;
|
||||
|
||||
@JsonProperty("Class_Soc_of_Issuer")
|
||||
private String classSocOfIssuer;
|
||||
|
||||
@JsonProperty("Other_Issuing_Authority")
|
||||
private String otherIssuingAuthority;
|
||||
|
||||
@JsonProperty("Issue_Date")
|
||||
private String issueDate;
|
||||
|
||||
@JsonProperty("Expiry_Date")
|
||||
private String expiryDate;
|
||||
|
||||
@JsonProperty("Last_Survey_Date")
|
||||
private String lastSurveyDate;
|
||||
|
||||
@JsonProperty("Survey_Authority_Code")
|
||||
private String surveyAuthorityCode;
|
||||
|
||||
@JsonProperty("Survey_Authority")
|
||||
private String surveyAuthority;
|
||||
|
||||
@JsonProperty("Other_Survey_Authority")
|
||||
private String otherSurveyAuthority;
|
||||
|
||||
@JsonProperty("Latest_Survey_Place")
|
||||
private String latestSurveyPlace;
|
||||
|
||||
@JsonProperty("Latest_Survey_Place_Code")
|
||||
private String latestSurveyPlaceCode;
|
||||
|
||||
@JsonProperty("Survey_Authority_Type")
|
||||
private String surveyAuthorityType;
|
||||
|
||||
@JsonProperty("Inspection_Date")
|
||||
private String inspectionDate;
|
||||
|
||||
@JsonProperty("Inspected_By")
|
||||
private String inspectedBy;
|
||||
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class PscApiResponseDto {
|
||||
|
||||
@JsonProperty("Inspections")
|
||||
private List<PscInspectionDto> inspections;
|
||||
@JsonProperty("inspectionCount")
|
||||
private Integer inspectionCount;
|
||||
|
||||
@JsonProperty("APSStatus")
|
||||
private PscApsStatusDto apsStatus;
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PscApsStatusDto {
|
||||
@JsonProperty("SystemVersion")
|
||||
private String systemVersion;
|
||||
|
||||
@JsonProperty("SystemDate")
|
||||
private String systemDate;
|
||||
|
||||
@JsonProperty("JobRunDate")
|
||||
private String jobRunDate;
|
||||
|
||||
@JsonProperty("CompletedOK")
|
||||
private Boolean completedOK;
|
||||
|
||||
@JsonProperty("ErrorLevel")
|
||||
private String errorLevel;
|
||||
|
||||
@JsonProperty("ErrorMessage")
|
||||
private String errorMessage;
|
||||
|
||||
@JsonProperty("RemedialAction")
|
||||
private String remedialAction;
|
||||
|
||||
@JsonProperty("Guid")
|
||||
private String guid;
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PscCertificateDto {
|
||||
@JsonProperty("Type_Id")
|
||||
private String typeId;
|
||||
|
||||
@JsonProperty("DataSetVersion")
|
||||
private PscDataSetVersionDto dataSetVersion;
|
||||
|
||||
@JsonProperty("Certificate_ID")
|
||||
private String certificateId;
|
||||
|
||||
@JsonProperty("Certificate_Title")
|
||||
private String certificateTitle;
|
||||
|
||||
@JsonProperty("Certificate_Title_Code")
|
||||
private String certificateTitleCode;
|
||||
|
||||
@JsonProperty("Class_SOC_Of_Issuer")
|
||||
private String classSocOfIssuer;
|
||||
|
||||
@JsonProperty("Expiry_Date")
|
||||
private String expiryDate; // ISO 날짜 문자열 그대로 받음
|
||||
|
||||
@JsonProperty("Inspection_ID")
|
||||
private String inspectionId;
|
||||
|
||||
@JsonProperty("Issue_Date")
|
||||
private String issueDate;
|
||||
|
||||
@JsonProperty("Issuing_Authority")
|
||||
private String issuingAuthority;
|
||||
|
||||
@JsonProperty("Issuing_Authority_Code")
|
||||
private String issuingAuthorityCode;
|
||||
|
||||
@JsonProperty("Last_Survey_Date")
|
||||
private String lastSurveyDate;
|
||||
|
||||
@JsonProperty("Latest_Survey_Place")
|
||||
private String latestSurveyPlace;
|
||||
|
||||
@JsonProperty("Latest_Survey_Place_Code")
|
||||
private String latestSurveyPlaceCode;
|
||||
|
||||
@JsonProperty("Lrno")
|
||||
private String lrno;
|
||||
|
||||
@JsonProperty("Other_Issuing_Authority")
|
||||
private String otherIssuingAuthority;
|
||||
|
||||
@JsonProperty("Other_Survey_Authority")
|
||||
private String otherSurveyAuthority;
|
||||
|
||||
@JsonProperty("Survey_Authority")
|
||||
private String surveyAuthority;
|
||||
|
||||
@JsonProperty("Survey_Authority_Code")
|
||||
private String surveyAuthorityCode;
|
||||
|
||||
@JsonProperty("Survey_Authority_Type")
|
||||
private String surveyAuthorityType;
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PscDataSetVersionDto {
|
||||
@JsonProperty("DataSetVersion")
|
||||
private String dataSetVersion;
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PscDefectDto {
|
||||
@JsonProperty("Type_Id")
|
||||
private String typeId;
|
||||
|
||||
@JsonProperty("DataSetVersion")
|
||||
private PscDataSetVersionDto dataSetVersion;
|
||||
|
||||
@JsonProperty("Action_1")
|
||||
private String action1;
|
||||
|
||||
@JsonProperty("Action_2")
|
||||
private String action2;
|
||||
|
||||
@JsonProperty("Action_3")
|
||||
private String action3;
|
||||
|
||||
@JsonProperty("Action_Code_1")
|
||||
private String actionCode1;
|
||||
|
||||
@JsonProperty("Action_Code_2")
|
||||
private String actionCode2;
|
||||
|
||||
@JsonProperty("Action_Code_3")
|
||||
private String actionCode3;
|
||||
|
||||
@JsonProperty("AmsA_Action_Code_1")
|
||||
private String amsaActionCode1;
|
||||
|
||||
@JsonProperty("AmsA_Action_Code_2")
|
||||
private String amsaActionCode2;
|
||||
|
||||
@JsonProperty("AmsA_Action_Code_3")
|
||||
private String amsaActionCode3;
|
||||
|
||||
@JsonProperty("Class_Is_Responsible")
|
||||
private String classIsResponsible;
|
||||
|
||||
@JsonProperty("Defect_Code")
|
||||
private String defectCode;
|
||||
|
||||
@JsonProperty("Defect_ID")
|
||||
private String defectId;
|
||||
|
||||
@JsonProperty("Defect_Text")
|
||||
private String defectText;
|
||||
|
||||
@JsonProperty("Defective_Item_Code")
|
||||
private String defectiveItemCode;
|
||||
|
||||
@JsonProperty("Detention_Reason_Deficiency")
|
||||
private String detentionReasonDeficiency;
|
||||
|
||||
@JsonProperty("Inspection_ID")
|
||||
private String inspectionId;
|
||||
|
||||
@JsonProperty("Main_Defect_Code")
|
||||
private String mainDefectCode;
|
||||
|
||||
@JsonProperty("Main_Defect_Text")
|
||||
private String mainDefectText;
|
||||
|
||||
@JsonProperty("Nature_Of_Defect_Code")
|
||||
private String natureOfDefectCode;
|
||||
|
||||
@JsonProperty("Nature_Of_Defect_DeCode")
|
||||
private String natureOfDefectDecode;
|
||||
|
||||
@JsonProperty("Other_Action")
|
||||
private String otherAction;
|
||||
|
||||
@JsonProperty("Other_Recognised_Org_Resp")
|
||||
private String otherRecognisedOrgResp;
|
||||
|
||||
@JsonProperty("Recognised_Org_Resp")
|
||||
private String recognisedOrgResp;
|
||||
|
||||
@JsonProperty("Recognised_Org_Resp_Code")
|
||||
private String recognisedOrgRespCode;
|
||||
|
||||
@JsonProperty("Recognised_Org_Resp_YN")
|
||||
private String recognisedOrgRespYn;
|
||||
|
||||
@JsonProperty("IsAccidentalDamage")
|
||||
private String isAccidentalDamage;
|
||||
}
|
||||
@ -0,0 +1,122 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class PscInspectionDto {
|
||||
|
||||
@JsonProperty("typeId")
|
||||
private String typeId;
|
||||
|
||||
@JsonProperty("DataSetVersion")
|
||||
private PscDataSetVersionDto dataSetVersion;
|
||||
|
||||
@JsonProperty("Authorisation")
|
||||
private String authorisation;
|
||||
|
||||
@JsonProperty("CallSign")
|
||||
private String callSign;
|
||||
|
||||
@JsonProperty("Cargo")
|
||||
private String cargo;
|
||||
|
||||
@JsonProperty("Charterer")
|
||||
private String charterer;
|
||||
|
||||
@JsonProperty("Class")
|
||||
private String shipClass;
|
||||
|
||||
@JsonProperty("Country")
|
||||
private String country;
|
||||
|
||||
@JsonProperty("Inspection_Date")
|
||||
private String inspectionDate;
|
||||
|
||||
@JsonProperty("Release_Date")
|
||||
private String releaseDate;
|
||||
|
||||
@JsonProperty("Ship_Detained")
|
||||
private String shipDetained;
|
||||
|
||||
@JsonProperty("Dead_Weight")
|
||||
private String deadWeight;
|
||||
|
||||
@JsonProperty("Expanded_Inspection")
|
||||
private String expandedInspection;
|
||||
|
||||
@JsonProperty("Flag")
|
||||
private String flag;
|
||||
|
||||
@JsonProperty("Follow_Up_Inspection")
|
||||
private String followUpInspection;
|
||||
|
||||
@JsonProperty("Gross_Tonnage")
|
||||
private String grossTonnage;
|
||||
|
||||
@JsonProperty("Inspection_ID")
|
||||
private String inspectionId;
|
||||
|
||||
@JsonProperty("Inspection_Port_Code")
|
||||
private String inspectionPortCode;
|
||||
|
||||
@JsonProperty("Inspection_Port_Decode")
|
||||
private String inspectionPortDecode;
|
||||
|
||||
@JsonProperty("Keel_Laid")
|
||||
private String keelLaid;
|
||||
|
||||
@JsonProperty("Last_Updated")
|
||||
private String lastUpdated;
|
||||
|
||||
@JsonProperty("IHSLR_or_IMO_Ship_No")
|
||||
private String ihslrOrImoShipNo;
|
||||
|
||||
@JsonProperty("Manager")
|
||||
private String manager;
|
||||
|
||||
@JsonProperty("Number_Of_Days_Detained")
|
||||
private Integer numberOfDaysDetained;
|
||||
|
||||
@JsonProperty("Number_Of_Defects")
|
||||
private String numberOfDefects;
|
||||
|
||||
@JsonProperty("Number_Of_Part_Days_Detained")
|
||||
private BigDecimal numberOfPartDaysDetained;
|
||||
|
||||
@JsonProperty("Other_Inspection_Type")
|
||||
private String otherInspectionType;
|
||||
|
||||
@JsonProperty("Owner")
|
||||
private String owner;
|
||||
|
||||
@JsonProperty("Ship_Name")
|
||||
private String shipName;
|
||||
|
||||
@JsonProperty("Ship_Type_Code")
|
||||
private String shipTypeCode;
|
||||
|
||||
@JsonProperty("Ship_Type_Decode")
|
||||
private String shipTypeDecode;
|
||||
|
||||
@JsonProperty("Source")
|
||||
private String source;
|
||||
|
||||
@JsonProperty("UNLOCODE")
|
||||
private String unlocode;
|
||||
|
||||
@JsonProperty("Year_Of_Build")
|
||||
private String yearOfBuild;
|
||||
|
||||
@JsonProperty("PSCDefects")
|
||||
private List<PscDefectDto> pscDefects;
|
||||
|
||||
@JsonProperty("PSCCertificates")
|
||||
private List<PscCertificateDto> pscCertificates;
|
||||
|
||||
@JsonProperty("PSCAllCertificates")
|
||||
private List<PscAllCertificateDto> pscAllCertificates;
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PscAllCertificateEntity {
|
||||
|
||||
private String certificateId;
|
||||
|
||||
private String typeId;
|
||||
private String dataSetVersion;
|
||||
|
||||
private String inspectionId;
|
||||
private String lrno;
|
||||
|
||||
private String certificateTitleCode;
|
||||
private String certificateTitle;
|
||||
|
||||
private String issuingAuthorityCode;
|
||||
private String issuingAuthority;
|
||||
|
||||
private String classSocOfIssuer;
|
||||
private String otherIssuingAuthority;
|
||||
|
||||
private LocalDateTime issueDate;
|
||||
private LocalDateTime expiryDate;
|
||||
private LocalDateTime lastSurveyDate;
|
||||
|
||||
private String surveyAuthorityCode;
|
||||
private String surveyAuthority;
|
||||
private String otherSurveyAuthority;
|
||||
|
||||
private String latestSurveyPlace;
|
||||
private String latestSurveyPlaceCode;
|
||||
|
||||
private String surveyAuthorityType;
|
||||
|
||||
private String inspectionDate;
|
||||
private String inspectedBy;
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PscCertificateEntity {
|
||||
|
||||
private String certificateId;
|
||||
|
||||
private String typeId;
|
||||
private String dataSetVersion;
|
||||
|
||||
private String certificateTitle;
|
||||
private String certificateTitleCode;
|
||||
|
||||
private String classSocOfIssuer;
|
||||
|
||||
private LocalDateTime expiryDate;
|
||||
private String inspectionId;
|
||||
private LocalDateTime issueDate;
|
||||
|
||||
private String issuingAuthority;
|
||||
private String issuingAuthorityCode;
|
||||
|
||||
private LocalDateTime lastSurveyDate;
|
||||
private String latestSurveyPlace;
|
||||
private String latestSurveyPlaceCode;
|
||||
|
||||
private String lrno;
|
||||
|
||||
private String otherIssuingAuthority;
|
||||
private String otherSurveyAuthority;
|
||||
|
||||
private String surveyAuthority;
|
||||
private String surveyAuthorityCode;
|
||||
private String surveyAuthorityType;
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PscDefectEntity {
|
||||
|
||||
private String defectId;
|
||||
|
||||
private String typeId;
|
||||
private String dataSetVersion;
|
||||
|
||||
private String action1;
|
||||
private String action2;
|
||||
private String action3;
|
||||
private String actionCode1;
|
||||
private String actionCode2;
|
||||
private String actionCode3;
|
||||
|
||||
private String amsaActionCode1;
|
||||
private String amsaActionCode2;
|
||||
private String amsaActionCode3;
|
||||
|
||||
private String classIsResponsible;
|
||||
|
||||
private String defectCode;
|
||||
private String defectText;
|
||||
|
||||
private String defectiveItemCode;
|
||||
private String detentionReasonDeficiency;
|
||||
|
||||
private String inspectionId;
|
||||
|
||||
private String mainDefectCode;
|
||||
private String mainDefectText;
|
||||
|
||||
private String natureOfDefectCode;
|
||||
private String natureOfDefectDecode;
|
||||
|
||||
private String otherAction;
|
||||
private String otherRecognisedOrgResp;
|
||||
private String recognisedOrgResp;
|
||||
private String recognisedOrgRespCode;
|
||||
private String recognisedOrgRespYn;
|
||||
|
||||
private String isAccidentalDamage;
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.entity;
|
||||
|
||||
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 lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PscInspectionEntity {
|
||||
|
||||
private String typeId;
|
||||
private String dataSetVersion;
|
||||
private String authorisation;
|
||||
private String callSign;
|
||||
private String shipClass;
|
||||
private String cargo;
|
||||
private String charterer;
|
||||
private String country;
|
||||
private LocalDateTime inspectionDate;
|
||||
private LocalDateTime releaseDate;
|
||||
private String shipDetained;
|
||||
private String deadWeight;
|
||||
private String expandedInspection;
|
||||
private String flag;
|
||||
private String followUpInspection;
|
||||
private String grossTonnage;
|
||||
|
||||
private String inspectionId;
|
||||
|
||||
private String inspectionPortCode;
|
||||
private String inspectionPortDecode;
|
||||
|
||||
private String keelLaid;
|
||||
private LocalDateTime lastUpdated;
|
||||
private String ihslrOrImoShipNo;
|
||||
private String manager;
|
||||
|
||||
private Integer numberOfDaysDetained;
|
||||
private String numberOfDefects;
|
||||
private BigDecimal numberOfPartDaysDetained;
|
||||
|
||||
private String otherInspectionType;
|
||||
private String owner;
|
||||
private String shipName;
|
||||
private String shipTypeCode;
|
||||
private String shipTypeDecode;
|
||||
private String source;
|
||||
private String unlocode;
|
||||
private String yearOfBuild;
|
||||
|
||||
private List<PscDefectEntity> defects;
|
||||
private List<PscCertificateEntity> certificates;
|
||||
private List<PscAllCertificateEntity> allCertificates;
|
||||
}
|
||||
@ -0,0 +1,268 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.processor;
|
||||
|
||||
import com.snp.batch.common.batch.processor.BaseProcessor;
|
||||
import com.snp.batch.jobs.pscInspection.batch.dto.*;
|
||||
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.PscDefectEntity;
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscInspectionEntity;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static jakarta.xml.bind.DatatypeConverter.parseDateTime;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class PscInspectionProcessor extends BaseProcessor<PscInspectionDto, PscInspectionEntity> {
|
||||
|
||||
@Override
|
||||
public PscInspectionEntity processItem(PscInspectionDto item) throws Exception {
|
||||
|
||||
PscInspectionEntity entity = new PscInspectionEntity();
|
||||
|
||||
entity.setTypeId(s(item.getTypeId()));
|
||||
entity.setDataSetVersion(item.getDataSetVersion() != null ? s(item.getDataSetVersion().getDataSetVersion()) : null);
|
||||
entity.setAuthorisation(s(item.getAuthorisation()));
|
||||
entity.setCallSign(s(item.getCallSign()));
|
||||
entity.setShipClass(s(item.getShipClass()));
|
||||
entity.setCargo(s(item.getCargo()));
|
||||
entity.setCharterer(s(item.getCharterer()));
|
||||
entity.setCountry(s(item.getCountry()));
|
||||
|
||||
entity.setInspectionDate(dt(item.getInspectionDate()));
|
||||
entity.setReleaseDate(dt(item.getReleaseDate()));
|
||||
entity.setShipDetained(s(item.getShipDetained()));
|
||||
entity.setDeadWeight(s(item.getDeadWeight()));
|
||||
|
||||
entity.setExpandedInspection(s(item.getExpandedInspection()));
|
||||
entity.setFlag(s(item.getFlag()));
|
||||
entity.setFollowUpInspection(s(item.getFollowUpInspection()));
|
||||
entity.setGrossTonnage(s(item.getGrossTonnage()));
|
||||
|
||||
entity.setInspectionId(s(item.getInspectionId()));
|
||||
entity.setInspectionPortCode(s(item.getInspectionPortCode()));
|
||||
entity.setInspectionPortDecode(s(item.getInspectionPortDecode()));
|
||||
|
||||
entity.setKeelLaid(s(item.getKeelLaid()));
|
||||
entity.setLastUpdated(dt(item.getLastUpdated()));
|
||||
entity.setIhslrOrImoShipNo(s(item.getIhslrOrImoShipNo()));
|
||||
entity.setManager(s(item.getManager()));
|
||||
|
||||
entity.setNumberOfDaysDetained(i(item.getNumberOfDaysDetained()));
|
||||
entity.setNumberOfDefects(s(item.getNumberOfDefects()));
|
||||
entity.setNumberOfPartDaysDetained(bd(item.getNumberOfPartDaysDetained()));
|
||||
|
||||
entity.setOtherInspectionType(s(item.getOtherInspectionType()));
|
||||
entity.setOwner(s(item.getOwner()));
|
||||
entity.setShipName(s(item.getShipName()));
|
||||
entity.setShipTypeCode(s(item.getShipTypeCode()));
|
||||
entity.setShipTypeDecode(s(item.getShipTypeDecode()));
|
||||
entity.setSource(s(item.getSource()));
|
||||
entity.setUnlocode(s(item.getUnlocode()));
|
||||
entity.setYearOfBuild(s(item.getYearOfBuild()));
|
||||
|
||||
// 리스트 null-safe
|
||||
entity.setDefects(item.getPscDefects() == null ? List.of() : convertDefectDtos(item.getPscDefects()));
|
||||
entity.setCertificates(item.getPscCertificates() == null ? List.of() : convertCertificateDtos(item.getPscCertificates()));
|
||||
entity.setAllCertificates(item.getPscAllCertificates() == null ? List.of() : convertAllCertificateDtos(item.getPscAllCertificates()));
|
||||
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------- 공통 메서드 ----------------------- */
|
||||
|
||||
private String s(Object v) {
|
||||
return (v == null) ? null : v.toString().trim();
|
||||
}
|
||||
|
||||
private Boolean b(Object v) {
|
||||
if (v == null) return null;
|
||||
String s = v.toString().trim().toLowerCase();
|
||||
if (s.equals("true") || s.equals("t") || s.equals("1")) return true;
|
||||
if (s.equals("false") || s.equals("f") || s.equals("0")) return false;
|
||||
return null;
|
||||
}
|
||||
private BigDecimal bd(Object v) {
|
||||
if (v == null) return null;
|
||||
try {
|
||||
return new BigDecimal(v.toString().trim());
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private Integer i(Object v) {
|
||||
if (v == null) return null;
|
||||
try {
|
||||
return Integer.parseInt(v.toString().trim());
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Double d(Object v) {
|
||||
if (v == null) return null;
|
||||
try {
|
||||
return Double.parseDouble(v.toString().trim());
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private LocalDateTime dt(String dateStr) {
|
||||
if (dateStr == null || dateStr.isBlank()) return null;
|
||||
|
||||
// 가장 흔한 ISO 형태
|
||||
try {
|
||||
return LocalDateTime.parse(dateStr);
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
// yyyy-MM-dd
|
||||
try {
|
||||
return LocalDate.parse(dateStr).atStartOfDay();
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
// yyyy-MM-dd HH:mm:ss
|
||||
try {
|
||||
return LocalDateTime.parse(dateStr,
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
// yyyy-MM-ddTHH:mm:ssZ 형태
|
||||
try {
|
||||
return OffsetDateTime.parse(dateStr).toLocalDateTime();
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
log.warn("⚠️ 날짜 변환 실패 → {}", dateStr);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<PscDefectEntity> convertDefectDtos(List<PscDefectDto> dtos) {
|
||||
if (dtos == null || dtos.isEmpty()) return List.of();
|
||||
|
||||
return dtos.stream()
|
||||
.map(dto -> PscDefectEntity.builder()
|
||||
.defectId(dto.getDefectId())
|
||||
.inspectionId(dto.getInspectionId())
|
||||
.typeId(dto.getTypeId())
|
||||
.dataSetVersion(dto.getDataSetVersion() != null ? dto.getDataSetVersion().getDataSetVersion() : null)
|
||||
.action1(dto.getAction1())
|
||||
.action2(dto.getAction2())
|
||||
.action3(dto.getAction3())
|
||||
.actionCode1(dto.getActionCode1())
|
||||
.actionCode2(dto.getActionCode2())
|
||||
.actionCode3(dto.getActionCode3())
|
||||
.amsaActionCode1(dto.getAmsaActionCode1())
|
||||
.amsaActionCode2(dto.getAmsaActionCode2())
|
||||
.amsaActionCode3(dto.getAmsaActionCode3())
|
||||
.classIsResponsible(dto.getClassIsResponsible())
|
||||
.defectCode(dto.getDefectCode())
|
||||
.defectText(dto.getDefectText())
|
||||
.defectiveItemCode(dto.getDefectiveItemCode())
|
||||
.detentionReasonDeficiency(dto.getDetentionReasonDeficiency())
|
||||
.mainDefectCode(dto.getMainDefectCode())
|
||||
.mainDefectText(dto.getMainDefectText())
|
||||
.natureOfDefectCode(dto.getNatureOfDefectCode())
|
||||
.natureOfDefectDecode(dto.getNatureOfDefectDecode())
|
||||
.otherAction(dto.getOtherAction())
|
||||
.otherRecognisedOrgResp(dto.getOtherRecognisedOrgResp())
|
||||
.recognisedOrgResp(dto.getRecognisedOrgResp())
|
||||
.recognisedOrgRespCode(dto.getRecognisedOrgRespCode())
|
||||
.recognisedOrgRespYn(dto.getRecognisedOrgRespYn())
|
||||
.isAccidentalDamage(dto.getIsAccidentalDamage())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
private List<PscCertificateEntity> convertCertificateDtos(List<PscCertificateDto> dtos) {
|
||||
if (dtos == null || dtos.isEmpty()) return List.of();
|
||||
|
||||
return dtos.stream()
|
||||
.map(dto -> PscCertificateEntity.builder()
|
||||
.certificateId(dto.getCertificateId())
|
||||
.typeId(dto.getTypeId())
|
||||
.dataSetVersion(dto.getDataSetVersion() != null ? dto.getDataSetVersion().getDataSetVersion() : null)
|
||||
.certificateTitle(dto.getCertificateTitle())
|
||||
.certificateTitleCode(dto.getCertificateTitleCode())
|
||||
.classSocOfIssuer(dto.getClassSocOfIssuer())
|
||||
.issueDate(dto.getIssueDate() != null ? parseFlexible(dto.getIssueDate()) : null)
|
||||
.expiryDate(dto.getExpiryDate() != null ? parseFlexible(dto.getExpiryDate()) : null)
|
||||
.inspectionId(dto.getInspectionId())
|
||||
.issuingAuthority(dto.getIssuingAuthority())
|
||||
.issuingAuthorityCode(dto.getIssuingAuthorityCode())
|
||||
.lastSurveyDate(dto.getLastSurveyDate() != null ? parseFlexible(dto.getLastSurveyDate()) : null)
|
||||
.latestSurveyPlace(dto.getLatestSurveyPlace())
|
||||
.latestSurveyPlaceCode(dto.getLatestSurveyPlaceCode())
|
||||
.lrno(dto.getLrno())
|
||||
.otherIssuingAuthority(dto.getOtherIssuingAuthority())
|
||||
.otherSurveyAuthority(dto.getOtherSurveyAuthority())
|
||||
.surveyAuthority(dto.getSurveyAuthority())
|
||||
.surveyAuthorityCode(dto.getSurveyAuthorityCode())
|
||||
.surveyAuthorityType(dto.getSurveyAuthorityType())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<PscAllCertificateEntity> convertAllCertificateDtos(List<PscAllCertificateDto> dtos) {
|
||||
if (dtos == null || dtos.isEmpty()) return List.of();
|
||||
|
||||
return dtos.stream()
|
||||
.map(dto -> PscAllCertificateEntity.builder()
|
||||
.certificateId(dto.getCertificateId())
|
||||
.typeId(dto.getTypeId())
|
||||
.dataSetVersion(dto.getDataSetVersion() != null ? dto.getDataSetVersion().getDataSetVersion() : null)
|
||||
.inspectionId(dto.getInspectionId())
|
||||
.lrno(dto.getLrno())
|
||||
.certificateTitleCode(dto.getCertificateTitleCode())
|
||||
.certificateTitle(dto.getCertificateTitle())
|
||||
.issuingAuthorityCode(dto.getIssuingAuthorityCode())
|
||||
.issuingAuthority(dto.getIssuingAuthority())
|
||||
.classSocOfIssuer(dto.getClassSocOfIssuer())
|
||||
.otherIssuingAuthority(dto.getOtherIssuingAuthority())
|
||||
.issueDate(dto.getIssueDate() != null ? parseFlexible(dto.getIssueDate()) : null)
|
||||
.expiryDate(dto.getExpiryDate() != null ? parseFlexible(dto.getExpiryDate()) : null)
|
||||
.lastSurveyDate(dto.getLastSurveyDate() != null ? parseFlexible(dto.getLastSurveyDate()) : null)
|
||||
.surveyAuthorityCode(dto.getSurveyAuthorityCode())
|
||||
.surveyAuthority(dto.getSurveyAuthority())
|
||||
.otherSurveyAuthority(dto.getOtherSurveyAuthority())
|
||||
.latestSurveyPlace(dto.getLatestSurveyPlace())
|
||||
.latestSurveyPlaceCode(dto.getLatestSurveyPlaceCode())
|
||||
.surveyAuthorityType(dto.getSurveyAuthorityType())
|
||||
.inspectionDate(dto.getInspectionDate())
|
||||
.inspectedBy(dto.getInspectedBy())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static final List<DateTimeFormatter> FORMATTERS = Arrays.asList(
|
||||
DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"),
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"),
|
||||
DateTimeFormatter.ISO_LOCAL_DATE_TIME
|
||||
);
|
||||
|
||||
public static LocalDateTime parseFlexible(String dateStr) {
|
||||
if (dateStr == null || dateStr.isEmpty()) return null;
|
||||
|
||||
for (DateTimeFormatter formatter : FORMATTERS) {
|
||||
try {
|
||||
return LocalDateTime.parse(dateStr, formatter);
|
||||
} catch (DateTimeParseException ignored) {
|
||||
// 포맷 실패 시 다음 시도
|
||||
}
|
||||
}
|
||||
// 모두 실패 시 null 반환
|
||||
System.err.println("날짜 파싱 실패: " + dateStr);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,173 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.reader;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.snp.batch.common.batch.reader.BaseApiReader;
|
||||
import com.snp.batch.jobs.pscInspection.batch.dto.PscApiResponseDto;
|
||||
import com.snp.batch.jobs.pscInspection.batch.dto.PscInspectionDto;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.batch.core.configuration.annotation.StepScope;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@StepScope
|
||||
public class PscApiReader extends BaseApiReader<PscInspectionDto> {
|
||||
|
||||
//private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
private final String fromDate;
|
||||
private final String toDate;
|
||||
// private List<String> allImoNumbers;
|
||||
private List<PscInspectionDto> allData;
|
||||
private int currentBatchIndex = 0;
|
||||
private final int batchSize = 10;
|
||||
|
||||
public PscApiReader(@Qualifier("maritimeApiWebClient") WebClient webClient,
|
||||
@Value("#{jobParameters['fromDate']}") String fromDate,
|
||||
@Value("#{jobParameters['toDate']}") String toDate) {
|
||||
super(webClient);
|
||||
//this.jdbcTemplate = jdbcTemplate;
|
||||
this.fromDate = fromDate;
|
||||
this.toDate = toDate;
|
||||
enableChunkMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getReaderName() {
|
||||
return "PscApiReader";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void resetCustomState() {
|
||||
this.currentBatchIndex = 0;
|
||||
// this.allImoNumbers = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getApiPath() {
|
||||
return "/MaritimeWCF/PSCService.svc/RESTFul/GetPSCDataByLastUpdateDateRange";
|
||||
}
|
||||
|
||||
private static final String GET_ALL_IMO_QUERY =
|
||||
"SELECT imo_number FROM ship_data ORDER BY id";
|
||||
// "SELECT imo_number FROM snp_data.ship_data where imo_number > (select max(imo) from snp_data.t_berthcalls) ORDER BY imo_number";
|
||||
|
||||
@Override
|
||||
protected void beforeFetch() {
|
||||
// 전처리 과정
|
||||
// Step 1. IMO 전체 번호 조회
|
||||
/*log.info("[{}] ship_data 테이블에서 IMO 번호 조회 시작...", getReaderName());
|
||||
|
||||
allImoNumbers = jdbcTemplate.queryForList(GET_ALL_IMO_QUERY, String.class);
|
||||
int totalBatches = (int) Math.ceil((double) allImoNumbers.size() / batchSize);
|
||||
|
||||
log.info("[{}] 총 {} 개의 IMO 번호 조회 완료", getReaderName(), allImoNumbers.size());
|
||||
log.info("[{}] {}개씩 배치로 분할하여 API 호출 예정", getReaderName(), batchSize);
|
||||
log.info("[{}] 예상 배치 수: {} 개", getReaderName(), totalBatches);
|
||||
|
||||
// API 통계 초기화
|
||||
updateApiCallStats(totalBatches, 0);*/
|
||||
log.info("[PSC] 요청 날짜 범위: {} → {}", fromDate, toDate);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected List<PscInspectionDto> fetchNextBatch() {
|
||||
|
||||
|
||||
// 1) 처음 호출이면 API 한 번 호출해서 전체 데이터를 가져온다
|
||||
if (allData == null) {
|
||||
log.info("[PSC] 최초 API 조회 실행: {} ~ {}", fromDate, toDate);
|
||||
allData = callApiWithBatch(fromDate, toDate);
|
||||
|
||||
if (allData == null || allData.isEmpty()) {
|
||||
log.warn("[PSC] 조회된 데이터 없음 → 종료");
|
||||
return null;
|
||||
}
|
||||
|
||||
log.info("[PSC] 총 {}건 데이터 조회됨. batchSize = {}", allData.size(), batchSize);
|
||||
}
|
||||
|
||||
// 2) 이미 끝까지 읽었으면 종료
|
||||
if (currentBatchIndex >= allData.size()) {
|
||||
log.info("[PSC] 모든 배치 처리 완료");
|
||||
return null; // Step 종료 신호
|
||||
}
|
||||
|
||||
// 3) 이번 배치의 end 계산
|
||||
int end = Math.min(currentBatchIndex + batchSize, allData.size());
|
||||
|
||||
// 4) 현재 batch 리스트 잘라서 반환
|
||||
List<PscInspectionDto> batch = allData.subList(currentBatchIndex, end);
|
||||
|
||||
int batchNum = (currentBatchIndex / batchSize) + 1;
|
||||
int totalBatches = (int) Math.ceil((double) allData.size() / batchSize);
|
||||
|
||||
log.info("[PSC] 배치 {}/{} 처리 중: {}건", batchNum, totalBatches, batch.size());
|
||||
|
||||
// 다음 batch 인덱스 이동
|
||||
currentBatchIndex = end;
|
||||
|
||||
return batch;
|
||||
}
|
||||
|
||||
// private List<PscInspectionDto> callApiWithBatch(String lrno) {
|
||||
private List<PscInspectionDto> callApiWithBatch(String from, String to) {
|
||||
|
||||
String[] f = from.split("-");
|
||||
String[] t = to.split("-");
|
||||
|
||||
String url = getApiPath()
|
||||
+ "?shipsCategory=0"
|
||||
+ "&fromYear=" + f[0]
|
||||
+ "&fromMonth=" + f[1]
|
||||
+ "&fromDay=" + f[2]
|
||||
+ "&toYear=" + t[0]
|
||||
+ "&toMonth=" + t[1]
|
||||
+ "&toDay=" + t[2];
|
||||
|
||||
log.info("[PSC] API 호출 URL = {}", url);
|
||||
|
||||
String json = webClient.get()
|
||||
.uri(url)
|
||||
.retrieve()
|
||||
.bodyToMono(String.class)
|
||||
.block();
|
||||
|
||||
if (json == null || json.isBlank()) {
|
||||
log.warn("[PSC] API 응답 없음");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
PscApiResponseDto resp = mapper.readValue(json, PscApiResponseDto.class);
|
||||
|
||||
if (resp.getInspections() == null) {
|
||||
log.warn("[PSC] inspections 필드 없음");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return resp.getInspections();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[PSC] JSON 파싱 실패: {}", e.getMessage());
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterFetch(List<PscInspectionDto> data) {
|
||||
if (data == null) {
|
||||
int totalBatches = (int) Math.ceil((double) allData.size() / batchSize);
|
||||
log.info("[{}] 전체 {} 개 배치 처리 완료", getReaderName(), totalBatches);
|
||||
log.info("[{}] 총 {} 개의 IMO 번호에 대한 API 호출 종료",
|
||||
getReaderName(), allData.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.repository;
|
||||
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscAllCertificateEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PscAllCertificateRepository {
|
||||
void saveAllCertificates(List<PscAllCertificateEntity> certificates);
|
||||
}
|
||||
@ -0,0 +1,146 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.repository;
|
||||
|
||||
import com.snp.batch.common.batch.repository.BaseJdbcRepository;
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscAllCertificateEntity;
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscCertificateEntity;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Repository
|
||||
public class PscAllCertificateRepositoryImpl extends BaseJdbcRepository<PscAllCertificateEntity, String>
|
||||
implements PscAllCertificateRepository {
|
||||
public PscAllCertificateRepositoryImpl(JdbcTemplate jdbcTemplate) {
|
||||
super(jdbcTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTableName() {
|
||||
return "new_snp.psc_all_certificate";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RowMapper<PscAllCertificateEntity> getRowMapper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEntityName() {
|
||||
return "PscAllCertificate";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String extractId(PscAllCertificateEntity entity) {
|
||||
return entity.getCertificateId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInsertSql() {
|
||||
return """
|
||||
INSERT INTO new_snp.psc_all_certificate(
|
||||
certificate_id,
|
||||
type_id,
|
||||
data_set_version,
|
||||
inspection_id,
|
||||
lrno,
|
||||
certificate_title_code,
|
||||
certificate_title,
|
||||
issuing_authority_code,
|
||||
issuing_authority,
|
||||
class_soc_of_issuer,
|
||||
other_issuing_authority,
|
||||
issue_date,
|
||||
expiry_date,
|
||||
last_survey_date,
|
||||
survey_authority_code,
|
||||
survey_authority,
|
||||
other_survey_authority,
|
||||
latest_survey_place,
|
||||
latest_survey_place_code,
|
||||
survey_authority_type,
|
||||
inspection_date,
|
||||
inspected_by
|
||||
) VALUES (
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, \s
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
||||
?, ?
|
||||
)
|
||||
ON CONFLICT (certificate_id)
|
||||
DO UPDATE SET
|
||||
type_id = EXCLUDED.type_id,
|
||||
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,
|
||||
class_soc_of_issuer = EXCLUDED.class_soc_of_issuer,
|
||||
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
|
||||
""";
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUpdateSql() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setInsertParameters(PreparedStatement ps, PscAllCertificateEntity e) throws Exception {
|
||||
int i = 1;
|
||||
|
||||
ps.setString(i++, e.getCertificateId());
|
||||
ps.setString(i++, e.getTypeId());
|
||||
ps.setString(i++, e.getDataSetVersion());
|
||||
ps.setString(i++, e.getInspectionId());
|
||||
ps.setString(i++, e.getLrno());
|
||||
ps.setString(i++, e.getCertificateTitleCode());
|
||||
ps.setString(i++, e.getCertificateTitle());
|
||||
ps.setString(i++, e.getIssuingAuthorityCode());
|
||||
ps.setString(i++, e.getIssuingAuthority());
|
||||
ps.setString(i++, e.getClassSocOfIssuer());
|
||||
ps.setString(i++, e.getOtherIssuingAuthority());
|
||||
ps.setTimestamp(i++, e.getIssueDate() != null ? Timestamp.valueOf(e.getIssueDate()) : null);
|
||||
ps.setTimestamp(i++, e.getExpiryDate() != null ? Timestamp.valueOf(e.getExpiryDate()) : null);
|
||||
ps.setTimestamp(i++, e.getLastSurveyDate() != null ? Timestamp.valueOf(e.getLastSurveyDate()) : null);
|
||||
ps.setString(i++, e.getSurveyAuthorityCode());
|
||||
ps.setString(i++, e.getSurveyAuthority());
|
||||
ps.setString(i++, e.getOtherSurveyAuthority());
|
||||
ps.setString(i++, e.getLatestSurveyPlace());
|
||||
ps.setString(i++, e.getLatestSurveyPlaceCode());
|
||||
ps.setString(i++, e.getSurveyAuthorityType());
|
||||
ps.setString(i++, e.getInspectionDate());
|
||||
ps.setString(i++, e.getInspectedBy());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpdateParameters(PreparedStatement ps, PscAllCertificateEntity entity) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAllCertificates(List<PscAllCertificateEntity> entities) {
|
||||
if (entities == null || entities.isEmpty()) return;
|
||||
log.info("PSC AllCertificates 저장 시작 = {}건", entities.size());
|
||||
batchInsert(entities);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.repository;
|
||||
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscCertificateEntity;
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscDefectEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PscCertificateRepository {
|
||||
void saveCertificates(List<PscCertificateEntity> certificates);
|
||||
}
|
||||
@ -0,0 +1,139 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.repository;
|
||||
|
||||
import com.snp.batch.common.batch.repository.BaseJdbcRepository;
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscCertificateEntity;
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscDefectEntity;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Repository
|
||||
public class PscCertificateRepositoryImpl extends BaseJdbcRepository<PscCertificateEntity, String>
|
||||
implements PscCertificateRepository {
|
||||
public PscCertificateRepositoryImpl(JdbcTemplate jdbcTemplate) {
|
||||
super(jdbcTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTableName() {
|
||||
return "new_snp.psc_certificate";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RowMapper<PscCertificateEntity> getRowMapper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEntityName() {
|
||||
return "PscCertificate";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String extractId(PscCertificateEntity entity) {
|
||||
return entity.getCertificateId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInsertSql() {
|
||||
return """
|
||||
INSERT INTO new_snp.psc_certificate(
|
||||
certificate_id,
|
||||
type_id,
|
||||
data_set_version,
|
||||
certificate_title,
|
||||
certificate_title_code,
|
||||
class_soc_of_issuer,
|
||||
expiry_date,
|
||||
inspection_id,
|
||||
issue_date,
|
||||
issuing_authority,
|
||||
issuing_authority_code,
|
||||
last_survey_date,
|
||||
latest_survey_place,
|
||||
latest_survey_place_code,
|
||||
lrno,
|
||||
other_issuing_authority,
|
||||
other_survey_authority,
|
||||
survey_authority,
|
||||
survey_authority_code,
|
||||
survey_authority_type
|
||||
) VALUES (
|
||||
?,?,?,?,?,?,?,?,?,?,
|
||||
?,?,?,?,?,?,?,?,?,?
|
||||
)
|
||||
ON CONFLICT (certificate_id)
|
||||
DO UPDATE SET
|
||||
type_id = EXCLUDED.type_id,
|
||||
data_set_version = EXCLUDED.data_set_version,
|
||||
certificate_title = EXCLUDED.certificate_title,
|
||||
certificate_title_code = EXCLUDED.certificate_title_code,
|
||||
class_soc_of_issuer = EXCLUDED.class_soc_of_issuer,
|
||||
expiry_date = EXCLUDED.expiry_date,
|
||||
inspection_id = EXCLUDED.inspection_id,
|
||||
issue_date = EXCLUDED.issue_date,
|
||||
issuing_authority = EXCLUDED.issuing_authority,
|
||||
issuing_authority_code = EXCLUDED.issuing_authority_code,
|
||||
last_survey_date = EXCLUDED.last_survey_date,
|
||||
latest_survey_place = EXCLUDED.latest_survey_place,
|
||||
latest_survey_place_code = EXCLUDED.latest_survey_place_code,
|
||||
lrno = EXCLUDED.lrno,
|
||||
other_issuing_authority = EXCLUDED.other_issuing_authority,
|
||||
other_survey_authority = EXCLUDED.other_survey_authority,
|
||||
survey_authority = EXCLUDED.survey_authority,
|
||||
survey_authority_code = EXCLUDED.survey_authority_code,
|
||||
survey_authority_type = EXCLUDED.survey_authority_type
|
||||
""";
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUpdateSql() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setInsertParameters(PreparedStatement ps, PscCertificateEntity e) throws Exception {
|
||||
int i = 1;
|
||||
|
||||
ps.setString(i++, e.getCertificateId());
|
||||
ps.setString(i++, e.getTypeId());
|
||||
ps.setString(i++, e.getDataSetVersion());
|
||||
ps.setString(i++, e.getCertificateTitle());
|
||||
ps.setString(i++, e.getCertificateTitleCode());
|
||||
ps.setString(i++, e.getClassSocOfIssuer());
|
||||
ps.setTimestamp(i++, e.getExpiryDate() != null ? Timestamp.valueOf(e.getExpiryDate()) : null);
|
||||
ps.setString(i++, e.getInspectionId());
|
||||
ps.setTimestamp(i++, e.getIssueDate() != null ? Timestamp.valueOf(e.getIssueDate()) : null);
|
||||
ps.setString(i++, e.getIssuingAuthority());
|
||||
ps.setString(i++, e.getIssuingAuthorityCode());
|
||||
ps.setTimestamp(i++, e.getLastSurveyDate() != null ? Timestamp.valueOf(e.getLastSurveyDate()) : null);
|
||||
ps.setString(i++, e.getLatestSurveyPlace());
|
||||
ps.setString(i++, e.getLatestSurveyPlaceCode());
|
||||
ps.setString(i++, e.getLrno());
|
||||
ps.setString(i++, e.getOtherIssuingAuthority());
|
||||
ps.setString(i++, e.getOtherSurveyAuthority());
|
||||
ps.setString(i++, e.getSurveyAuthority());
|
||||
ps.setString(i++, e.getSurveyAuthorityCode());
|
||||
ps.setString(i++, e.getSurveyAuthorityType());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpdateParameters(PreparedStatement ps, PscCertificateEntity entity) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveCertificates(List<PscCertificateEntity> entities) {
|
||||
if (entities == null || entities.isEmpty()) return;
|
||||
log.info("PSC Certificate 저장 시작 = {}건", entities.size());
|
||||
batchInsert(entities);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.repository;
|
||||
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscDefectEntity;
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscInspectionEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PscDefectRepository {
|
||||
void saveDefects(List<PscDefectEntity> defects);
|
||||
}
|
||||
@ -0,0 +1,163 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.repository;
|
||||
|
||||
import com.snp.batch.common.batch.repository.BaseJdbcRepository;
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscDefectEntity;
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscInspectionEntity;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Repository
|
||||
public class PscDefectRepositoryImpl extends BaseJdbcRepository<PscDefectEntity, String>
|
||||
implements PscDefectRepository {
|
||||
public PscDefectRepositoryImpl(JdbcTemplate jdbcTemplate) {
|
||||
super(jdbcTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTableName() {
|
||||
return "new_snp.psc_detail";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RowMapper<PscDefectEntity> getRowMapper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEntityName() {
|
||||
return "PscInspection";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String extractId(PscDefectEntity entity) {
|
||||
return entity.getInspectionId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInsertSql() {
|
||||
return """
|
||||
INSERT INTO new_snp.psc_defect(
|
||||
defect_id,
|
||||
inspection_id,
|
||||
type_id,
|
||||
data_set_version,
|
||||
action_1,
|
||||
action_2,
|
||||
action_3,
|
||||
action_code_1,
|
||||
action_code_2,
|
||||
action_code_3,
|
||||
amsa_action_code_1,
|
||||
amsa_action_code_2,
|
||||
amsa_action_code_3,
|
||||
class_is_responsible,
|
||||
defect_code,
|
||||
defect_text,
|
||||
defective_item_code,
|
||||
detention_reason_deficiency,
|
||||
main_defect_code,
|
||||
main_defect_text,
|
||||
nature_of_defect_code,
|
||||
nature_of_defect_decode,
|
||||
other_action,
|
||||
other_recognised_org_resp,
|
||||
recognised_org_resp,
|
||||
recognised_org_resp_code,
|
||||
recognised_org_resp_yn,
|
||||
is_accidental_damage
|
||||
) VALUES (?,?,?,?,?,?,?,?,?,?,
|
||||
?,?,?,?,?,?,?,?,?,?,
|
||||
?,?,?,?,?,?,?,?)
|
||||
ON CONFLICT (defect_id)
|
||||
DO UPDATE SET
|
||||
inspection_id = EXCLUDED.inspection_id,
|
||||
type_id = EXCLUDED.type_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,
|
||||
amsa_action_code_1 = EXCLUDED.amsa_action_code_1,
|
||||
amsa_action_code_2 = EXCLUDED.amsa_action_code_2,
|
||||
amsa_action_code_3 = EXCLUDED.amsa_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
|
||||
""";
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUpdateSql() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setInsertParameters(PreparedStatement ps, PscDefectEntity e) throws Exception {
|
||||
int i = 1;
|
||||
|
||||
ps.setString(i++, e.getDefectId());
|
||||
ps.setString(i++, e.getInspectionId());
|
||||
ps.setString(i++, e.getTypeId());
|
||||
ps.setString(i++, e.getDataSetVersion());
|
||||
ps.setString(i++, e.getAction1());
|
||||
ps.setString(i++, e.getAction2());
|
||||
ps.setString(i++, e.getAction3());
|
||||
ps.setString(i++, e.getActionCode1());
|
||||
ps.setString(i++, e.getActionCode2());
|
||||
ps.setString(i++, e.getActionCode3());
|
||||
ps.setString(i++, e.getAmsaActionCode1());
|
||||
ps.setString(i++, e.getAmsaActionCode2());
|
||||
ps.setString(i++, e.getAmsaActionCode3());
|
||||
ps.setString(i++, e.getClassIsResponsible());
|
||||
ps.setString(i++, e.getDefectCode());
|
||||
ps.setString(i++, e.getDefectText());
|
||||
ps.setString(i++, e.getDefectiveItemCode());
|
||||
ps.setString(i++, e.getDetentionReasonDeficiency());
|
||||
ps.setString(i++, e.getMainDefectCode());
|
||||
ps.setString(i++, e.getMainDefectText());
|
||||
ps.setString(i++, e.getNatureOfDefectCode());
|
||||
ps.setString(i++, e.getNatureOfDefectDecode());
|
||||
ps.setString(i++, e.getOtherAction());
|
||||
ps.setString(i++, e.getOtherRecognisedOrgResp());
|
||||
ps.setString(i++, e.getRecognisedOrgResp());
|
||||
ps.setString(i++, e.getRecognisedOrgRespCode());
|
||||
ps.setString(i++, e.getRecognisedOrgRespYn());
|
||||
ps.setString(i++, e.getIsAccidentalDamage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpdateParameters(PreparedStatement ps, PscDefectEntity entity) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveDefects(List<PscDefectEntity> entities) {
|
||||
if (entities == null || entities.isEmpty()) return;
|
||||
log.info("PSC Defect 저장 시작 = {}건", entities.size());
|
||||
batchInsert(entities);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.repository;
|
||||
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscInspectionEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PscInspectionRepository {
|
||||
void saveAll(List<PscInspectionEntity> entities);
|
||||
}
|
||||
@ -0,0 +1,186 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.repository;
|
||||
|
||||
import com.snp.batch.common.batch.repository.BaseJdbcRepository;
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscInspectionEntity;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Repository
|
||||
public class PscInspectionRepositoryImpl extends BaseJdbcRepository<PscInspectionEntity, String>
|
||||
implements PscInspectionRepository{
|
||||
public PscInspectionRepositoryImpl(JdbcTemplate jdbcTemplate) {
|
||||
super(jdbcTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTableName() {
|
||||
return "new_snp.psc_detail";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEntityName() {
|
||||
return "PscInspection";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String extractId(PscInspectionEntity entity) {
|
||||
return entity.getInspectionId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInsertSql() {
|
||||
return """
|
||||
INSERT INTO new_snp.psc_detail(
|
||||
inspection_id,
|
||||
type_id,
|
||||
data_set_version,
|
||||
authorisation,
|
||||
call_sign,
|
||||
class,
|
||||
cargo,
|
||||
charterer,
|
||||
country,
|
||||
inspection_date,
|
||||
release_date,
|
||||
ship_detained,
|
||||
dead_weight,
|
||||
expanded_inspection,
|
||||
flag,
|
||||
follow_up_inspection,
|
||||
gross_tonnage,
|
||||
inspection_port_code,
|
||||
inspection_port_decode,
|
||||
keel_laid,
|
||||
last_updated,
|
||||
ihslr_or_imo_ship_no,
|
||||
manager,
|
||||
number_of_days_detained,
|
||||
number_of_defects,
|
||||
number_of_part_days_detained,
|
||||
other_inspection_type,
|
||||
owner,
|
||||
ship_name,
|
||||
ship_type_code,
|
||||
ship_type_decode,
|
||||
source,
|
||||
unlocode,
|
||||
year_of_build
|
||||
) VALUES (
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
||||
?, ?, ?, ?
|
||||
)
|
||||
ON CONFLICT (inspection_id)
|
||||
DO UPDATE SET
|
||||
type_id = EXCLUDED.type_id,
|
||||
data_set_version = EXCLUDED.data_set_version,
|
||||
authorisation = EXCLUDED.authorisation,
|
||||
call_sign = EXCLUDED.call_sign,
|
||||
class = EXCLUDED.class,
|
||||
cargo = EXCLUDED.cargo,
|
||||
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_code = EXCLUDED.inspection_port_code,
|
||||
inspection_port_decode = EXCLUDED.inspection_port_decode,
|
||||
keel_laid = EXCLUDED.keel_laid,
|
||||
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
|
||||
""";
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setInsertParameters(PreparedStatement ps, PscInspectionEntity e) throws Exception {
|
||||
int i = 1;
|
||||
|
||||
ps.setString(i++, e.getInspectionId());
|
||||
ps.setString(i++, e.getTypeId());
|
||||
ps.setString(i++, e.getDataSetVersion());
|
||||
ps.setString(i++, e.getAuthorisation());
|
||||
ps.setString(i++, e.getCallSign());
|
||||
ps.setString(i++, e.getShipClass());
|
||||
ps.setString(i++, e.getCargo());
|
||||
ps.setString(i++, e.getCharterer());
|
||||
ps.setString(i++, e.getCountry());
|
||||
ps.setTimestamp(i++, e.getInspectionDate() != null ? Timestamp.valueOf(e.getInspectionDate()) : null);
|
||||
ps.setTimestamp(i++, e.getReleaseDate() != null ? Timestamp.valueOf(e.getReleaseDate()) : null);
|
||||
ps.setString(i++, e.getShipDetained());
|
||||
ps.setString(i++, e.getDeadWeight());
|
||||
ps.setString(i++, e.getExpandedInspection());
|
||||
ps.setString(i++, e.getFlag());
|
||||
ps.setString(i++, e.getFollowUpInspection());
|
||||
ps.setString(i++, e.getGrossTonnage());
|
||||
ps.setString(i++, e.getInspectionPortCode());
|
||||
ps.setString(i++, e.getInspectionPortDecode());
|
||||
ps.setString(i++, e.getKeelLaid());
|
||||
ps.setTimestamp(i++, e.getLastUpdated() != null ? Timestamp.valueOf(e.getLastUpdated()) : null);
|
||||
ps.setString(i++, e.getIhslrOrImoShipNo());
|
||||
ps.setString(i++, e.getManager());
|
||||
if (e.getNumberOfDaysDetained() != null) {
|
||||
ps.setInt(i++, e.getNumberOfDaysDetained());
|
||||
} else {
|
||||
ps.setNull(i++, Types.INTEGER);
|
||||
}
|
||||
ps.setString(i++, e.getNumberOfDefects());
|
||||
ps.setBigDecimal(i++, e.getNumberOfPartDaysDetained());
|
||||
ps.setString(i++, e.getOtherInspectionType());
|
||||
ps.setString(i++, e.getOwner());
|
||||
ps.setString(i++, e.getShipName());
|
||||
ps.setString(i++, e.getShipTypeCode());
|
||||
ps.setString(i++, e.getShipTypeDecode());
|
||||
ps.setString(i++, e.getSource());
|
||||
ps.setString(i++, e.getUnlocode());
|
||||
ps.setString(i++, e.getYearOfBuild());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAll(List<PscInspectionEntity> entities) {
|
||||
if (entities == null || entities.isEmpty()) return;
|
||||
log.info("PSC Inspection 저장 시작 = {}건", entities.size());
|
||||
batchInsert(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpdateParameters(PreparedStatement ps, PscInspectionEntity entity) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUpdateSql() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RowMapper<PscInspectionEntity> getRowMapper() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package com.snp.batch.jobs.pscInspection.batch.writer;
|
||||
|
||||
import com.snp.batch.common.batch.writer.BaseWriter;
|
||||
import com.snp.batch.jobs.pscInspection.batch.entity.PscInspectionEntity;
|
||||
import com.snp.batch.jobs.pscInspection.batch.repository.PscAllCertificateRepository;
|
||||
import com.snp.batch.jobs.pscInspection.batch.repository.PscCertificateRepository;
|
||||
import com.snp.batch.jobs.pscInspection.batch.repository.PscDefectRepository;
|
||||
import com.snp.batch.jobs.pscInspection.batch.repository.PscInspectionRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class PscInspectionWriter extends BaseWriter<PscInspectionEntity> {
|
||||
private final PscInspectionRepository pscInspectionRepository;
|
||||
private final PscDefectRepository pscDefectRepository;
|
||||
private final PscCertificateRepository pscCertificateRepository;
|
||||
private final PscAllCertificateRepository pscAllCertificateRepository;
|
||||
|
||||
public PscInspectionWriter(PscInspectionRepository pscInspectionRepository,
|
||||
PscDefectRepository pscDefectRepository,
|
||||
PscCertificateRepository pscCertificateRepository,
|
||||
PscAllCertificateRepository pscAllCertificateRepository) {
|
||||
super("PscInspection");
|
||||
this.pscInspectionRepository = pscInspectionRepository;
|
||||
this.pscDefectRepository = pscDefectRepository;
|
||||
this.pscCertificateRepository = pscCertificateRepository;
|
||||
this.pscAllCertificateRepository = pscAllCertificateRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeItems(List<PscInspectionEntity> items) throws Exception {
|
||||
|
||||
if (items == null || items.isEmpty()) return;
|
||||
//pscInspectionRepository.saveAll(items);
|
||||
log.info("PSC Inspection 저장: {} 건", items.size());
|
||||
|
||||
for (PscInspectionEntity entity : items) {
|
||||
pscInspectionRepository.saveAll(List.of(entity));
|
||||
pscDefectRepository.saveDefects(entity.getDefects());
|
||||
pscCertificateRepository.saveCertificates(entity.getCertificates());
|
||||
pscAllCertificateRepository.saveAllCertificates(entity.getAllCertificates());
|
||||
|
||||
// 효율적으로 로그
|
||||
int defectCount = entity.getDefects() != null ? entity.getDefects().size() : 0;
|
||||
int certificateCount = entity.getCertificates() != null ? entity.getCertificates().size() : 0;
|
||||
int allCertificateCount = entity.getAllCertificates() != null ? entity.getAllCertificates().size() : 0;
|
||||
|
||||
log.info("Inspection ID: {}, Defects: {}, Certificates: {}, AllCertificates: {}",
|
||||
entity.getInspectionId(), defectCount, certificateCount, allCertificateCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -82,7 +82,7 @@ public class BerthCallsReader extends BaseApiReader<BerthCallsDto> {
|
||||
|
||||
private static final String GET_ALL_IMO_QUERY =
|
||||
// "SELECT imo_number FROM ship_data ORDER BY id";
|
||||
"SELECT imo_number FROM snp_data.ship_data where imo_number > (select max(imo) from snp_data.t_berthcalls) ORDER BY imo_number";
|
||||
"SELECT imo_number FROM snp_data.ship_data where imo_number > (select max(imo) from snp_data.t_berthcall) ORDER BY imo_number";
|
||||
|
||||
/**
|
||||
* 최초 1회만 실행: ship_data 테이블에서 IMO 번호 전체 조회
|
||||
|
||||
불러오는 중...
Reference in New Issue
Block a user