diff --git a/k8s/dockerfiles/managent-dockerfile b/k8s/dockerfiles/managent-dockerfile index f3ac2be6..7338f094 100644 --- a/k8s/dockerfiles/managent-dockerfile +++ b/k8s/dockerfiles/managent-dockerfile @@ -1,6 +1,6 @@ # 基础镜像 -#FROM openjdk:8-jre -FROM 172.20.32.187/ci4s/openjdk-dvc:2024829 +FROM 172.20.32.187/ci4s/openjdk:8u162 +#FROM 172.20.32.187/ci4s/openjdk-dvc:2024829 # author MAINTAINER ruoyi diff --git a/react-ui/src/app.tsx b/react-ui/src/app.tsx index ff14f8c9..e6a09fb5 100644 --- a/react-ui/src/app.tsx +++ b/react-ui/src/app.tsx @@ -22,6 +22,7 @@ export { requestConfig as request } from './requestConfig'; // const isDev = process.env.NODE_ENV === 'development'; import { type GlobalInitialState } from '@/types'; import { menuItemRender } from '@/utils/menuRender'; +import ErrorBoundary from './components/ErrorBoundary'; import { gotoLoginPage } from './utils/ui'; /** @@ -65,6 +66,7 @@ export async function getInitialState(): Promise { // ProLayout 支持的api https://procomponents.ant.design/components/layout export const layout: RuntimeConfig['layout'] = ({ initialState }) => { return { + ErrorBoundary: ErrorBoundary, rightContentRender: false, waterMarkProps: { // content: initialState?.currentUser?.nickName, diff --git a/react-ui/src/assets/img/404.png b/react-ui/src/assets/img/404.png index 610b7986..21e86122 100644 Binary files a/react-ui/src/assets/img/404.png and b/react-ui/src/assets/img/404.png differ diff --git a/react-ui/src/assets/img/missing-back.png b/react-ui/src/assets/img/missing-back.png index 850651ce..5d9ad049 100644 Binary files a/react-ui/src/assets/img/missing-back.png and b/react-ui/src/assets/img/missing-back.png differ diff --git a/react-ui/src/assets/img/no-data.png b/react-ui/src/assets/img/no-data.png index d2239289..9ca6aead 100644 Binary files a/react-ui/src/assets/img/no-data.png and b/react-ui/src/assets/img/no-data.png differ diff --git a/react-ui/src/components/ErrorBoundary/index.tsx b/react-ui/src/components/ErrorBoundary/index.tsx index e69de29b..66bc8d94 100644 --- a/react-ui/src/components/ErrorBoundary/index.tsx +++ b/react-ui/src/components/ErrorBoundary/index.tsx @@ -0,0 +1,78 @@ +import KFEmpty, { EmptyType } from '@/components/KFEmpty'; +import { Button } from 'antd'; +import { Component, ReactNode } from 'react'; + +interface ErrorBoundaryProps { + children: ReactNode; + fallback?: ReactNode; // Optional fallback UI to show in case of error +} + +interface ErrorBoundaryState { + hasError: boolean; + error: Error | null; +} + +class ErrorBoundary extends Component { + constructor(props: ErrorBoundaryProps) { + super(props); + this.state = { + hasError: false, + error: null, + }; + } + + static getDerivedStateFromError(error: Error): ErrorBoundaryState { + // Update state so the next render shows the fallback UI + return { hasError: true, error }; + } + + // componentDidCatch(error: Error, errorInfo: ErrorInfo) { + // // You can log the error to an error reporting service here + // console.error('Error caught by ErrorBoundary:', error.message, errorInfo.componentStack); + // } + + render() { + if (this.state.hasError) { + return this.props.fallback || ; + } + return this.props.children; + } +} + +function ErrorBoundaryFallback({ error }: { error: Error | null }) { + const message = error && error instanceof Error ? error.message : 'Unknown error'; + const errorMsg = + process.env.NODE_ENV === 'development' ? message : '非常抱歉,程序运行错误,\n我们会尽快修复。'; + return ( + { + return ( + <> + + + + ); + }} + > + ); +} + +export default ErrorBoundary; diff --git a/react-ui/src/components/KFEmpty/index.less b/react-ui/src/components/KFEmpty/index.less index e62edff5..39f70281 100644 --- a/react-ui/src/components/KFEmpty/index.less +++ b/react-ui/src/components/KFEmpty/index.less @@ -18,6 +18,7 @@ } &__content { + max-width: 50%; margin-top: 15px; color: @text-color-secondary; font-size: 15px; diff --git a/react-ui/src/components/KFEmpty/index.tsx b/react-ui/src/components/KFEmpty/index.tsx index e9bc79e1..e36a4b2d 100644 --- a/react-ui/src/components/KFEmpty/index.tsx +++ b/react-ui/src/components/KFEmpty/index.tsx @@ -37,7 +37,7 @@ function KFEmpty({ type, title, content, - hasFooter = false, + hasFooter = true, footer, buttonTitle = '刷新', onRefresh, diff --git a/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx b/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx index 65446268..08549ab6 100644 --- a/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx +++ b/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx @@ -1,146 +1,159 @@ import BasicInfo, { BasicInfoData } from '@/components/BasicInfo'; import SubAreaTitle from '@/components/SubAreaTitle'; -import { ResourceData, ResourceType } from '@/pages/Dataset/config'; +import { DatasetData, ModelData, ResourceType } from '@/pages/Dataset/config'; import styles from './index.less'; type ResourceIntroProps = { resourceType: ResourceType; - info: ResourceData; + info: DatasetData | ModelData; }; -const formatArray = (arr?: string[]) => { +// const formatArray = (arr?: ResourceData[]) => { +// if (!arr || arr.length === 0) { +// return '--'; +// } +// return arr.map((item) => item.name).join('\n'); +// }; + +const formatDataset = (arr?: DatasetData[]) => { if (!arr || arr.length === 0) { - return '--'; + return undefined; } - return arr.join('\n'); + return arr.map((item) => item.name).join('\n'); }; const formatMap = (map?: Record) => { if (!map || Object.keys(map).length === 0) { - return '--'; + return undefined; } return Object.entries(map) .map(([key, value]) => `${key} = ${value}`) .join('\n'); }; -function ResourceIntro({ resourceType, info }: ResourceIntroProps) { - const datasetDatas: BasicInfoData[] = [ - { - label: '数据集名称', - value: info.name, - }, - { - label: '版本', - value: info.version, - }, - { - label: '创建人', - value: info.create_by, - }, - { - label: '更新时间', - value: info.update_time, - }, - { - label: '数据来源', - value: info.dataset_source, - }, - { - label: '处理代码', - value: info.processing_code, - }, - { - label: '数据集分类', - value: info.data_type, - }, - { - label: '研究方向', - value: info.data_tag, - }, - { - label: '数据集描述', - value: info.description, - }, - { - label: '版本描述', - value: info.version_desc, - }, - ]; +const getDatasetDatas = (data: DatasetData): BasicInfoData[] => [ + { + label: '数据集名称', + value: data.name, + }, + { + label: '版本', + value: data.version, + }, + { + label: '创建人', + value: data.create_by, + }, + { + label: '更新时间', + value: data.update_time, + }, + { + label: '数据来源', + value: data.dataset_source, + }, + { + label: '处理代码', + value: data.processing_code, + }, + { + label: '数据集分类', + value: data.data_type, + }, + { + label: '研究方向', + value: data.data_tag, + }, + { + label: '数据集描述', + value: data.description, + }, + { + label: '版本描述', + value: data.version_desc, + }, +]; - const modelDatas: BasicInfoData[] = [ - { - label: '模型名称', - value: info.name, - }, - { - label: '版本', - value: info.version, - }, - { - label: '创建人', - value: info.create_by, - }, - { - label: '更新时间', - value: info.update_time, - }, - { - label: '训练镜像', - value: info.image, - }, - { - label: '训练代码', - value: info.code, - }, - { - label: '训练数据集', - value: info.train_datasets, - format: formatArray, - }, - { - label: '测试数据集', - value: info.test_datasets, - format: formatArray, - }, - { - label: '参数', - value: info.params, - format: formatMap, - }, - { - label: '指标', - value: info.metrics, - format: formatMap, - }, - { - label: '训练任务', - value: info.train_task, - }, - { - label: '模型来源', - value: info.model_source, - }, - { - label: '模型框架', - value: info.model_type, - }, - { - label: '模型能力', - value: info.model_tag, - }, - { - label: '模型描述', - value: info.description, - }, - { - label: '版本描述', - value: info.version_desc, - }, - ]; +const getModelDatas = (data: ModelData): BasicInfoData[] => [ + { + label: '模型名称', + value: data.name, + }, + { + label: '版本', + value: data.version, + }, + { + label: '创建人', + value: data.create_by, + }, + { + label: '更新时间', + value: data.update_time, + }, + { + label: '训练镜像', + value: data.image, + }, + { + label: '训练代码', + value: data.code, + }, + { + label: '训练数据集', + value: data.train_datasets, + format: formatDataset, + }, + { + label: '测试数据集', + value: data.test_datasets, + format: formatDataset, + }, + { + label: '参数', + value: data.params, + format: formatMap, + }, + { + label: '指标', + value: data.metrics, + format: formatMap, + }, + { + label: '训练任务', + value: data.train_task, + format: (value?: any) => value?.name, + externalLink: data.train_task + ? `${location.origin}/pipeline/experiment/instance/${data.train_task.task_id}/${data.train_task.ins_id}` + : '', + }, + { + label: '模型来源', + value: data.model_source, + }, + { + label: '模型框架', + value: data.model_type, + }, + { + label: '模型能力', + value: data.model_tag, + }, + { + label: '模型描述', + value: data.description, + }, + { + label: '版本描述', + value: data.version_desc, + }, +]; +function ResourceIntro({ resourceType, info }: ResourceIntroProps) { const basicDatas: BasicInfoData[] = - resourceType === ResourceType.Dataset ? datasetDatas : modelDatas; + resourceType === ResourceType.Dataset + ? getDatasetDatas(info as DatasetData) + : getModelDatas(info as ModelData); return (
diff --git a/react-ui/src/pages/Dataset/config.tsx b/react-ui/src/pages/Dataset/config.tsx index b1677bc3..5a9fb008 100644 --- a/react-ui/src/pages/Dataset/config.tsx +++ b/react-ui/src/pages/Dataset/config.tsx @@ -128,7 +128,7 @@ export type CategoryData = { }; // 数据集、模型列表数据 -export type ResourceData = { +export interface ResourceData { id: number; name: string; identifier: string; @@ -142,25 +142,34 @@ export type ResourceData = { version_desc?: string; usage?: string; relative_paths?: string; - // 数据集 + resourceType: ResourceType.Dataset | ResourceType.Model; +} + +// 数据集数据 +export interface DatasetData extends ResourceData { + resourceType: ResourceType.Dataset; // 用于区别类型 data_type?: string; // 数据集分类 data_tag?: string; // 研究方向 processing_code?: string; // 处理代码 dataset_source?: string; // 数据来源 - dataset_version_vos: ResourceFileData[]; - // 模型 + dataset_version_vos?: ResourceFileData[]; +} + +// 模型数据 +export interface ModelData extends ResourceData { + resourceType: ResourceType.Model; // 用于区别类型 model_type?: string; // 模型框架 model_tag?: string; // 模型能力 image?: string; // 训练镜像 code?: string; // 训练镜像 - train_datasets?: string[]; // 训练数据集 - test_datasets?: string[]; // 测试数据集 + train_datasets?: DatasetData[]; // 训练数据集 + test_datasets?: DatasetData[]; // 测试数据集 params?: Record; // 参数 metrics?: Record; // 指标 - train_task?: string; // 训练任务 + train_task?: TrainTask; // 训练任务 model_source?: string; // 模型来源 - model_version_vos: ResourceFileData[]; -}; + model_version_vos?: ResourceFileData[]; +} // 版本数据 export type ResourceVersionData = { @@ -177,3 +186,10 @@ export type ResourceFileData = { url: string; update_time?: string; }; + +// 训练任务 +export type TrainTask = { + ins_id: number; + name: string; + task_id: string; +}; diff --git a/react-ui/src/pages/Model/components/ModelEvolution/utils.tsx b/react-ui/src/pages/Model/components/ModelEvolution/utils.tsx index d1c3ca15..c4511e17 100644 --- a/react-ui/src/pages/Model/components/ModelEvolution/utils.tsx +++ b/react-ui/src/pages/Model/components/ModelEvolution/utils.tsx @@ -1,3 +1,4 @@ +import { TrainTask } from '@/pages/Dataset/config'; import { changePropertyName, fittingString } from '@/utils'; import { EdgeConfig, GraphData, LayoutConfig, NodeConfig, TreeGraphData, Util } from '@antv/g6'; // @ts-ignore @@ -31,12 +32,6 @@ export type Rect = { height: number; }; -export type TrainTask = { - ins_id: number; - name: string; - task_id: string; -}; - export interface TrainDataset extends NodeConfig { repo_id: number; name: string; diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/AimServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/AimServiceImpl.java index 338fab19..943a1dc4 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/AimServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/AimServiceImpl.java @@ -1,14 +1,12 @@ package com.ruoyi.platform.service.impl; import com.ruoyi.platform.domain.ExperimentIns; -import com.ruoyi.platform.domain.ModelDependency; import com.ruoyi.platform.service.AimService; import com.ruoyi.platform.service.ExperimentInsService; -import com.ruoyi.platform.service.ModelDependencyService; import com.ruoyi.platform.utils.AIM64EncoderUtil; -import com.ruoyi.platform.utils.HttpUtils; import com.ruoyi.platform.utils.JacksonUtil; import com.ruoyi.platform.utils.JsonUtils; +import com.ruoyi.platform.utils.NewHttpUtils; import com.ruoyi.platform.vo.InsMetricInfoVo; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; @@ -28,6 +26,8 @@ public class AimServiceImpl implements AimService { private String aimUrl; @Value("${aim.proxyUrl}") private String aimProxyUrl; + @Resource + private NewHttpUtils httpUtils; @Override public List getExpTrainInfos(Integer experimentId) throws Exception { @@ -52,7 +52,7 @@ public class AimServiceImpl implements AimService { } String encodedUrlString = URLEncoder.encode("run.experiment==\""+experimentName+"\"", "UTF-8"); String url = aimProxyUrl+"/api/runs/search/run?query="+encodedUrlString; - String s = HttpUtils.sendGetRequest(url); + String s = httpUtils.sendGet(url,null); List> response = JacksonUtil.parseJSONStr2MapList(s); System.out.println("response: "+JacksonUtil.toJSONString(response)); if (response == null || response.size() == 0){ diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java index 5c04914b..e9457bcb 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentInsServiceImpl.java @@ -56,6 +56,8 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { @Value("${minio.endpoint}") private String minioEndpoint; @Resource + private NewHttpUtils httpUtils; + @Resource private K8sClientUtil k8sClientUtil; private final MinioUtil minioUtil; public ExperimentInsServiceImpl(MinioUtil minioUtil) { @@ -263,7 +265,7 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { try { // 发送POST请求到Argo工作流状态查询接口,并将请求数据转换为JSON - String req = HttpUtils.sendPost(argoUrl + argoWorkflowStatus, JsonUtils.mapToJson(res)); + String req = httpUtils.sendPost(argoUrl + argoWorkflowStatus,null, JsonUtils.mapToJson(res)); // 检查响应是否为空或无内容 if (req == null || StringUtils.isEmpty(req)) { throw new RuntimeException("工作流状态响应为空。"); @@ -357,7 +359,7 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { try { // 发送POST请求到Argo工作流状态查询接口,并将请求数据转换为JSON - String req = HttpUtils.sendPost(argoUrl + argoWorkflowTermination, JsonUtils.mapToJson(res)); + String req = httpUtils.sendPost(argoUrl + argoWorkflowTermination,null, JsonUtils.mapToJson(res)); // 检查响应是否为空或无内容 if (StringUtils.isEmpty(req)) { throw new RuntimeException("终止响应内容为空。"); @@ -415,7 +417,7 @@ public class ExperimentInsServiceImpl implements ExperimentInsService { try { // 发送POST请求到Argo工作流日志查询接口,并将请求数据转换为JSON - String req = HttpUtils.sendPost(argoUrl + argoWorkflowLog, JsonUtils.mapToJson(res)); + String req = httpUtils.sendPost(argoUrl + argoWorkflowLog, null,JsonUtils.mapToJson(res)); // 检查响应是否为空或无内容 if (StringUtils.isEmpty(req)) { throw new RuntimeException("响应内容为空"); diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentServiceImpl.java index 41f9d68a..811253e7 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ExperimentServiceImpl.java @@ -8,9 +8,9 @@ import com.ruoyi.platform.domain.dependencydomain.TrainTaskDepency; import com.ruoyi.platform.mapper.ExperimentDao; import com.ruoyi.platform.mapper.ExperimentInsDao; import com.ruoyi.platform.service.*; -import com.ruoyi.platform.utils.HttpUtils; import com.ruoyi.platform.utils.JacksonUtil; import com.ruoyi.platform.utils.JsonUtils; +import com.ruoyi.platform.utils.NewHttpUtils; import com.ruoyi.system.api.model.LoginUser; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; @@ -55,7 +55,8 @@ public class ExperimentServiceImpl implements ExperimentService { @Resource @Lazy private ExperimentInsService experimentInsService; - + @Resource + private NewHttpUtils httpUtils; @Value("${argo.url}") private String argoUrl; @Value("${argo.convert}") @@ -222,7 +223,7 @@ public class ExperimentServiceImpl implements ExperimentService { String dag = workflow.getDag(); // 调argo转换接口 try { - String convertRes = HttpUtils.sendPost(argoUrl + argoConvert, dag); + String convertRes = httpUtils.sendPost(argoUrl + argoConvert,null, dag); if (convertRes == null || StringUtils.isEmpty(convertRes)) { throw new RuntimeException("转换流水线失败"); } @@ -241,7 +242,7 @@ public class ExperimentServiceImpl implements ExperimentService { Map output = (Map) converMap.get("output"); // 调argo运行接口 - String runRes = HttpUtils.sendPost(argoUrl + argoWorkflowRun, JsonUtils.mapToJson(runReqMap)); + String runRes = httpUtils.sendPost(argoUrl + argoWorkflowRun,null, JsonUtils.mapToJson(runReqMap)); if (runRes == null || StringUtils.isEmpty(runRes)) { throw new RuntimeException("Failed to run workflow."); diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/GitServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/GitServiceImpl.java index f5b4333f..ce582396 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/GitServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/GitServiceImpl.java @@ -2,9 +2,9 @@ package com.ruoyi.platform.service.impl; import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.platform.service.GitService; -import com.ruoyi.platform.utils.HttpUtils; import com.ruoyi.platform.utils.JacksonUtil; import com.ruoyi.platform.utils.JsonUtils; +import com.ruoyi.platform.utils.NewHttpUtils; import com.ruoyi.platform.vo.GitProjectVo; import com.ruoyi.system.api.model.LoginUser; import org.apache.commons.lang3.StringUtils; @@ -16,9 +16,9 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import redis.clients.jedis.Jedis; +import javax.annotation.Resource; import java.io.File; import java.io.IOException; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -30,6 +30,10 @@ public class GitServiceImpl implements GitService { private String redisHost; @Value("${spring.redis.port}") private Integer redisPort; + @Value("${git.endpoint}") + String gitendpoint; + @Resource + private NewHttpUtils httpUtils; private static final Logger log = LoggerFactory.getLogger(GitServiceImpl.class); @Override @@ -43,7 +47,7 @@ public class GitServiceImpl implements GitService { params.put("client_secret", "L3wBKTNnRo-wPen7bxR3F1myCvtVDgpWa6MnpfyWeJE"); try { // 发送POST请求 - String req = HttpUtils.sendPostRequest("https://www.gitlink.org.cn/oauth/token", null, JsonUtils.mapToJson(params)); + String req = httpUtils.sendPost(gitendpoint + "/oauth/token", null,JsonUtils.mapToJson(params)); // 解析响应JSON if (StringUtils.isEmpty(req)) { throw new RuntimeException("终止响应内容为空。"); @@ -55,7 +59,7 @@ public class GitServiceImpl implements GitService { String accessToken = (String) runResMap.get("access_token"); //通过access_token获取用户信息 - String userReq = HttpUtils.sendGetWithToken("https://www.gitlink.org.cn/api/users/get_user_info.json", null, accessToken); + String userReq = httpUtils.sendGetWithToken(gitendpoint + "/api/users/get_user_info.json", null, accessToken); if (StringUtils.isEmpty(userReq)) { throw new RuntimeException("终止响应内容为空。"); } @@ -100,7 +104,7 @@ public class GitServiceImpl implements GitService { @Override public Map createProject(String token,GitProjectVo gitProjectVo) throws Exception { - String userReq = HttpUtils.sendPostWithToken("https://www.gitlink.org.cn/api/projects.json", JsonUtils.objectToJson(gitProjectVo), token); + String userReq = httpUtils.sendPostWithToken(gitendpoint + "/api/projects.json",null, token,JsonUtils.objectToJson(gitProjectVo)); return JsonUtils.jsonToMap(userReq); } @@ -115,7 +119,7 @@ public class GitServiceImpl implements GitService { Map resMap = new HashMap<>(); resMap.put("new_branch_name", branchName); resMap.put("old_branch_name", oldBranchName); - String req = HttpUtils.sendPostWithToken(createBranchUrl, JsonUtils.objectToJson(resMap), token); + String req = httpUtils.sendPostWithToken(createBranchUrl, null, token,JsonUtils.objectToJson(resMap)); System.out.println(req); } @@ -125,12 +129,12 @@ public class GitServiceImpl implements GitService { Map resMap = new HashMap<>(); resMap.put("project_id", id); resMap.put("name", topicName); - String req = HttpUtils.sendPostWithToken("https://www.gitlink.org.cn/api/v1/project_topics.json", JsonUtils.objectToJson(resMap), token); + String req = httpUtils.sendPostWithToken(gitendpoint + "/api/v1/project_topics.json",null, token ,JsonUtils.objectToJson(resMap)); } @Override public List> getBrancheList(String token,String owner, String projectName) throws Exception { - String req = HttpUtils.sendGetWithToken("https://www.gitlink.org.cn/api/v1/" + owner + "/" + projectName + "/branches/all.json", null, token); + String req = httpUtils.sendGetWithToken(gitendpoint + "/api/v1/" + owner + "/" + projectName + "/branches/all.json", null, token); // 解析响应JSON if (StringUtils.isEmpty(req)) { throw new RuntimeException("终止响应内容为空。"); @@ -142,7 +146,7 @@ public class GitServiceImpl implements GitService { @Override public void deleteProject(String token,String owner, String projectName) throws Exception { - HttpUtils.sendDeleteRequest("https://www.gitlink.org.cn/api/" + owner + "/" + projectName + ".json", token); + httpUtils.sendDeleteWithToken(gitendpoint + "/api/" + owner + "/" + projectName + ".json", null, token); } @Override @@ -153,12 +157,12 @@ public class GitServiceImpl implements GitService { } catch (IOException | GitAPIException e) { log.error("Exception occurred while creating local branch based on master",e); } - HttpUtils.sendDeleteRequest("https://www.gitlink.org.cn/api/v1/" + owner + "/" + projectName + "/branches/" + branchName + ".json", token); + httpUtils.sendDeleteWithToken(gitendpoint + "/api/v1/" + owner + "/" + projectName + "/branches/" + branchName + ".json", null, token); } @Override public Map getUserInfo(String token) throws Exception { - String userReq = HttpUtils.sendGetWithToken("https://www.gitlink.org.cn/api/users/get_user_info.json",null, token); + String userReq = httpUtils.sendGetWithToken(gitendpoint + "/api/users/get_user_info.json",null, token); if (StringUtils.isEmpty(userReq)){ return null; } diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelsServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelsServiceImpl.java index ad2309f8..63bdb299 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelsServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/ModelsServiceImpl.java @@ -76,7 +76,8 @@ public class ModelsServiceImpl implements ModelsService { @Resource private AssetIconService assetIconService; - + @Resource + private NewHttpUtils httpUtils; // 固定存储桶名 @Value("${minio.dataReleaseBucketName}") @@ -832,7 +833,7 @@ public class ModelsServiceImpl implements ModelsService { url = url + "&search=" + name; } - String req = HttpUtils.sendGetWithToken(url, null, token); + String req = httpUtils.sendGetWithToken(url, null, token); Map stringObjectMap = JacksonUtil.parseJSONStr2Map(req); Integer total = (Integer) stringObjectMap.get("count"); List> projects = (List>) stringObjectMap.get("projects"); @@ -863,7 +864,7 @@ public class ModelsServiceImpl implements ModelsService { url = url + "&search=" + name; } - String req = HttpUtils.sendGetWithToken(url, null, token); + String req = httpUtils.sendGetWithToken(url, null, token); Map stringObjectMap = JacksonUtil.parseJSONStr2Map(req); Integer total = (Integer) stringObjectMap.get("total_count"); List> projects = (List>) stringObjectMap.get("projects"); diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/NewDatasetServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/NewDatasetServiceImpl.java index 228f2877..6bdd1cbc 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/NewDatasetServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/NewDatasetServiceImpl.java @@ -63,6 +63,8 @@ public class NewDatasetServiceImpl implements NewDatasetService { @Value("${git.localPath}") String localPathlocal; @Resource + private NewHttpUtils httpUtils; + @Resource private DatasetTempStorageService datasetTempStorageService; @Override public String newCreateDataset(NewDatasetVo datasetVo) throws Exception { @@ -236,7 +238,7 @@ public class NewDatasetServiceImpl implements NewDatasetService { if (StringUtils.isNotEmpty(name)){ url =url + "&search=" + name; } - String req = HttpUtils.sendGetWithToken(url, null, token); + String req = httpUtils.sendGetWithToken(url, null, token); Map stringObjectMap = JacksonUtil.parseJSONStr2Map(req); Integer total = (Integer) stringObjectMap.get("count"); List> projects = (List>) stringObjectMap.get("projects"); @@ -264,7 +266,7 @@ public class NewDatasetServiceImpl implements NewDatasetService { url =url + "&search=" + name; } - String req = HttpUtils.sendGetWithToken(url, null, token); + String req = httpUtils.sendGetWithToken(url, null, token); Map stringObjectMap = JacksonUtil.parseJSONStr2Map(req); Integer total = (Integer) stringObjectMap.get("total_count"); List> projects = (List>) stringObjectMap.get("projects"); diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/WorkflowServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/WorkflowServiceImpl.java index 9c36d277..2b586f24 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/WorkflowServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/WorkflowServiceImpl.java @@ -2,15 +2,14 @@ package com.ruoyi.platform.service.impl; import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.platform.annotations.CheckDuplicate; -import com.ruoyi.platform.domain.Dataset; import com.ruoyi.platform.domain.Experiment; import com.ruoyi.platform.domain.Workflow; import com.ruoyi.platform.mapper.WorkflowDao; import com.ruoyi.platform.service.ExperimentService; import com.ruoyi.platform.service.WorkflowService; -import com.ruoyi.platform.utils.HttpUtils; import com.ruoyi.platform.utils.JsonUtils; import com.ruoyi.platform.utils.MinioUtil; +import com.ruoyi.platform.utils.NewHttpUtils; import com.ruoyi.system.api.model.LoginUser; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Value; @@ -45,7 +44,8 @@ public class WorkflowServiceImpl implements WorkflowService { @Value("${argo.workflowCopy}") private String argoWorkflowCopy; - + @Resource + private NewHttpUtils httpUtils; private final MinioUtil minioUtil; public WorkflowServiceImpl(MinioUtil minioUtil) { @@ -172,7 +172,7 @@ public class WorkflowServiceImpl implements WorkflowService { Map requestData = new HashMap<>(); requestData.put("data", oldDag); // 发送POST请求到Argo工作流复制接口,并将请求数据转换为JSON - String req = HttpUtils.sendPost(argoUrl + argoWorkflowCopy , JsonUtils.mapToJson(requestData)); + String req = httpUtils.sendPost(argoUrl + argoWorkflowCopy,null , JsonUtils.mapToJson(requestData)); // 检查响应是否为空或无内容 if (StringUtils.isEmpty(req)) { throw new RuntimeException("工作流复制接口响应内容为空"); 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 7a3d5518..1de5d84e 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 @@ -110,6 +110,7 @@ public class HttpUtils { * @return 所代表远程资源的响应结果 */ public static String sendGetWithToken(String url, String param, String token) { + System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2"); String result = ""; try (CloseableHttpClient httpClient = HttpClients.createDefault()) { URIBuilder uriBuilder = new URIBuilder(url); diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/NewHttpUtils.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/NewHttpUtils.java new file mode 100644 index 00000000..da117614 --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/utils/NewHttpUtils.java @@ -0,0 +1,132 @@ +package com.ruoyi.platform.utils; +import org.apache.http.HttpHost; +import org.apache.http.client.methods.*; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.net.ssl.SSLContext; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; + +@Component +public class NewHttpUtils { + + private static final Logger log = LoggerFactory.getLogger(NewHttpUtils.class); + + @Value("${proxy.useProxy:false}") + private boolean useProxy; + + @Value("${proxy.host}") + private String host; + + @Value("${proxy.port}") + private Integer port; + + private static CloseableHttpClient httpClient; + + @PostConstruct + public void init() { + try { + SSLContext sslContext = SSLContextBuilder.create() + .loadTrustMaterial(new TrustSelfSignedStrategy()) + .build(); + + SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext); + + if (useProxy) { + httpClient = HttpClients.custom() + .setSSLSocketFactory(sslSocketFactory) + .setProxy(new HttpHost(host, port)) + .build(); + } else { + httpClient = HttpClients.custom() + .setSSLSocketFactory(sslSocketFactory) + .build(); + } + } catch (Exception e) { + throw new RuntimeException("Failed to initialize HttpClient", e); + } + } + + public static String sendGet(String url, String param) { + return sendRequest(new HttpGet(), url, param, null, null); + } + + public static String sendPost(String url, String param, String body) { + return sendRequest(new HttpPost(), url, param, null, body); + } + + public static String sendGetWithToken(String url, String param, String token) { + return sendRequest(new HttpGet(), url, param, token, null); + } + + public static String sendPostWithToken(String url, String param, String token, String body) { + return sendRequest(new HttpPost(), url, param, token, body); + } + + public static String sendDeleteWithToken(String url, String param, String token) { + return sendRequest(new HttpDelete(), url, param, token, null); + } + + private static String sendRequest(HttpRequestBase request, String url, String param, String token, String body) { + if (httpClient == null) { + throw new IllegalStateException("HttpClient is not initialized"); + } + + String result = ""; + try { + URIBuilder uriBuilder = new URIBuilder(url); + if (param != null && !param.isEmpty()) { + String[] pairs = param.split("&"); + for (String pair : pairs) { + int idx = pair.indexOf("="); + if (idx != -1) { + uriBuilder.setParameter(pair.substring(0, idx), pair.substring(idx + 1)); + } + } + } + + URI uri = uriBuilder.build(); + request.setURI(uri); + + request.setHeader("Content-Type", "application/json"); + if (token != null) { + request.setHeader("Authorization", "Bearer " + token); + } + + if (request instanceof HttpEntityEnclosingRequestBase && body != null) { + ((HttpEntityEnclosingRequestBase) request).setEntity(new StringEntity(body, StandardCharsets.UTF_8)); + } + + log.info("Executing request: " + request.getRequestLine()); + + try (CloseableHttpResponse response = httpClient.execute(request)) { + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode >= 200 && statusCode < 300) { + result = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); + } else { + throw new IOException("HTTP request failed with response code: " + statusCode); + } + log.info("Response: " + result); + } + } catch (URISyntaxException e) { + log.error("URISyntaxException, url=" + url + ", param=" + param, e); + } catch (IOException e) { + log.error("IOException, url=" + url + ", param=" + param, e); + } + return result; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml index 17d17c3c..fa1d6384 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml @@ -3,7 +3,7 @@ server: port: 9201 # Spring -spring: +spring: application: # 应用名称 name: ruoyi-system @@ -13,21 +13,13 @@ spring: cloud: nacos: discovery: - namespace: 6caf5d79-c4ce-4e3b-a357-141b74e52a01 # 服务注册地址 - server-addr: 172.20.32.181:8848 - username: nacos - password: h1n2x3j4y5@ - retry: - enabled: true + server-addr: 172.20.32.181:18847 config: - namespace: 6caf5d79-c4ce-4e3b-a357-141b74e52a01 # 配置中心地址 - server-addr: 172.20.32.181:8848 + server-addr: 172.20.32.181:18847 # 配置文件格式 file-extension: yml # 共享配置 shared-configs: - - data-id: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} - group: DEFAULT_GROUP - refresh: true + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}