diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/dataset/DatasetVersionController.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/dataset/DatasetVersionController.java index b0c42144..71be192e 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/dataset/DatasetVersionController.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/dataset/DatasetVersionController.java @@ -4,6 +4,7 @@ import com.ruoyi.common.core.web.controller.BaseController; import com.ruoyi.common.core.web.domain.GenericsAjaxResult; import com.ruoyi.platform.domain.DatasetVersion; import com.ruoyi.platform.service.DatasetVersionService; +import com.ruoyi.platform.vo.LabelDatasetVersion; import io.swagger.annotations.ApiOperation; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -135,5 +136,10 @@ public class DatasetVersionController extends BaseController { return genericsSuccess(this.datasetVersionService.deleteDatasetVersion(datasetId, version)); } + @PostMapping("/addDatasetVersionsFromLabel") + @ApiOperation("从数据标注添加数据集版本") + public GenericsAjaxResult addDatasetVersionsFromLabel(@RequestBody LabelDatasetVersion labelDatasetVersion) throws Exception { + return genericsSuccess(true); + } } diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/DatasetVersionService.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/DatasetVersionService.java index 5a184925..59032c6b 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/DatasetVersionService.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/DatasetVersionService.java @@ -5,6 +5,7 @@ package com.ruoyi.platform.service; import com.ruoyi.platform.domain.Dataset; import com.ruoyi.platform.domain.DatasetVersion; +import com.ruoyi.platform.vo.LabelDatasetVersion; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -73,4 +74,6 @@ public interface DatasetVersionService { void checkDeclaredVersion(DatasetVersion insert) throws Exception; String addDatasetVersions(List datasetVersions) throws Exception; + + void addDatasetVersionsFromLabel(LabelDatasetVersion labelDatasetVersion) throws Exception; } diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DatasetVersionServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DatasetVersionServiceImpl.java index 98e587d7..0fa1d0be 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DatasetVersionServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/DatasetVersionServiceImpl.java @@ -8,6 +8,8 @@ import com.ruoyi.platform.domain.ModelsVersion; import com.ruoyi.platform.domain.Workflow; import com.ruoyi.platform.mapper.DatasetVersionDao; import com.ruoyi.platform.service.DatasetVersionService; +import com.ruoyi.platform.utils.HttpUtils; +import com.ruoyi.platform.vo.LabelDatasetVersion; import com.ruoyi.system.api.model.LoginUser; import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Page; @@ -16,6 +18,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.io.InputStream; import java.lang.reflect.Field; import java.util.Date; import java.util.HashMap; @@ -32,7 +35,6 @@ import java.util.Map; public class DatasetVersionServiceImpl implements DatasetVersionService { @Resource private DatasetVersionDao datasetVersionDao; - // 固定存储桶名 private final String bucketName = "platform-data"; @@ -193,8 +195,15 @@ public class DatasetVersionServiceImpl implements DatasetVersionService { throw new Exception("新增数据集版本失败: " + e.getMessage()); } + } + @Override + public void addDatasetVersionsFromLabel(LabelDatasetVersion labelDatasetVersion) throws Exception{ + // 获取label-studio数据流 + InputStream inputStream = HttpUtils.getInputStream("http://127.0.0.1:8080/api/projects/"+labelDatasetVersion.getProject_id()+"/export?exportType="+labelDatasetVersion.getExportType(), labelDatasetVersion.getToken()); + // 上传镜像至minio + //保存DatasetVersion } private void insertPrepare(DatasetVersion datasetVersion) throws Exception { diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java index d7e835f8..2d8da4cf 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ImageServiceImpl.java @@ -1,5 +1,6 @@ package com.ruoyi.platform.service.impl; +import com.alibaba.fastjson2.util.DateUtils; import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.platform.domain.Image; import com.ruoyi.platform.domain.ImageVersion; @@ -12,6 +13,7 @@ import com.ruoyi.platform.utils.FileUtil; import com.ruoyi.platform.utils.K8sClientUtil; import com.ruoyi.platform.vo.ImageVo; import com.ruoyi.system.api.model.LoginUser; +import io.kubernetes.client.openapi.models.V1PersistentVolumeClaim; import io.kubernetes.client.openapi.models.V1Pod; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; @@ -64,6 +66,15 @@ public class ImageServiceImpl implements ImageService { private String deploymentName; @Value("${harbor.serviceNS}") private String serviceNS; + + @Value("${dockerpush.image}") + private String image; + @Value("${dockerpush.mountPath}") + private String mountPath; + @Value("${dockerpush.proxyUrl}") + private String proxyUrl; + @Value("${minio.pvcName}") + private String pvcName; /** * 通过ID查询单条数据 * @@ -251,7 +262,8 @@ public class ImageServiceImpl implements ImageService { // 得到容器 V1Pod pod = k8sClientUtil.getNSPodList(serviceNS, deploymentName); if (pod == null) { - throw new Exception("镜像推送服务不存在"); + String podName = deploymentName+"-"+ DateUtils.formatYMD10(new Date()); + pod = createPod(serviceNS, podName); } String loginCmd = "docker login -u " + harborUser +" -p "+harborpassword+" "+harborUrl; // 执行命令 docker login -u admin -p Harbor12345 172.20.32.187 @@ -292,7 +304,8 @@ public class ImageServiceImpl implements ImageService { // 得到容器 V1Pod pod = k8sClientUtil.getNSPodList(serviceNS, deploymentName); if (pod == null) { - throw new Exception("镜像推送服务不存在"); + String podName = deploymentName+"-"+ DateUtils.formatYMD10(new Date()); + pod = createPod(serviceNS, podName); } String loginCmd = "docker login -u " + harborUser +" -p "+harborpassword+" "+harborUrl; // 执行命令 docker login -u admin -p Harbor12345 172.20.32.187 @@ -333,4 +346,8 @@ public class ImageServiceImpl implements ImageService { String path = loginUser.getUsername()+"/"+file.getOriginalFilename(); return minioService.uploadFile(bucketName, path, file); } + + private V1Pod createPod(String namespace, String podName){ + return k8sClientUtil.createPodWithEnv(podName,namespace,proxyUrl,mountPath,pvcName,image); + } } diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/HttpUtils.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/HttpUtils.java index 6e415221..2102b376 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/HttpUtils.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/HttpUtils.java @@ -374,6 +374,29 @@ public class HttpUtils { return httpClient; } + + /** + * 发送 HTTP 请求并返回二进制数据流(InputStream)。 + * + * @param url 请求的 URL 地址。 + * @param token 要携带的 Token。 + * @return 服务器响应的二进制数据流(InputStream)。 + * @throws IOException 如果请求失败或发生其他 I/O 错误。 + */ + public static InputStream getInputStream(String url, String token) throws IOException { + URL requestUrl = new URL(url); + HttpURLConnection connection = (HttpURLConnection) requestUrl.openConnection(); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Authorization", "Bearer " + token); // 添加 Authorization 头部,携带 Token + + int responseCode = connection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + return connection.getInputStream(); // 获取响应的输入流 + } else { + throw new IOException("HTTP 请求失败,状态码:" + responseCode); + } + } + private static class TrustAnyTrustManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java index b23b0143..35ae8632 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/K8sClientUtil.java @@ -382,7 +382,7 @@ public class K8sClientUtil { // invokes the CoreV1Api client for (V1Pod item : v1PodList.getItems()) { - String generateName = item.getMetadata().getGenerateName(); + String generateName = item.getMetadata().getName(); if (StringUtils.isNotEmpty(generateName) && generateName.startsWith(deploymentName)) { // 找到匹配的Pod,获取其名称 return item; @@ -440,4 +440,46 @@ public class K8sClientUtil { } } + + + public V1Pod createPodWithEnv(String podName,String namespace,String proxyUrl ,String mountPath,String pvcName, String image){ + CoreV1Api api = new CoreV1Api(apiClient); + V1PodList v1PodList = null; + V1Pod pod = new V1PodBuilder() + .withNewMetadata() + .withName(podName) + .endMetadata() + .withNewSpec() + .addNewContainer() + .withName(podName) + .withImage(image) // 替换为您实际要使用的镜像名称 + .withVolumeMounts(new V1VolumeMount().name("workspace").mountPath(mountPath)) + .withNewSecurityContext().withNewPrivileged(true).endSecurityContext() + .addNewEnv() + .withName("HTTP_PROXY") + .withValue(proxyUrl) + .endEnv() + .addNewEnv() + .withName("HTTPS_PROXY") + .withValue(proxyUrl) + .endEnv() + .addNewEnv() + .withName("NO_PROXY") + .withValue("localhost,kubernetes.default.svc") + .endEnv() + .endContainer() + .addNewVolume() + .withName("workspace").withPersistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvcName)) + .endVolume() + .endSpec() + .build(); + try { + pod = api.createNamespacedPod(namespace, pod, null, null, null); + } catch (ApiException e) { + log.error("创建pod异常:" + e.getResponseBody(), e); + } catch (Exception e) { + log.error("创建pod系统异常:", e); + } + return pod; + } } diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/LabelDatasetVersion.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/LabelDatasetVersion.java new file mode 100644 index 00000000..bf223e73 --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/LabelDatasetVersion.java @@ -0,0 +1,63 @@ +package com.ruoyi.platform.vo; + +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +import java.io.Serializable; + +@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) +public class LabelDatasetVersion implements Serializable { + private String token; + private String project_id; + private String dataset_id; + private String version; + private String desc; + private String exportType; + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getProject_id() { + return project_id; + } + + public void setProject_id(String project_id) { + this.project_id = project_id; + } + + public String getDataset_id() { + return dataset_id; + } + + public void setDataset_id(String dataset_id) { + this.dataset_id = dataset_id; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getExportType() { + return exportType; + } + + public void setExportType(String exportType) { + this.exportType = exportType; + } +}