[server] [func.xray] - 完成xray 的对象存储,任务分发全流程 - 1
This commit is contained in:
@@ -8,6 +8,7 @@ import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.wdd.common.beans.response.R;
|
||||
import io.wdd.func.oss.config.OctopusObjectSummary;
|
||||
import io.wdd.func.oss.config.OssConfig;
|
||||
import io.wdd.func.oss.service.OSSCoreService;
|
||||
import io.wdd.func.oss.service.OssBackendSelect;
|
||||
@@ -125,9 +126,29 @@ public class OSSController {
|
||||
));
|
||||
}
|
||||
|
||||
@PostMapping("/object/simple")
|
||||
@ApiOperation("[对象] - 简单查询")
|
||||
public R<OctopusObjectSummary> objectDetailSimple(
|
||||
@RequestParam(value = "BackendPrefixName", required = true)
|
||||
@ApiParam(value = "BackendPrefixName") String BackendPrefixName,
|
||||
@RequestParam(value = "bucketName", required = true)
|
||||
@ApiParam(value = "bucketName") String bucketName,
|
||||
@RequestParam(value = "objectName", required = true)
|
||||
@ApiParam(value = "objectName") String objectName
|
||||
) {
|
||||
|
||||
OssConfig ossConfig = ossBackendSelect.one(BackendPrefixName);
|
||||
|
||||
return R.ok(OSSCoreService.getObjectSimple(
|
||||
ossConfig,
|
||||
bucketName,
|
||||
objectName
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/object/one")
|
||||
@ApiOperation("[对象] - 查询下载地址")
|
||||
@ApiOperation("[对象] - 默认查询")
|
||||
public R<S3Object> objectDetailOne(
|
||||
@RequestParam(value = "BackendPrefixName", required = true)
|
||||
@ApiParam(value = "BackendPrefixName") String BackendPrefixName,
|
||||
|
||||
@@ -1,25 +1,67 @@
|
||||
package io.wdd.func.controller;
|
||||
|
||||
|
||||
import io.wdd.func.xray.beans.node.ProxyNode;
|
||||
import io.wdd.func.xray.service.XrayConfigDistribute;
|
||||
import io.wdd.func.xray.service.XrayCoreService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static io.wdd.func.xray.beans.node.ProxyNodeSet.*;
|
||||
import static io.wdd.func.xray.beans.node.ProxyNodeSet.phoenix2;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/server/func/xray/")
|
||||
@RequestMapping("/server/func/xray")
|
||||
public class XrayController {
|
||||
|
||||
|
||||
@Resource
|
||||
XrayCoreService xrayCoreService;
|
||||
|
||||
@Resource
|
||||
XrayConfigDistribute xrayConfigDistribute;
|
||||
|
||||
@GetMapping("/test")
|
||||
public void test(){
|
||||
|
||||
xrayCoreService.generateXrayJsonFromNodeList(null);
|
||||
ArrayList<ArrayList<ProxyNode>> allNetworkPathList = new ArrayList<>();
|
||||
|
||||
ArrayList<ProxyNode> pathA = new ArrayList<>(
|
||||
Arrays.asList(
|
||||
shanghai,
|
||||
seoul2,
|
||||
tokyo2,
|
||||
phoenix2
|
||||
)
|
||||
);
|
||||
|
||||
/*ArrayList<ProxyNode> pathB = new ArrayList<>(
|
||||
Arrays.asList(
|
||||
shanghai,
|
||||
seoul2,
|
||||
london2
|
||||
)
|
||||
);
|
||||
|
||||
ArrayList<ProxyNode> pathC = new ArrayList<>(
|
||||
Arrays.asList(
|
||||
seoul2,
|
||||
phoenix2
|
||||
)
|
||||
);*/
|
||||
|
||||
allNetworkPathList.add(pathA);
|
||||
// allNetworkPathList.add(pathB);
|
||||
// allNetworkPathList.add(pathC);
|
||||
|
||||
xrayCoreService.generateXrayJsonFromNodeList(allNetworkPathList);
|
||||
|
||||
xrayConfigDistribute.uploadXrayConfigToOSS(allNetworkPathList.get(0));
|
||||
|
||||
System.out.println("结束!");
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package io.wdd.func.oss.config;
|
||||
|
||||
|
||||
import com.amazonaws.services.s3.model.Owner;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 参考 com.amazonaws.services.s3.model.S3ObjectSummary
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@ApiModel("Octopus项目使用的对象存储的标准模型")
|
||||
public class OctopusObjectSummary {
|
||||
|
||||
/**
|
||||
* The name of the bucket in which this object is stored
|
||||
*/
|
||||
String bucketName;
|
||||
|
||||
/**
|
||||
* The key under which this object is stored
|
||||
*/
|
||||
String key;
|
||||
|
||||
/**
|
||||
* Hex encoded MD5 hash of this object's contents, as computed by Amazon S3
|
||||
*/
|
||||
String eTag;
|
||||
|
||||
/**
|
||||
* The size of this object, in bytes
|
||||
*/
|
||||
long size;
|
||||
|
||||
/**
|
||||
* The date, according to Amazon S3, when this object was last modified
|
||||
*/
|
||||
Date lastModified;
|
||||
|
||||
/**
|
||||
* The class of storage used by Amazon S3 to store this object
|
||||
*/
|
||||
String storageClass;
|
||||
|
||||
String contentType;
|
||||
|
||||
/**
|
||||
* The owner of this object - can be null if the requester doesn't have
|
||||
* permission to view object ownership information
|
||||
*/
|
||||
Owner owner;
|
||||
|
||||
AccessDTO access;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
public static class AccessDTO {
|
||||
URI originUrl;
|
||||
|
||||
String cloudflareUrl;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.amazonaws.services.s3.model.Bucket;
|
||||
import com.amazonaws.services.s3.model.ObjectListing;
|
||||
import com.amazonaws.services.s3.model.ObjectMetadata;
|
||||
import com.amazonaws.services.s3.model.S3Object;
|
||||
import io.wdd.func.oss.config.OctopusObjectSummary;
|
||||
import io.wdd.func.oss.config.OssConfig;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@@ -93,6 +94,18 @@ public interface OSSCoreService {
|
||||
* */
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves an object.
|
||||
* https://docs.oracle.com/en-us/iaas/api/#/en/s3objectstorage/20160918/Object/GetObject
|
||||
*
|
||||
* @param ossConfig
|
||||
* @param bucketName
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
OctopusObjectSummary getObjectSimple(OssConfig ossConfig, String bucketName, String objectName);
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves an object.
|
||||
* https://docs.oracle.com/en-us/iaas/api/#/en/s3objectstorage/20160918/Object/GetObject
|
||||
@@ -138,6 +151,17 @@ public interface OSSCoreService {
|
||||
*/
|
||||
HashMap<String, String> createObject(OssConfig ossConfig, String bucketName, String objectName, MultipartFile file);
|
||||
|
||||
|
||||
/**
|
||||
* 根据ossConfig查询得到一个随机公开的桶,然后上传
|
||||
*
|
||||
* @param ossConfig
|
||||
* @param objectName
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
OctopusObjectSummary createObject(OssConfig ossConfig, String objectName, File file);
|
||||
|
||||
/**
|
||||
* Creates a new object or overwrites an existing one.
|
||||
* <p>
|
||||
@@ -148,7 +172,7 @@ public interface OSSCoreService {
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
ObjectMetadata createObject(OssConfig ossConfig, String bucketName, String objectName, File file);
|
||||
OctopusObjectSummary createObject(OssConfig ossConfig, String bucketName, String objectName, File file);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,9 +5,11 @@ import com.amazonaws.SdkClientException;
|
||||
import com.amazonaws.services.s3.AmazonS3;
|
||||
import com.amazonaws.services.s3.model.*;
|
||||
import io.wdd.common.handler.MyRuntimeException;
|
||||
import io.wdd.func.oss.config.OctopusObjectSummary;
|
||||
import io.wdd.func.oss.config.OssConfig;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
@@ -102,6 +104,15 @@ public class OSSCoreServiceImpl implements OSSCoreService {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public OctopusObjectSummary getObjectSimple(OssConfig ossConfig, String bucketName, String objectName) {
|
||||
return buildOctopusObjectSummary(
|
||||
ossConfig,
|
||||
bucketName,
|
||||
objectName
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public S3Object getObject(OssConfig ossConfig, String bucketName, String objectName) {
|
||||
|
||||
@@ -113,7 +124,10 @@ public class OSSCoreServiceImpl implements OSSCoreService {
|
||||
objectName
|
||||
);
|
||||
} catch (SdkClientException e) {
|
||||
log.error("出查询单个对象 出现错误, 错误原因为 => {}", e.getMessage());
|
||||
log.error(
|
||||
"出查询单个对象 出现错误, 错误原因为 => {}",
|
||||
e.getMessage()
|
||||
);
|
||||
throw new MyRuntimeException(e.getMessage());
|
||||
|
||||
}
|
||||
@@ -156,7 +170,10 @@ public class OSSCoreServiceImpl implements OSSCoreService {
|
||||
);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("查询对象的Head信息错误, 错误原因 => {}", e.getMessage());
|
||||
log.error(
|
||||
"查询对象的Head信息错误, 错误原因 => {}",
|
||||
e.getMessage()
|
||||
);
|
||||
|
||||
throw new MyRuntimeException(e.getMessage());
|
||||
}
|
||||
@@ -197,29 +214,122 @@ public class OSSCoreServiceImpl implements OSSCoreService {
|
||||
.getObjectContent()
|
||||
.getHttpRequest()
|
||||
.getURI();
|
||||
map.put("origin",
|
||||
String.valueOf(uri));
|
||||
map.put(
|
||||
"origin",
|
||||
String.valueOf(uri)
|
||||
);
|
||||
|
||||
|
||||
return map;
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("文件-创建一个对象失败,原因为 => {}", e.getMessage());
|
||||
log.error(
|
||||
"文件-创建一个对象失败,原因为 => {}",
|
||||
e.getMessage()
|
||||
);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMetadata createObject(OssConfig ossConfig, String bucketName, String objectName, File file) {
|
||||
AmazonS3 client = ossConfig.getClient();
|
||||
public OctopusObjectSummary createObject(OssConfig ossConfig, String objectName, File file) {
|
||||
|
||||
PutObjectResult putObjectResult = client.putObject(
|
||||
bucketName,
|
||||
AmazonS3 client = ossConfig.getClient();
|
||||
List<Bucket> bucketList = client.listBuckets(
|
||||
);
|
||||
|
||||
Bucket randomBucket = bucketList
|
||||
.stream()
|
||||
// 理论上此处应该增加筛选公开的桶的策略
|
||||
.findAny()
|
||||
.get();
|
||||
|
||||
Assert.notNull(
|
||||
randomBucket,
|
||||
"[对象]-创建失败! 未获取到有效的 bucketName"
|
||||
);
|
||||
|
||||
return createObject(
|
||||
ossConfig,
|
||||
randomBucket.getName(),
|
||||
objectName,
|
||||
file
|
||||
);
|
||||
}
|
||||
|
||||
return putObjectResult.getMetadata();
|
||||
@Override
|
||||
public OctopusObjectSummary createObject(OssConfig ossConfig, String bucketName, String objectName, File file) {
|
||||
|
||||
AmazonS3 client = ossConfig.getClient();
|
||||
|
||||
log.info(
|
||||
"[对象]-创建新的对象,OSS后端为 [ {} ], 桶名称为 [ {} ], 文件名称为 [ {} ]",
|
||||
ossConfig.getName() + "-" + ossConfig.getRegion(),
|
||||
bucketName,
|
||||
objectName
|
||||
);
|
||||
|
||||
try {
|
||||
|
||||
// 调用sdk上传文件
|
||||
client.putObject(
|
||||
bucketName,
|
||||
objectName,
|
||||
file
|
||||
);
|
||||
|
||||
} catch (SdkClientException e) {
|
||||
log.error(
|
||||
"[对象]-创建对象失败! OSS后端为 [ {} ], 桶名称为 [ {} ], 文件名称为 [ {} ] 原因为 {}",
|
||||
ossConfig.getName() + "-" + ossConfig.getRegion(),
|
||||
bucketName,
|
||||
objectName,
|
||||
e.getMessage()
|
||||
);
|
||||
throw new MyRuntimeException(e);
|
||||
}
|
||||
|
||||
// 查询对象的相关信息返回不一样的内容
|
||||
return buildOctopusObjectSummary(
|
||||
ossConfig,
|
||||
bucketName,
|
||||
objectName
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
private OctopusObjectSummary buildOctopusObjectSummary(OssConfig ossConfig, String bucketName, String objectName) {
|
||||
|
||||
S3Object s3Object = this.getObject(
|
||||
ossConfig,
|
||||
bucketName,
|
||||
objectName
|
||||
);
|
||||
|
||||
return convertOOSFromS3Object(s3Object);
|
||||
}
|
||||
|
||||
private OctopusObjectSummary convertOOSFromS3Object(S3Object s3Object) {
|
||||
S3ObjectInputStream objectContent = s3Object.getObjectContent();
|
||||
ObjectMetadata objectMetadata = s3Object.getObjectMetadata();
|
||||
|
||||
OctopusObjectSummary.AccessDTO accessDTO = OctopusObjectSummary.AccessDTO
|
||||
.builder()
|
||||
.originUrl(objectContent
|
||||
.getHttpRequest()
|
||||
.getURI())
|
||||
.build();
|
||||
|
||||
return OctopusObjectSummary
|
||||
.builder()
|
||||
.key(s3Object.getKey())
|
||||
.size(objectMetadata.getContentLength())
|
||||
.lastModified(objectMetadata.getLastModified())
|
||||
.contentType(objectMetadata.getContentType())
|
||||
.eTag(objectMetadata.getETag())
|
||||
.bucketName(s3Object.getBucketName())
|
||||
.access(accessDTO)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -234,7 +344,6 @@ public class OSSCoreServiceImpl implements OSSCoreService {
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
return restoreObjectResult.getRestoreOutputPath();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
package io.wdd.func.xray.beans.node;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@ApiModel("代理节点的信息")
|
||||
public class ProxyNode {
|
||||
|
||||
/**
|
||||
@@ -31,8 +36,11 @@ public class ProxyNode {
|
||||
|
||||
String publicIPv6;
|
||||
|
||||
@ApiModelProperty("保存生成的Xray Config信息")
|
||||
XrayConfigInfo xrayConfigInfo;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProxyNode: [ "+ agentTopicName + " ]";
|
||||
return "ProxyNode: [ " + agentTopicName + " ]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package io.wdd.func.xray.beans.node;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.wdd.func.oss.config.OctopusObjectSummary;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@ApiModel("保存ProxyNode对应生成的 Config信息")
|
||||
public class XrayConfigInfo {
|
||||
|
||||
@ApiModelProperty("文件名称,为1-<agentTopicName>-<timeString>.json")
|
||||
String xrayConfigFileName;
|
||||
|
||||
/**
|
||||
* 保存生成的XrayConfig文件的全路径
|
||||
*/
|
||||
@ApiModelProperty("保存生成的XrayConfig文件,全路径")
|
||||
File xrayConfigFile;
|
||||
|
||||
|
||||
@ApiModelProperty("xray config file的对象存储的相关信息")
|
||||
OctopusObjectSummary objectSummary;
|
||||
|
||||
}
|
||||
@@ -1,9 +1,173 @@
|
||||
package io.wdd.func.xray.service;
|
||||
|
||||
import io.wdd.func.oss.config.OctopusObjectSummary;
|
||||
import io.wdd.func.oss.config.OssConfig;
|
||||
import io.wdd.func.oss.service.OSSCoreService;
|
||||
import io.wdd.func.oss.service.OssBackendSelect;
|
||||
import io.wdd.func.xray.beans.node.ProxyNode;
|
||||
import io.wdd.func.xray.beans.node.XrayConfigInfo;
|
||||
import io.wdd.rpc.execute.service.CoreExecutionService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 需要完成 Tmp目录中Xray文件的上传工作,上传至 OSS中
|
||||
* <p>
|
||||
* 生成操作命令
|
||||
* 调用rpc,执行命令下发操作,等待agent进行相关操作
|
||||
* <p>
|
||||
* 检查任务流程的结果,判断是否符合预期
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class XrayConfigDistribute {
|
||||
|
||||
/**
|
||||
* 存储更新 Xray的命令行
|
||||
*/
|
||||
private static final List<List<String>> updateXrayCommandList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 发送至agent的操作类型
|
||||
*/
|
||||
private static final String updateCommandType = "OctopusXray";
|
||||
|
||||
static {
|
||||
ArrayList<String> first = new ArrayList<>(
|
||||
List.of(
|
||||
"cp",
|
||||
"/usr/local/etc/xray/config.json",
|
||||
"/usr/local/etc/xray/config-bak-$(date +%Y-%m-%d-%H-%M-%S)"
|
||||
|
||||
)
|
||||
);
|
||||
|
||||
ArrayList<String> second = new ArrayList<>(
|
||||
List.of(
|
||||
"wget",
|
||||
"url",
|
||||
"-O",
|
||||
"/usr/local/etc/xray/config.json"
|
||||
)
|
||||
);
|
||||
|
||||
ArrayList<String> third = new ArrayList<>(
|
||||
List.of(
|
||||
"systemctl",
|
||||
"restart",
|
||||
"xray"
|
||||
)
|
||||
);
|
||||
|
||||
ArrayList<String> fourth = new ArrayList<>(
|
||||
List.of(
|
||||
"systemctl",
|
||||
"status",
|
||||
"xray",
|
||||
"|",
|
||||
"grep",
|
||||
"-c",
|
||||
"active,(running)"
|
||||
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
updateXrayCommandList.add(first);
|
||||
updateXrayCommandList.add(second);
|
||||
updateXrayCommandList.add(third);
|
||||
updateXrayCommandList.add(fourth);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Resource
|
||||
OssBackendSelect ossBackendSelect;
|
||||
@Resource
|
||||
OSSCoreService ossCoreService;
|
||||
|
||||
@Resource
|
||||
CoreExecutionService executionService;
|
||||
|
||||
public void uploadXrayConfigToOSS(ArrayList<ProxyNode> networkPathList) {
|
||||
|
||||
// 所有的文件全部存储至一个对象存储的后端中
|
||||
OssConfig ossConfig = ossBackendSelect.oneRandom();
|
||||
log.info(
|
||||
"[Xray] 开始上传所有的xray config 至对象存储中 => [{}]",
|
||||
ossConfig.getName() + "-" + ossConfig.getRegion()
|
||||
);
|
||||
|
||||
// 依次存储所有的config文件
|
||||
networkPathList
|
||||
.stream()
|
||||
.forEach(
|
||||
node -> {
|
||||
XrayConfigInfo xrayConfigInfo = node.getXrayConfigInfo();
|
||||
// 上传OSS
|
||||
OctopusObjectSummary octopusObjectSummary = ossCoreService
|
||||
.createObject(
|
||||
ossConfig,
|
||||
xrayConfigInfo.getXrayConfigFileName(),
|
||||
xrayConfigInfo.getXrayConfigFile()
|
||||
);
|
||||
// 设置oss的相关信息
|
||||
|
||||
xrayConfigInfo.setObjectSummary(octopusObjectSummary);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public void buildXrayUpdateResult(ArrayList<ProxyNode> networkPathList) {
|
||||
|
||||
|
||||
List<String> resultKeyList = networkPathList
|
||||
.stream()
|
||||
.map(
|
||||
proxyNode -> {
|
||||
OctopusObjectSummary.AccessDTO access = proxyNode
|
||||
.getXrayConfigInfo()
|
||||
.getObjectSummary()
|
||||
.getAccess();
|
||||
|
||||
String realUrl = access
|
||||
.getOriginUrl()
|
||||
.getPath();
|
||||
if (StringUtils.isNotEmpty(access.getCloudflareUrl())) {
|
||||
// 优先使用 被cloudflare包装过的的下载网址
|
||||
realUrl = access.getCloudflareUrl();
|
||||
}
|
||||
// 修改命令中的下载url
|
||||
updateXrayCommandList
|
||||
.get(1)
|
||||
.set(
|
||||
1,
|
||||
realUrl
|
||||
);
|
||||
|
||||
// 向Agent发送命令,执行更新操作!
|
||||
String resultKey = executionService.SendCommandToAgent(
|
||||
proxyNode.getAgentTopicName(),
|
||||
updateCommandType,
|
||||
null,
|
||||
updateXrayCommandList,
|
||||
null
|
||||
);
|
||||
|
||||
return resultKey;
|
||||
}
|
||||
)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
log.debug("发送所有的配置到各个Agent成功, 结果查看为 => {}", resultKeyList);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
@@ -29,7 +28,7 @@ public class XrayConfigPersistor {
|
||||
public static AtomicInteger cleanVersion = new AtomicInteger(0);
|
||||
|
||||
|
||||
public void write(String fileName , String content, int currentVersion) {
|
||||
public File write(String fileName , String content, int currentVersion) {
|
||||
|
||||
System.out.println("currentVersion = " + currentVersion);
|
||||
|
||||
@@ -44,7 +43,6 @@ public class XrayConfigPersistor {
|
||||
File resultFile = getResultFile(fileName);
|
||||
try {
|
||||
|
||||
|
||||
log.debug("开始写入XrayConfig进入文件中,文件名为 => {}",fileName);
|
||||
FileWriter fileWriter = new FileWriter(
|
||||
resultFile
|
||||
@@ -60,12 +58,13 @@ public class XrayConfigPersistor {
|
||||
bufferedWriter.close();
|
||||
fileWriter.close();
|
||||
|
||||
|
||||
return resultFile;
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("打开文件失败,写入tmp文件失败! 文件为 => {}", resultFile.getName());
|
||||
throw new MyRuntimeException(e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void clearOldRemainStaff() {
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.wdd.common.utils.TimeUtils;
|
||||
import io.wdd.func.xray.beans.node.ProxyNode;
|
||||
import io.wdd.func.xray.beans.node.XrayConfigInfo;
|
||||
import io.wdd.func.xray.beans.xray.RoutingObject;
|
||||
import io.wdd.func.xray.beans.xray.RuleObject;
|
||||
import io.wdd.func.xray.beans.xray.XrayConfig;
|
||||
@@ -19,14 +20,17 @@ import org.apache.commons.beanutils.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static io.wdd.func.xray.beans.config.InboundVmessHTTPTemplateClass.InboundVmessHTTPTemplate;
|
||||
import static io.wdd.func.xray.beans.config.InboundVmessHTTPTemplateClass.ListenAddress;
|
||||
import static io.wdd.func.xray.beans.config.LogTemplateClass.LogTemplate;
|
||||
import static io.wdd.func.xray.beans.config.OutboundVmessHTTPTemplateClass.*;
|
||||
import static io.wdd.func.xray.beans.node.ProxyNodeSet.*;
|
||||
import static io.wdd.func.xray.service.XrayConfigPersistor.cleanVersion;
|
||||
|
||||
@Service
|
||||
@@ -43,38 +47,6 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
||||
@Override
|
||||
public void generateXrayJsonFromNodeList(ArrayList<ArrayList<ProxyNode>> allNetworkPathList) {
|
||||
|
||||
|
||||
allNetworkPathList = new ArrayList<>();
|
||||
|
||||
ArrayList<ProxyNode> pathA = new ArrayList<>(
|
||||
Arrays.asList(
|
||||
shanghai,
|
||||
seoul2,
|
||||
tokyo2,
|
||||
phoenix2
|
||||
)
|
||||
);
|
||||
|
||||
/*ArrayList<ProxyNode> pathB = new ArrayList<>(
|
||||
Arrays.asList(
|
||||
shanghai,
|
||||
seoul2,
|
||||
london2
|
||||
)
|
||||
);
|
||||
|
||||
ArrayList<ProxyNode> pathC = new ArrayList<>(
|
||||
Arrays.asList(
|
||||
seoul2,
|
||||
phoenix2
|
||||
)
|
||||
);*/
|
||||
|
||||
allNetworkPathList.add(pathA);
|
||||
// allNetworkPathList.add(pathB);
|
||||
// allNetworkPathList.add(pathC);
|
||||
|
||||
|
||||
// 需要根据所有的交叉链路进行计算
|
||||
// A -> B -> C -> D
|
||||
// B -> D
|
||||
@@ -87,12 +59,11 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
||||
|
||||
// 返回每一条的结果至于 Map中 key => shanghai->seoul2->tokyo2
|
||||
// value => xray配置信息
|
||||
HashMap<String, String> interfaceMap = new HashMap<>();
|
||||
// HashMap<String, String> interfaceMap = new HashMap<>();
|
||||
|
||||
// 最终Xray Json配置应该放置于 Map中 key => ProxyNode
|
||||
// value => Xray Config Json
|
||||
HashMap<ProxyNode, XrayConfig> resultMap = new HashMap<>();
|
||||
|
||||
// HashMap<ProxyNode, XrayConfig> resultMap = new HashMap<>();
|
||||
|
||||
allNetworkPathList
|
||||
.stream()
|
||||
@@ -100,9 +71,7 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
||||
networkPathList -> {
|
||||
// 每一条每一条的执行,依次添加相应的 in-out 连接
|
||||
generateXrayJsonSinglePath(
|
||||
networkPathList,
|
||||
interfaceMap,
|
||||
resultMap
|
||||
networkPathList
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -110,7 +79,7 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
||||
|
||||
}
|
||||
|
||||
private void generateXrayJsonSinglePath(ArrayList<ProxyNode> networkPathList, HashMap<String, String> interfaceMap, HashMap<ProxyNode, XrayConfig> resultMap) {
|
||||
private void generateXrayJsonSinglePath(ArrayList<ProxyNode> networkPathList) {
|
||||
int pathLength = networkPathList.size();
|
||||
if (pathLength == 1) {
|
||||
log.error("网络路径节点仅为一个");
|
||||
@@ -146,7 +115,6 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
||||
// 清楚tmp目录时候使用的一个锁
|
||||
int currentVersion = cleanVersion.get();
|
||||
|
||||
|
||||
for (int pos = 0; pos < pathLength; pos++) {
|
||||
|
||||
ProxyNode proxyNode = networkPathList.get(pos);
|
||||
@@ -178,12 +146,19 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
||||
);
|
||||
|
||||
// 文件持久化!
|
||||
xrayConfigPersistor.write(
|
||||
File xrayConfigFile = xrayConfigPersistor.write(
|
||||
fileName,
|
||||
resultContent,
|
||||
currentVersion
|
||||
);
|
||||
|
||||
// 文件写入完成,保存文件信息
|
||||
XrayConfigInfo xrayConfigInfo = new XrayConfigInfo();
|
||||
xrayConfigInfo.setXrayConfigFile(xrayConfigFile);
|
||||
xrayConfigInfo.setXrayConfigFileName(fileName);
|
||||
|
||||
proxyNode.setXrayConfigInfo(xrayConfigInfo);
|
||||
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -376,7 +351,6 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
||||
);
|
||||
|
||||
// 去掉末尾的 ->
|
||||
|
||||
String s = sb.toString();
|
||||
|
||||
return s.substring(
|
||||
|
||||
@@ -11,6 +11,8 @@ public interface CoreExecutionService {
|
||||
String SendCommandToAgent(String agentTopicName, List<String> commandList);
|
||||
|
||||
/**
|
||||
* 调用 单行命令脚本的 最底层函数
|
||||
*
|
||||
* @param agentTopicName agent唯一表示名
|
||||
* @param type 任务执行类型
|
||||
* @param commandList 任务列表内容
|
||||
@@ -21,10 +23,20 @@ public interface CoreExecutionService {
|
||||
|
||||
String SendCommandToAgent(String agentTopicName, String type, List<String> commandList, List<List<String>> commandListComplete);
|
||||
|
||||
/**
|
||||
*
|
||||
* 调用 完整脚本的 最底层函数
|
||||
*
|
||||
* @param agentTopicName
|
||||
* @param type
|
||||
* @param commandList
|
||||
* @param commandListComplete
|
||||
* @param futureKey
|
||||
* @return resultKey 本次操作在Redis中记录的结果Key
|
||||
*/
|
||||
String SendCommandToAgent(String agentTopicName, String type, List<String> commandList, List<List<String>> commandListComplete, String futureKey);
|
||||
|
||||
|
||||
|
||||
List<String> SendCommandToAgent(List<String> agentTopicNameList, String type, List<String> command);
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.wdd.rpc.openfeign;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
|
||||
@FeignClient(url = "")
|
||||
public interface AgentOperationFeign {
|
||||
}
|
||||
Reference in New Issue
Block a user