package com.cym.service;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.noear.solon.annotation.Inject;
import org.noear.solon.aspect.annotation.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.cym.config.HomeConfig;
import com.cym.ext.AsycPack;
import com.cym.ext.ConfExt;
import com.cym.ext.ConfFile;
import com.cym.model.Bak;
import com.cym.model.BakSub;
import com.cym.model.Basic;
import com.cym.model.Cert;
import com.cym.model.Http;
import com.cym.model.Location;
import com.cym.model.Param;
import com.cym.model.Password;
import com.cym.model.Server;
import com.cym.model.Stream;
import com.cym.model.Template;
import com.cym.model.Upstream;
import com.cym.model.UpstreamServer;
import com.cym.sqlhelper.bean.Sort;
import com.cym.sqlhelper.bean.Sort.Direction;
import com.cym.sqlhelper.utils.ConditionAndWrapper;
import com.cym.sqlhelper.utils.SqlHelper;
import com.cym.utils.ToolUtils;
import com.github.odiszapc.nginxparser.NgxBlock;
import com.github.odiszapc.nginxparser.NgxConfig;
import com.github.odiszapc.nginxparser.NgxDumper;
import com.github.odiszapc.nginxparser.NgxEntry;
import com.github.odiszapc.nginxparser.NgxParam;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
@Service
public class ConfService {
Logger logger = LoggerFactory.getLogger(this.getClass());
@Inject
UpstreamService upstreamService;
@Inject
SettingService settingService;
@Inject
ServerService serverService;
@Inject
LocationService locationService;
@Inject
ParamService paramService;
@Inject
SqlHelper sqlHelper;
@Inject
TemplateService templateService;
@Inject
OperateLogService operateLogService;
@Inject
HomeConfig homeConfig;
public synchronized ConfExt buildConf(Boolean decompose, Boolean check) {
ConfExt confExt = new ConfExt();
confExt.setFileList(new ArrayList<>());
String nginxPath = settingService.get("nginxPath");
if (check) {
nginxPath = homeConfig.home + "temp/nginx.conf";
}
try {
NgxConfig ngxConfig = new NgxConfig();
// 获取基本参数
List<Basic> basicList = sqlHelper.findAll(new Sort("seq", Direction.ASC), Basic.class);
for (Basic basic : basicList) {
NgxParam ngxParam = new NgxParam();
ngxParam.addValue(basic.getName().trim() + " " + basic.getValue().trim());
ngxConfig.addEntry(ngxParam);
}
// 获取http
List<Http> httpList = sqlHelper.findAll(new Sort("seq", Direction.ASC), Http.class);
boolean hasHttp = false;
NgxBlock ngxBlockHttp = new NgxBlock();
ngxBlockHttp.addValue("http");
for (Http http : httpList) {
NgxParam ngxParam = new NgxParam();
ngxParam.addValue(http.getName().trim() + " " + http.getValue().trim());
ngxBlockHttp.addEntry(ngxParam);
hasHttp = true;
}
// 添加upstream
NgxParam ngxParam;
List<Upstream> upstreams = upstreamService.getListByProxyType(0);
for (Upstream upstream : upstreams) {
NgxBlock ngxBlockServer = new NgxBlock();
ngxBlockServer.addValue("upstream " + upstream.getName().trim());
if (StrUtil.isNotEmpty(upstream.getDescr())) {
String[] descrs = upstream.getDescr().split("\n");
for (String d : descrs) {
ngxParam = new NgxParam();
ngxParam.addValue("# " + d);
ngxBlockServer.addEntry(ngxParam);
}
}
if (StrUtil.isNotEmpty(upstream.getTactics())) {
ngxParam = new NgxParam();
ngxParam.addValue(upstream.getTactics());
ngxBlockServer.addEntry(ngxParam);
}
List<UpstreamServer> upstreamServers = upstreamService.getUpstreamServers(upstream.getId());
for (UpstreamServer upstreamServer : upstreamServers) {
ngxParam = new NgxParam();
ngxParam.addValue("server " + buildNodeStr(upstreamServer));
ngxBlockServer.addEntry(ngxParam);
}
// 自定义参数
List<Param> paramList = paramService.getListByTypeId(upstream.getId(), "upstream");
for (Param param : paramList) {
setSameParam(param, ngxBlockServer);
}
hasHttp = true;
if (decompose) {
addConfFile(confExt, "upstreams." + upstream.getName() + ".conf", ngxBlockServer);
ngxParam = new NgxParam();
ngxParam.addValue("include " + new File(nginxPath).getParent().replace("\\", "/") + "/conf.d/upstreams." + upstream.getName().replace(" ", "_").replace("*", "-") + ".conf");
ngxBlockHttp.addEntry(ngxParam);
} else {
ngxBlockHttp.addEntry(ngxBlockServer);
}
}
// 添加server
List<Server> servers = serverService.getListByProxyType(new String[] { "0" });
for (Server server : servers) {
if (server.getEnable() == null || !server.getEnable()) {
continue;
}
NgxBlock ngxBlockServer = bulidBlockServer(server);
hasHttp = true;
// 是否需要分解
if (decompose) {
String name = "all";
if (StrUtil.isNotEmpty(server.getServerName())) {
name = server.getServerName();
}
addConfFile(confExt, name + ".conf", ngxBlockServer);
ngxParam = new NgxParam();
ngxParam.addValue("include " + new File(nginxPath).getParent().replace("\\", "/") + "/conf.d/" + name.replace(" ", "_").replace("*", "-") + ".conf");
if (noContain(ngxBlockHttp, ngxParam)) {
ngxBlockHttp.addEntry(ngxParam);
}
} else {
ngxBlockHttp.addEntry(ngxBlockServer);
}
}
if (hasHttp) {
ngxConfig.addEntry(ngxBlockHttp);
}
// TCP/UDP转发
// 创建stream
List<Stream> streamList = sqlHelper.findAll(new Sort("seq", Direction.ASC), Stream.class);
boolean hasStream = false;
NgxBlock ngxBlockStream = new NgxBlock();
ngxBlockStream.addValue("stream");
for (Stream stream : streamList) {
ngxParam = new NgxParam();
ngxParam.addValue(stream.getName() + " " + stream.getValue());
ngxBlockStream.addEntry(ngxParam);
hasStream = true;
}
// 添加upstream
upstreams = upstreamService.getListByProxyType(1);
for (Upstream upstream : upstreams) {
NgxBlock ngxBlockServer = buildBlockUpstream(upstream);
if (decompose) {
addConfFile(confExt, "upstreams." + upstream.getName() + ".conf", ngxBlockServer);
ngxParam = new NgxParam();
ngxParam.addValue("include " + new File(nginxPath).getParent().replace("\\", "/") + "/conf.d/upstreams." + upstream.getName().replace(" ", "_").replace("*", "-") + ".conf");
ngxBlockStream.addEntry(ngxParam);
} else {
ngxBlockStream.addEntry(ngxBlockServer);
}
hasStream = true;
}
// 添加server
servers = serverService.getListByProxyType(new String[] { "1", "2" });
for (Server server : servers) {
if (server.getEnable() == null || !server.getEnable()) {
continue;
}
NgxBlock ngxBlockServer = bulidBlockServer(server);
if (decompose) {
String type = "";
if (server.getProxyType() == 0) {
type = "http";
} else if (server.getProxyType() == 1) {
type = "tcp";
} else if (server.getProxyType() == 2) {
type = "udp";
}
addConfFile(confExt, type + "." + server.getListen() + ".conf", ngxBlockServer);
ngxParam = new NgxParam();
ngxParam.addValue("include " + new File(nginxPath).getParent().replace("\\", "/") + "/conf.d/" + type + "." + server.getListen() + ".conf");
ngxBlockStream.addEntry(ngxParam);
} else {
ngxBlockStream.addEntry(ngxBlockServer);
}
hasStream = true;
}
if (hasStream) {
ngxConfig.addEntry(ngxBlockStream);
}
String conf = ToolUtils.handleConf(new NgxDumper(ngxConfig).dump());
confExt.setConf(conf);
return confExt;
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
public NgxBlock buildBlockUpstream(Upstream upstream) {
NgxParam ngxParam = null;
NgxBlock ngxBlockServer = new NgxBlock();
ngxBlockServer.addValue("upstream " + upstream.getName());
if (StrUtil.isNo