package kr.re.etri.autoflow.controllers; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import kr.re.etri.autoflow.service.PipelineUploadService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.Map; @Slf4j @RestController @RequestMapping("/api") @RequiredArgsConstructor @CrossOrigin(origins = "*") @io.swagger.v3.oas.annotations.tags.Tag(name = "Kubeflow Pipeline", description = "Kubeflow 파이프라인 API") public class KubeflowExperimentsController { private final PipelineUploadService pipelineUploadService; @Operation( summary = "실험 목록 조회", description = "Kubeflow에 등록된 Experiment 리스트를 조회합니다." ) @ApiResponses({ @ApiResponse(responseCode = "200", description = "실험 목록 조회 성공"), @ApiResponse(responseCode = "500", description = "서버 내부 오류", content = @Content) }) @GetMapping("/experiments") public ResponseEntity> listExperiments( @Parameter(description = "조회할 namespace (생략 시 기본값)") @RequestParam(value = "namespace", required = false) String namespace, @Parameter(description = "페이지 크기 (기본값: 10)") @RequestParam(value = "pageSize", required = false, defaultValue = "10") int pageSize, @Parameter(description = "다음 페이지 토큰") @RequestParam(value = "pageToken", required = false) String pageToken ) { try { Map result = pipelineUploadService.listExperiments(namespace, pageSize, pageToken); return ResponseEntity.ok(result); } catch (Exception e) { log.error("List experiments failed", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(Map.of( "status", 500, "error", "Internal Server Error", "message", e.getMessage() )); } } @Operation( summary = "실험 단건 조회", description = "experiment_id로 Kubeflow Experiment 상세 정보를 조회합니다." ) @ApiResponses({ @ApiResponse(responseCode = "200", description = "실험 조회 성공"), @ApiResponse(responseCode = "404", description = "실험을 찾을 수 없음"), @ApiResponse(responseCode = "500", description = "서버 내부 오류") }) @GetMapping("/experiments/{experimentId}") public ResponseEntity getExperimentById( @Parameter(description = "조회할 Experiment ID") @PathVariable String experimentId ) { try { Map result = pipelineUploadService.getExperimentById(experimentId); if (result == null || result.isEmpty()) { return ResponseEntity.status(HttpStatus.NOT_FOUND) .body(Map.of( "status", 404, "error", "Not Found", "message", "Experiment not found" )); } return ResponseEntity.ok(result); } catch (IllegalArgumentException e) { log.warn("잘못된 요청: experimentId={}", experimentId, e); return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body(Map.of( "status", 400, "error", "Bad Request", "message", "Invalid experiment ID format" )); } catch (Exception e) { log.error("Experiment 조회 실패: experimentId={}", experimentId, e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(Map.of( "status", 500, "error", "Internal Server Error", "message", "An unexpected error occurred while retrieving experiment" )); } } }