- Response JSON 원본 반환 (ApiResponse 래핑 제거, executeRaw 추가) - 메뉴명 변경: Bypass API → API 관리 - 사용자용 API 카탈로그 페이지 (/bypass-catalog) 추가 - 운영 환경 코드 생성 차단 (app.environment=prod 시 비활성화) - Bypass API 코드 생성 (compliance, risk 도메인) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
132 lines
6.0 KiB
Java
132 lines
6.0 KiB
Java
package com.snp.batch.global.controller;
|
|
|
|
import com.snp.batch.common.web.ApiResponse;
|
|
import com.snp.batch.global.dto.BypassConfigRequest;
|
|
import com.snp.batch.global.dto.BypassConfigResponse;
|
|
import com.snp.batch.global.dto.CodeGenerationResult;
|
|
import com.snp.batch.global.model.BypassApiConfig;
|
|
import com.snp.batch.global.repository.BypassApiConfigRepository;
|
|
import com.snp.batch.service.BypassCodeGenerator;
|
|
import com.snp.batch.service.BypassConfigService;
|
|
import io.swagger.v3.oas.annotations.Operation;
|
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
|
import org.springframework.web.bind.annotation.GetMapping;
|
|
import org.springframework.web.bind.annotation.PathVariable;
|
|
import org.springframework.web.bind.annotation.PostMapping;
|
|
import org.springframework.web.bind.annotation.PutMapping;
|
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
import org.springframework.web.bind.annotation.RequestParam;
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* BYPASS API 설정 관리 및 코드 생성 컨트롤러
|
|
*/
|
|
@Slf4j
|
|
@RestController
|
|
@RequestMapping("/api/bypass-config")
|
|
@RequiredArgsConstructor
|
|
@Tag(name = "Bypass Config", description = "BYPASS API 설정 관리 및 코드 생성")
|
|
public class BypassConfigController {
|
|
|
|
private final BypassConfigService bypassConfigService;
|
|
private final BypassCodeGenerator bypassCodeGenerator;
|
|
private final BypassApiConfigRepository configRepository;
|
|
|
|
@Value("${app.environment:dev}")
|
|
private String environment;
|
|
|
|
@Operation(summary = "설정 목록 조회")
|
|
@GetMapping
|
|
public ResponseEntity<ApiResponse<List<BypassConfigResponse>>> getConfigs() {
|
|
return ResponseEntity.ok(ApiResponse.success(bypassConfigService.getConfigs()));
|
|
}
|
|
|
|
@Operation(summary = "설정 상세 조회")
|
|
@GetMapping("/{id}")
|
|
public ResponseEntity<ApiResponse<BypassConfigResponse>> getConfig(@PathVariable Long id) {
|
|
return ResponseEntity.ok(ApiResponse.success(bypassConfigService.getConfig(id)));
|
|
}
|
|
|
|
@Operation(summary = "설정 등록")
|
|
@PostMapping
|
|
public ResponseEntity<ApiResponse<BypassConfigResponse>> createConfig(
|
|
@RequestBody BypassConfigRequest request) {
|
|
return ResponseEntity.ok(ApiResponse.success(bypassConfigService.createConfig(request)));
|
|
}
|
|
|
|
@Operation(summary = "설정 수정")
|
|
@PutMapping("/{id}")
|
|
public ResponseEntity<ApiResponse<BypassConfigResponse>> updateConfig(
|
|
@PathVariable Long id,
|
|
@RequestBody BypassConfigRequest request) {
|
|
return ResponseEntity.ok(ApiResponse.success(bypassConfigService.updateConfig(id, request)));
|
|
}
|
|
|
|
@Operation(summary = "설정 삭제")
|
|
@DeleteMapping("/{id}")
|
|
public ResponseEntity<ApiResponse<Void>> deleteConfig(@PathVariable Long id) {
|
|
bypassConfigService.deleteConfig(id);
|
|
return ResponseEntity.ok(ApiResponse.success("삭제 완료", null));
|
|
}
|
|
|
|
@Operation(
|
|
summary = "코드 생성",
|
|
description = "등록된 설정의 도메인 전체를 기반으로 Controller, Service 소스 코드를 생성합니다. 같은 도메인의 모든 설정을 하나의 Controller로 합칩니다."
|
|
)
|
|
@PostMapping("/{id}/generate")
|
|
public ResponseEntity<ApiResponse<CodeGenerationResult>> generateCode(
|
|
@PathVariable Long id,
|
|
@RequestParam(defaultValue = "false") boolean force) {
|
|
if ("prod".equals(environment)) {
|
|
return ResponseEntity.badRequest()
|
|
.body(ApiResponse.error("운영 환경에서는 코드 생성이 불가합니다. 개발 환경에서 생성 후 배포해주세요."));
|
|
}
|
|
try {
|
|
BypassApiConfig config = configRepository.findById(id)
|
|
.orElseThrow(() -> new IllegalArgumentException("설정을 찾을 수 없습니다: " + id));
|
|
|
|
List<BypassApiConfig> domainConfigs = configRepository.findByDomainNameOrderById(config.getDomainName());
|
|
|
|
CodeGenerationResult result = bypassCodeGenerator.generate(domainConfigs, force);
|
|
|
|
domainConfigs.forEach(c -> bypassConfigService.markAsGenerated(c.getId()));
|
|
|
|
return ResponseEntity.ok(ApiResponse.success(result));
|
|
} catch (IllegalStateException e) {
|
|
return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage()));
|
|
} catch (Exception e) {
|
|
log.error("코드 생성 실패", e);
|
|
return ResponseEntity.internalServerError().body(ApiResponse.error("코드 생성 실패: " + e.getMessage()));
|
|
}
|
|
}
|
|
|
|
@Operation(summary = "환경 정보", description = "현재 서버 환경 정보를 반환합니다 (dev/prod).")
|
|
@GetMapping("/environment")
|
|
public ResponseEntity<ApiResponse<Map<String, Object>>> getEnvironment() {
|
|
return ResponseEntity.ok(ApiResponse.success(Map.of(
|
|
"environment", environment,
|
|
"codeGenerationEnabled", !"prod".equals(environment)
|
|
)));
|
|
}
|
|
|
|
@Operation(summary = "WebClient 빈 목록", description = "사용 가능한 WebClient 빈 이름 목록을 반환합니다.")
|
|
@GetMapping("/webclient-beans")
|
|
public ResponseEntity<ApiResponse<List<Map<String, String>>>> getWebclientBeans() {
|
|
List<Map<String, String>> beans = List.of(
|
|
Map.of("name", "maritimeApiWebClient", "description", "Ship API (shipsapi.maritime.spglobal.com)"),
|
|
Map.of("name", "maritimeAisApiWebClient", "description", "AIS API (aisapi.maritime.spglobal.com)"),
|
|
Map.of("name", "maritimeServiceApiWebClient", "description", "Web Service API (webservices.maritime.spglobal.com)")
|
|
);
|
|
return ResponseEntity.ok(ApiResponse.success(beans));
|
|
}
|
|
}
|