From f6eecba7ffb1535a2748f3f31ca255e2e0743267 Mon Sep 17 00:00:00 2001 From: dongyukun <1208714201@qq.com> Date: 星期五, 03 一月 2025 14:00:41 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/controller/admin/MdkController.java | 178 ++++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 134 insertions(+), 44 deletions(-) diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/controller/admin/MdkController.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/controller/admin/MdkController.java index 0c77b58..279bf16 100644 --- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/controller/admin/MdkController.java +++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/controller/admin/MdkController.java @@ -1,13 +1,21 @@ package com.iailab.module.model.mpk.controller.admin; +import cn.hutool.cache.CacheUtil; +import cn.hutool.cache.impl.FIFOCache; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; +import com.iail.utils.RSAUtils; import com.iailab.framework.common.exception.enums.GlobalErrorCodeConstants; import com.iailab.framework.common.pojo.CommonResult; +import com.iailab.framework.tenant.core.context.TenantContextHolder; import com.iailab.module.model.mpk.common.MdkConstant; +import com.iailab.module.model.mpk.common.utils.DllUtils; import com.iailab.module.model.mpk.common.utils.Readtxt; import com.iailab.module.model.mpk.dto.MdkDTO; +import com.iailab.module.model.mpk.dto.MdkRunDTO; +import com.iailab.module.model.mpk.dto.MethodSettingDTO; import io.swagger.v3.oas.annotations.Operation; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; @@ -15,11 +23,11 @@ import java.io.File; import java.lang.reflect.Method; -import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.UUID; import static com.iailab.framework.common.pojo.CommonResult.error; import static com.iailab.framework.common.pojo.CommonResult.success; @@ -30,44 +38,63 @@ * @createTime 2024年08月08日 */ @RestController +@Slf4j @RequestMapping("/model/mpk/api") public class MdkController { @Value("${mpk.bak-file-path}") private String mpkBakFilePath; + // 先进先出缓存 + private static FIFOCache<String, String> cache = CacheUtil.newFIFOCache(100); - @PostMapping("run") - public CommonResult<String> run(@RequestBody MdkDTO dto) { + /** + * @description: 模型测试运行 + * @author: dzd + * @date: 2024/10/14 15:26 + **/ + @PostMapping("test") + public CommonResult<String> test(@RequestBody MdkDTO dto) { + Long tenantId = TenantContextHolder.getTenantId(); + // 备份文件 租户隔离 + String mpkTenantBakFilePath = mpkBakFilePath + File.separator + tenantId; + Class<?> clazz; + URLClassLoader classLoader; try { - File jarFile = new File(mpkBakFilePath + File.separator + MdkConstant.JAR + File.separator + dto.getPyName() + ".jar"); + File jarFile = new File(mpkTenantBakFilePath + File.separator + MdkConstant.JAR + File.separator + dto.getPyName() + ".jar"); if (!jarFile.exists()) { throw new RuntimeException("jar包不存在,请先生成代码。jarPath:" + jarFile.getAbsolutePath()); } - File dllFile = new File(mpkBakFilePath + File.separator + MdkConstant.DLL + File.separator + dto.getPyName() + ".dll"); + File dllFile = new File(mpkTenantBakFilePath + File.separator + MdkConstant.DLL + File.separator + dto.getPyName() + ".dll"); if (!dllFile.exists()) { - throw new RuntimeException("dllw文件不存在,请先生成代码。dllPath:" + dllFile.getAbsolutePath()); + throw new RuntimeException("dll文件不存在,请先生成代码。dllPath:" + dllFile.getAbsolutePath()); } // 加载jar包 - loadJar(jarFile.getAbsolutePath()); - // 加载dll - System.load(dllFile.getAbsolutePath()); + classLoader = DllUtils.loadJar(jarFile.getAbsolutePath()); + // 实现类 + clazz = classLoader.loadClass(dto.getClassName()); + // 加载dll到实现类 + DllUtils.loadDll(clazz,dllFile.getAbsolutePath()); } catch (Exception e) { + e.printStackTrace(); throw new RuntimeException("加载运行环境失败。"); } System.out.println("runTime=" + System.currentTimeMillis()); try { - List<String> datas = dto.getDatas(); + List<String> uuids = dto.getUuids(); - int paramLength = dto.getHasModel() ? datas.size() + 2 : datas.size() + 1; + int paramLength = dto.getHasModel() ? uuids.size() + 2 : uuids.size() + 1; Object[] paramsValueArray = new Object[paramLength]; Class<?>[] paramsArray = new Class[paramLength]; try { - for (int i = 0; i < datas.size(); i++) { - String json = datas.get(i); - JSONArray jsonArray = JSON.parseArray(json); + for (int i = 0; i < uuids.size(); i++) { + String uuid = uuids.get(i); + if (!cache.containsKey(uuid)) { + return error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),"请重新导入模型参数"); + } + JSONArray jsonArray = JSON.parseArray(cache.get(uuid)); double[][] data = new double[jsonArray.size()][jsonArray.getJSONArray(0).size()]; for (int j = 0; j < jsonArray.size(); j++) { for (int k = 0; k < jsonArray.getJSONArray(j).size(); k++) { @@ -79,58 +106,121 @@ } } catch (Exception e) { e.printStackTrace(); - return error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),"参数错误,请检查!"); + return error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),"模型参数错误,请检查!"); } - if (dto.getHasModel()) { - paramsValueArray[datas.size()] = dto.getModel(); - paramsValueArray[datas.size() + 1] = dto.getModelSettings(); - paramsArray[datas.size()] = HashMap.class; - paramsArray[datas.size() + 1] = HashMap.class; - }else { - paramsValueArray[datas.size()] = dto.getModelSettings(); - paramsArray[datas.size()] = HashMap.class; + try { + if (dto.getModelSettings().stream().noneMatch(e -> e.getSettingKey().equals(MdkConstant.PY_FILE_KEY))) { + return error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),"模型设置参数缺少必要信息【" + MdkConstant.PY_FILE_KEY + "】,请重新上传模型!"); + } + + if (dto.getHasModel()) { + paramsValueArray[uuids.size()] = dto.getModel(); + paramsValueArray[uuids.size() + 1] = handleModelSettings(dto.getModelSettings()); + paramsArray[uuids.size()] = HashMap.class; + paramsArray[uuids.size() + 1] = HashMap.class; + }else { + paramsValueArray[uuids.size()] = handleModelSettings(dto.getModelSettings()); + paramsArray[uuids.size()] = HashMap.class; + } + } catch (Exception e) { + e.printStackTrace(); + return error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),"模型设置错误,请检查!"); } - Class<?> clazz = Class.forName(dto.getClassName()); - Method method = clazz.getMethod(dto.getMethodName(), paramsArray); - HashMap result = (HashMap)method.invoke(clazz.newInstance(), paramsValueArray); + HashMap result = (HashMap) clazz.getDeclaredMethod(dto.getMethodName(), paramsArray).invoke(clazz.newInstance(), paramsValueArray); return success(JSON.toJSONString(result)); } catch (Exception ex) { ex.printStackTrace(); return error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"运行异常"); } finally { + if (classLoader != null) { + DllUtils.unloadDll(classLoader); + DllUtils.unloadJar(classLoader); + } System.gc(); } } + private HashMap<String, Object> handleModelSettings(List<MethodSettingDTO> modelSettings) { + HashMap<String, Object> resultMap = null; + try { + resultMap = new HashMap<>(modelSettings.size()); + for (MethodSettingDTO modelSetting : modelSettings) { + switch (modelSetting.getValueType()) { + case "int": + resultMap.put(modelSetting.getSettingKey(), Integer.valueOf(modelSetting.getSettingValue())); + break; + case "string": + resultMap.put(modelSetting.getSettingKey(), modelSetting.getSettingValue()); + break; + case "decimal": + resultMap.put(modelSetting.getSettingKey(), Double.valueOf(modelSetting.getSettingValue())); + break; + case "decimalArray": + JSONArray jsonArray = JSON.parseArray(modelSetting.getSettingValue()); + double[] doubles = new double[jsonArray.size()]; + for (int i = 0; i < jsonArray.size(); i++) { + doubles[i] = Double.valueOf(String.valueOf(jsonArray.get(i))); + } + resultMap.put(modelSetting.getSettingKey(), doubles); + break; + } + } + } catch (NumberFormatException e) { + throw new RuntimeException("模型参数有误,请检查!!!"); + } + return resultMap; + } + + /** + * @description: 模型运行 + * @author: dzd + * @date: 2024/10/14 15:26 + **/ + @PostMapping("run") + public CommonResult<String> run(@RequestBody MdkRunDTO dto) { + if (RSAUtils.checkLisenceBean().getCode() != 1) { + log.error("Lisence 不可用!"); + return CommonResult.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"Lisence 不可用!"); + } else { + try { + URLClassLoader classLoader = DllUtils.getClassLoader(dto.getProjectId()); + if (null == classLoader) { + return CommonResult.error(GlobalErrorCodeConstants.ERROR_CONFIGURATION.getCode(),"请先发布项目!"); + } + + Class<?> clazz = classLoader.loadClass(dto.getClassName()); + Method method = clazz.getMethod(dto.getMethodName(), dto.getParamsClassArray()); + HashMap invoke = (HashMap) method.invoke(clazz.newInstance(), dto.getParamsValueArray()); + + // todo 将结果存入数据库 + + } catch (Exception e) { + log.error("模型运行失败",e); + return CommonResult.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"模型运行失败!"); + } + } + return CommonResult.success(); + } + @PostMapping("/import") @Operation(summary = "导入参数") - public CommonResult<List<String>> importExcel(@RequestParam("file") MultipartFile file) throws Exception { + public CommonResult<List<HashMap<String,Object>>> importExcel(@RequestParam("file") MultipartFile file) throws Exception { List<double[][]> datas = Readtxt.readMethodExcel(file); - List<String> result = new ArrayList<>(); + List<HashMap<String,Object>> result = new ArrayList<>(); if (!CollectionUtils.isEmpty(datas)) { for (double[][] data : datas) { if (data.length > 0) { - result.add(JSON.toJSONString(data)); + HashMap<String,Object> map = new HashMap<>(); + String uuid = UUID.randomUUID().toString(); + map.put("uuid",uuid); + map.put("data",JSON.toJSONString(data)); + cache.put(uuid,JSON.toJSONString(data)); + result.add(map); } } } return success(result); - } - - private void loadJar(String jarPath) throws Exception { - File jarFile = new File(jarPath); - if (!jarFile.exists()) { - throw new Exception("jar沒有找到!"); - } else { - Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); - boolean accessible = method.isAccessible(); - method.setAccessible(true); - URLClassLoader classLoader = (URLClassLoader)ClassLoader.getSystemClassLoader(); - URL url = jarFile.toURI().toURL(); - method.invoke(classLoader, url); - method.setAccessible(accessible); - } } } \ No newline at end of file -- Gitblit v1.9.3