feat():下载OSS class编译
parent
ff79402d06
commit
c84190f6fb
|
@ -107,6 +107,12 @@
|
||||||
<version>2.3.3</version>
|
<version>2.3.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itranswarp</groupId>
|
||||||
|
<artifactId>compiler</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.muyu.compile;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load class from byte[] which is compiled in memory.
|
||||||
|
*
|
||||||
|
* @author michael
|
||||||
|
*/
|
||||||
|
class MemoryClassLoader extends URLClassLoader {
|
||||||
|
|
||||||
|
// class name to class bytes:
|
||||||
|
Map<String, byte[]> classBytes = new HashMap<String, byte[]>();
|
||||||
|
|
||||||
|
public MemoryClassLoader(Map<String, byte[]> classBytes) {
|
||||||
|
super(new URL[0], MemoryClassLoader.class.getClassLoader());
|
||||||
|
this.classBytes.putAll(classBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||||
|
byte[] buf = classBytes.get(name);
|
||||||
|
if (buf == null) {
|
||||||
|
return super.findClass(name);
|
||||||
|
}
|
||||||
|
classBytes.remove(name);
|
||||||
|
return defineClass(name, buf, 0, buf.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
package com.muyu.compile;
|
||||||
|
|
||||||
|
import javax.tools.*;
|
||||||
|
import javax.tools.JavaFileObject.Kind;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FilterOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In-memory java file manager.
|
||||||
|
*
|
||||||
|
* @author michael
|
||||||
|
*/
|
||||||
|
class MemoryJavaFileManager extends ForwardingJavaFileManager<JavaFileManager> {
|
||||||
|
|
||||||
|
// compiled classes in bytes:
|
||||||
|
final Map<String, byte[]> classBytes = new HashMap<String, byte[]>();
|
||||||
|
|
||||||
|
MemoryJavaFileManager(JavaFileManager fileManager) {
|
||||||
|
super(fileManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, byte[]> getClassBytes() {
|
||||||
|
return new HashMap<String, byte[]>(this.classBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
classBytes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind,
|
||||||
|
FileObject sibling) throws IOException {
|
||||||
|
if (kind == Kind.CLASS) {
|
||||||
|
return new MemoryOutputJavaFileObject(className);
|
||||||
|
} else {
|
||||||
|
return super.getJavaFileForOutput(location, className, kind, sibling);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaFileObject makeStringSource(String name, String code) {
|
||||||
|
return new MemoryInputJavaFileObject(name, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MemoryInputJavaFileObject extends SimpleJavaFileObject {
|
||||||
|
|
||||||
|
final String code;
|
||||||
|
|
||||||
|
MemoryInputJavaFileObject(String name, String code) {
|
||||||
|
super(URI.create("string:///" + name), Kind.SOURCE);
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharBuffer getCharContent(boolean ignoreEncodingErrors) {
|
||||||
|
return CharBuffer.wrap(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MemoryOutputJavaFileObject extends SimpleJavaFileObject {
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
MemoryOutputJavaFileObject(String name) {
|
||||||
|
super(URI.create("string:///" + name), Kind.CLASS);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream openOutputStream() {
|
||||||
|
return new FilterOutputStream(new ByteArrayOutputStream()) {
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
out.close();
|
||||||
|
ByteArrayOutputStream bos = (ByteArrayOutputStream) out;
|
||||||
|
classBytes.put(name, bos.toByteArray());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.muyu.compile;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.tools.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:蓬叁
|
||||||
|
* @Package:com.muyu.compile
|
||||||
|
* @Project:cloud-rule
|
||||||
|
* @name:OSSFileCompile
|
||||||
|
* @Date:2024/8/31 下午7:08
|
||||||
|
*/
|
||||||
|
public class OSSFileCompile{
|
||||||
|
|
||||||
|
public static Map<String, byte[]> compile(String fileName, String source,String extLib) throws IOException {
|
||||||
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||||
|
StandardJavaFileManager stdManager = compiler.getStandardFileManager(null, null, null);
|
||||||
|
try (MemoryJavaFileManager manager = new MemoryJavaFileManager(stdManager)) {
|
||||||
|
JavaFileObject javaFileObject = manager.makeStringSource(fileName, source);
|
||||||
|
// 传入诊断监听器 size和传入的javaObject相同
|
||||||
|
DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
|
||||||
|
List<String> optionList = Arrays.asList("-extdirs",extLib);
|
||||||
|
JavaCompiler.CompilationTask task = compiler.getTask(null, manager,diagnosticCollector, optionList, null, Arrays.asList(javaFileObject));
|
||||||
|
Boolean result = task.call();
|
||||||
|
if (result == null || !result.booleanValue()) {
|
||||||
|
throw new RuntimeException("Compilation failed.");
|
||||||
|
}
|
||||||
|
return manager.getClassBytes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package com.muyu.load;
|
||||||
|
|
||||||
|
import com.aliyun.oss.OSSClient;
|
||||||
|
import com.aliyun.oss.model.OSSObject;
|
||||||
|
import com.muyu.common.core.domain.Result;
|
||||||
|
import com.muyu.compile.OSSFileCompile;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:蓬叁
|
||||||
|
* @Package:com.muyu.load
|
||||||
|
* @Project:cloud-rule
|
||||||
|
* @name:OSSFileLoad
|
||||||
|
* @Date:2024/8/31 下午6:38
|
||||||
|
*/
|
||||||
|
public class OSSFileLoad {
|
||||||
|
|
||||||
|
// 阿里云 endpoint
|
||||||
|
private static final String endpoint = "oss-cn-shanghai.aliyuncs.com";
|
||||||
|
// 阿里云 accessKeyId
|
||||||
|
private static final String accessKeyId = "LTAI5tHKdDATVKeBjFH8mb8D";
|
||||||
|
// 阿里云 accessKeySecret
|
||||||
|
private static final String accessKeySecret = "5ejb4qdgukfD1FdM181kdeAkSuURo7";
|
||||||
|
// bucket
|
||||||
|
private static final String bucketName = "java-web-generating-class";
|
||||||
|
|
||||||
|
public static Result<Object> streamingDownload(String fileName) {
|
||||||
|
try {
|
||||||
|
// 创建 OSSClient 实例
|
||||||
|
OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
|
||||||
|
// 判断 bucket 是否存在
|
||||||
|
Boolean flag_bucket = ossClient.doesBucketExist(bucketName);
|
||||||
|
if (!flag_bucket) {
|
||||||
|
return Result.error("bucket不存在");
|
||||||
|
}
|
||||||
|
// 判断 要下载的文件 是否存在
|
||||||
|
Boolean flag_file = ossClient.doesObjectExist(bucketName, fileName);
|
||||||
|
if (!flag_file) {
|
||||||
|
return Result.error("预下载文件不存在");
|
||||||
|
}
|
||||||
|
// ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流
|
||||||
|
OSSObject ossObject = ossClient.getObject(bucketName, fileName);
|
||||||
|
// 按行读取文件内容
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
|
||||||
|
|
||||||
|
String source = null;
|
||||||
|
|
||||||
|
while(true){
|
||||||
|
String line = reader.readLine();
|
||||||
|
source = source + line;
|
||||||
|
if (line == null) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作
|
||||||
|
reader.close();
|
||||||
|
// 关闭oss
|
||||||
|
ossClient.shutdown();
|
||||||
|
|
||||||
|
Map<String, byte[]> compile = OSSFileCompile.compile(fileName, source, "target/classes/com/muyu/generate");
|
||||||
|
compile.forEach((key, value) -> {});
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.fillInStackTrace();
|
||||||
|
}
|
||||||
|
return Result.success(null,"编译成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -45,7 +45,7 @@ public class ALiYunUpload {
|
||||||
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
|
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
|
||||||
|
|
||||||
// 上传到OSS后文件保存的目录,例如:folder/subfolder/,最后以斜杠结尾
|
// 上传到OSS后文件保存的目录,例如:folder/subfolder/,最后以斜杠结尾
|
||||||
String objectName = "build/rule/"+fileName+".java";
|
String objectName = "build/version/rule/"+fileName+".java";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 将内容转换为字节数组输入流
|
// 将内容转换为字节数组输入流
|
||||||
|
|
|
@ -1,162 +0,0 @@
|
||||||
package com.muyu.upload;
|
|
||||||
|
|
||||||
import com.aliyun.oss.OSS;
|
|
||||||
import com.aliyun.oss.OSSClientBuilder;
|
|
||||||
import com.aliyun.oss.model.GetObjectRequest;
|
|
||||||
import com.aliyun.oss.model.PutObjectRequest;
|
|
||||||
import lombok.extern.log4j.Log4j2;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Oss服务调用
|
|
||||||
*/
|
|
||||||
@Log4j2
|
|
||||||
public class OssUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Endpoint 存储对象概述 阿里云主账号AccessKey,accessKeySecret拥有所有API的访问权限 访问路径前缀 存储对象概述
|
|
||||||
*/
|
|
||||||
private static String endPoint = "oss-cn-shanghai.aliyuncs.com";
|
|
||||||
private static String accessKeyId = "LTAI5tHKdDATVKeBjFH8mb8D";
|
|
||||||
private static String accessKeySecret = "5ejb4qdgukfD1FdM181kdeAkSuURo7";
|
|
||||||
private static String accessPre = "https://mall-bw.oss-cn-shanghai.aliyuncs.com/";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bucket名称
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static String bucketName = "mall-bw";
|
|
||||||
|
|
||||||
private static OSS ossClient;
|
|
||||||
|
|
||||||
static {
|
|
||||||
ossClient = new OSSClientBuilder().build(
|
|
||||||
endPoint,
|
|
||||||
accessKeyId,
|
|
||||||
accessKeySecret);
|
|
||||||
log.info("oss服务连接成功!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 默认路径上传本地文件
|
|
||||||
*
|
|
||||||
* @param filePath
|
|
||||||
*/
|
|
||||||
public static String uploadFile(String filePath) {
|
|
||||||
return uploadFileForBucket(bucketName, getOssFilePath(filePath), filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 默认路径上传multipartFile文件
|
|
||||||
*
|
|
||||||
* @param multipartFile
|
|
||||||
*/
|
|
||||||
public static String uploadMultipartFile(MultipartFile multipartFile) {
|
|
||||||
return uploadMultipartFile(bucketName, getOssFilePath(multipartFile.getOriginalFilename()), multipartFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传 multipartFile 类型文件
|
|
||||||
*
|
|
||||||
* @param bucketName
|
|
||||||
* @param ossPath
|
|
||||||
* @param multipartFile
|
|
||||||
*/
|
|
||||||
public static String uploadMultipartFile(String bucketName, String ossPath, MultipartFile multipartFile) {
|
|
||||||
InputStream inputStream = null;
|
|
||||||
try {
|
|
||||||
inputStream = multipartFile.getInputStream();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
uploadFileInputStreamForBucket(bucketName, ossPath, inputStream);
|
|
||||||
return accessPre + ossPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用File上传PutObject上传文件 ** 程序默认使用次方法上传
|
|
||||||
*
|
|
||||||
* @param bucketName 实例名称
|
|
||||||
* @param ossPath oss存储路径
|
|
||||||
* @param filePath 本地文件路径
|
|
||||||
*/
|
|
||||||
public static String uploadFileForBucket(String bucketName, String ossPath, String filePath) {
|
|
||||||
// 创建PutObjectRequest对象。
|
|
||||||
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, ossPath, new File(filePath));
|
|
||||||
|
|
||||||
// 上传
|
|
||||||
ossClient.putObject(putObjectRequest);
|
|
||||||
return accessPre + ossPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用文件流上传到指定的bucket实例
|
|
||||||
*
|
|
||||||
* @param bucketName 实例名称
|
|
||||||
* @param ossPath oss存储路径
|
|
||||||
* @param filePath 本地文件路径
|
|
||||||
*/
|
|
||||||
public static String uploadFileInputStreamForBucket(String bucketName, String ossPath, String filePath) {
|
|
||||||
|
|
||||||
// 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
|
|
||||||
InputStream inputStream = null;
|
|
||||||
try {
|
|
||||||
inputStream = new FileInputStream(filePath);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
// 填写Bucket名称和Object完整路径。Object完整路径中不能包含Bucket名称。
|
|
||||||
uploadFileInputStreamForBucket(bucketName, ossPath, inputStream);
|
|
||||||
return accessPre + ossPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void uploadFileInputStreamForBucket(String bucketName, String ossPath, InputStream inputStream) {
|
|
||||||
ossClient.putObject(bucketName, ossPath, inputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下载
|
|
||||||
*
|
|
||||||
* @param ossFilePath
|
|
||||||
* @param filePath
|
|
||||||
*/
|
|
||||||
public static void downloadFile(String ossFilePath, String filePath) {
|
|
||||||
downloadFileForBucket(bucketName, ossFilePath, filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下载
|
|
||||||
*
|
|
||||||
* @param bucketName 实例名称
|
|
||||||
* @param ossFilePath oss存储路径
|
|
||||||
* @param filePath 本地文件路径
|
|
||||||
*/
|
|
||||||
public static void downloadFileForBucket(String bucketName, String ossFilePath, String filePath) {
|
|
||||||
ossClient.getObject(new GetObjectRequest(bucketName, ossFilePath), new File(filePath));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String getOssDefaultPath() {
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
String url =
|
|
||||||
now.getYear() + "/" +
|
|
||||||
now.getMonth() + "/" +
|
|
||||||
now.getDayOfMonth() + "/" +
|
|
||||||
now.getHour() + "/" +
|
|
||||||
now.getMinute() + "/";
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getOssFilePath(String filePath) {
|
|
||||||
String fileSuf = filePath.substring(filePath.indexOf(".") + 1);
|
|
||||||
return getOssDefaultPath() + UUID.randomUUID().toString() + "." + fileSuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -8,6 +8,7 @@ import com.muyu.common.domain.req.RuleDataUpdReq;
|
||||||
import com.muyu.common.domain.req.RuleVersionAddReq;
|
import com.muyu.common.domain.req.RuleVersionAddReq;
|
||||||
import com.muyu.common.domain.req.RuleVersionUpdReq;
|
import com.muyu.common.domain.req.RuleVersionUpdReq;
|
||||||
import com.muyu.common.domain.resp.RuleVersionResp;
|
import com.muyu.common.domain.resp.RuleVersionResp;
|
||||||
|
import com.muyu.load.OSSFileLoad;
|
||||||
import com.muyu.servier.RuleVersionService;
|
import com.muyu.servier.RuleVersionService;
|
||||||
import com.muyu.upload.ALiYunUpload;
|
import com.muyu.upload.ALiYunUpload;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import com.muyu.common.domain.RuleVersion;
|
||||||
import com.muyu.common.domain.req.RuleVersionUpdReq;
|
import com.muyu.common.domain.req.RuleVersionUpdReq;
|
||||||
import com.muyu.common.domain.resp.RuleVersionResp;
|
import com.muyu.common.domain.resp.RuleVersionResp;
|
||||||
import com.muyu.constant.GenerateConstant;
|
import com.muyu.constant.GenerateConstant;
|
||||||
|
import com.muyu.load.OSSFileLoad;
|
||||||
import com.muyu.mapper.RuleVersionMapper;
|
import com.muyu.mapper.RuleVersionMapper;
|
||||||
import com.muyu.servier.RuleDataService;
|
import com.muyu.servier.RuleDataService;
|
||||||
import com.muyu.servier.RuleVersionService;
|
import com.muyu.servier.RuleVersionService;
|
||||||
|
@ -76,6 +77,7 @@ public class RuleVersionServiceImpl
|
||||||
RuleData ruleData = ruleDataService.getById(ruleVersion.getRuleId());
|
RuleData ruleData = ruleDataService.getById(ruleVersion.getRuleId());
|
||||||
ruleVersion.setRuleVersionType("generate"+"_"+ruleData.getRuleCoding()+"_"+ruleVersion.getRuleVersionCode());
|
ruleVersion.setRuleVersionType("generate"+"_"+ruleData.getRuleCoding()+"_"+ruleVersion.getRuleVersionCode());
|
||||||
ruleVersion.setRuleVersionText(GenerateConstant.generateConstant(ruleData,ruleVersion));
|
ruleVersion.setRuleVersionText(GenerateConstant.generateConstant(ruleData,ruleVersion));
|
||||||
|
OSSFileLoad.streamingDownload(ruleVersion.getRuleVersionType()+".java");
|
||||||
return ruleVersion;
|
return ruleVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue