Unverified Commit fbbdec08 authored by ZackYoung's avatar ZackYoung Committed by GitHub

[Feature][admin] Add build udf jar (#1049)

* add build udf jar

* change message
parent b20dab93
......@@ -22,10 +22,15 @@ package com.dlink.controller;
import com.dlink.common.result.ProTableResult;
import com.dlink.common.result.Result;
import com.dlink.model.Jar;
import com.dlink.model.Task;
import com.dlink.service.JarService;
import com.dlink.service.TaskService;
import com.dlink.utils.UDFUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
......@@ -38,6 +43,7 @@ import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.JsonNode;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
/**
......@@ -53,6 +59,9 @@ public class JarController {
@Autowired
private JarService jarService;
@Autowired
private TaskService taskService;
/**
* 新增或者更新
*/
......@@ -113,4 +122,14 @@ public class JarController {
List<Jar> jars = jarService.listEnabledAll();
return Result.succeed(jars, "获取成功");
}
@PostMapping("/udf/generateJar")
public Result<Map<String, List<String>>> generateJar() {
List<Task> allUDF = taskService.getAllUDF();
List<String> udfCodes = allUDF.stream().map(Task::getStatement).collect(Collectors.toList());
Map<String, List<String>> resultMap = UDFUtil.buildJar(udfCodes);
String msg = StrUtil.format("udf jar生成成功,jar文件在dinky安装目录下tmp/udf/udf.jar;\n本次成功 class:{}。\n失败 class:{}"
, resultMap.get("success"), resultMap.get("failed"));
return Result.succeed(resultMap, msg);
}
}
......@@ -65,6 +65,8 @@ public interface TaskService extends ISuperService<Task> {
Task getUDFByClassName(String className);
List<Task> getAllUDF();
Result releaseTask(Integer id);
boolean developTask(Integer id);
......
......@@ -460,6 +460,15 @@ public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implemen
return task;
}
@Override
public List<Task> getAllUDF() {
List<Task> tasks = list(new QueryWrapper<Task>().eq("dialect", "Java").eq("enabled", 1).isNotNull("save_point_path"));
return tasks.stream().peek(task -> {
Assert.check(task);
task.setStatement(statementService.getById(task.getId()).getStatement());
}).collect(Collectors.toList());
}
@Override
public Result releaseTask(Integer id) {
Task task = getTaskInfoById(id);
......
......@@ -20,10 +20,12 @@
package com.dlink.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
......@@ -39,8 +41,12 @@ import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
/**
* CustomStringJavaCompiler
*
......@@ -92,6 +98,29 @@ public class CustomStringJavaCompiler {
return task.call();
}
/**
* 编译字符串源代码,并放在缓存目录下,编译失败在 diagnosticsCollector 中获取提示信息
*
* @return true:编译成功 false:编译失败
*/
public boolean compilerToTmpPath(String tmpPath) {
long startTime = System.currentTimeMillis();
File codeFile = FileUtil.writeUtf8String(sourceCode, tmpPath + StrUtil.replace(fullClassName, ".", "/") + ".java");
//标准的内容管理器,更换成自己的实现,覆盖部分方法
StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(diagnosticsCollector, null, null);
try {
standardFileManager.setLocation(StandardLocation.CLASS_OUTPUT, Collections.singletonList(new File(tmpPath)));
} catch (IOException e) {
throw new RuntimeException(e);
}
Iterable<? extends JavaFileObject> javaFileObject = standardFileManager.getJavaFileObjectsFromFiles(Collections.singletonList(codeFile));
//获取一个编译任务
JavaCompiler.CompilationTask task = compiler.getTask(null, standardFileManager, diagnosticsCollector, null, null, javaFileObject);
//设置编译耗时
compilerTakeTime = System.currentTimeMillis() - startTime;
return task.call();
}
/**
* @return 编译信息(错误 警告)
*/
......
......@@ -22,8 +22,18 @@ package com.dlink.utils;
import com.dlink.pool.ClassEntity;
import com.dlink.pool.ClassPool;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.codehaus.groovy.control.CompilerConfiguration;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import groovy.lang.GroovyClassLoader;
/**
......@@ -61,4 +71,33 @@ public class UDFUtil {
Thread.currentThread().setContextClassLoader(groovyClassLoader);
//Class<?> clazz = groovyClassLoader.parseClass(codeSource,"com.dlink.ud.udf.SubstringFunction");
}
public static Map<String, List<String>> buildJar(List<String> codeList) {
List<String> successList = new ArrayList<>();
List<String> failedList = new ArrayList<>();
String tmpPath = System.getProperty("user.dir") + File.separator + "tmp/udf/";
String udfJarPath = tmpPath + "udf.jar";
//删除jar缓存
FileUtil.del(udfJarPath);
codeList.forEach(code -> {
CustomStringJavaCompiler compiler = new CustomStringJavaCompiler(code);
boolean res = compiler.compilerToTmpPath(tmpPath);
String className = compiler.getFullClassName();
if (res) {
System.out.println("编译成功");
System.out.println("compilerTakeTime:" + compiler.getCompilerTakeTime());
successList.add(className);
} else {
System.out.println("编译失败");
System.out.println(compiler.getCompilerMessage());
failedList.add(className);
}
});
String[] clazzs = successList.stream().map(className -> StrUtil.replace(className, ".", "/") + ".class").toArray(String[]::new);
InputStream[] fileInputStreams = successList.stream().map(className -> tmpPath + StrUtil.replace(className, ".", "/") + ".class")
.map(FileUtil::getInputStream).toArray(InputStream[]::new);
// 编译好的文件打包jar
ZipUtil.zip(FileUtil.file(udfJarPath), clazzs, fileInputStreams);
return MapUtil.builder("success", successList).put("failed", failedList).build();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment