[ADD] 외부 데이터셋 목록 조회 및 다운로드 API 추가, 관련 Controller 및 Service 로직 구현

main
bjkim 8 months ago
parent ea87fef5b0
commit 17f1a1670d

@ -0,0 +1,60 @@
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.enums.ParameterIn;
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 io.swagger.v3.oas.annotations.tags.Tag;
import kr.re.etri.autoflow.service.DatasetService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@Tag(name = "Dataset API", description = "외부 데이터셋 목록 조회 API (Python requests 코드 기반)")
@RestController
@RequestMapping("/api/datasets")
@RequiredArgsConstructor
public class ExternalDataSetController {
private final DatasetService datasetService;
@Operation(
summary = "데이터셋 목록 조회",
description = "외부 API(/export/dataset_list)를 호출하여 데이터셋 목록을 조회합니다."
)
@ApiResponses({
@ApiResponse(responseCode = "200", description = "성공적으로 데이터셋을 조회했습니다."),
@ApiResponse(responseCode = "400", description = "잘못된 요청입니다.", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 내부 오류", content = @Content)
})
@GetMapping("/list")
public ResponseEntity<?> getDatasetList(
@Parameter(description = "프로젝트 인덱스", example = "10")
@RequestParam(required = false) Integer ds_prj_idx,
@Parameter(description = "검색 키워드", example = "traffic")
@RequestParam(required = false) String search_keyword,
@Parameter(description = "그룹 이름", example = "AIGroup")
@RequestParam(required = false) String grp_name
) {
Map<String, Object> result = datasetService.getDatasetList(ds_prj_idx, search_keyword, grp_name);
return ResponseEntity.ok(result);
}
@PostMapping("/download")
@Operation(
summary = "데이터셋 다운로드",
description = "외부 API 서버로 POST 요청을 보내 ZIP 파일을 다운로드합니다.",
parameters = {
@Parameter(name = "datasetName", description = "다운로드할 데이터셋 이름", in = ParameterIn.QUERY, required = true)
}
)
public ResponseEntity<?> downloadDataset(
@RequestParam("datasetName") String datasetName
) {
return datasetService.downloadDataset(datasetName);
}
}

@ -0,0 +1,133 @@
package kr.re.etri.autoflow.service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Service
@RequiredArgsConstructor
@Slf4j
public class DatasetService {
private final RestTemplate restTemplate;
private static final String BASE_URL = "http://52.14.11.43:18010";
private static final String LIST_ENDPOINT = "/export/dataset_list";
@SuppressWarnings("unchecked")
public Map<String, Object> getDatasetList(Integer ds_prj_idx, String search_keyword, String grp_name) {
try {
// ✅ URL + 파라미터 구성
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(BASE_URL + LIST_ENDPOINT);
if (ds_prj_idx != null) builder.queryParam("ds_prj_idx", ds_prj_idx);
if (search_keyword != null) builder.queryParam("search_keyword", search_keyword);
if (grp_name != null) builder.queryParam("grp_name", grp_name);
String apiUrl = builder.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
HttpEntity<Void> request = new HttpEntity<>(headers);
ResponseEntity<Map> response = restTemplate.exchange(
apiUrl,
HttpMethod.GET,
request,
Map.class
);
Map<String, Object> body = response.getBody();
if (body == null) {
return Map.of(
"success", false,
"message", "API 응답이 비어 있습니다."
);
}
boolean success = Boolean.TRUE.equals(body.get("success"));
if (success) {
return Map.of(
"success", true,
"data", body.get("data"),
"total_count", body.get("total_count")
);
} else {
return Map.of(
"success", false,
"message", body.get("message")
);
}
} catch (Exception e) {
return Map.of(
"success", false,
"message", "API 요청 실패: " + e.getMessage()
);
}
}
@Value("${external.api.base-url:http://52.14.11.43:18010}")
private String baseUrl;
private static final String DOWNLOAD_ENDPOINT = "/export/dataset";
private final WebClient webClient = WebClient.builder()
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
public ResponseEntity<?> downloadDataset(String datasetName) {
String apiUrl = baseUrl + DOWNLOAD_ENDPOINT;
log.info("외부 API 요청 URL: {}", apiUrl);
log.info("요청 데이터셋 이름: {}", datasetName);
// 요청 본문(JSON)
String requestBody = String.format("{\"dataset_name\":\"%s\"}", datasetName);
try {
// WebClient로 외부 API POST 요청
return webClient.post()
.uri(apiUrl)
.bodyValue(requestBody)
.exchangeToMono(response -> {
if (response.statusCode().equals(HttpStatus.OK)) {
// 파일 스트림 수신
return response.bodyToMono(byte[].class)
.map(bytes -> {
ByteArrayResource resource = new ByteArrayResource(bytes);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDisposition(ContentDisposition.attachment()
.filename(datasetName + ".zip", StandardCharsets.UTF_8)
.build());
return new ResponseEntity<>(resource, headers, HttpStatus.OK);
});
} else {
// 오류 응답 처리
return response.bodyToMono(String.class)
.map(errorBody -> {
log.error("다운로드 실패 (HTTP {}): {}", response.statusCode(), errorBody);
return ResponseEntity.status(response.statusCode())
.contentType(MediaType.APPLICATION_JSON)
.body(errorBody);
});
}
})
.block();
} catch (Exception e) {
log.error("API 요청 중 오류 발생", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("API 요청 중 오류 발생: " + e.getMessage());
}
}
}
Loading…
Cancel
Save