Merge remote-tracking branch 'origin/dev' into dev-czh

This commit is contained in:
chenzhihang 2024-09-18 09:57:54 +08:00
commit dac7b2138a
21 changed files with 422 additions and 182 deletions

View File

@ -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

View File

@ -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<GlobalInitialState> {
// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RuntimeConfig['layout'] = ({ initialState }) => {
return {
ErrorBoundary: ErrorBoundary,
rightContentRender: false,
waterMarkProps: {
// content: initialState?.currentUser?.nickName,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 KiB

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 459 KiB

After

Width:  |  Height:  |  Size: 335 KiB

View File

@ -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<ErrorBoundaryProps, ErrorBoundaryState> {
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 || <ErrorBoundaryFallback error={this.state.error} />;
}
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 (
<KFEmpty
style={{ height: '100vh' }}
type={EmptyType.NotFound}
title="出错了"
content={errorMsg}
footer={() => {
return (
<>
<Button
type="default"
onClick={() => {
window.history.pushState({}, '', '/');
window.location.reload();
}}
>
</Button>
<Button
type="primary"
style={{ marginLeft: 20 }}
onClick={() => window.location.reload()}
>
</Button>
</>
);
}}
></KFEmpty>
);
}
export default ErrorBoundary;

View File

@ -18,6 +18,7 @@
}
&__content {
max-width: 50%;
margin-top: 15px;
color: @text-color-secondary;
font-size: 15px;

View File

@ -37,7 +37,7 @@ function KFEmpty({
type,
title,
content,
hasFooter = false,
hasFooter = true,
footer,
buttonTitle = '刷新',
onRefresh,

View File

@ -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<string, string>) => {
if (!map || Object.keys(map).length === 0) {
return '--';
return undefined;
}
return Object.entries(map)
.map(([key, value]) => `${key} = ${value}`)
.join('\n');
};
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 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 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 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 basicDatas: BasicInfoData[] =
resourceType === ResourceType.Dataset ? datasetDatas : modelDatas;
resourceType === ResourceType.Dataset
? getDatasetDatas(info as DatasetData)
: getModelDatas(info as ModelData);
return (
<div className={styles['resource-intro']}>

View File

@ -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<string, string>; // 参数
metrics?: Record<string, string>; // 指标
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;
};

View File

@ -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;

View File

@ -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<InsMetricInfoVo> 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<Map<String, Object>> response = JacksonUtil.parseJSONStr2MapList(s);
System.out.println("response: "+JacksonUtil.toJSONString(response));
if (response == null || response.size() == 0){

View File

@ -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("响应内容为空");

View File

@ -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<String ,Object> output = (Map<String, Object>) 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.");

View File

@ -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<String, Object> 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<String, Object> 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<Map<String, Object>> 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;
}

View File

@ -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<String, Object> stringObjectMap = JacksonUtil.parseJSONStr2Map(req);
Integer total = (Integer) stringObjectMap.get("count");
List<Map<String, Object>> projects = (List<Map<String, Object>>) 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<String, Object> stringObjectMap = JacksonUtil.parseJSONStr2Map(req);
Integer total = (Integer) stringObjectMap.get("total_count");
List<Map<String, Object>> projects = (List<Map<String, Object>>) stringObjectMap.get("projects");

View File

@ -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<String, Object> stringObjectMap = JacksonUtil.parseJSONStr2Map(req);
Integer total = (Integer) stringObjectMap.get("count");
List<Map<String, Object>> projects = (List<Map<String, Object>>) 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<String, Object> stringObjectMap = JacksonUtil.parseJSONStr2Map(req);
Integer total = (Integer) stringObjectMap.get("total_count");
List<Map<String, Object>> projects = (List<Map<String, Object>>) stringObjectMap.get("projects");

View File

@ -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<String,Object> 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("工作流复制接口响应内容为空");

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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}