package kr.re.etri.autoflow.controllers; import com.fasterxml.jackson.databind.JsonNode; import io.swagger.v3.oas.annotations.Operation; import kr.re.etri.autoflow.payload.request.TagWithDigest; import kr.re.etri.autoflow.service.DockerRegistryService; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Mono; import java.util.List; import java.util.Map; @RestController @RequestMapping("/api/docker") @RequiredArgsConstructor public class DockerRegistryController { private final DockerRegistryService dockerRegistryService; @GetMapping("/repositories") @Operation(summary = "모든 리포지토리 조회") public Mono> listRepositories() { return dockerRegistryService.listRepositories() .map(ResponseEntity::ok); } @GetMapping("/repositories/search") @Operation(summary = "리포지토리 검색 (키워드 + 페이지네이션)") public Mono> searchRepositories( @RequestParam(required = false) String keyword, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) { return dockerRegistryService.searchRepositories(keyword, page, size) .map(ResponseEntity::ok); } @GetMapping("/repositories/{repo}/tags") @Operation(summary = "특정 리포지토리의 태그 조회") public Mono> listTags(@PathVariable String repo) { return dockerRegistryService.listTags(repo) .map(ResponseEntity::ok); } @GetMapping("/repositories/{repo}/tags-with-digest") @Operation(summary = "태그 목록 + digest 조회") public Mono>> listTagsWithDigest( @PathVariable String repo) { return dockerRegistryService.listTagsWithDigest(repo) .map(ResponseEntity::ok); } @PostMapping(value = "/repositories/{repo}/upload", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE) @Operation(summary = "이미지 업로드") public Mono> uploadImage(@PathVariable String repo, @RequestParam String tag, @RequestBody byte[] content) { return dockerRegistryService.uploadImage(repo, tag, content) .map(ResponseEntity::ok); } @GetMapping("/repositories/{repo}/download/{digest}") @Operation(summary = "이미지 다운로드") public Mono> downloadImage(@PathVariable String repo, @PathVariable String digest) { return dockerRegistryService.downloadImage(repo, digest) .map(bytes -> ResponseEntity.ok() .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(bytes)); } @GetMapping("/repositories/{repo}/manifest/{tag}") @Operation(summary = "태그로 manifest 조회") public Mono> getManifest( @PathVariable String repo, @PathVariable String tag) { return dockerRegistryService.getManifestByTag(repo, tag) .map(ResponseEntity::ok); } @GetMapping("/repositories/{repo}/digest/{tag}") @Operation(summary = "태그로 digest 조회") public Mono> getDigest( @PathVariable String repo, @PathVariable String tag) { return dockerRegistryService.getDigestByTag(repo, tag) .map(ResponseEntity::ok); } }