[UPDATE] Experiments API에 Kubeflow 및 MLflow 연동 로직 추가, 엔티티 필드 업데이트 및 응답 처리 개선 (ExperimentsController)

main
bjkim 9 months ago
parent 9a65c44efa
commit 90141f1925

@ -40,6 +40,15 @@ public class ExperimentsController {
@Value("${kubeflow.url}")
private String kubeflowBaseUrl; // 예: http://192.168.10.135:32473/
@Value("${mlflow.url}")
private String mlflowBaseUrl; // 예: http://192.168.10.135:32473/
@Value("${mlflow.user}")
private String mlflowUser; // 예: http://192.168.10.135:32473/
@Value("${mlflow.password}")
private String mlflowPassword; // 예: http://192.168.10.135:32473/
@Operation(summary = "모든 Experiments 조회")
@GetMapping
@ -115,60 +124,78 @@ public class ExperimentsController {
// .doOnError(e -> log.error("Kubeflow experiment 등록 실패", e));
// }
@Operation(summary = "Experiment 등록")
@Operation(summary = "Experiment 등록 (Kubeflow + MLflow)")
@PostMapping
public Mono<ResponseEntity<ExperimentsEntity>> createExperiment(@RequestBody ExperimentsEntity experiment) {
// 1⃣ DB 저장
ExperimentsEntity saved = experimentsService.save(experiment);
Map<String, Object> payload = new HashMap<>();
payload.put("display_name", saved.getDisplayName());
payload.put("description", saved.getDescription());
payload.put("namespace", "default"); // 필요에 따라 변경
// 2⃣ Kubeflow payload
Map<String, Object> kubeflowPayload = new HashMap<>();
kubeflowPayload.put("display_name", saved.getDisplayName());
kubeflowPayload.put("description", saved.getDescription());
kubeflowPayload.put("namespace", "default");
return webClientBuilder.build()
// Kubeflow 등록
.post()
.uri(kubeflowBaseUrl + "/apis/v2beta1/experiments")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(payload)
.bodyValue(kubeflowPayload)
.retrieve()
.bodyToMono(Map.class) // Kubeflow 응답 받기
.flatMap(resp -> {
// Kubeflow 응답에서 값 꺼내기
if (resp.containsKey("experiment_id")) {
saved.setKubeFlowId((String) resp.get("experiment_id"));
.bodyToMono(Map.class)
.flatMap(kubeflowResp -> {
// Kubeflow 응답 처리
if (kubeflowResp.containsKey("experiment_id")) {
saved.setKubeFlowId((String) kubeflowResp.get("experiment_id"));
}
if (resp.containsKey("created_at")) {
if (kubeflowResp.containsKey("created_at")) {
saved.setKubeflowCreatedAt(
Instant.parse((String) resp.get("created_at"))
Instant.parse((String) kubeflowResp.get("created_at"))
.atZone(ZoneId.of("Asia/Seoul"))
.toLocalDateTime()
);
}
if (resp.containsKey("last_run_created_at")) {
if (kubeflowResp.containsKey("last_run_created_at")) {
saved.setKubeflowLastRunCreatedAt(
Instant.parse((String) resp.get("last_run_created_at"))
Instant.parse((String) kubeflowResp.get("last_run_created_at"))
.atZone(ZoneId.of("Asia/Seoul"))
.toLocalDateTime()
);
}
if (resp.containsKey("storage_state")) {
saved.setKubeflowStorageState((String) resp.get("storage_state"));
if (kubeflowResp.containsKey("storage_state")) {
saved.setKubeflowStorageState((String) kubeflowResp.get("storage_state"));
}
// DB 업데이트
experimentsService.save(saved);
log.info("Kubeflow experiment 등록 완료: {}", kubeflowResp);
log.info("Kubeflow experiment 등록 완료: {}", resp);
// 3⃣ MLflow 등록
Map<String, Object> mlflowPayload = new HashMap<>();
mlflowPayload.put("name", saved.getDisplayName());
mlflowPayload.put("artifact_location", "/default/artifacts"); // 필요 시 변경
// mlflowPayload.put("tags", ...); // 태그 필요 시 설정
return webClientBuilder.build()
.post()
.uri(mlflowBaseUrl + "/ajax-api/2.0/mlflow/experiments/create")
.headers(headers -> headers.setBasicAuth(mlflowUser, mlflowPassword))
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(mlflowPayload)
.retrieve()
.bodyToMono(Map.class)
.flatMap(mlflowResp -> {
log.info("MLflow experiment 등록 완료: {}", mlflowResp);
return Mono.just(ResponseEntity.ok(saved));
});
})
.doOnError(e -> log.error("Kubeflow experiment 등록 실패", e));
.doOnError(e -> log.error("Experiment 등록 실패", e));
}
@Operation(summary = "Experiment 수정")
@PutMapping("/{id}")
public ResponseEntity<ExperimentsEntity> updateExperiment(

Loading…
Cancel
Save