- BypassApiConfig에 endpointName 필드 추가 (externalPath에서 자동 추출) - domainName unique 제약 → domainName + endpointName 복합 unique로 변경 - 코드 생성 시 같은 도메인의 모든 설정을 합쳐 Controller 1개 생성 - Service/DTO는 엔드포인트별로 별도 생성 - CodeGenerationResult에 servicePaths/dtoPaths 목록 반환 - 프론트엔드 타입/UI 업데이트 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
137 lines
6.1 KiB
Java
137 lines
6.1 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.BypassFieldDto;
|
|
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 com.snp.batch.service.JsonSchemaParser;
|
|
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.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 JsonSchemaParser jsonSchemaParser;
|
|
private final BypassApiConfigRepository configRepository;
|
|
|
|
@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, DTO Java 소스 코드를 생성합니다. 같은 도메인의 모든 설정을 하나의 Controller로 합칩니다."
|
|
)
|
|
@PostMapping("/{id}/generate")
|
|
public ResponseEntity<ApiResponse<CodeGenerationResult>> generateCode(
|
|
@PathVariable Long id,
|
|
@RequestParam(defaultValue = "false") boolean force) {
|
|
try {
|
|
BypassApiConfig config = configRepository.findById(id)
|
|
.orElseThrow(() -> new IllegalArgumentException("설정을 찾을 수 없습니다: " + id));
|
|
|
|
// 같은 도메인의 모든 설정을 조회하여 함께 생성
|
|
List<BypassApiConfig> domainConfigs = configRepository.findByDomainNameOrderById(config.getDomainName());
|
|
|
|
CodeGenerationResult result = bypassCodeGenerator.generate(domainConfigs, force);
|
|
|
|
// 같은 도메인의 모든 설정을 generated로 마킹
|
|
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 = "JSON 샘플 파싱",
|
|
description = "JSON 샘플에서 DTO 필드 목록을 추출합니다."
|
|
)
|
|
@PostMapping("/parse-json")
|
|
public ResponseEntity<ApiResponse<List<BypassFieldDto>>> parseJson(@RequestBody String jsonSample) {
|
|
try {
|
|
List<BypassFieldDto> fields = jsonSchemaParser.parse(jsonSample);
|
|
return ResponseEntity.ok(ApiResponse.success(fields));
|
|
} catch (Exception e) {
|
|
return ResponseEntity.badRequest().body(ApiResponse.error("JSON 파싱 실패: " + e.getMessage()));
|
|
}
|
|
}
|
|
|
|
@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));
|
|
}
|
|
}
|