package com.snp.batch.global.config; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.function.client.WebClient; /** * Maritime API WebClient 설정 * * 목적: * - Maritime API 서버에 대한 WebClient Bean 등록 * - 동일한 API 서버를 사용하는 여러 Job에서 재사용 * - 설정 변경 시 한 곳에서만 수정 * * 사용 Job: * - shipDataImportJob: IMO 번호 조회 * - shipDetailImportJob: 선박 상세 정보 조회 * * 다른 API 서버 추가 시: * - 새로운 Config 클래스 생성 (예: OtherApiWebClientConfig) * - Bean 이름을 다르게 지정 (예: @Bean(name = "otherApiWebClient")) */ @Slf4j @Configuration public class MaritimeApiWebClientConfig { @Value("${app.batch.ship-api.url}") private String maritimeApiUrl; @Value("${app.batch.ais-api.url}") private String maritimeAisApiUrl; @Value("${app.batch.webservice-api.url}") private String maritimeServiceApiUrl; @Value("${app.batch.ship-api.username}") private String maritimeApiUsername; @Value("${app.batch.ship-api.password}") private String maritimeApiPassword; /** * Maritime API용 WebClient Bean * * 설정: * - Base URL: Maritime API 서버 주소 * - 인증: Basic Authentication * - 버퍼: 20MB (대용량 응답 처리) * * @return Maritime API WebClient */ @Bean(name = "maritimeApiWebClient") public WebClient maritimeApiWebClient() { log.info("========================================"); log.info("Maritime API WebClient 생성"); log.info("Base URL: {}", maritimeApiUrl); log.info("========================================"); return WebClient.builder() .baseUrl(maritimeApiUrl) .defaultHeaders(headers -> headers.setBasicAuth(maritimeApiUsername, maritimeApiPassword)) .codecs(configurer -> configurer .defaultCodecs() .maxInMemorySize(100 * 1024 * 1024)) // 30MB 버퍼 .build(); } @Bean(name = "maritimeAisApiWebClient") public WebClient maritimeAisApiWebClient(){ log.info("========================================"); log.info("Maritime AIS API WebClient 생성"); log.info("Base URL: {}", maritimeAisApiUrl); log.info("========================================"); return WebClient.builder() .baseUrl(maritimeAisApiUrl) .defaultHeaders(headers -> headers.setBasicAuth(maritimeApiUsername, maritimeApiPassword)) .codecs(configurer -> configurer .defaultCodecs() .maxInMemorySize(50 * 1024 * 1024)) // 50MB 버퍼 (AIS GetTargets 응답 ~20MB+) .build(); } @Bean(name = "maritimeServiceApiWebClient") public WebClient maritimeServiceApiWebClient(){ log.info("========================================"); log.info("Maritime AIS API WebClient 생성"); log.info("Base URL: {}", maritimeServiceApiUrl); log.info("========================================"); return WebClient.builder() .baseUrl(maritimeServiceApiUrl) .defaultHeaders(headers -> headers.setBasicAuth(maritimeApiUsername, maritimeApiPassword)) .codecs(configurer -> configurer .defaultCodecs() .maxInMemorySize(100 * 1024 * 1024)) // 100MB 버퍼 .build(); } } /** * ======================================== * 다른 API 서버 추가 예시 * ======================================== * * 1. 새로운 Config 클래스 생성: * * @Configuration * public class ExternalApiWebClientConfig { * * @Bean(name = "externalApiWebClient") * public WebClient externalApiWebClient( * @Value("${app.batch.external-api.url}") String url, * @Value("${app.batch.external-api.token}") String token) { * * return WebClient.builder() * .baseUrl(url) * .defaultHeader("Authorization", "Bearer " + token) * .build(); * } * } * * 2. JobConfig에서 사용: * * public ExternalJobConfig( * ..., * @Qualifier("externalApiWebClient") WebClient externalApiWebClient) { * this.webClient = externalApiWebClient; * } * * 3. application.yml에 설정 추가: * * app: * batch: * external-api: * url: https://external-api.example.com * token: ${EXTERNAL_API_TOKEN} */